Changeset 8 for trunk/src/ahci.c


Ignore:
Timestamp:
Sep 10, 2010, 11:30:39 AM (15 years ago)
Author:
markus
Message:

latest changes by Christian

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/ahci.c

    r4 r8  
    3737/* -------------------------- function prototypes -------------------------- */
    3838
    39 static int  exec_polled_cmd       (AD_INFO *ai, int p, int d, int timeout,
    40                                    int cmd, ...);
    4139static void ahci_setup_device     (AD_INFO *ai, int p, int d, u16 *id_buf);
    4240static void _far timeout_callback (ULONG timer_handle, ULONG p1, ULONG p2);
     
    265263
    266264  /* set maximum command slot number */
    267   ai->cmd_max = (u16) ((ai->cap >> 8) & 31);
     265  ai->cmd_max = (u16) ((ai->cap >> 8) & 0x1f);
    268266
    269267  return(0);
     
    404402 *  - This function is expected to be called with the spinlock released but
    405403 *    the corresponding adapter's busy flag set. It will aquire the spinlock
    406  *    temporarily to allocate/free memory for ATA identify buffer.
     404 *    temporarily to allocate/free memory for the ATA identify buffer.
    407405 */
    408406int ahci_scan_ports(AD_INFO *ai)
     
    457455      /* this port has a device attached and is ready to accept commands */
    458456      ddprintf("port #%d seems to be attached to a device; probing...\n", p);
    459       rc = exec_polled_cmd(ai, p, 0, 500, ATA_CMD_ID_ATA,
    460                            AP_VADDR, (void _far *) id_buf, 512,
    461                            AP_END);
     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);
    462460
    463461      if (rc != 0 || id_buf[ATA_ID_CONFIG] & (1U << 15)) {
    464462        /* this might be an ATAPI device; run IDENTIFY_PACKET_DEVICE */
    465         rc = exec_polled_cmd(ai, p, 0, 500, ATA_CMD_ID_ATAPI,
    466                              AP_VADDR, (void _far *) id_buf, 512,
    467                              AP_END);
     463        rc = ahci_exec_polled_cmd(ai, p, 0, 500, ATA_CMD_ID_ATAPI,
     464                                  AP_VADDR, (void _far *) id_buf, 512,
     465                                  AP_END);
    468466      }
    469467
     
    826824{
    827825  volatile u32 *cmds;
     826  ADD_WORKSPACE _far *aws = add_workspace(iorb);
    828827  AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb);
    829828  P_INFO *port = ai->ports + iorb_unit_port(iorb);
    830829  ULONG timeout = (iorb->Timeout > 0) ? iorb->Timeout : DEFAULT_TIMEOUT;
    831830  u8 _far *port_mmio = port_base(ai, iorb_unit_port(iorb));
    832   int is_ncq = ((ai->cap & HOST_CAP_NCQ) &&
    833                 ncq_capable &&
    834                 !add_workspace(iorb)->no_ncq);
    835831  int i;
    836832
    837   /* NCQ disabled temporarily until non-NCQ commands are working fine */
    838   is_ncq = 0;
     833  /* 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 */
     837  aws->is_ncq = 0;
    839838
    840839  /* check whether adapter is available */
     
    851850
    852851    /* prevent NCQ/regular command mix */
    853     if (is_ncq && port->reg_cmds == 0 || !is_ncq && port->ncq_cmds == 0) {
     852    if (aws->is_ncq && port->reg_cmds == 0 ||
     853        !aws->is_ncq && port->ncq_cmds == 0) {
    854854
    855855      /* Find next available command slot. We use a simple round-robin
     
    857857       * from stalling when new commands are coming in frequently.
    858858       */
    859       cmds = (is_ncq) ? &port->ncq_cmds : &port->reg_cmds;
     859      cmds = (aws->is_ncq) ? &port->ncq_cmds : &port->reg_cmds;
    860860      for (i = 0; i <= ai->cmd_max; i++) {
    861861        if ((*cmds & (1UL << port->cmd_slot)) == 0) {
    862862          break;
    863863        }
    864         if (++(port->cmd_slot) >= ai->cmd_max) {
     864        if (++(port->cmd_slot) > ai->cmd_max) {
    865865          port->cmd_slot = 0;
    866866        }
     
    879879
    880880        /* start timer for this IORB */
    881         ADD_StartTimerMS(&add_workspace(iorb)->timer, timeout,
    882                          (PFN) timeout_callback, iorb, 0);
    883 
    884         /* update IORB and increment next command index */
    885         add_workspace(iorb)->queued_hw = 1;
    886         add_workspace(iorb)->cmd_slot = port->cmd_slot;
    887         if (++(port->cmd_slot) >= ai->cmd_max) {
    888           port->cmd_slot = 0;
    889         }
     881        ADD_StartTimerMS(&aws->timer, timeout, (PFN) timeout_callback, iorb, 0);
     882
     883        /* update IORB */
     884        aws->queued_hw = 1;
     885        aws->cmd_slot = port->cmd_slot;
    890886
    891887        /* issue command to hardware */
    892         dprintf("issuing command on slot %d\n", port->cmd_slot);
     888        ddprintf("issuing command on slot %d\n", port->cmd_slot);
    893889        *cmds |= (1UL << port->cmd_slot);
    894         if (is_ncq) {
     890        if (aws->is_ncq) {
    895891          writel(port_mmio + PORT_SCR_ACT, (1UL << port->cmd_slot));
    896892          readl(port_mmio + PORT_SCR_ACT); /* flush */
     
    899895        readl(port_mmio + PORT_CMD_ISSUE); /* flush */
    900896
     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        }
    901901        spin_unlock(drv_lock);
    902902        return;
     
    906906
    907907  /* requeue this IORB; it will be picked up again in trigger_engine() */
    908   add_workspace(iorb)->processing = 0;
     908  aws->processing = 0;
    909909  spin_unlock(drv_lock);
    910910}
     
    916916 *
    917917 *  - We need to restore the BIOS configuration after we're done with this
    918  *    command because we might still need the BIOS to load additional drivers.
     918 *    command because someone might still call int 13 routines; sending
     919 *    asynchronous commands and waiting for interrupts to indicate completion
     920 *    won't work in such a scenario.
    919921 *  - Our context hooks won't work while the device managers are initializing
    920922 *    (they can't yield at init time).
     
    951953  }
    952954
    953   /* restart port (includes the necessary port configuration */
     955  /* restart port (includes the necessary port configuration) */
    954956  if (ahci_stop_port(ai, p) || ahci_start_port(ai, p, 0)) {
    955957    iorb_seterr(iorb, IOERR_ADAPTER_NONSPECIFIC);
     
    983985      if (add_workspace(iorb)->ppfunc != NULL) {
    984986        add_workspace(iorb)->ppfunc(iorb);
     987      } else {
     988        add_workspace(iorb)->complete = 1;
    985989      }
    986990    }
     
    994998  ahci_restore_bios_config(ai);
    995999
    996   iorb_done(iorb);
     1000  if (add_workspace(iorb)->complete | (iorb->Status | IORB_ERROR)) {
     1001    aws_free(add_workspace(iorb));
     1002    iorb_done(iorb);
     1003  }
    9971004  return;
     1005}
     1006
     1007/******************************************************************************
     1008 * Execute polled ATA/ATAPI command. This function will block until the command
     1009 * has completed or the timeout has expired, thus it should only be used during
     1010 * initialization. Furthermore, it will always use command slot zero.
     1011 *
     1012 * The difference to ahci_exec_polled_iorb() is that this function executes
     1013 * arbitrary ATA/ATAPI commands outside the context of an IORB. It's typically
     1014 * used when scanning for devices during initialization.
     1015 */
     1016int ahci_exec_polled_cmd(AD_INFO *ai, int p, int d, int timeout, int cmd, ...)
     1017{
     1018  va_list va;
     1019  u8 _far *port_mmio = port_base(ai, p);
     1020  u32 tmp;
     1021  int rc;
     1022
     1023  /* verify that command slot 0 is idle */
     1024  if (readl(port_mmio + PORT_CMD_ISSUE) & 1) {
     1025    ddprintf("port %d slot 0 is not idle; not executing polled cmd\n", p);
     1026    return(-1);
     1027  }
     1028
     1029  /* fill in command slot 0 */
     1030  va_start(va, cmd);
     1031  if ((rc = v_ata_cmd(ai, p, d, 0, cmd, va)) != 0) {
     1032    return(rc);
     1033  }
     1034
     1035  /* start command execution for slot 0 */
     1036  ddprintf("executing polled cmd...");
     1037  writel(port_mmio + PORT_CMD_ISSUE, 1);
     1038
     1039  /* wait until command has completed */
     1040  while (timeout > 0 && (readl(port_mmio + PORT_CMD_ISSUE) & 1)) {
     1041    mdelay(10);
     1042    timeout -= 10;
     1043  }
     1044  ddprintf(" done (time left = %d)\n", timeout);
     1045
     1046  /* check error condition */
     1047  if ((tmp = readl(port_mmio + PORT_SCR_ERR)) != 0) {
     1048    dprintf("SERR = 0x%08lx\n", tmp);
     1049    return(-1);
     1050  }
     1051  if (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) {
     1052    dprintf("TFDATA = 0x%08lx\n", tmp);
     1053    return(-1);
     1054  }
     1055
     1056  return((timeout <= 0) ? -1 : 0);
    9981057}
    9991058
     
    11191178      if (aws->ppfunc != NULL) {
    11201179        aws->ppfunc(iorb);
     1180      } else {
     1181        aws->complete = 1;
    11211182      }
    1122       aws_free(aws);
    1123 
    1124       /* move IORB to our temporary done queue */
    1125       iorb_queue_del(&ai->ports[p].iorb_queue, iorb);
    1126       iorb_queue_add(&done_queue, iorb);
     1183
     1184      if (aws->complete) {
     1185        /* this IORB is complete */
     1186        aws_free(aws);
     1187
     1188        /* move IORB to our temporary done queue */
     1189        iorb_queue_del(&ai->ports[p].iorb_queue, iorb);
     1190        iorb_queue_add(&done_queue, iorb);
     1191      }
    11271192
    11281193      /* clear corresponding bit in issued command bitmaps */
     
    12051270void ahci_get_geometry(IORBH _far *iorb)
    12061271{
     1272  dprintf("ahci_get_geometry(%d.%d.%d)\n", (int) iorb_unit_adapter(iorb),
     1273          (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb));
     1274
    12071275  ahci_exec_iorb(iorb, 0, cmd_func(iorb, get_geometry));
    12081276}
     
    12131281void ahci_unit_ready(IORBH _far *iorb)
    12141282{
     1283  dprintf("ahci_unit_ready(%d.%d.%d)\n", (int) iorb_unit_adapter(iorb),
     1284          (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb));
     1285
    12151286  ahci_exec_iorb(iorb, 0, cmd_func(iorb, unit_ready));
    12161287}
     
    12211292void ahci_read(IORBH _far *iorb)
    12221293{
     1294  dprintf("ahci_read(%d.%d.%d, %ld, %ld)\n", (int) iorb_unit_adapter(iorb),
     1295          (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb),
     1296          (long) ((IORB_EXECUTEIO _far *) iorb)->RBA,
     1297          (long) ((IORB_EXECUTEIO _far *) iorb)->BlockCount);
     1298
    12231299  ahci_exec_iorb(iorb, 1, cmd_func(iorb, read));
    12241300
     
    12291305void ahci_verify(IORBH _far *iorb)
    12301306{
     1307  dprintf("ahci_verify(%d.%d.%d, %ld, %ld)\n", (int) iorb_unit_adapter(iorb),
     1308          (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb),
     1309          (long) ((IORB_EXECUTEIO _far *) iorb)->RBA,
     1310          (long) ((IORB_EXECUTEIO _far *) iorb)->BlockCount);
     1311
    12311312  ahci_exec_iorb(iorb, 0, cmd_func(iorb, verify));
    12321313}
     
    12371318void ahci_write(IORBH _far *iorb)
    12381319{
     1320  dprintf("ahci_write(%d.%d.%d, %ld, %ld)\n", (int) iorb_unit_adapter(iorb),
     1321          (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb),
     1322          (long) ((IORB_EXECUTEIO _far *) iorb)->RBA,
     1323          (long) ((IORB_EXECUTEIO _far *) iorb)->BlockCount);
     1324
    12391325  ahci_exec_iorb(iorb, 1, cmd_func(iorb, write));
    12401326}
     
    12481334  int p = iorb_unit_port(iorb);
    12491335  int d = iorb_unit_device(iorb);
     1336
     1337  dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd,
     1338        ((IORB_ADAPTER_PASSTHRU _far *) iorb)->ControllerCmdLen,
     1339        "ahci_execute_cdb(%d.%d.%d)", (int) iorb_unit_adapter(iorb),
     1340        (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb));
    12501341 
    12511342  if (ad_infos[a].ports[p].devs[d].atapi) {
     
    12661357  int d = iorb_unit_device(iorb);
    12671358 
     1359  dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd,
     1360        ((IORB_ADAPTER_PASSTHRU _far *) iorb)->ControllerCmdLen,
     1361        "ahci_execute_cdb(%d.%d.%d)", (int) iorb_unit_adapter(iorb),
     1362        (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb));
     1363 
    12681364  if (ad_infos[a].ports[p].devs[d].atapi) {
    12691365    iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED);
     
    12721368    ahci_exec_iorb(iorb, 0, ata_execute_ata);
    12731369  }
    1274 }
    1275 
    1276 /******************************************************************************
    1277  * Execute polled ATA/ATAPI command. This function will block until the command
    1278  * has completed or the timeout has expired, thus it should only be used during
    1279  * initialization. Furthermore, it will always use command slot zero...
    1280  */
    1281 static int exec_polled_cmd(AD_INFO *ai, int p, int d, int timeout, int cmd, ...)
    1282 {
    1283   va_list va;
    1284   u8 _far *port_mmio = port_base(ai, p);
    1285   u32 tmp;
    1286   int rc;
    1287 
    1288   /* verify that command slot 0 is idle */
    1289   if (readl(port_mmio + PORT_CMD_ISSUE) & 1) {
    1290     ddprintf("port %d slot 0 is not idle; not executing polled cmd\n", p);
    1291     return(-1);
    1292   }
    1293 
    1294   /* fill in command slot 0 */
    1295   va_start(va, cmd);
    1296   if ((rc = v_ata_cmd(ai, p, d, 0, cmd, va)) != 0) {
    1297     return(rc);
    1298   }
    1299 
    1300   /* start command execution for slot 0 */
    1301   ddprintf("executing polled cmd...");
    1302   writel(port_mmio + PORT_CMD_ISSUE, 1);
    1303 
    1304   /* wait until command has completed */
    1305   while (timeout > 0 && (readl(port_mmio + PORT_CMD_ISSUE) & 1)) {
    1306     mdelay(10);
    1307     timeout -= 10;
    1308   }
    1309   ddprintf(" done (time left = %d)\n", timeout);
    1310 
    1311   /* check error condition */
    1312   if ((tmp = readl(port_mmio + PORT_SCR_ERR)) != 0) {
    1313     dprintf("SERR = 0x%08lx\n", tmp);
    1314     return(-1);
    1315   }
    1316   if (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) {
    1317     dprintf("TFDATA = 0x%08lx\n", tmp);
    1318     return(-1);
    1319   }
    1320 
    1321   return((timeout <= 0) ? -1 : 0);
    13221370}
    13231371
Note: See TracChangeset for help on using the changeset viewer.