Ignore:
Timestamp:
Sep 14, 2010, 10:07:59 AM (15 years ago)
Author:
root
Message:

latest NCQ changes from Christian

Location:
trunk/src/os2ahci
Files:
1 added
1 moved

Legend:

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

    r12 r13  
    171171        if (val & HOST_CAP_EMS)        printf(" ems");
    172172        if (val & HOST_CAP_SXS)        printf(" sxs");
    173         printf(" ports:%d", (val & 0x1f) + 1);
     173        printf(" cmd_slots:%d", (u16) ((val >> 8) & 0x1f) + 1);
     174        printf(" ports:%d",     (u16) (val & 0x1f) + 1);
    174175
    175176      } else if (i == HOST_CTL) {
     
    829830  ULONG timeout = (iorb->Timeout > 0) ? iorb->Timeout : DEFAULT_TIMEOUT;
    830831  u8 _far *port_mmio = port_base(ai, iorb_unit_port(iorb));
     832  u16 cmd_max = ai->cmd_max;
    831833  int i;
    832834
    833835  /* determine whether this will be an NCQ request */
    834   aws->is_ncq = ((ai->cap & HOST_CAP_NCQ) && ncq_capable && !aws->no_ncq);
    835 
    836   /* NCQ disabled temporarily until non-NCQ commands are fully working */
    837836  aws->is_ncq = 0;
    838 
    839   /* check whether adapter is available */
     837  if (ncq_capable && port->devs[iorb_unit_device(iorb)].ncq_max > 1 &&
     838      (ai->cap & HOST_CAP_NCQ) && !aws->no_ncq && init_complete) {
     839
     840    /* We can make this an NCQ request; limit command slots to the maximum
     841     * NCQ tag number reported by the device - 1. Why "minus one"? I seem to
     842     * recall an issue related to using all 32 tag numbers but can't quite
     843     * pinpoint it right now. One less won't make much of a difference...
     844     */
     845    aws->is_ncq = 1;
     846    if ((cmd_max = port->devs[iorb_unit_device(iorb)].ncq_max - 1) > ai->cmd_max) {
     847      cmd_max = ai->cmd_max;
     848    }
     849    ddprintf("NCQ command; cmd_max = %d->%d\n", (u16) ai->cmd_max, cmd_max);
     850  }
     851
     852  /* make sure adapter is available */
    840853  spin_lock(drv_lock);
    841854  if (!ai->busy) {
     
    849862    }
    850863
    851     /* prevent NCQ/regular command mix */
    852     if (aws->is_ncq && port->reg_cmds == 0 ||
    853         !aws->is_ncq && port->ncq_cmds == 0) {
     864    /* make sure we don't mix NCQ and regular commands */
     865    if (aws->is_ncq && port->reg_cmds == 0 || !aws->is_ncq && port->ncq_cmds == 0) {
    854866
    855867      /* Find next available command slot. We use a simple round-robin
     
    858870       */
    859871      cmds = (aws->is_ncq) ? &port->ncq_cmds : &port->reg_cmds;
    860       for (i = 0; i <= ai->cmd_max; i++) {
     872      for (i = 0; i <= cmd_max; i++) {
     873        if (++(port->cmd_slot) > cmd_max) {
     874          port->cmd_slot = 0;
     875        }
    861876        if ((*cmds & (1UL << port->cmd_slot)) == 0) {
    862877          break;
    863         }
    864         if (++(port->cmd_slot) > ai->cmd_max) {
    865           port->cmd_slot = 0;
    866878        }
    867879      }
     
    895907        readl(port_mmio + PORT_CMD_ISSUE); /* flush */
    896908
    897         /* make sure next cmd won't use the same slot to prevent starvation */
    898         if (++(port->cmd_slot) > ai->cmd_max) {
    899           port->cmd_slot = 0;
    900         }
    901909        spin_unlock(drv_lock);
    902910        return;
     
    916924 *
    917925 *  - We need to restore the BIOS configuration after we're done with this
    918  *    command because someone might still call int 13 routines; sending
     926 *    command because someone might still call int 13h routines; sending
    919927 *    asynchronous commands and waiting for interrupts to indicate completion
    920928 *    won't work in such a scenario.
     
    12261234  u8 _far *port_mmio = port_base(ai, p);
    12271235  int reset_port = 0;
     1236  u32 tmp;
    12281237
    12291238  /* Handle adapter and interface errors. Those typically require a port
     
    13361345  dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd,
    13371346        ((IORB_ADAPTER_PASSTHRU _far *) iorb)->ControllerCmdLen,
    1338         "ahci_execute_cdb(%d.%d.%d)", (int) iorb_unit_adapter(iorb),
    1339         (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb));
     1347        "ahci_execute_cdb(%d.%d.%d)", a, p, d);
    13401348 
    13411349  if (ad_infos[a].ports[p].devs[d].atapi) {
     
    13581366  dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd,
    13591367        ((IORB_ADAPTER_PASSTHRU _far *) iorb)->ControllerCmdLen,
    1360         "ahci_execute_cdb(%d.%d.%d)", (int) iorb_unit_adapter(iorb),
    1361         (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb));
     1368        "ahci_execute_cdb(%d.%d.%d)", a, p, d);
    13621369 
    13631370  if (ad_infos[a].ports[p].devs[d].atapi) {
     
    14031410  } else {
    14041411    /* complete ATA-specific device information */
    1405     ai->ports[p].devs[d].ncq_max   = id_buf[ATA_ID_QUEUE_DEPTH] & 0x001fU;
    1406     if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x40) {
     1412    if (!disable_ncq[ad_no(ai)][p]) {
     1413      ai->ports[p].devs[d].ncq_max = id_buf[ATA_ID_QUEUE_DEPTH] & 0x001fU;
     1414    }
     1415    if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x0400U) {
    14071416      ai->ports[p].devs[d].lba48   = 1;
    14081417    }
Note: See TracChangeset for help on using the changeset viewer.