Changeset 74 for trunk


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
Location:
trunk/src/os2ahci
Files:
5 edited

Legend:

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

    r73 r74  
    408408  AHCI_PORT_CFG *pc = NULL;
    409409  u16 *id_buf;
     410  int is_ata;
    410411  int rc;
    411412  int p;
     413  int i;
    412414
    413415  spin_lock(drv_lock);
     
    453455      }
    454456
    455       /* this port has a device attached and is ready to accept commands */
     457      /* this port seems to have a device attached and ready for commands */
    456458      ddprintf("port #%d seems to be attached to a device; probing...\n", p);
    457       rc = ahci_exec_polled_cmd(ai, p, 0, 500, ATA_CMD_ID_ATA,
    458                                 AP_VADDR, (void _far *) id_buf, 512,
    459                                 AP_END);
    460       if (rc != 0 || id_buf[ATA_ID_CONFIG] & (1U << 15)) {
    461         /* this might be an ATAPI device; run IDENTIFY_PACKET_DEVICE */
    462         rc = ahci_exec_polled_cmd(ai, p, 0, 500, ATA_CMD_ID_ATAPI,
     459
     460      /* Get ATA(PI) identity. The so-called signature gives us a hint whether
     461       * this is an ATA or an ATAPI device but we'll try both in either case;
     462       * the signature will merely determine whether we're going to probe for
     463       * an ATA or ATAPI device, first, in order to reduce the chance of sending
     464       * the wrong command (which would result in a port reset given the way
     465       * ahci_exec_polled_cmd() was implemented).
     466       */
     467      is_ata = readl(port_base(ai, p) + PORT_SIG) == 0x00000101UL;
     468      for (i = 0; i < 2; i++) {
     469        rc = ahci_exec_polled_cmd(ai, p, 0, 500,
     470                                  (is_ata) ? ATA_CMD_ID_ATA : ATA_CMD_ID_ATAPI,
    463471                                  AP_VADDR, (void _far *) id_buf, 512,
    464472                                  AP_END);
     473        if (rc == 0) {
     474          break;
     475        }
     476
     477        /* try again with ATA/ATAPI swapped */
     478        is_ata = !is_ata;
    465479      }
    466480
    467481      if (rc == 0) {
    468482        /* we have a valid IDENTIFY or IDENTIFY_PACKET response */
    469         ddphex(id_buf, 512, "ATA_IDENTIFY(_PACKET) results:\n");
     483        ddphex(id_buf, 512, "ATA_IDENTIFY%s results:\n", (is_ata) ? "" : "_PACKET");
    470484        ahci_setup_device(ai, p, 0, id_buf);
    471485      } else {
     
    13991413  int d = iorb_unit_device(iorb);
    14001414
     1415  dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd,
     1416        ((IORB_ADAPTER_PASSTHRU _far *) iorb)->ControllerCmdLen,
     1417        "ahci_execute_cdb(%d.%d.%d): ", a, p, d);
     1418
    14011419  if (ad_infos[a].ports[p].devs[d].atapi) {
    14021420    ahci_exec_iorb(iorb, 0, atapi_execute_cdb);
     
    14181436  dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd,
    14191437        ((IORB_ADAPTER_PASSTHRU _far *) iorb)->ControllerCmdLen,
    1420         "ahci_execute_cdb(%d.%d.%d)", a, p, d);
     1438        "ahci_execute_cdb(%d.%d.%d): ", a, p, d);
    14211439
    14221440  if (ad_infos[a].ports[p].devs[d].atapi) {
     
    14611479    ai->ports[p].devs[d].atapi_16  = (id_buf[ATA_ID_CONFIG] & 0x0001U) != 0;
    14621480    ai->ports[p].devs[d].dev_type  = (id_buf[ATA_ID_CONFIG] & 0x1f00U) >> 8;
     1481    ai->ports[p].devs[d].ncq_max   = 1;
    14631482
    14641483  } else {
  • 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
  • trunk/src/os2ahci/ctxhook.c

    r69 r74  
    143143        /* sanity check: issued command bitmaps should be 0 now */
    144144        if (ai->ports[p].ncq_cmds != 0 || ai->ports[p].reg_cmds != 0) {
    145           dprintf("warning: commands issued not 0 (%08lx/%08lx)\n",
     145          dprintf("warning: commands issued not 0 (%08lx/%08lx); resetting...\n",
    146146                  ai->ports[p].ncq_cmds, ai->ports[p].reg_cmds);
     147          need_reset = 1;
    147148        }
    148149
  • trunk/src/os2ahci/init.asm

    r69 r74  
    5151
    5252_DATA           SEGMENT WORD PUBLIC 'DATA'
    53 readl_dbg_fmt   db      "readl(%04x:%04x) = 0x%08lx [addr %% 0x80 = 0x%02x]"
     53readl_dbg_fmt   db      "readl(%04x:%04x) = 0x%08lx"
    5454                db      10, 0
    55 writel_dbg_fmt  db      "writel(%04x:%04x, 0x%08lx) [addr %% 0x80 = 0x%02x]"
     55writel_dbg_fmt  db      "writel(%04x:%04x, 0x%08lx)"
    5656                db      10, 0
    5757_DATA           ENDS
     
    143143                JB      no_debug
    144144                PUSH    EDX             ; save value read from MMIO port
    145                 MOV     BX, AX          ; addr & 0x7f (port reg index)
    146                 AND     BX, 7FH
    147                 PUSH    BX
    148145                PUSH    EDX             ; value read from MMIO address
    149146                PUSH    AX              ; offset of MMIO address
     
    187184                CMP     _debug, 3
    188185                JB      no_debug2
    189                 MOV     BX, AX          ; addr & 0x7f (port reg index)
    190                 AND     BX, 7FH
    191                 PUSH    BX
    192186                PUSH    EDX             ; value written to MMIO address
    193187                PUSH    AX              ; offset of MMIO address
  • trunk/src/os2ahci/version.h

    r27 r74  
    66
    77
    8 #define VERSION            100       /* driver version (2 implied decimals) */
     8#define VERSION            101       /* driver version (2 implied decimals) */
    99
    1010/* BLDLEVEL information (in C source modules added via macro
Note: See TracChangeset for help on using the changeset viewer.