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/os2ahci.c

    r12 r13  
    3232      goto init_fail;                                     \
    3333    }                                                     \
    34     value = (type) strtol((s) + 2,                        \
    35                           (const char _far* _far*) &_ep,  \
    36                           radix);                         \
     34    value = (type) strtol((s) + 2, &_ep, radix);          \
    3735    s = _ep;                                              \
    3836  }
    39 
    40 
    41 /* MT: got to fix include paths... */
    42 #ifndef IOCM_EXECUTE_ATA
    43 #define IOCM_EXECUTE_ATA 0x0003
    44 #endif
    4537
    4638/* ------------------------ typedefs and structures ------------------------ */
     
    8476
    8577/* apapter/port-specific options saved when parsing the command line */
    86 int             link_speed[MAX_AD][AHCI_MAX_PORTS];
     78u8              link_speed[MAX_AD][AHCI_MAX_PORTS];
     79u8              disable_ncq[MAX_AD][AHCI_MAX_PORTS];
    8780
    8881static char     init_msg[] = "OS2AHCI driver version %d.%02d\n";
     
    123116  DDD_PARM_LIST _far *ddd_pl = (DDD_PARM_LIST _far *) req->InitArgs;
    124117  APIRET rmrc;
     118  PSEL p;
    125119  char _far *cmd_line;
     120  char _far *ep;
    126121  char _far *s;
    127122  int adapter_index;
     
    159154      s++;
    160155      switch(tolower(*s)) {
     156
     157      case 'c':
     158        /* set COM port base address for debug messages */
     159        drv_parm_int(s, com_base, u16, 16);
     160        break;
    161161
    162162      case 'd':
     
    210210        break;
    211211
     212      case 'n':
     213        /* disable NCQ on this port */
     214        drv_parm_int(s, disable_ncq[adapter_index][port_index], u8, 10);
     215        break;
     216
    212217      default:
    213218        cprintf("invalid option: /%c\n", *s);
     
    382387 * - This function is expected to be called with the spinlock aquired
    383388 *
    384  * - The handler functions are free to process more than one IORB (i.e.
    385  *   command queuing). The idea is that the root IORB (and potential next
    386  *   IORBs) are marked as "processing" which keeps trigger_engine() from
    387  *   touching this IORB queue until all of those IORBs have completed
    388  *   processing and have been removed from the queue.
    389  *
    390389 * - Adapters can be flagged as 'busy' which means no new IORBs are sent (they
    391390 *   just remain in the queue). This can be used to release the driver-level
     
    394393 *   need to invoke trigger_engine() after resetting the busy flag.
    395394 *
    396  *   - Handlers that use the adapter 'busy' flag when processing driver-level
    397  *     IORBs don't need to protect themselves against new IORBs on the driver
    398  *     level because those will always be queued at the end of the driver-
    399  *     level queue (there are no driver-level priority IORBs).
     395 * - Driver-level IORBs are not synchronized by adapter-level 'busy' flags.
     396 *   However, the driver-level queue is worked "one entry at a time" which
     397 *   means that no new IORBs will be queued on the driver-level queue until
     398 *   the head element has completed processing. This means that driver-
     399 *   level IORB handlers don't need to protect against each other. But they
     400 *   they do need to keep in mind interference with port-level IORBs:
     401 *
     402 *   - Driver-level IORB handlers must obtain the spinlock and/or flag all
     403 *     adapters as 'busy' which are affected by the driver-level IORB
     404 *
     405 *   - Driver-level IORB handlers must not access the hardware of a
     406 *     particular adapter if it's flagged as 'busy'
    400407 */
    401408int trigger_engine_1(void)
    402409{
    403410  IORBH _far *iorb;
     411  IORBH _far *next;
    404412  int iorbs_sent = 0;
    405413  int a;
     
    422430    }
    423431    for (p = 0; p <= ai->port_max; p++) {
    424       if ((iorb = ai->ports[p].iorb_queue.root) != NULL &&
    425           !add_workspace(iorb)->processing) {
    426         send_iorb(iorb);
    427         iorbs_sent++;
     432      /* send all queued IORBs on this port */
     433      next = NULL;
     434      for (iorb = ai->ports[p].iorb_queue.root; iorb != NULL; iorb = next) {
     435        next = iorb->pNxtIORB;
     436        if (!add_workspace(iorb)->processing) {
     437          send_iorb(iorb);
     438          iorbs_sent++;
     439        }
    428440      }
    429441    }
     
    447459   * invocations of trigger_engine() (e.g. at interrupt time) will ignore this
    448460   * IORB.
    449    *
    450    * NOTE: Handler functions are free to look at follow-up IORBs in order to
    451    *       queue them to the hardware (native command queueing). If they
    452    *       choose to do so, they must mark those IORBs as "processing" as
    453    *       well.
    454461   */
    455462  add_workspace(iorb)->processing = 1;
     
    511518     * use interrupts, timers and context hooks instead of polling).
    512519     */
    513     dprintf("leaving initialization mode\n");
    514     spin_lock(drv_lock);
    515520    if (!init_complete) {
     521      dprintf("leaving initialization mode\n");
     522      spin_lock(drv_lock);
    516523      for (a = 0; a < ad_info_cnt; a++) {
    517524        ahci_complete_init(ad_infos + a);
    518525      }
    519526      init_complete = 1;
    520     }
    521     spin_unlock(drv_lock);
     527      spin_unlock(drv_lock);
     528    }
    522529    iorb_done(iorb);
    523530    break;
     
    540547void iocc_device_control(IORBH _far *iorb)
    541548{
    542   AD_INFO *ai;
     549  AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb);
    543550  IORBH _far *ptr;
    544551  IORBH _far *next = NULL;
    545   int a = iorb_unit_adapter(iorb);
    546552  int p = iorb_unit_port(iorb);
    547553  int d = iorb_unit_device(iorb);
     
    551557  case IOCM_ABORT:
    552558    /* abort all pending commands on specified port and device */
    553     ai = ad_infos + a;
    554559    spin_lock(drv_lock);
    555560    for (ptr = ai->ports[p].iorb_queue.root; ptr != NULL; ptr = next) {
     
    762767            ui->UnitHandle   = iorb_unit(a, p, d);
    763768            ui->UnitType     = ad_info->ports[p].devs[d].dev_type;
    764             ui->QueuingCount = AHCI_MAX_CMDS;
     769            ui->QueuingCount = ad_info->ports[p].devs[d].ncq_max;;
    765770            if (ad_info->ports[p].devs[d].removable) {
    766771              ui->UnitFlags |= UF_REMOVABLE;
     
    865870
    866871  case IOCM_EXECUTE_CDB:
     872    add_workspace(iorb)->idempotent = 0;
    867873    ahci_execute_cdb(iorb);
    868874    break;
    869875
    870876  case IOCM_EXECUTE_ATA:
     877    add_workspace(iorb)->idempotent = 0;
    871878    ahci_execute_ata(iorb);
    872879    break;
     
    900907  }
    901908
    902   ddprintf("IORB queued:  %d/%d (queue = %Fp, IORB = %Fp)\n",
    903            iorb->CommandCode, iorb->CommandModifier, queue, iorb);
     909  dprintf("IORB queued:  %d/%d (queue = %Fp, IORB = %Fp)\n",
     910          iorb->CommandCode, iorb->CommandModifier, queue, iorb);
    904911}
    905912
     
    931938
    932939  if (found) {
    933     ddprintf("IORB removed: %d/%d (queue = %Fp, IORB = %Fp) - %04x/%04x\n",
    934              iorb->CommandCode, iorb->CommandModifier, queue, iorb,
    935              iorb->Status, iorb->ErrorCode);
     940    dprintf("IORB removed: %d/%d (queue = %Fp, IORB = %Fp) - %04x/%04x\n",
     941            iorb->CommandCode, iorb->CommandModifier, queue, iorb,
     942            iorb->Status, iorb->ErrorCode);
    936943  } else {
    937     ddprintf("IORB %Fp not found in queue %Fp\n", iorb, queue);
     944    dprintf("IORB %Fp not found in queue %Fp\n", iorb, queue);
    938945  }
    939946
Note: See TracChangeset for help on using the changeset viewer.