Changeset 60


Ignore:
Timestamp:
Dec 16, 2010, 3:54:53 PM (15 years ago)
Author:
markus
Message:

added atapi_ calls; untested

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/os2ahci/ata.c

    r59 r60  
    627627
    628628  io->BlocksXferred += add_workspace(iorb)->blocks;
    629   ddprintf("ata_read_pp(): blocks transferred = %d\n", (int) io->BlocksXferred);
     629  ddprintf("ata(pi)_read_pp(): blocks transferred = %d\n", (int) io->BlocksXferred);
    630630
    631631  if (io->BlocksXferred >= io->BlockCount) {
  • trunk/src/os2ahci/atapi.c

    r39 r60  
    2323#include "os2ahci.h"
    2424#include "ata.h"
     25#include "atapi.h"
    2526
    2627/* -------------------------- macros and constants ------------------------- */
     
    2930
    3031/* -------------------------- function prototypes -------------------------- */
     32
     33static void atapi_req_sense_pp      (IORBH _far *iorb);
     34static void atapi_execute_cdb_pp    (IORBH _far *iorb);
     35
    3136
    3237/* ------------------------ global/static variables ------------------------ */
     
    4954int atapi_unit_ready(IORBH _far *iorb, int slot)
    5055{
     56  dprintf("atapi_unit_ready called\n");
    5157  iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED);
    5258  return(-1);
     
    5864int atapi_read(IORBH _far *iorb, int slot)
    5965{
    60   iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED);
    61   return(-1);
    62 
     66  IORB_EXECUTEIO _far *io = (IORB_EXECUTEIO _far *) iorb;
     67  ATAPI_CDB_12 cdb;
     68  AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb);
     69  USHORT count = io->BlockCount - io->BlocksXferred;
     70  USHORT sg_indx;
     71  USHORT sg_cnt;
     72  int p = iorb_unit_port(iorb);
     73  int d = iorb_unit_device(iorb);
     74  int rc;
     75
     76  /* translate read command to SCSI/ATAPI READ12 command.
     77   * READ12 seems to be the most supported READ variant - according to MMC,
     78   * and its enough even for BluRay.
     79   */
     80  memset(&cdb, 0x00, sizeof(cdb));
     81  cdb.cmd = ATAPI_CMD_READ_12;
     82  SET_CDB_32(cdb.lba, io->RBA + io->BlocksXferred);
     83
     84  do {
     85    /* update sector count (might have been updated due to S/G limitations) */
     86    SET_CDB_32(cdb.trans_len, (u32) count);
     87
     88    /* update S/G count and index */
     89    sg_indx = ata_get_sg_indx(io);
     90    sg_cnt = io->cSGList - sg_indx;
     91
     92    /* issue command */
     93    rc = ata_cmd(ai, p, d, slot, ATA_CMD_PACKET,
     94                 AP_ATAPI_CMD, (void _far *) &cdb, sizeof(cdb),
     95                 AP_SGLIST,    io->pSGList + sg_indx, (u16) sg_cnt,
     96                 AP_DEVICE,    0x4000,
     97                 AP_END);
     98
     99    if (rc > 0) {
     100      /* couldn't map all S/G elements */
     101      ata_max_sg_cnt(io, sg_indx, (USHORT) rc, &sg_cnt, &count);
     102    }
     103  } while (rc > 0 && sg_cnt > 0);
     104   
     105  if (rc == 0) {
     106    add_workspace(iorb)->blocks = count;
     107    add_workspace(iorb)->ppfunc = ata_read_pp;
     108
     109  } else if (rc > 0) {
     110    iorb_seterr(iorb, IOERR_CMD_SGLIST_BAD);
     111
     112  } else {
     113    iorb_seterr(iorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
     114  }
     115
     116  return(rc);
     117}
    63118
    64119/******************************************************************************
     
    67122int atapi_verify(IORBH _far *iorb, int slot)
    68123{
     124  dprintf("atapi_verify called\n");
    69125  iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED);
    70126  return(-1);
     
    76132int atapi_write(IORBH _far *iorb, int slot)
    77133{
     134  dprintf("atapi_write called\n");
    78135  iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED);
    79136  return(-1);
     
    85142int atapi_execute_cdb(IORBH _far *iorb, int slot)
    86143{
    87   iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED);
    88   return(-1);
     144  IORB_ADAPTER_PASSTHRU _far *pt = (IORB_ADAPTER_PASSTHRU _far *) iorb;
     145  int rc;
     146
     147  /* we do not perform the S/G limitation recovery loop here:
     148   * "ADDs are not required to iterate commands through the CDB PassThru
     149   * mechanism:" -- Storage Device Driver Reference, Scatter/Gather Lists
     150   */
     151  rc = ata_cmd(ad_infos + iorb_unit_adapter(iorb),
     152               iorb_unit_port(iorb),
     153               iorb_unit_device(iorb),
     154               slot, ATA_CMD_PACKET,
     155               AP_ATAPI_CMD, (void _far *) pt->pControllerCmd,
     156                             pt->ControllerCmdLen,
     157               AP_SGLIST,    pt->pSGList, pt->cSGList,
     158               AP_END);
     159
     160  if (rc == 0) {
     161    add_workspace(iorb)->blocks = pt->cSGList;
     162    add_workspace(iorb)->ppfunc = atapi_execute_cdb_pp;
     163
     164  } else if (rc > 0) {
     165    iorb_seterr(iorb, IOERR_CMD_SGLIST_BAD);
     166
     167  } else {
     168    iorb_seterr(iorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
     169  }
     170 
     171  return(rc);
     172}
     173
     174/******************************************************************************
     175 * Post processing function for atapi_execute_cdb(); since we have no
     176 * knowledge of the command itself, we just tell the IRQ handler that
     177 * we're done.
     178 */
     179static void atapi_execute_cdb_pp(IORBH _far *iorb)
     180{
     181  add_workspace(iorb)->complete = 1;
    89182}
    90183
     
    100193int atapi_req_sense(IORBH _far *iorb, int slot)
    101194{
    102   iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED);
    103   return(-1);
    104 }
    105 
     195  ADD_WORKSPACE _far *aws = add_workspace(iorb);
     196  ATAPI_CDB_REQ_SENSE cdb;
     197  int rc;
     198 
     199  /* allocate sense buffer in ADD workspace */
     200  aws->buf = malloc(ATAPI_SENSE_LEN);
     201  if (aws->buf == NULL) {
     202    iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE);
     203    return(-1);
     204  }
     205  memset(aws->buf, 0x00, ATAPI_SENSE_LEN);
     206
     207  /* prepare request sense command */
     208  memset(&cdb, 0x00, sizeof(cdb));
     209  cdb.cmd = ATAPI_CMD_REQUEST_SENSE;
     210  aws->ppfunc = atapi_req_sense_pp;
     211  rc = ata_cmd(ad_infos + iorb_unit_adapter(iorb),
     212               iorb_unit_port(iorb),
     213               iorb_unit_device(iorb),
     214               slot,
     215               ATA_CMD_PACKET,
     216               AP_ATAPI_CMD, (void _far*) &cdb, sizeof(cdb),
     217               AP_VADDR, (void _far *) aws->buf, ATAPI_SENSE_LEN,
     218               AP_END);
     219
     220  if (rc > 0) {
     221    /* should never happen - we got 64 bytes here */
     222    iorb_seterr(iorb, IOERR_CMD_SGLIST_BAD);
     223
     224  } else {
     225    /* we failed to get info about an error -> return
     226     * non specific device error
     227     */
     228    iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC);
     229  }
     230
     231  return(rc);
     232}
     233
     234/******************************************************************************
     235 * Post processing function for ATAPI request sense; examines the sense
     236 * data returned and maps sense info to IORB error info.
     237 */
     238static void atapi_req_sense_pp(IORBH _far *iorb)
     239{
     240  ADD_WORKSPACE _far *aws = add_workspace(iorb);
     241  ATAPI_SENSE_DATA *psd = (ATAPI_SENSE_DATA *) aws->buf;
     242
     243  /* map sense data to some IOERR_ value */
     244  switch (ATAPI_GET_SENSE(psd)) {
     245
     246  case ASENSE_NO_SENSE:
     247  case ASENSE_RECOVERED_ERROR:
     248    /* no error */
     249    break;
     250
     251  case ASENSE_NOT_READY:
     252    iorb_seterr(iorb, IOERR_UNIT_NOT_READY);
     253    break;
     254
     255  case ASENSE_UNIT_ATTENTION:
     256    iorb_seterr(iorb, IOERR_MEDIA_CHANGED);
     257    break;
     258
     259  case ASENSE_MEDIUM_ERROR:
     260    iorb_seterr(iorb, IOERR_MEDIA);
     261    break;
     262
     263  case ASENSE_ILLEGAL_REQUEST:
     264    iorb_seterr(iorb, IOERR_CMD_SYNTAX);
     265    break;
     266
     267  case ASENSE_DATA_PROTECT:
     268    iorb_seterr(iorb, IOERR_MEDIA_WRITE_PROTECT);
     269    break;
     270
     271  case ASENSE_BLANK_CHECK:
     272    iorb_seterr(iorb, IOERR_MEDIA_NOT_FORMATTED);
     273    break;
     274
     275  case ASENSE_ABORTED_COMMAND:
     276  case ASENSE_COPY_ABORTED:
     277    iorb_seterr(iorb, IOERR_CMD_ABORTED);
     278    break;
     279 
     280  default:
     281    iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC);
     282    break;
     283  }
     284
     285  /* free sense buffer */
     286  aws_free(aws);
     287
     288}
  • trunk/src/os2ahci/atapi.h

    r13 r60  
    22 * atapi.h - ATAPI structures and macros for os2ahci driver
    33 *
    4  * Copyright (c) 2010 Christian Mueller. Parts copied from/inspired by the
    5  * Linux AHCI driver; those parts are (c) Linux AHCI/ATA maintainers
     4 * Copyright (c) 2010 Christian Mueller, Markus Thielen.
     5 * Parts copied from/inspired by the  Linux AHCI driver;
     6 * those parts are (c) Linux AHCI/ATA maintainers
    67 *
    78 *  This program is free software; you can redistribute it and/or modify
     
    2223/* -------------------------- macros and constants ------------------------- */
    2324
     25/******************************************************************************
     26 * macros to fill in ATAPI CDB values
     27 */
     28#define SET_CDB_16(_t, _v)  (_t)[0] = (u8) ((_v) >> 8);       \
     29                            (_t)[1] = (u8)  (_v)
     30#define SET_CDB_24(_t, _v)  (_t)[0] = (u8) ((_v) >> 16);      \
     31                            (_t)[1] = (u8) ((_v) >> 8);       \
     32                            (_t)[2] = (u8)  (_v)
     33#define SET_CDB_32(_t, _v)  (_t)[0] = (u8) ((_v) >> 24);      \
     34                            (_t)[1] = (u8) ((_v) >> 16);      \
     35                            (_t)[2] = (u8) ((_v) >> 8);       \
     36                            (_t)[3] = (u8)  (_v)
     37
     38#define GET_CDB_16(_f)      ((u16) (_f)[0] << 8  |            \
     39                             (u16) (_f)[1])
     40#define GET_CDB_24(_f)      ((u32) (_f)[0] << 16 |            \
     41                             (u32) (_f)[1] << 8   |           \
     42                             (u32) (_f)[2])
     43#define GET_CDB_32(_f)      ((u32) (_f)[0] << 24  |           \
     44                             (u32) (_f)[1] << 16  |           \
     45                             (u32) (_f)[2] << 24  |           \
     46                             (u32) (_f)[3])
     47
     48
     49/******************************************************************************
     50 * ATAPI/MMC command codes (as far as relevant for us)
     51 */
     52#define ATAPI_CMD_READ_6           0x08
     53#define ATAPI_CMD_READ_10          0x28
     54#define ATAPI_CMD_READ_12          0xa8
     55#define ATAPI_CMD_READ_16          0x88
     56#define ATAPI_CMD_WRITE_6          0x0a
     57#define ATAPI_CMD_WRITE_10         0x2a
     58#define ATAPI_CMD_WRITE_12         0xaa
     59#define ATAPI_CMD_WRITE_16         0x8a
     60#define ATAPI_CMD_REQUEST_SENSE    0x03
     61
     62/******************************************************************************
     63 * ATAPI command flag bits
     64 */
     65#define ATAPI_FLAG_FUA             0x80
     66#define ATAPI_FLAG_DPO             0x10
     67
     68/******************************************************************************
     69 * ATAPI sense data
     70 */
     71#define ATAPI_SENSE_LEN            64
     72
     73#define ASENSE_NO_SENSE            0x00  /* no sense -> success */
     74#define ASENSE_RECOVERED_ERROR     0x01  /* recovered error -> success */
     75#define ASENSE_NOT_READY           0x02  /* device not ready */
     76#define ASENSE_MEDIUM_ERROR        0x03  /* medium/CRC error */
     77#define ASENSE_HARDWARE_ERROR      0x04  /* device error */
     78#define ASENSE_ILLEGAL_REQUEST     0x05  /* invalid command/parameters issued */
     79#define ASENSE_UNIT_ATTENTION      0x06  /* new medium */
     80#define ASENSE_DATA_PROTECT        0x07  /* protected LBA */
     81#define ASENSE_BLANK_CHECK         0x08  /* unformatted or write protected */
     82#define ASENSE_VENDOR_SPECIFIC     0x09  /* vendor specific sense data */
     83#define ASENSE_COPY_ABORTED        0x0a  /* copy, ...command aborted */
     84#define ASENSE_ABORTED_COMMAND     0x0b  /* command has been aborted */
     85#define ASENSE_EQUAL               0x0c
     86#define ASENSE_VOLUME_OVERFLOW     0x0d  /* out of space */
     87#define ASENSE_MISCOMPARE          0x0e  /* verification failed */
     88#define ASENSE_RESERVED            0x0f
     89
     90/******************************************************************************
     91 * macro to get sense key from ATAPI_SENSE_DATA pointer
     92 */
     93#define ATAPI_GET_SENSE(p_) (u8)(p_->sense.sense_key & 0x0f)
     94
    2495/* ------------------------ typedefs and structures ------------------------ */
     96
     97/******************************************************************************
     98 * ATAPI_SENSE_DATA - define layout of ATAPI sense data
     99 */
     100typedef union _ATAPI_SENSE_DATA {
     101  struct {
     102    u8 valid_respc;      /* valid bit (bit 7), response code (bits 6:0) */
     103    u8 segment;          /* segment number (obsolete) */
     104    u8 sense_key;        /* some flags (bits 7:4), sense key (bits 3:0) */
     105    u8 info[4];          /* information (?) */
     106    u8 adl_len;          /* additional sense info length */
     107    u8 cmd_specific[4];  /* command specific stuff (ignored) */
     108    u8 asc;              /* additional sense code */
     109    u8 ascq;             /* additional sense code qualifier */
     110    u8 fruc;             /* field replaceable unit code */
     111    u8 flags;            /* vendor-specific flags */
     112    u8 field_off[2];     /* offset to invalid field in parm list */
     113  } sense;
     114
     115  u8 padding[ATAPI_SENSE_LEN]; /* pad to 64 bytes */
     116
     117} ATAPI_SENSE_DATA;
     118
     119/******************************************************************************
     120 * ATAPI_CDB_10 - describes layout of generic 10 byte ATAPI command
     121 */
     122typedef struct _ATAPI_CMD_10 {
     123  u8   cmd;            /* SCSI/ATAPI command code */
     124  u8   flags;          /* flags (DPO, FUA) */
     125  u8   lba[4];         /* logical block address */
     126  u8   trans_len[2];   /* number of blocks to transfer */
     127  u8   control;        /* (nothing much) */
     128} ATAPI_CDB_10;
     129
     130/******************************************************************************
     131 * ATAPI_CDB_12 - describes layout of generic 12 byte ATAPI command
     132 */
     133typedef struct _ATAPI_CMD_12 {
     134  u8   cmd;            /* SCSI/ATAPI command code */
     135  u8   flags;          /* flags (DPO, FUA) */
     136  u8   lba[4];         /* logical block address */
     137  u8   trans_len[4];   /* number of blocks to transfer */
     138  u8   reserved;
     139  u8   control;        /* (nothing much) */
     140} ATAPI_CDB_12;
     141
     142/******************************************************************************Ü
     143 * ATAPI_CDB_REQ_SENSE - describes request sense command
     144 */
     145typedef struct _ATAPI_CMD_REQ_SENSE {
     146  u8   cmd;            /* command code (0x03) */
     147  u8   lun:3;          /* SCSI lun (ignored) */
     148  u8   resvd:5;
     149  u8   buffer_len;     /* sense buffer length */
     150  u8   control;
     151} ATAPI_CDB_REQ_SENSE;
     152
    25153
    26154/* ---------------------------- global variables --------------------------- */
  • trunk/src/os2ahci/os2ahci.def

    r58 r60  
    11library os2ahci
    2 Description '$@#thi.guten (www.thiguten.de):1.00.20101215#@OS/2 AHCI Adapter Device Driver'
     2Description '$@#thi.guten (www.thiguten.de):1.00.20101216#@OS/2 AHCI Adapter Device Driver'
    33protmode
    44
  • trunk/tools/bldlvl.cmd

    r39 r60  
    267267    Return 0
    268268
     269
Note: See TracChangeset for help on using the changeset viewer.