Changeset 13 for trunk/src/os2ahci/os2ahci.c
- Timestamp:
- Sep 14, 2010, 10:07:59 AM (15 years ago)
- Location:
- trunk/src/os2ahci
- Files:
-
- 1 added
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/os2ahci.c
r12 r13 32 32 goto init_fail; \ 33 33 } \ 34 value = (type) strtol((s) + 2, \ 35 (const char _far* _far*) &_ep, \ 36 radix); \ 34 value = (type) strtol((s) + 2, &_ep, radix); \ 37 35 s = _ep; \ 38 36 } 39 40 41 /* MT: got to fix include paths... */42 #ifndef IOCM_EXECUTE_ATA43 #define IOCM_EXECUTE_ATA 0x000344 #endif45 37 46 38 /* ------------------------ typedefs and structures ------------------------ */ … … 84 76 85 77 /* apapter/port-specific options saved when parsing the command line */ 86 int link_speed[MAX_AD][AHCI_MAX_PORTS]; 78 u8 link_speed[MAX_AD][AHCI_MAX_PORTS]; 79 u8 disable_ncq[MAX_AD][AHCI_MAX_PORTS]; 87 80 88 81 static char init_msg[] = "OS2AHCI driver version %d.%02d\n"; … … 123 116 DDD_PARM_LIST _far *ddd_pl = (DDD_PARM_LIST _far *) req->InitArgs; 124 117 APIRET rmrc; 118 PSEL p; 125 119 char _far *cmd_line; 120 char _far *ep; 126 121 char _far *s; 127 122 int adapter_index; … … 159 154 s++; 160 155 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; 161 161 162 162 case 'd': … … 210 210 break; 211 211 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 212 217 default: 213 218 cprintf("invalid option: /%c\n", *s); … … 382 387 * - This function is expected to be called with the spinlock aquired 383 388 * 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 next386 * IORBs) are marked as "processing" which keeps trigger_engine() from387 * touching this IORB queue until all of those IORBs have completed388 * processing and have been removed from the queue.389 *390 389 * - Adapters can be flagged as 'busy' which means no new IORBs are sent (they 391 390 * just remain in the queue). This can be used to release the driver-level … … 394 393 * need to invoke trigger_engine() after resetting the busy flag. 395 394 * 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' 400 407 */ 401 408 int trigger_engine_1(void) 402 409 { 403 410 IORBH _far *iorb; 411 IORBH _far *next; 404 412 int iorbs_sent = 0; 405 413 int a; … … 422 430 } 423 431 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 } 428 440 } 429 441 } … … 447 459 * invocations of trigger_engine() (e.g. at interrupt time) will ignore this 448 460 * IORB. 449 *450 * NOTE: Handler functions are free to look at follow-up IORBs in order to451 * queue them to the hardware (native command queueing). If they452 * choose to do so, they must mark those IORBs as "processing" as453 * well.454 461 */ 455 462 add_workspace(iorb)->processing = 1; … … 511 518 * use interrupts, timers and context hooks instead of polling). 512 519 */ 513 dprintf("leaving initialization mode\n");514 spin_lock(drv_lock);515 520 if (!init_complete) { 521 dprintf("leaving initialization mode\n"); 522 spin_lock(drv_lock); 516 523 for (a = 0; a < ad_info_cnt; a++) { 517 524 ahci_complete_init(ad_infos + a); 518 525 } 519 526 init_complete = 1; 520 }521 spin_unlock(drv_lock);527 spin_unlock(drv_lock); 528 } 522 529 iorb_done(iorb); 523 530 break; … … 540 547 void iocc_device_control(IORBH _far *iorb) 541 548 { 542 AD_INFO *ai ;549 AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb); 543 550 IORBH _far *ptr; 544 551 IORBH _far *next = NULL; 545 int a = iorb_unit_adapter(iorb);546 552 int p = iorb_unit_port(iorb); 547 553 int d = iorb_unit_device(iorb); … … 551 557 case IOCM_ABORT: 552 558 /* abort all pending commands on specified port and device */ 553 ai = ad_infos + a;554 559 spin_lock(drv_lock); 555 560 for (ptr = ai->ports[p].iorb_queue.root; ptr != NULL; ptr = next) { … … 762 767 ui->UnitHandle = iorb_unit(a, p, d); 763 768 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;; 765 770 if (ad_info->ports[p].devs[d].removable) { 766 771 ui->UnitFlags |= UF_REMOVABLE; … … 865 870 866 871 case IOCM_EXECUTE_CDB: 872 add_workspace(iorb)->idempotent = 0; 867 873 ahci_execute_cdb(iorb); 868 874 break; 869 875 870 876 case IOCM_EXECUTE_ATA: 877 add_workspace(iorb)->idempotent = 0; 871 878 ahci_execute_ata(iorb); 872 879 break; … … 900 907 } 901 908 902 d dprintf("IORB queued: %d/%d (queue = %Fp, IORB = %Fp)\n",903 909 dprintf("IORB queued: %d/%d (queue = %Fp, IORB = %Fp)\n", 910 iorb->CommandCode, iorb->CommandModifier, queue, iorb); 904 911 } 905 912 … … 931 938 932 939 if (found) { 933 d dprintf("IORB removed: %d/%d (queue = %Fp, IORB = %Fp) - %04x/%04x\n",934 935 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); 936 943 } else { 937 d dprintf("IORB %Fp not found in queue %Fp\n", iorb, queue);944 dprintf("IORB %Fp not found in queue %Fp\n", iorb, queue); 938 945 } 939 946
Note:
See TracChangeset
for help on using the changeset viewer.