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

added atapi_ calls; untested

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.