Changeset 69 for trunk/src/os2ahci/ahci.c
- Timestamp:
- Jan 7, 2011, 4:54:46 PM (15 years ago)
- File:
-
- 1 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
Note:
See TracChangeset
for help on using the changeset viewer.