Ignore:
Timestamp:
Feb 16, 2011, 3:39:48 AM (14 years ago)
Author:
chris
Message:
  • ATAPI fixes; still having trouble with INQUIRY command bein sent with incorrect direction
  • fixes to port reset and restart handling
  • improved ATA IDENTIFY handling based on ATA reset signature
File:
1 edited

Legend:

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

    r71 r74  
    2424#include "ata.h"
    2525#include "atapi.h"
     26
     27/* need this for the SCSI status block */
     28#include <scsi.h>
    2629
    2730/* -------------------------- macros and constants ------------------------- */
     
    147150  u8 cdb[ATAPI_MAX_CDB_LEN];
    148151  u16 cdb_len;
     152  int old_debug;
    149153
    150154  if (pt->ControllerCmdLen > ATAPI_MAX_CDB_LEN) {
     
    155159  atapi_pad_cdb(pt->pControllerCmd, pt->ControllerCmdLen,
    156160                (u8 _far *) cdb, (u16 _far *) &cdb_len);
     161
     162  if (cdb[0] == 0x12) {
     163    /* Some buggy entity asks for a SCSI INQUIRY command during boot without
     164     * the flag PT_DIRECTION_IN which causes a timeout and port reset. The
     165     * easiest way around this is to hack the flag PT_DIRECTION_IN into the
     166     * request because SCSI INQUIRY commands are always device -> host.
     167     */
     168    pt->Flags |= PT_DIRECTION_IN;
     169    old_debug = debug;
     170    debug = 2;
     171  }
    157172
    158173  /* we do not perform the S/G limitation recovery loop here:
     
    175190  }
    176191 
     192  if (cdb[0] == 0x12) {
     193    debug = old_debug;
     194  }
     195
    177196  return(rc);
    178197}
     
    190209int atapi_req_sense(IORBH _far *iorb, int slot)
    191210{
     211  SCSI_STATUS_BLOCK _far *ssb;
    192212  ADD_WORKSPACE _far *aws = add_workspace(iorb);
    193213  int rc;
    194214  u8 cdb[ATAPI_MIN_CDB_LEN];
    195215  ATAPI_CDB_6 _far *pcdb = (ATAPI_CDB_6 _far *) cdb;
    196  
     216
     217  if ((iorb->RequestControl & IORB_REQ_STATUSBLOCK) &&
     218      iorb->StatusBlockLen >= sizeof(*ssb) && iorb->pStatusBlock != 0) {
     219
     220    /* don't request sense data if caller asked us not to; the flag
     221     * STATUS_DISABLE_REQEST_SENSE is not defined in the old DDK we've been
     222     * using so we'll use the hard-coded value (0x0008) */
     223    ssb = (SCSI_STATUS_BLOCK _far *) (((u32) iorb & 0xffff0000U) +
     224                                       (u16) iorb->pStatusBlock);
     225    if (ssb->Flags & 0x0008U) {
     226      /* set a generic error code and skip automatic sense code handling */
     227      iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC);
     228      return(-1);
     229    }
     230  }
     231
    197232  /* allocate sense buffer in ADD workspace */
    198   aws->buf = malloc(ATAPI_SENSE_LEN);
    199   if (aws->buf == NULL) {
     233  if ((aws->buf = malloc(ATAPI_SENSE_LEN)) == NULL) {
    200234    iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE);
    201235    return(-1);
     
    238272static void atapi_req_sense_pp(IORBH _far *iorb)
    239273{
     274  SCSI_STATUS_BLOCK _far *ssb;
    240275  ADD_WORKSPACE _far *aws = add_workspace(iorb);
    241276  ATAPI_SENSE_DATA *psd = (ATAPI_SENSE_DATA *) aws->buf;
    242277
    243   dphex(psd, sizeof(psd), "sense buffer:\n");
     278  dphex(psd, sizeof(*psd), "sense buffer:\n");
     279
     280  if ((iorb->RequestControl & IORB_REQ_STATUSBLOCK) &&
     281      iorb->StatusBlockLen >= sizeof(*ssb) && iorb->pStatusBlock != 0) {
     282
     283    /* copy sense data to IORB */
     284    ssb = (SCSI_STATUS_BLOCK _far *) (((u32) iorb & 0xffff0000U) +
     285                                       (u16) iorb->pStatusBlock);
     286    ssb->AdapterErrorCode = 0;
     287    ssb->TargetStatus = SCSI_STAT_CHECKCOND;
     288    ssb->ResidualLength = 0;
     289    memset(ssb->AdapterDiagInfo, 0x00, sizeof(ssb->AdapterDiagInfo));
     290
     291    if (ssb->SenseData != NULL) {
     292      memcpy(ssb->SenseData, psd, max(ssb->ReqSenseLen, ATAPI_SENSE_LEN));
     293      ssb->Flags != STATUS_SENSEDATA_VALID;
     294    }
     295  }
    244296
    245297  /* map sense data to some IOERR_ value */
     
    248300  case ASENSE_NO_SENSE:
    249301  case ASENSE_RECOVERED_ERROR:
    250     /* no error */
     302    /* no error; this shouldn't happen because we'll only call
     303     * atapi_req_sense() if we received an error interrupt */
     304    iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC);
    251305    break;
    252306
Note: See TracChangeset for help on using the changeset viewer.