- Timestamp:
- Jan 7, 2011, 4:54:46 PM (15 years ago)
- Location:
- trunk/src/os2ahci
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/ahci.c
r68 r69 38 38 39 39 static void ahci_setup_device (AD_INFO *ai, int p, int d, u16 *id_buf); 40 static void _cdecl _far timeout_callback (ULONG timer_handle, ULONG p1, ULONG p2);41 40 42 41 /* ------------------------ global/static variables ------------------------ */ … … 745 744 int rc; 746 745 746 /* disable port interrupts */ 747 writel(port_mmio + PORT_IRQ_MASK, PORT_IRQ_TF_ERR); 748 747 749 /* disable FIS reception */ 748 750 if ((rc = ahci_stop_fis_rx(ai, p)) != 0) { … … 1035 1037 1036 1038 /****************************************************************************** 1039 * Execute polled ATA/ATAPI command. This function will block until the command 1040 * has completed or the timeout has expired, thus it should only be used during 1041 * initialization. Furthermore, it will always use command slot zero. 1042 * 1043 * The difference to ahci_exec_polled_iorb() is that this function executes 1044 * arbitrary ATA/ATAPI commands outside the context of an IORB. It's typically 1045 * used when scanning for devices during initialization. 1046 */ 1047 int ahci_exec_polled_cmd(AD_INFO *ai, int p, int d, int timeout, int cmd, ...) 1048 { 1049 va_list va; 1050 u8 _far *port_mmio = port_base(ai, p); 1051 u32 tmp; 1052 int rc; 1053 1054 /* verify that command slot 0 is idle */ 1055 if (readl(port_mmio + PORT_CMD_ISSUE) & 1) { 1056 ddprintf("port %d slot 0 is not idle; not executing polled cmd\n", p); 1057 return(-1); 1058 } 1059 1060 /* fill in command slot 0 */ 1061 va_start(va, cmd); 1062 if ((rc = v_ata_cmd(ai, p, d, 0, cmd, va)) != 0) { 1063 return(rc); 1064 } 1065 1066 /* start command execution for slot 0 */ 1067 ddprintf("executing polled cmd..."); 1068 writel(port_mmio + PORT_CMD_ISSUE, 1); 1069 1070 /* wait until command has completed */ 1071 while (timeout > 0 && (readl(port_mmio + PORT_CMD_ISSUE) & 1)) { 1072 mdelay(10); 1073 timeout -= 10; 1074 } 1075 ddprintf(" done (time left = %d)\n", timeout); 1076 1077 /* check error condition */ 1078 if ((tmp = readl(port_mmio + PORT_SCR_ERR)) != 0) { 1079 dprintf("SERR = 0x%08lx\n", tmp); 1080 timeout = 0; 1081 } 1082 if (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) { 1083 dprintf("TFDATA = 0x%08lx\n", tmp); 1084 timeout = 0; 1085 } 1086 1087 if (timeout <= 0) { 1088 ahci_reset_port(ai, p, 0); 1089 return(-1); 1090 } 1091 return(0); 1092 } 1093 1094 /****************************************************************************** 1095 * Flush write cache of the specified device. Since there's no equivalent IORB 1096 * command, we'll execute this command directly using polling. Otherwise, we 1097 * would have to create a fake IORB, add it to the port's IORB queue, ... 1098 * 1099 * Besides, this function is only called when shutting down and the code there 1100 * would have to wait for the flush cache command to complete as well, using 1101 * polling just the same... 1102 */ 1103 int ahci_flush_cache(AD_INFO *ai, int p, int d) 1104 { 1105 dprintf("flushing cache on %d.%d.%d\n", ad_no(ai), p, d); 1106 return(ahci_exec_polled_cmd(ai, p, d, 30000, 1107 ai->ports[p].devs[d].lba48 ? ATA_CMD_FLUSH_EXT 1108 : ATA_CMD_FLUSH, 1109 AP_END)); 1110 } 1111 1112 /****************************************************************************** 1037 1113 * set device into IDLE mode (spin down); this was used during 1038 1114 * debugging/testing and is still there since it does not hurt... … … 1040 1116 * is turned off. 1041 1117 */ 1042 int ahci_set_dev_idle(AD_INFO *ai, int p, int idle)1118 int ahci_set_dev_idle(AD_INFO *ai, int p, int d, int idle) 1043 1119 { 1044 1120 ddprintf("sending IDLE=%d command to port %d\n", idle, p); 1045 return ahci_exec_polled_cmd(ai, p, 0, 500, ATA_CMD_IDLE, AP_COUNT,1121 return ahci_exec_polled_cmd(ai, p, d, 500, ATA_CMD_IDLE, AP_COUNT, 1046 1122 idle ? 1 : 0, AP_END); 1047 }1048 1049 /******************************************************************************1050 * Execute polled ATA/ATAPI command. This function will block until the command1051 * has completed or the timeout has expired, thus it should only be used during1052 * initialization. Furthermore, it will always use command slot zero.1053 *1054 * The difference to ahci_exec_polled_iorb() is that this function executes1055 * arbitrary ATA/ATAPI commands outside the context of an IORB. It's typically1056 * used when scanning for devices during initialization.1057 */1058 int ahci_exec_polled_cmd(AD_INFO *ai, int p, int d, int timeout, int cmd, ...)1059 {1060 va_list va;1061 u8 _far *port_mmio = port_base(ai, p);1062 u32 tmp;1063 int rc;1064 1065 /* verify that command slot 0 is idle */1066 if (readl(port_mmio + PORT_CMD_ISSUE) & 1) {1067 ddprintf("port %d slot 0 is not idle; not executing polled cmd\n", p);1068 return(-1);1069 }1070 1071 /* fill in command slot 0 */1072 va_start(va, cmd);1073 if ((rc = v_ata_cmd(ai, p, d, 0, cmd, va)) != 0) {1074 return(rc);1075 }1076 1077 /* start command execution for slot 0 */1078 ddprintf("executing polled cmd...");1079 writel(port_mmio + PORT_CMD_ISSUE, 1);1080 1081 /* wait until command has completed */1082 while (timeout > 0 && (readl(port_mmio + PORT_CMD_ISSUE) & 1)) {1083 mdelay(10);1084 timeout -= 10;1085 }1086 ddprintf(" done (time left = %d)\n", timeout);1087 1088 /* check error condition */1089 if ((tmp = readl(port_mmio + PORT_SCR_ERR)) != 0) {1090 dprintf("SERR = 0x%08lx\n", tmp);1091 timeout = 0;1092 }1093 if (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) {1094 dprintf("TFDATA = 0x%08lx\n", tmp);1095 timeout = 0;1096 }1097 1098 if (timeout <= 0) {1099 ahci_reset_port(ai, p, 0);1100 return(-1);1101 }1102 return(0);1103 1123 } 1104 1124 … … 1502 1522 pci_hack_virtualbox(); 1503 1523 } 1504 1505 1506 } 1507 1508 /****************************************************************************** 1509 * Timeout handler for I/O commands. Since timeout handling can involve 1510 * lengthy operations like port resets, the main code is located in a 1511 * separate function which is invoked via a context hook. 1512 */ 1513 static void _cdecl _far timeout_callback(ULONG timer_handle, ULONG p1, 1514 ULONG p2) 1515 { 1516 IORBH _far *iorb = (IORBH _far *) p1; 1517 int a = iorb_unit_adapter(iorb); 1518 int p = iorb_unit_port(iorb); 1519 1520 ADD_CancelTimer(timer_handle); 1521 dprintf("timeout for IORB %Fp\n", iorb); 1522 1523 /* Move the timed-out IORB to the abort queue. Since it's possible that the 1524 * IORB has completed after the timeout has expired but before we got to 1525 * this line of code, we'll check the return code of iorb_queue_del(): If it 1526 * returns an error, the IORB must have completed a few microseconds ago and 1527 * there is no timeout. 1528 */ 1529 spin_lock(drv_lock); 1530 if (iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, iorb) == 0) { 1531 iorb_queue_add(&abort_queue, iorb); 1532 iorb->ErrorCode = IOERR_ADAPTER_TIMEOUT; 1533 } 1534 spin_unlock(drv_lock); 1535 1536 /* Trigger abort processing function. We don't really care whether this 1537 * succeeds because the only reason why it would fail should be multiple 1538 * calls to DevHelp_ArmCtxHook() before the context hook had a chance to 1539 * start executing, which leaves two scenarios: 1540 * 1541 * - We succeded in arming the context hook. Fine. 1542 * 1543 * - We armed the context hook a second time before it had a chance to 1544 * start executing. In this case, the already scheduled context hook 1545 * will process our IORB as well. 1546 */ 1547 DevHelp_ArmCtxHook(0, reset_ctxhook_h); 1548 } 1549 1550 1524 } 1525 1526 -
trunk/src/os2ahci/ata.c
r66 r69 107 107 case AP_FEATURES: 108 108 /* ATA features word */ 109 ata_cmd.features = va_arg(va, u16);109 ata_cmd.features |= va_arg(va, u16); 110 110 break; 111 111 … … 118 118 /* 28-bit sector address */ 119 119 ata_cmd.lba_l = va_arg(va, u32); 120 dprintf("LBA28: 0x%08lx\n", ata_cmd.lba_l);121 120 if (ata_cmd.lba_l & 0xf0000000UL) { 122 121 dprintf("error: LBA-28 address %ld has more than 28 bits\n", ata_cmd.lba_l); … … 133 132 ata_cmd.lba_l = va_arg(va, u32); 134 133 ata_cmd.lba_h = va_arg(va, u16); 135 dprintf("LBA48: 0x%08lx\n", ata_cmd.lba_l);136 134 break; 137 135 … … 703 701 AP_COUNT, (u16) (slot << 3), /* tag = slot */ 704 702 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 705 AP_DEVICE, 0xc000, /* force unit access (FUA) */ 703 AP_DEVICE, 0x4000, 704 AP_DEVICE, (io->Flags & XIO_DISABLE_HW_WRITE_CACHE) ? 705 0x8000 : 0, /* force unit access */ 706 706 AP_WRITE, 1, 707 707 AP_END); -
trunk/src/os2ahci/atapi.c
r68 r69 75 75 /* translate read command to SCSI/ATAPI READ12 command. 76 76 * READ12 seems to be the most supported READ variant - according to MMC, 77 * and it s enough even for BluRay.77 * and it's enough even for BluRay. 78 78 */ 79 79 memset(&cdb, 0x00, sizeof(cdb)); … … 167 167 AP_SGLIST, pt->pSGList, pt->cSGList, 168 168 AP_WRITE, !(pt->Flags & PT_DIRECTION_IN), 169 /* TODO: do we have to clear DMA_TO_HOST bit for 170 * write, mode select etc. commands? 171 */ 172 AP_FEATURES, ATAPI_FEAT_DMA | ATAPI_FEAT_DMA_TO_HOST, 169 AP_FEATURES, ATAPI_FEAT_DMA, 170 AP_FEATURES, (pt->Flags & PT_DIRECTION_IN) ? ATAPI_FEAT_DMA_TO_HOST : 0, 173 171 AP_END); 174 172 … … 224 222 iorb_seterr(iorb, IOERR_CMD_SGLIST_BAD); 225 223 226 } else {224 } else if (rc < 0) { 227 225 /* we failed to get info about an error -> return 228 226 * non specific device error … … 242 240 ADD_WORKSPACE _far *aws = add_workspace(iorb); 243 241 ATAPI_SENSE_DATA *psd = (ATAPI_SENSE_DATA *) aws->buf; 242 243 ddphex(psd, sizeof(psd), "sense buffer:\n"); 244 244 245 245 /* map sense data to some IOERR_ value */ -
trunk/src/os2ahci/ctxhook.c
r68 r69 191 191 if (req_sense(problem_iorb, 0) == 0) { 192 192 /* execute request sense on slot #0 before anything else comes along */ 193 ADD_StartTimerMS(&aws->timer, 5000, (PFN) timeout_callback, iorb, 0); 194 aws->cmd_slot = 0; 193 195 ai->ports[p].reg_cmds = 1; 194 196 writel(port_mmio + PORT_CMD_ISSUE, 1); -
trunk/src/os2ahci/init.asm
r61 r69 34 34 db "OS2AHCI$" ; name of character device 35 35 dq 0 ; 8 reserved bytes 36 dd DEV_ ADAPTER_DD + DEV_INITCOMPLETE + 20h ; ADD flags36 dd DEV_IOCTL2 + DEV_ADAPTER_DD + DEV_INITCOMPLETE + 20h ; ADD flags 37 37 dw 0 38 38 DEVHDR ENDS -
trunk/src/os2ahci/os2ahci.c
r67 r69 107 107 break; 108 108 109 case CMDShutdown: 110 rc = exit_drv(((RPSAVERESTORE _far *) req)->FuncCode); 111 break; 112 109 113 default: 110 114 rc = STDON | STATUS_ERR_UNKCMD; … … 284 288 cprintf(exit_msg); 285 289 return(STDON | ERROR_I24_QUIET_INIT_FAIL); 290 } 291 292 /****************************************************************************** 293 * Device driver exit handler. This handler is called when OS/2 shuts down and 294 * flushes the write caches of all attached devices. 295 * 296 * NOTE: Errors are ignored because there's no way we could stop the shutdown 297 * or do something about the error, unless retrying endlessly is 298 * considered an option. 299 */ 300 USHORT exit_drv(int func) 301 { 302 int a; 303 int p; 304 int d; 305 306 dprintf("exit_drv(%d) called\n", func); 307 308 if (func == 0) { 309 /* we're only interested in the second phase of the shutdown */ 310 return(STDON); 311 } 312 313 for (a = 0; a < ad_info_cnt; a++) { 314 AD_INFO *ai = ad_infos + a; 315 316 for (p = 0; p <= ai->port_max; p++) { 317 for (d = 0; d <= ai->ports[p].dev_max; d++) { 318 if (ai->ports[p].devs[d].present) { 319 ahci_flush_cache(ai, p, d); 320 } 321 } 322 } 323 } 324 325 return(STDON); 286 326 } 287 327 … … 1035 1075 1036 1076 /****************************************************************************** 1077 * Timeout handler for I/O commands. Since timeout handling can involve 1078 * lengthy operations like port resets, the main code is located in a 1079 * separate function which is invoked via a context hook. 1080 */ 1081 void _cdecl _far timeout_callback(ULONG timer_handle, ULONG p1, 1082 ULONG p2) 1083 { 1084 IORBH _far *iorb = (IORBH _far *) p1; 1085 int a = iorb_unit_adapter(iorb); 1086 int p = iorb_unit_port(iorb); 1087 1088 ADD_CancelTimer(timer_handle); 1089 dprintf("timeout for IORB %Fp\n", iorb); 1090 1091 /* Move the timed-out IORB to the abort queue. Since it's possible that the 1092 * IORB has completed after the timeout has expired but before we got to 1093 * this line of code, we'll check the return code of iorb_queue_del(): If it 1094 * returns an error, the IORB must have completed a few microseconds ago and 1095 * there is no timeout. 1096 */ 1097 spin_lock(drv_lock); 1098 if (iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, iorb) == 0) { 1099 iorb_queue_add(&abort_queue, iorb); 1100 iorb->ErrorCode = IOERR_ADAPTER_TIMEOUT; 1101 } 1102 spin_unlock(drv_lock); 1103 1104 /* Trigger abort processing function. We don't really care whether this 1105 * succeeds because the only reason why it would fail should be multiple 1106 * calls to DevHelp_ArmCtxHook() before the context hook had a chance to 1107 * start executing, which leaves two scenarios: 1108 * 1109 * - We succeded in arming the context hook. Fine. 1110 * 1111 * - We armed the context hook a second time before it had a chance to 1112 * start executing. In this case, the already scheduled context hook 1113 * will process our IORB as well. 1114 */ 1115 DevHelp_ArmCtxHook(0, reset_ctxhook_h); 1116 } 1117 1118 /****************************************************************************** 1037 1119 * small_code_ - this dummy func resolves the undefined reference linker 1038 1120 * error that occurrs when linking WATCOM objects with DDK's link.exe -
trunk/src/os2ahci/os2ahci.def
r68 r69 1 1 library os2ahci 2 Description '$@#thi.guten (www.thiguten.de):1.00.201 01227#@OS/2 AHCI Adapter Device Driver'2 Description '$@#thi.guten (www.thiguten.de):1.00.20110107#@OS/2 AHCI Adapter Device Driver' 3 3 protmode 4 4 -
trunk/src/os2ahci/os2ahci.h
r68 r69 368 368 /* os2ahci.c */ 369 369 extern USHORT init_drv (RPINITIN _far *req); 370 extern USHORT exit_drv (int func); 370 371 extern void _cdecl _far _loadds add_entry (IORBH _far *iorb); 371 372 extern void trigger_engine (void); … … 385 386 extern void iorb_done (IORBH _far *iorb); 386 387 extern void iorb_requeue (IORBH _far *iorb); 388 extern void _cdecl _far timeout_callback (ULONG timer_handle, ULONG p1, ULONG p2); 387 389 388 390 /* ahci.c */ … … 410 412 extern int ahci_exec_polled_cmd (AD_INFO *ai, int p, int d, 411 413 int timeout, int cmd, ...); 412 extern int ahci_set_dev_idle (AD_INFO *ai, int p, int idle); 414 extern int ahci_set_dev_idle (AD_INFO *ai, int p, int d, int idle); 415 extern int ahci_flush_cache (AD_INFO *ai, int p, int d); 413 416 414 417 extern int ahci_intr (u16 irq);
Note:
See TracChangeset
for help on using the changeset viewer.