- Timestamp:
- Sep 14, 2010, 10:07:59 AM (15 years ago)
- Location:
- trunk/src/os2ahci
- Files:
-
- 1 added
- 17 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/ahci.c
r12 r13 171 171 if (val & HOST_CAP_EMS) printf(" ems"); 172 172 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); 174 175 175 176 } else if (i == HOST_CTL) { … … 829 830 ULONG timeout = (iorb->Timeout > 0) ? iorb->Timeout : DEFAULT_TIMEOUT; 830 831 u8 _far *port_mmio = port_base(ai, iorb_unit_port(iorb)); 832 u16 cmd_max = ai->cmd_max; 831 833 int i; 832 834 833 835 /* 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 836 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 */ 840 853 spin_lock(drv_lock); 841 854 if (!ai->busy) { … … 849 862 } 850 863 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) { 854 866 855 867 /* Find next available command slot. We use a simple round-robin … … 858 870 */ 859 871 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 } 861 876 if ((*cmds & (1UL << port->cmd_slot)) == 0) { 862 877 break; 863 }864 if (++(port->cmd_slot) > ai->cmd_max) {865 port->cmd_slot = 0;866 878 } 867 879 } … … 895 907 readl(port_mmio + PORT_CMD_ISSUE); /* flush */ 896 908 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 }901 909 spin_unlock(drv_lock); 902 910 return; … … 916 924 * 917 925 * - We need to restore the BIOS configuration after we're done with this 918 * command because someone might still call int 13 routines; sending926 * command because someone might still call int 13h routines; sending 919 927 * asynchronous commands and waiting for interrupts to indicate completion 920 928 * won't work in such a scenario. … … 1226 1234 u8 _far *port_mmio = port_base(ai, p); 1227 1235 int reset_port = 0; 1236 u32 tmp; 1228 1237 1229 1238 /* Handle adapter and interface errors. Those typically require a port … … 1336 1345 dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd, 1337 1346 ((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); 1340 1348 1341 1349 if (ad_infos[a].ports[p].devs[d].atapi) { … … 1358 1366 dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd, 1359 1367 ((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); 1362 1369 1363 1370 if (ad_infos[a].ports[p].devs[d].atapi) { … … 1403 1410 } else { 1404 1411 /* 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) { 1407 1416 ai->ports[p].devs[d].lba48 = 1; 1408 1417 } -
trunk/src/os2ahci/ata.c
r12 r13 99 99 100 100 case AP_WRITE: 101 ahci_flags |= AHCI_CMD_WRITE; 101 if (va_arg(va, u16) != 0) { 102 ahci_flags |= AHCI_CMD_WRITE; 103 } 102 104 break; 103 105 … … 126 128 ata_cmd.lba_h = va_arg(va, u16); 127 129 break; 128 130 129 131 case AP_DEVICE: 130 132 /* ATA device byte */ … … 147 149 148 150 case AP_ATAPI_CMD: 151 /* ATAPI command */ 149 152 atapi_cmd = va_arg(va, void _far *); 150 153 atapi_cmd_len = va_arg(va, u16); 151 154 ahci_flags |= AHCI_CMD_ATAPI; 155 break; 156 157 case AP_ATA_CMD: 158 /* ATA command "pass-through" */ 159 memcpy(&ata_cmd, va_arg(va, void _far *), sizeof(ATA_CMD)); 152 160 break; 153 161 … … 236 244 return(i - 1); 237 245 } 238 ddprintf("s/g list element: addr = 0x%08lx, size = 0x%04lx\n", sg_addr, chunk);239 246 cmd_tbl->sg_list[n].addr = sg_addr; 240 247 cmd_tbl->sg_list[n].size = chunk - 1; … … 515 522 sg_cnt = io->cSGList - sg_indx; 516 523 517 if (sector >= (1UL << 28) || count > 256 ) {524 if (sector >= (1UL << 28) || count > 256 || add_workspace(iorb)->is_ncq) { 518 525 /* need LBA48 for this command */ 519 526 if (!ai->ports[p].devs[d].lba48) { … … 521 528 return(-1); 522 529 } 523 rc = ata_cmd(ai, p, d, slot, ATA_CMD_READ_EXT, 524 AP_SECTOR_48, (u32) sector, (u16) 0, 525 AP_COUNT, (u16) count, 526 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 527 AP_DEVICE, 0x4000, 528 AP_END); 530 if (add_workspace(iorb)->is_ncq) { 531 /* use NCQ read; count goes into feature register, tag into count! */ 532 rc = ata_cmd(ai, p, d, slot, ATA_CMD_FPDMA_READ, 533 AP_SECTOR_48, (u32) sector, (u16) 0, 534 AP_FEATURES, (u16) count, 535 AP_COUNT, (u16) slot, /* tag = slot */ 536 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 537 AP_DEVICE, 0x4000, 538 AP_END); 539 } else { 540 rc = ata_cmd(ai, p, d, slot, ATA_CMD_READ_EXT, 541 AP_SECTOR_48, (u32) sector, (u16) 0, 542 AP_COUNT, (u16) count, 543 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 544 AP_DEVICE, 0x4000, 545 AP_END); 546 } 547 529 548 } else { 530 549 rc = ata_cmd(ai, p, d, slot, ATA_CMD_READ, … … 630 649 sg_cnt = io->cSGList - sg_indx; 631 650 632 if (sector >= (1UL << 28) || count > 256 ) {651 if (sector >= (1UL << 28) || count > 256 || add_workspace(iorb)->is_ncq) { 633 652 /* need LBA48 for this command */ 634 653 if (!ai->ports[p].devs[d].lba48) { … … 636 655 return(-1); 637 656 } 638 rc = ata_cmd(ai, p, d, slot, ATA_CMD_WRITE_EXT, 639 AP_SECTOR_48, (u32) sector, (u16) 0, 640 AP_COUNT, (u16) count, 641 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 642 AP_DEVICE, 0x4000, 643 AP_WRITE, 644 AP_END); 657 if (add_workspace(iorb)->is_ncq) { 658 /* use NCQ write; count goes into feature register, tag into count! */ 659 rc = ata_cmd(ai, p, d, slot, ATA_CMD_FPDMA_WRITE, 660 AP_SECTOR_48, (u32) sector, (u16) 0, 661 AP_FEATURES, (u16) count, 662 AP_COUNT, (u16) slot, /* tag = slot */ 663 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 664 AP_DEVICE, 0xc000, /* force unit access (FUA) */ 665 AP_WRITE, 1, 666 AP_END); 667 } else { 668 rc = ata_cmd(ai, p, d, slot, ATA_CMD_WRITE_EXT, 669 AP_SECTOR_48, (u32) sector, (u16) 0, 670 AP_COUNT, (u16) count, 671 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 672 AP_DEVICE, 0x4000, 673 AP_WRITE, 1, 674 AP_END); 675 } 676 645 677 } else { 646 678 rc = ata_cmd(ai, p, d, slot, ATA_CMD_WRITE, … … 699 731 int ata_execute_ata(IORBH _far *iorb, int slot) 700 732 { 701 iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED); 702 return(-1); 733 IORB_ADAPTER_PASSTHRU _far *apt = (IORB_ADAPTER_PASSTHRU _far *) iorb; 734 AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb); 735 int p = iorb_unit_port(iorb); 736 int d = iorb_unit_device(iorb); 737 int rc; 738 739 if (apt->ControllerCmdLen != sizeof(ATA_CMD)) { 740 iorb_seterr(iorb, IOERR_CMD_SYNTAX); 741 return(-1); 742 } 743 744 rc = ata_cmd(ai, p, d, slot, 0, 745 AP_SGLIST, apt->pSGList, apt->ppSGLIST, 746 AP_ATA_CMD, apt->pControllerCmd, 747 AP_WRITE, !(apt->Flags & PT_DIRECTION_IN), 748 AP_END); 749 750 return(rc); 703 751 } 704 752 … … 745 793 } 746 794 747 /* TBD: fill in SCSI sense buffer in IORB */748 749 795 /* Return an error to indicate there's no HW command to be submitted and 750 796 * that the IORB can be completed "as is" (the upstream code expects the -
trunk/src/os2ahci/ata.h
r12 r13 389 389 */ 390 390 typedef enum { 391 AP_FEATURES, /* [u16] ATA command features (read: flags) */ 392 AP_COUNT, /* [u16] number of sectors (0 = 65536) */ 393 AP_SECTOR_28, /* [u32] 28-bit sector address */ 394 AP_SECTOR_48, /* [u32, u16] 48-bit sector address */ 395 AP_DEVICE, /* [u16] ATA command "device" field (LSB ignored) */ 396 AP_SGLIST, /* [void _far *, u16] buffer S/G (SCATGATENTRY/count) */ 397 AP_VADDR, /* [void _far *, u16] buffer virtual address (buf/len) */ 398 AP_WRITE, /* [] indicates a DMA write operation */ 399 AP_AHCI_FLAGS, /* [u16] AHCI command header flags */ 400 AP_ATAPI_CMD, /* [void _far *, u16] ATAPI command (CDB) and length */ 401 AP_END /* [] end of variable argument list */ 391 AP_FEATURES, /* [u16] ATA command features (read: flags) */ 392 AP_COUNT, /* [u16] number of sectors (0 = 65536) */ 393 AP_SECTOR_28, /* [u32] 28-bit sector address */ 394 AP_SECTOR_48, /* [u32, u16] 48-bit sector address */ 395 AP_DEVICE, /* [u16] ATA cmd "device" field (LSB masked) */ 396 AP_SGLIST, /* [void _far *, u16] buffer S/G (SCATGATENTRY/count) */ 397 AP_VADDR, /* [void _far *, u16] buffer virtual address (buf/len) */ 398 AP_WRITE, /* [u16] if != 0, data is written to device */ 399 AP_AHCI_FLAGS, /* [u16] AHCI command header flags */ 400 AP_ATAPI_CMD, /* [void _far *, u16] ATAPI command (CDB) and length */ 401 AP_ATA_CMD, /* [void _far *] ATA command (fixed len) */ 402 AP_END /* [] end of variable argument list */ 402 403 } ATA_PARM; 403 404 -
trunk/src/os2ahci/atapi.c
r12 r13 89 89 90 90 /****************************************************************************** 91 * Request sense information. 91 * Request sense information for a failed command. 92 * 93 * NOTE: This function must be called right after an ATAPI command has failed 94 * and before any other commands are queued on the corresponding device. 95 * This function is typically called in the port restart context hook 96 * which is triggered by an AHCI error interrupt. 97 * 92 98 */ 93 99 int atapi_req_sense(IORBH _far *iorb, int slot) -
trunk/src/os2ahci/init.asm
r12 r13 158 158 159 159 160 ; Write long value to MMIO address; 160 ; Write long value to MMIO address; need to do this here to get real 161 161 ; 32-bit operations because at least the AHCI device in VirtualBox doesn't 162 162 ; seem to support reading 32-bit MMIO registers in two 16-bit steps and the … … 182 182 ; print debug message if debug level is 3+ 183 183 CMP _debug, 3 184 JB no_debug 2184 JB no_debug 185 185 MOV BX, AX ; addr & 0x7f (port reg index) 186 186 AND BX, 7FH … … 193 193 ADD SP, 12 194 194 195 no_debug 2:LEAVE195 no_debug: LEAVE 196 196 RET 197 197 _writel ENDP -
trunk/src/os2ahci/libc.c
r12 r13 27 27 * for printing custom messages via 28 28 * DevHelp_Save_Message() */ 29 30 #define COM_BASE 0x03f8 /* base address of COM port (COM1) */31 29 32 30 /* heap management constants */ … … 54 52 55 53 /* ------------------------ global/static variables ------------------------ */ 54 55 /* debug COM port base address */ 56 u16 com_base = 0x03f8; 56 57 57 58 static char hex_digits[] = "0123456789abcdef"; … … 99 100 100 101 for (i = 0; com1_init_sequence[i].reg != -1; i++) { 101 u16 port = COM_BASE+ com1_init_sequence[i].reg;102 u16 port = com_base + com1_init_sequence[i].reg; 102 103 u8 data = com1_init_sequence[i].data; 103 104 _asm { … … 248 249 * The C equivalent would look like this: 249 250 * 250 * while (!(inp( COM_BASE+ 5) & 0x20));251 * outp( COM_BASE, *s);251 * while (!(inp(com_base + 5) & 0x20)); 252 * outp(com_base, *s); 252 253 */ 253 254 254 255 _asm { 255 256 /* wait until COM transmitter is idle */ 256 mov dx, COM_BASE + 5; 257 mov dx, com_base; 258 add dx, 5; 257 259 transmitter_not_idle: 258 260 in al, dx; … … 261 263 262 264 /* output character to be sent */ 263 mov dx, COM_BASE;265 mov dx, com_base; 264 266 mov bx, s; 265 267 mov al, [bx]; … … 655 657 int disable(void) 656 658 { 657 int rc = 0;659 int rc; 658 660 659 661 _asm { -
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 -
trunk/src/os2ahci/os2ahci.h
r12 r13 261 261 IORB_QUEUE iorb_queue; /* IORB queue for this port */ 262 262 unsigned dev_max : 4; /* maximum device number on this port (0-15) */ 263 unsigned cmd_slot : 4; /* current command slot index (using round-263 unsigned cmd_slot : 5; /* current command slot index (using round- 264 264 * robin indexes to prevent starvation) */ 265 265 … … 284 284 PCI_ID *pci; /* pointer to corresponding PCI ID */ 285 285 286 unsigned port_max : 4; /* maximum port number (0-31) */287 unsigned cmd_max : 4; /* maximum cmd slot number (0-31) */286 unsigned port_max : 5; /* maximum port number (0-31) */ 287 unsigned cmd_max : 5; /* maximum cmd slot number (0-31) */ 288 288 unsigned port_scan_done : 1; /* if != 0, port scan already done */ 289 289 unsigned busy : 1; /* if != 0, adapter is busy */ … … 327 327 unsigned is_ncq : 1; /* should use native command queueing */ 328 328 unsigned complete : 1; /* IORB has completed processing */ 329 unsigned cmd_slot : 4; /* AHCI command slot for this IORB */329 unsigned cmd_slot : 5; /* AHCI command slot for this IORB */ 330 330 } ADD_WORKSPACE; 331 331 … … 452 452 extern int init_complete; /* if != 0, initialization has completed */ 453 453 454 extern u16 com_base; /* debug COM port base address */ 455 454 456 /* port restart context hook and input data */ 455 457 extern ULONG restart_ctxhook_h; … … 465 467 466 468 /* apapter/port-specific options saved when parsing the command line */ 467 extern int link_speed[MAX_AD][AHCI_MAX_PORTS]; 468 469 extern u8 link_speed[MAX_AD][AHCI_MAX_PORTS]; 470 extern u8 disable_ncq[MAX_AD][AHCI_MAX_PORTS]; 471 -
trunk/src/os2ahci/pci.c
r12 r13 483 483 UCHAR dev_func = data->find_class.dev_func; 484 484 ULONG val; 485 UCHAR rc; 485 486 SEL gdt[PORT_DMA_BUF_SEGS + 1]; 486 487 char tmp[40]; … … 829 830 { 830 831 void (_far *func)(void); 831 unsigned short prot_idc_DS;832 832 RP_GENIOCTL ioctl; 833 833 … … 867 867 func = oemhlp.ProtIDCEntry; 868 868 869 /* MT: the Watcom inline assembler does not support struct member reference,870 * so we have to pass it in a stack variable871 */872 prot_idc_DS = oemhlp.ProtIDC_DS;873 874 869 _asm { 875 870 push ds; … … 882 877 pop es 883 878 lea bx, ioctl; 884 mov ds, prot_idc_DS;879 mov ds, oemhlp.ProtIDC_DS; 885 880 call dword ptr [func]; 886 881
Note:
See TracChangeset
for help on using the changeset viewer.