Changeset 178 for trunk/src/os2ahci/ahci.c
- Timestamp:
- Nov 29, 2016, 5:30:22 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/ahci.c
r176 r178 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-201 5David Azarewicz6 * Copyright (c) 2013-2016 David Azarewicz 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 43 43 /* -------------------------- function prototypes -------------------------- */ 44 44 45 static void ahci_setup_device 45 static void ahci_setup_device(AD_INFO *ai, int p, int d, u16 *id_buf); 46 46 47 47 /* ------------------------ global/static variables ------------------------ */ … … 58 58 * pointers to all handler functions which may need to be overridden. 59 59 */ 60 u16 initial_flags[] = { 60 u16 initial_flags[] = 61 { 61 62 0, /* board_ahci */ 62 63 AHCI_HFLAG_NO_NCQ | /* board_ahci_vt8251 */ … … 84 85 * index to the corresponding IRQ. 85 86 */ 86 static u16 87 static int 87 static u16 irq_map[MAX_AD]; /* IRQ level for each stub IRQ func */ 88 static int irq_map_cnt; /* number of IRQ stub funcs used */ 88 89 89 90 /* ----------------------------- start of code ----------------------------- */ … … 106 107 * bit 0 will be set when the interrupt was not handled. 107 108 */ 108 #define call_ahci_intr(i) return(ahci_intr(irq_map[i]) >> 1) 109 110 static USHORT _cdecl _far irq_handler_00(void) { call_ahci_intr(0); } 111 static USHORT _cdecl _far irq_handler_01(void) { call_ahci_intr(1); } 112 static USHORT _cdecl _far irq_handler_02(void) { call_ahci_intr(2); } 113 static USHORT _cdecl _far irq_handler_03(void) { call_ahci_intr(3); } 114 static USHORT _cdecl _far irq_handler_04(void) { call_ahci_intr(4); } 115 static USHORT _cdecl _far irq_handler_05(void) { call_ahci_intr(5); } 116 static USHORT _cdecl _far irq_handler_06(void) { call_ahci_intr(6); } 117 static USHORT _cdecl _far irq_handler_07(void) { call_ahci_intr(7); } 118 119 PFN irq_handlers[] = { 109 #define call_ahci_intr(i) return(ahci_intr(irq_map[i])) 110 111 static USHORT _cdecl irq_handler_00(void) { call_ahci_intr(0); } 112 static USHORT _cdecl irq_handler_01(void) { call_ahci_intr(1); } 113 static USHORT _cdecl irq_handler_02(void) { call_ahci_intr(2); } 114 static USHORT _cdecl irq_handler_03(void) { call_ahci_intr(3); } 115 static USHORT _cdecl irq_handler_04(void) { call_ahci_intr(4); } 116 static USHORT _cdecl irq_handler_05(void) { call_ahci_intr(5); } 117 static USHORT _cdecl irq_handler_06(void) { call_ahci_intr(6); } 118 static USHORT _cdecl irq_handler_07(void) { call_ahci_intr(7); } 119 120 PFN irq_handlers[] = 121 { 120 122 (PFN) irq_handler_00, (PFN) irq_handler_01, (PFN) irq_handler_02, 121 123 (PFN) irq_handler_03, (PFN) irq_handler_04, (PFN) irq_handler_05, … … 123 125 }; 124 126 127 #ifdef DEBUG 125 128 void ahci_dump_host_regs(AD_INFO *ai, int bios_regs) 126 129 { 127 #ifdef DEBUG128 130 int i; 129 131 u32 version; 130 132 131 aprintf("AHCI global registers for adapter %d %d:%d:%d irq=%d addr=0x%lx\n", 132 ad_no(ai), ai->bus, ai->dev_func>>3, ai->dev_func&7, ai->irq, ai->mmio_phys); 133 DPRINTF(2,"AHCI global registers for adapter %d %d:%d:%d irq=%d addr=0x%x\n", 134 ad_no(ai), 135 PCI_BUS_FROM_BDF(ai->bus_dev_func), PCI_DEV_FROM_BDF(ai->bus_dev_func), 136 PCI_FUNC_FROM_BDF(ai->bus_dev_func), ai->irq, ai->mmio_phys); 133 137 134 138 for (i = 0; i <= HOST_CAP2; i += sizeof(u32)) { … … 144 148 if (i == HOST_VERSION) version = val; 145 149 146 ntprintf(" %02x: %08lx", i, val);150 NTPRINTF(" %02x: %08lx", i, val); 147 151 148 152 if (i == HOST_CAP) { 149 ntprintf(" -");150 if (val & HOST_CAP_64) ntprintf(" 64bit");151 if (val & HOST_CAP_NCQ) ntprintf(" ncq");152 if (val & HOST_CAP_SNTF) ntprintf(" sntf");153 if (val & HOST_CAP_MPS) ntprintf(" mps");154 if (val & HOST_CAP_SSS) ntprintf(" sss");155 if (val & HOST_CAP_ALPM) ntprintf(" alpm");156 if (val & HOST_CAP_LED) ntprintf(" led");157 if (val & HOST_CAP_CLO) ntprintf(" clo");158 if (val & HOST_CAP_ONLY) ntprintf(" ahci_only");159 if (val & HOST_CAP_PMP) ntprintf(" pmp");160 if (val & HOST_CAP_FBS) ntprintf(" fbs");161 if (val & HOST_CAP_PIO_MULTI) ntprintf(" pio_multi");162 if (val & HOST_CAP_SSC) ntprintf(" ssc");163 if (val & HOST_CAP_PART) ntprintf(" part");164 if (val & HOST_CAP_CCC) ntprintf(" ccc");165 if (val & HOST_CAP_EMS) ntprintf(" ems");166 if (val & HOST_CAP_SXS) ntprintf(" sxs");167 ntprintf(" cmd_slots:%d", (u16)((val >> 8) & 0x1f) + 1);168 ntprintf(" ports:%d", (u16)(val & 0x1f) + 1);153 NTPRINTF(" -"); 154 if (val & HOST_CAP_64) NTPRINTF(" 64bit"); 155 if (val & HOST_CAP_NCQ) NTPRINTF(" ncq"); 156 if (val & HOST_CAP_SNTF) NTPRINTF(" sntf"); 157 if (val & HOST_CAP_MPS) NTPRINTF(" mps"); 158 if (val & HOST_CAP_SSS) NTPRINTF(" sss"); 159 if (val & HOST_CAP_ALPM) NTPRINTF(" alpm"); 160 if (val & HOST_CAP_LED) NTPRINTF(" led"); 161 if (val & HOST_CAP_CLO) NTPRINTF(" clo"); 162 if (val & HOST_CAP_ONLY) NTPRINTF(" ahci_only"); 163 if (val & HOST_CAP_PMP) NTPRINTF(" pmp"); 164 if (val & HOST_CAP_FBS) NTPRINTF(" fbs"); 165 if (val & HOST_CAP_PIO_MULTI) NTPRINTF(" pio_multi"); 166 if (val & HOST_CAP_SSC) NTPRINTF(" ssc"); 167 if (val & HOST_CAP_PART) NTPRINTF(" part"); 168 if (val & HOST_CAP_CCC) NTPRINTF(" ccc"); 169 if (val & HOST_CAP_EMS) NTPRINTF(" ems"); 170 if (val & HOST_CAP_SXS) NTPRINTF(" sxs"); 171 NTPRINTF(" cmd_slots:%d", ((val >> 8) & 0x1f) + 1); 172 NTPRINTF(" ports:%d", (val & 0x1f) + 1); 169 173 } else if (i == HOST_CTL) { 170 ntprintf(" -");171 if (val & HOST_AHCI_EN) ntprintf(" ahci_enabled");172 if (val & HOST_IRQ_EN) ntprintf(" irq_enabled");173 if (val & HOST_RESET) ntprintf(" resetting");174 NTPRINTF(" -"); 175 if (val & HOST_AHCI_EN) NTPRINTF(" ahci_enabled"); 176 if (val & HOST_IRQ_EN) NTPRINTF(" irq_enabled"); 177 if (val & HOST_RESET) NTPRINTF(" resetting"); 174 178 } else if (i == HOST_CAP2) { 175 ntprintf(" -"); 176 if (val & HOST_CAP2_BOH) ntprintf(" boh"); 177 if (val & HOST_CAP2_NVMHCI) ntprintf(" nvmhci"); 178 if (val & HOST_CAP2_APST) ntprintf(" apst"); 179 } 180 ntprintf("\n"); 181 } 182 #endif 179 NTPRINTF(" -"); 180 if (val & HOST_CAP2_BOH) NTPRINTF(" boh"); 181 if (val & HOST_CAP2_NVMHCI) NTPRINTF(" nvmhci"); 182 if (val & HOST_CAP2_APST) NTPRINTF(" apst"); 183 } 184 NTPRINTF("\n"); 185 } 183 186 } 184 187 185 188 void ahci_dump_port_regs(AD_INFO *ai, int p) 186 189 { 187 #ifdef DEBUG 188 u8 _far *port_mmio = port_base(ai, p); 189 190 aprintf("AHCI port %d registers:\n", p); 191 ntprintf(" PORT_CMD = 0x%lx\n", readl(port_mmio + PORT_CMD)); 192 ntprintf("command engine status:\n"); 193 ntprintf(" PORT_SCR_ACT = 0x%lx\n", readl(port_mmio + PORT_SCR_ACT)); 194 ntprintf(" PORT_CMD_ISSUE = 0x%lx\n", readl(port_mmio + PORT_CMD_ISSUE)); 195 ntprintf("link/device status:\n"); 196 ntprintf(" PORT_SCR_STAT = 0x%lx\n", readl(port_mmio + PORT_SCR_STAT)); 197 ntprintf(" PORT_SCR_CTL = 0x%lx\n", readl(port_mmio + PORT_SCR_CTL)); 198 ntprintf(" PORT_SCR_ERR = 0x%lx\n", readl(port_mmio + PORT_SCR_ERR)); 199 ntprintf(" PORT_TFDATA = 0x%lx\n", readl(port_mmio + PORT_TFDATA)); 200 ntprintf("interrupt status:\n"); 201 ntprintf(" PORT_IRQ_STAT = 0x%lx\n", readl(port_mmio + PORT_IRQ_STAT)); 202 ntprintf(" PORT_IRQ_MASK = 0x%lx\n", readl(port_mmio + PORT_IRQ_MASK)); 203 ntprintf(" HOST_IRQ_STAT = 0x%lx\n", readl(ai->mmio + HOST_IRQ_STAT)); 204 #endif 205 } 190 u8 *port_mmio = port_base(ai, p); 191 192 dprintf(0,"AHCI port %d registers:\n", p); 193 dprintf(0," PORT_CMD = 0x%x\n", readl(port_mmio + PORT_CMD)); 194 dprintf(0," command engine status:\n"); 195 dprintf(0," PORT_SCR_ACT = 0x%x\n", readl(port_mmio + PORT_SCR_ACT)); 196 dprintf(0," PORT_CMD_ISSUE = 0x%x\n", readl(port_mmio + PORT_CMD_ISSUE)); 197 dprintf(0," link/device status:\n"); 198 dprintf(0," PORT_SCR_STAT = 0x%x\n", readl(port_mmio + PORT_SCR_STAT)); 199 dprintf(0," PORT_SCR_CTL = 0x%x\n", readl(port_mmio + PORT_SCR_CTL)); 200 dprintf(0," PORT_SCR_ERR = 0x%x\n", readl(port_mmio + PORT_SCR_ERR)); 201 dprintf(0," PORT_TFDATA = 0x%x\n", readl(port_mmio + PORT_TFDATA)); 202 dprintf(0," interrupt status:\n"); 203 dprintf(0," PORT_IRQ_STAT = 0x%x\n", readl(port_mmio + PORT_IRQ_STAT)); 204 dprintf(0," PORT_IRQ_MASK = 0x%x\n", readl(port_mmio + PORT_IRQ_MASK)); 205 dprintf(0," HOST_IRQ_STAT = 0x%x\n", readl(ai->mmio + HOST_IRQ_STAT)); 206 } 207 #endif 206 208 207 209 /****************************************************************************** … … 221 223 222 224 /* save BIOS configuration */ 223 for (i = 0; i < HOST_CAP2; i += sizeof(u32)) { 225 for (i = 0; i < HOST_CAP2; i += sizeof(u32)) 226 { 224 227 ai->bios_config[i / sizeof(u32)] = readl(ai->mmio + i); 225 228 } 226 229 227 ddprintf("ahci_save_bios_config: BIOS AHCI mode is %d\n", ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN);230 DPRINTF(3,"ahci_save_bios_config: BIOS AHCI mode is %d\n", ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN); 228 231 229 232 /* HOST_CAP2 only exists for AHCI V1.2 and later */ 230 if (ai->bios_config[HOST_VERSION / sizeof(u32)] >= 0x00010200L) { 233 if (ai->bios_config[HOST_VERSION / sizeof(u32)] >= 0x00010200L) 234 { 231 235 ai->bios_config[HOST_CAP2 / sizeof(u32)] = readl(ai->mmio + HOST_CAP2); 232 } else { 236 } 237 else 238 { 233 239 ai->bios_config[HOST_CAP2 / sizeof(u32)] = 0; 234 240 } 235 241 236 242 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && 237 ai->pci_vendor == PCI_VENDOR_ID_INTEL) { 243 ai->pci_vendor == PCI_VENDOR_ID_INTEL) 244 { 238 245 /* Adapter is not in AHCI mode and the spec says a COMRESET is 239 246 * required when switching from SATA to AHCI mode and vice versa. … … 242 249 } 243 250 244 #ifdef DEBUG 245 /* print AHCI register debug information */ 246 if (debug) ahci_dump_host_regs(ai, 1); 247 #endif 251 DUMP_HOST_REGS(2,ai,1); 248 252 249 253 /* Save working copies of CAP, CAP2 and port_map and remove broken feature … … 255 259 ai->port_map = ai->bios_config[HOST_PORTS_IMPL / sizeof(u32)]; 256 260 257 if (ai->pci->board >= sizeof(initial_flags) / sizeof(*initial_flags)) { 258 dprintf("error: invalid board index in PCI info\n"); 261 if (ai->pci->board >= sizeof(initial_flags) / sizeof(*initial_flags)) 262 { 263 DPRINTF(0,"error: invalid board index in PCI info\n"); 259 264 return(-1); 260 265 } … … 262 267 ai->hw_ports = (ai->cap & 0x1f) + 1; 263 268 264 if ((ai->cap & HOST_CAP_64) && (ai->flags & AHCI_HFLAG_32BIT_ONLY)) { 269 if ((ai->cap & HOST_CAP_64) && (ai->flags & AHCI_HFLAG_32BIT_ONLY)) 270 { 265 271 /* disable 64-bit support for faulty controllers; OS/2 can't do 64 bits at 266 272 * this point, of course, but who knows where all this will be in a few … … 270 276 } 271 277 272 if ((ai->cap & HOST_CAP_NCQ) && (ai->flags & AHCI_HFLAG_NO_NCQ)) { 273 dprintf("controller can't do NCQ, turning off CAP_NCQ\n"); 278 if ((ai->cap & HOST_CAP_NCQ) && (ai->flags & AHCI_HFLAG_NO_NCQ)) 279 { 280 DPRINTF(1,"controller can't do NCQ, turning off CAP_NCQ\n"); 274 281 ai->cap &= ~HOST_CAP_NCQ; 275 282 } 276 283 277 if (!(ai->cap & HOST_CAP_NCQ) && (ai->flags & AHCI_HFLAG_YES_NCQ)) { 278 dprintf("controller can do NCQ, turning on CAP_NCQ\n"); 284 if (!(ai->cap & HOST_CAP_NCQ) && (ai->flags & AHCI_HFLAG_YES_NCQ)) 285 { 286 DPRINTF(1,"controller can do NCQ, turning on CAP_NCQ\n"); 279 287 ai->cap |= HOST_CAP_NCQ; 280 288 } 281 289 282 if ((ai->cap & HOST_CAP_PMP) && (ai->flags & AHCI_HFLAG_NO_PMP)) { 283 dprintf("controller can't do PMP, turning off CAP_PMP\n"); 290 if ((ai->cap & HOST_CAP_PMP) && (ai->flags & AHCI_HFLAG_NO_PMP)) 291 { 292 DPRINTF(1,"controller can't do PMP, turning off CAP_PMP\n"); 284 293 ai->cap |= HOST_CAP_PMP; 285 294 } 286 295 287 if ((ai->cap & HOST_CAP_SNTF) && (ai->flags & AHCI_HFLAG_NO_SNTF)) { 288 dprintf("controller can't do SNTF, turning off CAP_SNTF\n"); 296 if ((ai->cap & HOST_CAP_SNTF) && (ai->flags & AHCI_HFLAG_NO_SNTF)) 297 { 298 DPRINTF(1,"controller can't do SNTF, turning off CAP_SNTF\n"); 289 299 ai->cap &= ~HOST_CAP_SNTF; 290 300 } 291 301 292 if (ai->pci_vendor == PCI_VENDOR_ID_JMICRON && 293 ai->pci_device == 0x2361 && ai->port_map != 1){294 dprintf("JMB361 has only one port, port_map 0x%lx -> 0x%lx\n", ai->port_map, 1);302 if (ai->pci_vendor == PCI_VENDOR_ID_JMICRON && ai->pci_device == 0x2361 && ai->port_map != 1) 303 { 304 DPRINTF(1,"JMB361 has only one port, port_map 0x%x -> 0x%x\n", ai->port_map, 1); 295 305 ai->port_map = 1; 296 306 ai->hw_ports = 1; … … 307 317 */ 308 318 ports = ai->hw_ports; 309 for (i = 0; i < AHCI_MAX_PORTS; i++) { 310 if (ai->port_map & (1UL << i)) { 319 for (i = 0; i < AHCI_MAX_PORTS; i++) 320 { 321 if (ai->port_map & (1UL << i)) 322 { 311 323 ports--; 312 324 } 313 325 } 314 if (ports < 0) { 326 if (ports < 0) 327 { 315 328 /* more ports in port_map than in HOST_CAP & 0x1f */ 316 329 ports = ai->hw_ports; 317 dprintf("implemented port map (0x%lx) contains more ports than nr_ports (%d), using nr_ports\n", ai->port_map, ports);330 DPRINTF(1,"implemented port map (0x%x) contains more ports than nr_ports (%d), using nr_ports\n", ai->port_map, ports); 318 331 ai->port_map = (1UL << ports) - 1UL; 319 332 } 320 333 321 334 /* set maximum command slot number */ 322 ai->cmd_max = ( u16) ((ai->cap >> 8) & 0x1f);335 ai->cmd_max = ((ai->cap >> 8) & 0x1f); 323 336 324 337 return(0); … … 332 345 int ahci_restore_bios_config(AD_INFO *ai) 333 346 { 334 ddprintf("ahci_restore_bios_config: restoring AHCI BIOS configuration on adapter %d\n", ad_no(ai));347 DPRINTF(3,"ahci_restore_bios_config: restoring AHCI BIOS configuration on adapter %d\n", ad_no(ai)); 335 348 336 349 /* Restore saved BIOS configuration; please note that HOST_CTL is restored … … 345 358 readl(ai->mmio + HOST_CTL); 346 359 347 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && ai->pci_vendor == PCI_VENDOR_ID_INTEL) {348 360 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && ai->pci_vendor == PCI_VENDOR_ID_INTEL) 361 { 349 362 /* This BIOS apparently accesses the controller via SATA registers and 350 363 * the AHCI spec says that we should issue a COMRESET on each port after … … 361 374 int p; 362 375 363 for (p = 0; p < AHCI_MAX_PORTS; p++) { 364 if (ai->port_map & (1UL << p)) { 365 u8 _far *port_mmio = port_base(ai, p); 376 for (p = 0; p < AHCI_MAX_PORTS; p++) 377 { 378 if (ai->port_map & (1UL << p)) 379 { 380 u8 *port_mmio = port_base(ai, p); 366 381 u32 tmp; 367 382 … … 388 403 int ahci_restore_initial_config(AD_INFO *ai) 389 404 { 390 ddprintf("ahci_restore_initial_config: restoring initial configuration on adapter %d\n", ad_no(ai));405 DPRINTF(3,"ahci_restore_initial_config: restoring initial configuration on adapter %d\n", ad_no(ai)); 391 406 392 407 /* restore saved BIOS configuration */ … … 413 428 TIMER Timer; 414 429 415 dprintf("controller reset starting on adapter %d\n", ad_no(ai));430 DPRINTF(2,"controller reset starting on adapter %d\n", ad_no(ai)); 416 431 417 432 /* we must be in AHCI mode, before using anything AHCI-specific, such as HOST_RESET. */ … … 431 446 * the hardware should be considered fried. 432 447 */ 433 timer_init(&Timer, 1000);448 TimerInit(&Timer, 1000); 434 449 while (((tmp = readl(ai->mmio + HOST_CTL)) & HOST_RESET) != 0) { 435 if ( timer_check_and_block(&Timer)) {436 dprintf("controller reset failed (0x%lx)\n", tmp);450 if (TimerCheckAndBlock(&Timer)) { 451 DPRINTF(0,"controller reset failed (0x%x)\n", tmp); 437 452 return(-1); 438 453 } … … 448 463 u32 tmp16 = 0; 449 464 450 ddprintf("ahci_reset_controller: intel detected\n");465 DPRINTF(1,"ahci_reset_controller: intel detected\n"); 451 466 /* configure PCS */ 452 pci_read_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), &tmp16);467 PciReadConfig(ai->bus, ai->dev_func, 0x92, sizeof(u16), &tmp16); 453 468 if ((tmp16 & ai->port_map) != ai->port_map) { 454 ddprintf("ahci_reset_controller: updating PCS %x/%x\n", (u16)tmp16, ai->port_map);469 DPRINTF(3,"ahci_reset_controller: updating PCS %x/%x\n", tmp16, ai->port_map); 455 470 tmp16 |= ai->port_map; 456 pci_write_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), tmp16);471 PciWriteConfig(ai->bus, ai->dev_func, 0x92, sizeof(u16), tmp16); 457 472 } 458 473 } … … 472 487 { 473 488 AHCI_PORT_CFG *pc; 474 u8 _far *port_mmio = port_base(ai, p); 475 476 if ((pc = malloc(sizeof(*pc))) == NULL) { 477 return(NULL); 478 } 489 u8 *port_mmio = port_base(ai, p); 490 491 if ((pc = MemAlloc(sizeof(*pc))) == NULL) return(NULL); 479 492 480 493 pc->cmd_list = readl(port_mmio + PORT_LST_ADDR); … … 496 509 void ahci_restore_port_config(AD_INFO *ai, int p, AHCI_PORT_CFG *pc) 497 510 { 498 u8 _far*port_mmio = port_base(ai, p);511 u8 *port_mmio = port_base(ai, p); 499 512 500 513 /* stop the port, first */ 501 514 ahci_stop_port(ai, p); 502 515 503 if (ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) { 516 if (ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) 517 { 504 518 /* BIOS uses AHCI, too, so we need to restore the port settings; 505 519 * restoring PORT_CMD may well start the port again but that's what … … 516 530 } 517 531 518 free(pc);532 MemFree(pc); 519 533 } 520 534 … … 527 541 int i; 528 542 529 if (ctl & HOST_AHCI_EN) { 543 if (ctl & HOST_AHCI_EN) 544 { 530 545 /* AHCI mode already enabled */ 531 546 return(0); … … 533 548 534 549 /* some controllers need AHCI_EN to be written multiple times */ 535 for (i = 0; i < 5; i++) { 550 for (i = 0; i < 5; i++) 551 { 536 552 ctl |= HOST_AHCI_EN; 537 553 writel(ai->mmio + HOST_CTL, ctl); 538 554 ctl = readl(ai->mmio + HOST_CTL); /* flush && sanity check */ 539 if (ctl & HOST_AHCI_EN) { 555 if (ctl & HOST_AHCI_EN) 556 { 540 557 return(0); 541 558 } … … 544 561 545 562 /* couldn't enable AHCI mode */ 546 dprintf("failed to enable AHCI mode on adapter %d\n", ad_no(ai));563 DPRINTF(0,"failed to enable AHCI mode on adapter %d\n", ad_no(ai)); 547 564 return(1); 548 565 } … … 575 592 TIMER Timer; 576 593 577 if ((id_buf = malloc(ATA_ID_WORDS * sizeof(u16))) == NULL) { 578 return(-1); 579 } 580 581 if (ai->bios_config[0] == 0) { 582 /* first call */ 583 ahci_save_bios_config(ai); 584 } 585 586 if (ahci_enable_ahci(ai)) { 587 goto exit_port_scan; 588 } 594 if ((id_buf = MemAlloc(ATA_ID_WORDS * sizeof(u16))) == NULL) return(-1); 595 596 if (ai->bios_config[0] == 0) ahci_save_bios_config(ai); /* first call */ 597 598 if (ahci_enable_ahci(ai)) goto exit_port_scan; 589 599 590 600 /* perform port scan */ 591 dprintf("ahci_scan_ports: scanning ports on adapter %d\n", ad_no(ai)); 592 for (p = 0; p < AHCI_MAX_PORTS; p++) { 601 DPRINTF(1,"ahci_scan_ports: scanning ports on adapter %d\n", ad_no(ai)); 602 for (p = 0; p < AHCI_MAX_PORTS; p++) 603 { 593 604 if (!(ai->port_map & (1UL << p))) continue; 594 605 if (port_ignore[ad_no(ai)][p]) continue; 595 606 596 ddprintf("ahci_scan_ports: Wait till not busy on port %d\n", p);607 DPRINTF(3,"ahci_scan_ports: Wait till not busy on port %d\n", p); 597 608 /* wait until all active commands have completed on this port */ 598 timer_init(&Timer, 250);599 while (ahci_port_busy(ai, p)) {600 if (timer_check_and_block(&Timer)) break;601 }602 603 if (!init_complete) { 604 if ((pc = ahci_save_port_config(ai, p)) == NULL) {605 goto exit_port_scan;606 }609 TimerInit(&Timer, 250); 610 while (ahci_port_busy(ai, p)) 611 { 612 if (TimerCheckAndBlock(&Timer)) break; 613 } 614 615 if (!init_complete) 616 { 617 if ((pc = ahci_save_port_config(ai, p)) == NULL) goto exit_port_scan; 607 618 } 608 619 609 620 /* start/reset port; if no device is attached, this is expected to fail */ 610 if (init_reset) { 621 if (init_reset) 622 { 611 623 rc = ahci_reset_port(ai, p, 0); 612 } else { 613 ddprintf("ahci_scan_ports: (re)starting port %d\n", p); 624 } 625 else 626 { 627 DPRINTF(3,"ahci_scan_ports: (re)starting port %d\n", p); 614 628 ahci_stop_port(ai, p); 615 629 rc = ahci_start_port(ai, p, 0); 616 630 } 617 if (rc) { 631 if (rc) 632 { 618 633 /* no device attached to this port */ 619 634 ai->port_map &= ~(1UL << p); … … 622 637 623 638 /* this port seems to have a device attached and ready for commands */ 624 ddprintf("ahci_scan_ports: port %d seems to be attached to a device; probing...\n", p);639 DPRINTF(1,"ahci_scan_ports: port %d seems to be attached to a device; probing...\n", p); 625 640 626 641 /* Get ATA(PI) identity. The so-called signature gives us a hint whether … … 632 647 */ 633 648 is_ata = readl(port_base(ai, p) + PORT_SIG) == 0x00000101UL; 634 for (i = 0; i < 2; i++) { 649 for (i = 0; i < 2; i++) 650 { 635 651 rc = ahci_exec_polled_cmd(ai, p, 0, 500, 636 652 (is_ata) ? ATA_CMD_ID_ATA : ATA_CMD_ID_ATAPI, 637 AP_VADDR, (void _far *) id_buf, 512,653 AP_VADDR, (void *) id_buf, ATA_ID_WORDS * sizeof(u16), 638 654 AP_END); 639 if (rc == 0) { 640 break; 641 } 655 if (rc == 0) break; 642 656 643 657 /* try again with ATA/ATAPI swapped */ … … 645 659 } 646 660 647 if (rc == 0) { 661 if (rc == 0) 662 { 648 663 /* we have a valid IDENTIFY or IDENTIFY_PACKET response */ 649 ddphex(id_buf, 512, "ATA_IDENTIFY%s results:\n", (is_ata) ? "" : "_PACKET");664 DHEXDUMP(2,id_buf, ATA_ID_WORDS * sizeof(u16), "ATA_IDENTIFY%s results:\n", (is_ata) ? "" : "_PACKET"); 650 665 ahci_setup_device(ai, p, 0, id_buf); 651 } else { 666 } 667 else 668 { 652 669 /* no device attached to this port */ 653 670 ai->port_map &= ~(1UL << p); … … 661 678 662 679 exit_port_scan: 663 if (!init_complete) { 680 if (!init_complete) 681 { 664 682 ahci_restore_bios_config(ai); 665 683 } 666 free(id_buf);684 MemFree(id_buf); 667 685 return(0); 668 686 } … … 676 694 { 677 695 int rc; 678 intp;696 u32 p; 679 697 int i; 680 698 681 dprintf("ahci_complete_init: completing initialization of adapter #%d\n", ad_no(ai));699 DPRINTF(1,"ahci_complete_init: completing initialization of adapter #%d\n", ad_no(ai)); 682 700 683 701 /* register IRQ handlers; each IRQ level is registered only once */ 684 for (i = 0; i < irq_map_cnt; i++) { 685 if (irq_map[i] == ai->irq) { 686 /* we already have this IRQ registered */ 687 break; 688 } 689 } 690 if (i >= irq_map_cnt) { 691 dprintf("registering interrupt #%d\n", ai->irq); 692 if (DevHelp_SetIRQ(mk_NPFN(irq_handlers[irq_map_cnt]), ai->irq, 1) != 0) { 693 dprintf("failed to register shared interrupt\n"); 694 if (DevHelp_SetIRQ(mk_NPFN(irq_handlers[irq_map_cnt]), ai->irq, 0) != 0) { 695 dprintf("failed to register exclusive interrupt\n"); 702 for (i = 0; i < irq_map_cnt; i++) 703 { 704 if (irq_map[i] == ai->irq) break; /* we already have this IRQ registered */ 705 } 706 if (i >= irq_map_cnt) 707 { 708 DPRINTF(2,"registering interrupt #%d\n", ai->irq); 709 if (Dev32Help_SetIRQ(irq_handlers[irq_map_cnt], ai->irq, 1) != 0) 710 { 711 DPRINTF(0,"failed to register shared interrupt\n"); 712 if (Dev32Help_SetIRQ(irq_handlers[irq_map_cnt], ai->irq, 0) != 0) 713 { 714 DPRINTF(0,"failed to register exclusive interrupt\n"); 696 715 return(-1); 697 716 } … … 701 720 702 721 /* enable AHCI mode */ 703 if ((rc = ahci_enable_ahci(ai)) != 0) { 704 return(rc); 705 } 722 if ((rc = ahci_enable_ahci(ai)) != 0) return(rc); 706 723 707 724 /* Start all ports. The main purpose is to set the command list and FIS … … 710 727 * enough if a previously detected device has problems. 711 728 */ 712 for (p = 0; p < AHCI_MAX_PORTS; p++) { 713 if (ai->port_map & (1UL << p)) { 714 if (init_reset) { 715 ddprintf("ahci_complete_init: resetting port %d\n", p); 729 for (p = 0; p < AHCI_MAX_PORTS; p++) 730 { 731 if (ai->port_map & (1UL << p)) 732 { 733 if (init_reset) 734 { 735 DPRINTF(3,"ahci_complete_init: resetting port %d\n", p); 716 736 ahci_reset_port(ai, p, 1); 717 } else { 718 ddprintf("ahci_complete_init: restarting port #%d\n", p); 737 } 738 else 739 { 740 DPRINTF(3,"ahci_complete_init: restarting port #%d\n", p); 719 741 ahci_stop_port(ai, p); 720 742 ahci_start_port(ai, p, 1); … … 734 756 /* pci_enable_int(ai->bus, ai->dev_func); */ 735 757 758 DPRINTF(1,"ahci_complete_init: done\n"); 736 759 return(0); 737 760 } … … 751 774 int ahci_reset_port(AD_INFO *ai, int p, int ei) 752 775 { 753 u8 _far*port_mmio = port_base(ai, p);776 u8 *port_mmio = port_base(ai, p); 754 777 u32 tmp; 755 778 TIMER Timer; 756 779 757 dprintf("ahci_reset_port: resetting port %d.%d\n", ad_no(ai), p);758 if (debug > 1) ahci_dump_port_regs(ai,p);780 DPRINTF(2,"ahci_reset_port: resetting port %d.%d\n", ad_no(ai), p); 781 DUMP_PORT_REGS(2,ai,p); 759 782 760 783 /* stop port engines (we don't care whether there is an error doing so) */ … … 772 795 773 796 /* set link speed and power management options */ 774 ddprintf("ahci_reset_port: setting link speed and power management options\n");797 DPRINTF(3,"ahci_reset_port: setting link speed and power management options\n"); 775 798 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000fffUL; 776 tmp |= ( (u32)link_speed[ad_no(ai)][p] & 0x0f) << 4;777 tmp |= ( (u32)link_power[ad_no(ai)][p] & 0x0f) << 8;799 tmp |= (link_speed[ad_no(ai)][p] & 0x0f) << 4; 800 tmp |= (link_power[ad_no(ai)][p] & 0x0f) << 8; 778 801 writel(port_mmio + PORT_SCR_CTL, tmp); 779 802 780 803 /* issue COMRESET on the port */ 781 ddprintf("ahci_reset_port: issuing COMRESET on port %d\n", p);804 DPRINTF(3,"ahci_reset_port: issuing COMRESET on port %d\n", p); 782 805 writel(port_mmio + PORT_SCR_CTL, tmp | 1); 783 806 readl(port_mmio + PORT_SCR_CTL); /* flush */ … … 790 813 791 814 /* wait for communication to be re-established after port reset */ 792 dprintf("Wait for communication...\n"); 793 timer_init(&Timer, 500); 794 while (((tmp = readl(port_mmio + PORT_SCR_STAT)) & 3) != 3) { 795 if (timer_check_and_block(&Timer)) { 796 dprintf("no device present after resetting port #%d (PORT_SCR_STAT = 0x%lx)\n", p, tmp); 815 DPRINTF(2,"Wait for communication...\n"); 816 TimerInit(&Timer, 500); 817 while (((tmp = readl(port_mmio + PORT_SCR_STAT)) & 3) != 3) 818 { 819 if (TimerCheckAndBlock(&Timer)) 820 { 821 DPRINTF(0,"no device present after resetting port #%d (PORT_SCR_STAT = 0x%x)\n", p, tmp); 797 822 return(-1); 798 823 } … … 804 829 805 830 /* start port so we can receive the COMRESET FIS */ 806 dprintf("ahci_reset_port: starting port %d again\n", p);831 DPRINTF(2,"ahci_reset_port: starting port %d again\n", p); 807 832 ahci_start_port(ai, p, ei); 808 833 809 834 /* wait for device to be ready ((PxTFD & (BSY | DRQ | ERR)) == 0) */ 810 timer_init(&Timer, 1000); 811 while (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) { 812 if (timer_check_and_block(&Timer)) { 813 dprintf("device not ready on port #%d (PORT_TFDATA = 0x%lx)\n", p, tmp); 835 TimerInit(&Timer, 1000); 836 while (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) 837 { 838 if (TimerCheckAndBlock(&Timer)) 839 { 840 DPRINTF(0,"device not ready on port #%d (PORT_TFDATA = 0x%x)\n", p, tmp); 814 841 ahci_stop_port(ai, p); 815 842 return(-1); 816 843 } 817 844 } 818 ddprintf("ahci_reset_port: PORT_TFDATA = 0x%lx\n", readl(port_mmio + PORT_TFDATA));845 DPRINTF(3,"ahci_reset_port: PORT_TFDATA = 0x%x\n", readl(port_mmio + PORT_TFDATA)); 819 846 820 847 return(0); … … 826 853 int ahci_start_port(AD_INFO *ai, int p, int ei) 827 854 { 828 u8 _far*port_mmio = port_base(ai, p);855 u8 *port_mmio = port_base(ai, p); 829 856 u32 status; 830 857 831 ddprintf("ahci_start_port %d.%d\n", ad_no(ai), p);858 DPRINTF(3,"ahci_start_port %d.%d\n", ad_no(ai), p); 832 859 /* check whether device presence is detected and link established */ 833 860 834 861 status = readl(port_mmio + PORT_SCR_STAT); 835 ddprintf("ahci_start_port: PORT_SCR_STAT = 0x%lx\n", status); 836 if ((status & 0xf) != 3) { 837 return(-1); 838 } 862 DPRINTF(3,"ahci_start_port: PORT_SCR_STAT = 0x%x\n", status); 863 if ((status & 0xf) != 3) return(-1); 839 864 840 865 /* clear SError, if any */ 841 866 status = readl(port_mmio + PORT_SCR_ERR); 842 ddprintf("ahci_start_port: PORT_SCR_ERR = 0x%lx\n", status);867 DPRINTF(3,"ahci_start_port: PORT_SCR_ERR = 0x%x\n", status); 843 868 writel(port_mmio + PORT_SCR_ERR, status); 844 869 … … 849 874 ahci_start_engine(ai, p); 850 875 851 if (ei) { 876 if (ei) 877 { 852 878 /* clear any pending interrupts on this port */ 853 if ((status = readl(port_mmio + PORT_IRQ_STAT)) != 0) { 879 if ((status = readl(port_mmio + PORT_IRQ_STAT)) != 0) 880 { 854 881 writel(port_mmio + PORT_IRQ_STAT, status); 855 882 } … … 867 894 PORT_IRQ_PIOS_FIS | 868 895 PORT_IRQ_D2H_REG_FIS); 869 } else { 896 } 897 else 898 { 870 899 writel(port_mmio + PORT_IRQ_MASK, 0); 871 900 } … … 881 910 void ahci_start_fis_rx(AD_INFO *ai, int p) 882 911 { 883 u8 _far*port_mmio = port_base(ai, p);912 u8 *port_mmio = port_base(ai, p); 884 913 u32 port_dma = port_dma_base_phys(ai, p); 885 914 u32 tmp; … … 905 934 void ahci_start_engine(AD_INFO *ai, int p) 906 935 { 907 u8 _far*port_mmio = port_base(ai, p);936 u8 *port_mmio = port_base(ai, p); 908 937 u32 tmp; 909 938 … … 920 949 int ahci_stop_port(AD_INFO *ai, int p) 921 950 { 922 u8 _far*port_mmio = port_base(ai, p);951 u8 *port_mmio = port_base(ai, p); 923 952 u32 tmp; 924 953 int rc; 925 954 926 ddprintf("ahci_stop_port %d.%d\n", ad_no(ai), p);955 DPRINTF(3,"ahci_stop_port %d.%d\n", ad_no(ai), p); 927 956 928 957 /* disable port interrupts */ … … 930 959 931 960 /* disable FIS reception */ 932 if ((rc = ahci_stop_fis_rx(ai, p)) != 0) { 933 dprintf("error: failed to stop FIS receive (%d)\n", rc); 961 if ((rc = ahci_stop_fis_rx(ai, p)) != 0) 962 { 963 DPRINTF(0,"error: failed to stop FIS receive (%d)\n", rc); 934 964 return(rc); 935 965 } 936 966 937 967 /* disable command engine */ 938 if ((rc = ahci_stop_engine(ai, p)) != 0) { 939 dprintf("error: failed to stop port HW engine (%d)\n", rc); 968 if ((rc = ahci_stop_engine(ai, p)) != 0) 969 { 970 DPRINTF(0,"error: failed to stop port HW engine (%d)\n", rc); 940 971 return(rc); 941 972 } … … 943 974 /* clear any pending port IRQs */ 944 975 tmp = readl(port_mmio + PORT_IRQ_STAT); 945 if (tmp) { 946 writel(port_mmio + PORT_IRQ_STAT, tmp); 947 } 976 if (tmp) writel(port_mmio + PORT_IRQ_STAT, tmp); 948 977 writel(ai->mmio + HOST_IRQ_STAT, 1UL << p); 949 978 … … 965 994 int ahci_stop_fis_rx(AD_INFO *ai, int p) 966 995 { 967 u8 _far*port_mmio = port_base(ai, p);996 u8 *port_mmio = port_base(ai, p); 968 997 TIMER Timer; 969 998 u32 tmp; … … 977 1006 /* wait for completion, spec says 500ms, give it 1000ms */ 978 1007 status = 0; 979 timer_init(&Timer, 1000); 980 while (readl(port_mmio + PORT_CMD) & PORT_CMD_FIS_ON) { 981 status = timer_check_and_block(&Timer); 1008 TimerInit(&Timer, 1000); 1009 while (readl(port_mmio + PORT_CMD) & PORT_CMD_FIS_ON) 1010 { 1011 status = TimerCheckAndBlock(&Timer); 982 1012 if (status) break; 983 1013 } … … 995 1025 int ahci_stop_engine(AD_INFO *ai, int p) 996 1026 { 997 u8 _far*port_mmio = port_base(ai, p);1027 u8 *port_mmio = port_base(ai, p); 998 1028 TIMER Timer; 999 1029 int status; … … 1003 1033 1004 1034 /* check if the port is already stopped */ 1005 if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) { 1006 return 0; 1007 } 1035 if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) return 0; 1008 1036 1009 1037 /* set port to idle */ … … 1013 1041 /* wait for engine to stop. This could be as long as 500 msec */ 1014 1042 status = 0; 1015 timer_init(&Timer, 500); 1016 while (readl(port_mmio + PORT_CMD) & PORT_CMD_LIST_ON) { 1017 status = timer_check_and_block(&Timer); 1043 TimerInit(&Timer, 500); 1044 while (readl(port_mmio + PORT_CMD) & PORT_CMD_LIST_ON) 1045 { 1046 status = TimerCheckAndBlock(&Timer); 1018 1047 if (status) break; 1019 1048 } … … 1027 1056 int ahci_port_busy(AD_INFO *ai, int p) 1028 1057 { 1029 u8 _far *port_mmio = port_base(ai, p); 1030 1031 return(readl(port_mmio + PORT_SCR_ACT) != 0 || 1032 readl(port_mmio + PORT_CMD_ISSUE) != 0); 1058 u8 *port_mmio = port_base(ai, p); 1059 1060 return(readl(port_mmio + PORT_SCR_ACT) != 0 || readl(port_mmio + PORT_CMD_ISSUE) != 0); 1033 1061 } 1034 1062 … … 1043 1071 * involve delays), we're going with the spinlock for the time being. 1044 1072 */ 1045 void ahci_exec_iorb(IORBH _far *iorb, int ncq_capable, 1046 int (*func)(IORBH _far *, int)) 1073 void ahci_exec_iorb(IORBH FAR16DATA *vIorb, IORBH *pIorb, int ncq_capable, int (*func)(IORBH FAR16DATA *, IORBH *pIorb, int)) 1047 1074 { 1048 1075 volatile u32 *cmds; 1049 ADD_WORKSPACE _far *aws = add_workspace(iorb);1050 AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb);1051 P_INFO *port = ai->ports + iorb_unit_port(iorb);1076 ADD_WORKSPACE *aws = add_workspace(pIorb); 1077 AD_INFO *ai = &ad_infos[iorb_unit_adapter(pIorb)]; 1078 P_INFO *port = &ai->ports[iorb_unit_port(pIorb)]; 1052 1079 ULONG timeout; 1053 u8 _far *port_mmio = port_base(ai, iorb_unit_port(iorb));1080 u8 *port_mmio = port_base(ai, iorb_unit_port(pIorb)); 1054 1081 u16 cmd_max = ai->cmd_max; 1055 1082 int i; 1056 1083 1057 1084 /* determine timeout in milliseconds */ 1058 switch (iorb->Timeout) { 1085 switch (pIorb->Timeout) 1086 { 1059 1087 case 0: 1060 1088 timeout = DEFAULT_TIMEOUT; … … 1064 1092 break; 1065 1093 default: 1066 timeout = iorb->Timeout * 1000;1094 timeout = pIorb->Timeout * 1000; 1067 1095 break; 1068 1096 } 1097 1098 DPRINTF(1,"---------- ahci_exec_iorb: iorb=%x\n", vIorb); 1069 1099 1070 1100 /* Enable AHCI mode; apparently, the AHCI mode may end up becoming … … 1078 1108 /* determine whether this will be an NCQ request */ 1079 1109 aws->is_ncq = 0; 1080 if (ncq_capable && port->devs[iorb_unit_device(iorb)].ncq_max > 1 && 1081 (ai->cap & HOST_CAP_NCQ) && !aws->no_ncq && init_complete) { 1110 if (ncq_capable && port->devs[iorb_unit_device(pIorb)].ncq_max > 1 && 1111 (ai->cap & HOST_CAP_NCQ) && !aws->no_ncq && init_complete) 1112 { 1082 1113 1083 1114 /* We can make this an NCQ request; limit command slots to the maximum … … 1087 1118 */ 1088 1119 aws->is_ncq = 1; 1089 if ((cmd_max = port->devs[iorb_unit_device(iorb)].ncq_max - 1) > ai->cmd_max) { 1120 if ((cmd_max = port->devs[iorb_unit_device(pIorb)].ncq_max - 1) > ai->cmd_max) 1121 { 1090 1122 cmd_max = ai->cmd_max; 1091 1123 } 1092 ddprintf("NCQ command; cmd_max = %d->%d\n", (u16)ai->cmd_max, cmd_max);1124 DPRINTF(3,"NCQ command; cmd_max = %d->%d\n", ai->cmd_max, cmd_max); 1093 1125 } 1094 1126 1095 1127 /* make sure adapter is available */ 1096 1128 spin_lock(drv_lock); 1097 if (!ai->busy) { 1098 1099 if (!init_complete) { 1129 if (!ai->busy) 1130 { 1131 1132 if (!init_complete) 1133 { 1100 1134 /* no IRQ handlers or context hooks availabe at this point */ 1101 1135 ai->busy = 1; 1102 1136 spin_unlock(drv_lock); 1103 ahci_exec_polled_iorb( iorb, func, timeout);1137 ahci_exec_polled_iorb(vIorb, pIorb, func, timeout); 1104 1138 ai->busy = 0; 1105 1139 return; … … 1107 1141 1108 1142 /* make sure we don't mix NCQ and regular commands */ 1109 if (aws->is_ncq && port->reg_cmds == 0 || !aws->is_ncq && port->ncq_cmds == 0) {1110 1143 if (aws->is_ncq && port->reg_cmds == 0 || !aws->is_ncq && port->ncq_cmds == 0) 1144 { 1111 1145 /* Find next available command slot. We use a simple round-robin 1112 1146 * algorithm for this to prevent commands with higher slot indexes … … 1114 1148 */ 1115 1149 cmds = (aws->is_ncq) ? &port->ncq_cmds : &port->reg_cmds; 1116 for (i = 0; i <= cmd_max; i++) { 1117 if (++(port->cmd_slot) > cmd_max) { 1118 port->cmd_slot = 0; 1119 } 1120 if ((*cmds & (1UL << port->cmd_slot)) == 0) { 1121 break; 1122 } 1150 for (i = 0; i <= cmd_max; i++) 1151 { 1152 if (++(port->cmd_slot) > cmd_max) port->cmd_slot = 0; 1153 if ((*cmds & (1UL << port->cmd_slot)) == 0) break; 1123 1154 } 1124 1155 1125 if ((*cmds & (1UL << port->cmd_slot)) == 0) { 1156 if ((*cmds & (1UL << port->cmd_slot)) == 0) 1157 { 1126 1158 /* found idle command slot; prepare command */ 1127 if (func(iorb, port->cmd_slot)) { 1159 if (func(vIorb, pIorb, port->cmd_slot)) 1160 { 1128 1161 /* Command preparation failed, or no HW command required; IORB 1129 1162 * will already have the error code if there was an error. 1130 1163 */ 1131 1164 spin_unlock(drv_lock); 1132 iorb_done( iorb);1165 iorb_done(vIorb, pIorb); 1133 1166 return; 1134 1167 } 1135 1168 1136 1169 /* start timer for this IORB */ 1137 ADD_StartTimerMS(&aws->timer, timeout, (PFN) timeout_callback, iorb, 0);1170 Timer_StartTimerMS(&aws->timer, timeout, timeout_callback, CastFar16ToULONG(vIorb)); 1138 1171 1139 1172 /* issue command to hardware */ … … 1142 1175 aws->cmd_slot = port->cmd_slot; 1143 1176 1144 ddprintf("issuing command on slot %d\n", port->cmd_slot); 1145 if (aws->is_ncq) { 1177 DPRINTF(1,"Issuing command Slot=%d cmds=%x\n", port->cmd_slot, *cmds); 1178 if (aws->is_ncq) 1179 { 1146 1180 writel(port_mmio + PORT_SCR_ACT, (1UL << port->cmd_slot)); 1147 1181 readl(port_mmio + PORT_SCR_ACT); /* flush */ … … 1178 1212 * without the driver-level spinlock held. 1179 1213 */ 1180 void ahci_exec_polled_iorb(IORBH _far *iorb, int (*func)(IORBH _far *, int), 1181 ULONG timeout) 1214 void ahci_exec_polled_iorb(IORBH FAR16DATA *vIorb, IORBH *pIorb, int (*func)(IORBH FAR16DATA *, IORBH *pIorb, int), ULONG timeout) 1182 1215 { 1183 1216 AHCI_PORT_CFG *pc = NULL; 1184 AD_INFO *ai = ad_infos + iorb_unit_adapter( iorb);1185 int p = iorb_unit_port( iorb);1186 u8 _far*port_mmio = port_base(ai, p);1217 AD_INFO *ai = ad_infos + iorb_unit_adapter(vIorb); 1218 int p = iorb_unit_port(pIorb); 1219 u8 *port_mmio = port_base(ai, p); 1187 1220 TIMER Timer; 1188 1221 int rc; 1189 1222 1190 1223 /* enable AHCI mode */ 1191 if (ahci_enable_ahci(ai) != 0) { 1192 iorb_seterr(iorb, IOERR_ADAPTER_NONSPECIFIC); 1224 if (ahci_enable_ahci(ai) != 0) 1225 { 1226 iorb_seterr(pIorb, IOERR_ADAPTER_NONSPECIFIC); 1193 1227 goto restore_bios_config; 1194 1228 } 1195 1229 1196 1230 /* check whether command slot 0 is available */ 1197 if ((readl(port_mmio + PORT_CMD_ISSUE) & 1) != 0) { 1198 iorb_seterr(iorb, IOERR_DEVICE_BUSY); 1231 if ((readl(port_mmio + PORT_CMD_ISSUE) & 1) != 0) 1232 { 1233 iorb_seterr(pIorb, IOERR_DEVICE_BUSY); 1199 1234 goto restore_bios_config; 1200 1235 } 1201 1236 1202 1237 /* save port configuration */ 1203 if ((pc = ahci_save_port_config(ai, p)) == NULL) { 1204 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 1238 if ((pc = ahci_save_port_config(ai, p)) == NULL) 1239 { 1240 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE); 1205 1241 goto restore_bios_config; 1206 1242 } 1207 1243 1208 1244 /* restart/reset port (includes the necessary port configuration) */ 1209 if (init_reset) { 1245 if (init_reset) 1246 { 1210 1247 /* As outlined in ahci_restore_bios_config(), switching back and 1211 1248 * forth between SATA and AHCI mode requires a COMRESET to force … … 1214 1251 * starting it. 1215 1252 */ 1216 if (ahci_reset_port(ai, p, 0)) { 1217 iorb_seterr(iorb, IOERR_ADAPTER_NONSPECIFIC); 1253 if (ahci_reset_port(ai, p, 0)) 1254 { 1255 iorb_seterr(pIorb, IOERR_ADAPTER_NONSPECIFIC); 1218 1256 goto restore_bios_config; 1219 1257 } 1220 1258 1221 } else if (ahci_stop_port(ai, p) || ahci_start_port(ai, p, 0)) { 1222 iorb_seterr(iorb, IOERR_ADAPTER_NONSPECIFIC); 1259 } 1260 else if (ahci_stop_port(ai, p) || ahci_start_port(ai, p, 0)) 1261 { 1262 iorb_seterr(pIorb, IOERR_ADAPTER_NONSPECIFIC); 1223 1263 goto restore_bios_config; 1224 1264 } 1225 1265 1226 1266 /* prepare command */ 1227 if (func(iorb, 0) == 0) { 1267 if (func(vIorb, pIorb, 0) == 0) 1268 { 1228 1269 /* successfully prepared cmd; issue cmd and wait for completion */ 1229 ddprintf("executing polled cmd on slot 0...");1270 DPRINTF(3,"---------- executing polled cmd on slot 0..."); 1230 1271 writel(port_mmio + PORT_CMD_ISSUE, 1); 1231 timer_init(&Timer, timeout); 1232 while (readl(port_mmio + PORT_CMD_ISSUE) & 1) { 1233 rc = timer_check_and_block(&Timer); 1272 TimerInit(&Timer, timeout); 1273 while (readl(port_mmio + PORT_CMD_ISSUE) & 1) 1274 { 1275 rc = TimerCheckAndBlock(&Timer); 1234 1276 if (rc) break; 1235 1277 } 1236 1278 1237 1279 /* 0x89 = BSY(0x80) | DRQ(0x08) | ERR(0x01) */ 1238 if (rc) { 1239 dprintf(" timeout for IORB %Fp", iorb); 1240 iorb_seterr(iorb, IOERR_ADAPTER_TIMEOUT); 1241 } else if (readl(port_mmio + PORT_SCR_ERR) != 0 || readl(port_mmio + PORT_TFDATA) & 0x89) { 1242 dprintf(" polled cmd error for IORB %Fp", iorb); 1243 iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC); 1244 ahci_reset_port(ai, iorb_unit_port(iorb), 0); 1245 } else { 1280 if (rc) 1281 { 1282 DPRINTF(3," timeout for IORB %x", vIorb); 1283 iorb_seterr(pIorb, IOERR_ADAPTER_TIMEOUT); 1284 } 1285 else if (readl(port_mmio + PORT_SCR_ERR) != 0 || readl(port_mmio + PORT_TFDATA) & 0x89) 1286 { 1287 DPRINTF(3," polled cmd error for IORB %x", vIorb); 1288 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC); 1289 ahci_reset_port(ai, iorb_unit_port(pIorb), 0); 1290 } 1291 else 1292 { 1246 1293 /* successfully executed command */ 1247 if (add_workspace(iorb)->ppfunc != NULL) { 1248 add_workspace(iorb)->ppfunc(iorb); 1249 } else { 1250 add_workspace(iorb)->complete = 1; 1294 if (add_workspace(pIorb)->ppfunc != NULL) 1295 { 1296 add_workspace(pIorb)->ppfunc(vIorb, pIorb); 1251 1297 } 1252 } 1253 ddprintf("\n"); 1298 else 1299 { 1300 add_workspace(pIorb)->complete = 1; 1301 } 1302 } 1303 DPRINTF(3,"\n"); 1254 1304 } 1255 1305 1256 1306 restore_bios_config: 1257 1307 /* restore BIOS configuration */ 1258 if (pc != NULL) { 1308 if (pc != NULL) 1309 { 1259 1310 ahci_restore_port_config(ai, p, pc); 1260 1311 } 1261 1312 ahci_restore_bios_config(ai); 1262 1313 1263 if (add_workspace(iorb)->complete | (iorb->Status | IORB_ERROR)) { 1264 iorb_done(iorb); 1314 if (add_workspace(pIorb)->complete | (pIorb->Status | IORB_ERROR)) 1315 { 1316 iorb_done(vIorb, pIorb); 1265 1317 } 1266 1318 return; … … 1279 1331 { 1280 1332 va_list va; 1281 u8 _far*port_mmio = port_base(ai, p);1333 u8 *port_mmio = port_base(ai, p); 1282 1334 u32 tmp; 1283 1335 int rc; … … 1285 1337 1286 1338 /* verify that command slot 0 is idle */ 1287 if (readl(port_mmio + PORT_CMD_ISSUE) & 1) { 1288 ddprintf("port %d slot 0 is not idle; not executing polled cmd\n", p); 1339 if (readl(port_mmio + PORT_CMD_ISSUE) & 1) 1340 { 1341 DPRINTF(3,"port %d slot 0 is not idle; not executing polled cmd\n", p); 1289 1342 return(-1); 1290 1343 } … … 1292 1345 /* fill in command slot 0 */ 1293 1346 va_start(va, cmd); 1294 if ((rc = v_ata_cmd(ai, p, d, 0, cmd, va)) != 0) { 1295 return(rc); 1296 } 1347 if ((rc = v_ata_cmd(ai, p, d, 0, cmd, va)) != 0) return(rc); 1297 1348 1298 1349 /* start command execution for slot 0 */ 1299 ddprintf("executing polled cmd...");1350 DPRINTF(3,"---------- executing polled cmd..."); 1300 1351 writel(port_mmio + PORT_CMD_ISSUE, 1); 1301 1352 1302 1353 /* wait until command has completed */ 1303 timer_init(&Timer, timeout);1354 TimerInit(&Timer, timeout); 1304 1355 rc = 0; 1305 while (readl(port_mmio + PORT_CMD_ISSUE) & 1) { 1306 rc = timer_check_and_block(&Timer); 1307 if (rc) { 1308 dprintf(" Timeout"); 1356 while (readl(port_mmio + PORT_CMD_ISSUE) & 1) 1357 { 1358 rc = TimerCheckAndBlock(&Timer); 1359 if (rc) 1360 { 1361 DPRINTF(2," Timeout"); 1309 1362 break; 1310 1363 } … … 1312 1365 1313 1366 tmp = readl(port_mmio + PORT_SCR_ERR); 1314 if (tmp & PORT_ERR_FAIL_BITS) { 1315 dprintf(" SERR = 0x%08lx", tmp); 1367 if (tmp & PORT_ERR_FAIL_BITS) 1368 { 1369 DPRINTF(2," SERR = 0x%08lx", tmp); 1316 1370 rc = 1; 1317 1371 } 1318 1372 /* 0x89 = BSY(0x80) | DRQ(0x08) | ERR(0x01) */ 1319 if (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) { 1320 dprintf(" TFDATA = 0x%08lx", tmp); 1373 if (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) 1374 { 1375 DPRINTF(2," TFDATA = 0x%08lx", tmp); 1321 1376 rc = 1; 1322 1377 } 1323 1378 1324 if (rc) { 1325 ddprintf("failed\n"); 1379 if (rc) 1380 { 1381 DPRINTF(3,"failed\n"); 1326 1382 ahci_reset_port(ai, p, 0); 1327 1383 return(-1); 1328 1384 } 1329 ddprintf("success\n");1385 DPRINTF(3,"success\n"); 1330 1386 return(0); 1331 1387 } … … 1342 1398 int ahci_flush_cache(AD_INFO *ai, int p, int d) 1343 1399 { 1344 if (!ai->ports[p].devs[d].atapi) { 1345 dprintf("flushing cache on %d.%d.%d\n", ad_no(ai), p, d); 1400 if (!ai->ports[p].devs[d].atapi) 1401 { 1402 DPRINTF(2,"flushing cache on %d.%d.%d\n", ad_no(ai), p, d); 1346 1403 return(ahci_exec_polled_cmd(ai, p, d, 30000, 1347 1404 ai->ports[p].devs[d].lba48 ? ATA_CMD_FLUSH_EXT : ATA_CMD_FLUSH, AP_END)); … … 1360 1417 int ahci_set_dev_idle(AD_INFO *ai, int p, int d, int idle) 1361 1418 { 1362 ddprintf("sending IDLE=%d command to port %d\n", idle, p); 1363 return ahci_exec_polled_cmd(ai, p, d, 500, ATA_CMD_IDLE, AP_COUNT, 1364 idle ? 1 : 0, AP_END); 1419 DPRINTF(3,"sending IDLE=%d command to port %d\n", idle, p); 1420 return ahci_exec_polled_cmd(ai, p, d, 500, ATA_CMD_IDLE, AP_COUNT, idle ? 1 : 0, AP_END); 1365 1421 } 1366 1422 … … 1375 1431 * the driver-level spinlock when actually changing the driver state (IORB 1376 1432 * queues, ...) 1377 * 1378 * NOTE: OS/2 expects the carry flag set upon return from an interrupt 1379 * handler if the interrupt has not been handled. We do this by 1380 * shifting the return code from this function one bit to the right, 1381 * thus the return code must set bit 0 in this case. 1382 */ 1433 */ 1434 u32 DazCount = 0; 1435 1383 1436 int ahci_intr(u16 irq) 1384 1437 { … … 1388 1441 int p; 1389 1442 1443 DPRINTF(1,"AI=%x",DazCount++); 1444 1390 1445 /* find adapter(s) with pending interrupts */ 1391 for (a = 0; a < ad_info_cnt; a++) { 1446 for (a = 0; a < ad_info_cnt; a++) 1447 { 1392 1448 AD_INFO *ai = ad_infos + a; 1393 1449 1394 if (ai->irq == irq && (irq_stat = readl(ai->mmio + HOST_IRQ_STAT)) != 0) { 1450 if (ai->irq == irq && (irq_stat = readl(ai->mmio + HOST_IRQ_STAT)) != 0) 1451 { 1395 1452 /* this adapter has interrupts pending */ 1396 1453 u32 irq_masked = irq_stat & ai->port_map; 1397 1454 1398 for (p = 0; p <= ai->port_max; p++) { 1399 if (irq_masked & (1UL << p)) { 1455 for (p = 0; p <= ai->port_max; p++) 1456 { 1457 if (irq_masked & (1UL << p)) 1458 { 1400 1459 ahci_port_intr(ai, p); 1401 1460 } … … 1409 1468 } 1410 1469 1411 if (handled) { 1470 if (handled) 1471 { 1412 1472 /* Trigger state machine to process next IORBs, if any. Due to excessive 1413 1473 * IORB requeue operations (e.g. when processing large unaligned reads or 1414 1474 * writes), we may be stacking interrupts on top of each other. If we 1415 1475 * detect this, we'll pass this on to the engine context hook. 1416 *1417 * Rousseau:1418 * The "Physycal Device Driver Reference" states that it's a good idea1419 * to disable interrupts before doing EOI so that it can proceed for this1420 * level without being interrupted, which could cause stacked interrupts,1421 * possibly exhausting the interrupt stack.1422 * (?:\IBMDDK\DOCS\PDDREF.INF->Device Helper (DevHlp) Services)->EOI)1423 *1424 * This is what seemed to happen when running in VirtualBox.1425 * Since in VBox the AHCI-controller is a software implementation, it is1426 * just not fast enough to handle a large bulk of requests, like when JFS1427 * flushes it's caches.1428 *1429 * Cross referencing with DANIS506 shows she does the same in the1430 * state-machine code in s506sm.c around line 244; disable interrupts1431 * before doing the EOI.1432 *1433 * Comments on the disable() function state that SMP systems should use1434 * a spinlock, but putting the EOI before spin_unlock() did not solve the1435 * VBox ussue. This is probably because spin_unlock() enables interrupts,1436 * which implies we need to return from this handler with interrupts1437 * disabled.1438 1476 */ 1439 if ((u16) (u32) (void _far *) &irq_stat < 0xf000) { 1440 ddprintf("IRQ stack running low; arming engine context hook\n"); 1477 #if 0 1478 if ((u32)&irq_stat < 0xf000) 1479 { 1480 DPRINTF(0,"IRQ stack running low; arming engine context hook\n"); 1441 1481 /* Rousseau: 1442 1482 * A context hook cannot be re-armed before it has completed. … … 1453 1493 * This needs some more investigation. 1454 1494 */ 1455 DevHelp_ArmCtxHook(0, engine_ctxhook_h); 1456 } else { 1495 KernArmHook(engine_ctxhook_h, 0, 0); 1496 } 1497 else 1498 #endif 1499 { 1457 1500 spin_lock(drv_lock); 1458 1501 trigger_engine(); 1459 1502 spin_unlock(drv_lock); 1460 1503 } 1461 /* disable interrupts to prevent stacking. (See comments above) */ 1462 disable(); 1463 /* complete the interrupt */ 1464 DevHelp_EOI(irq); 1465 return(0); 1466 } else { 1467 return(1); 1468 } 1504 DevCli(); 1505 Dev32Help_EOI(irq); 1506 return(1); /* handled */ 1507 } 1508 1509 return(0); /* not handled */ 1469 1510 } 1470 1511 … … 1477 1518 { 1478 1519 IORB_QUEUE done_queue; 1479 IORBH _far *iorb;1480 IORBH _far *next = NULL;1481 u8 _far*port_mmio = port_base(ai, p);1520 IORBH FAR16DATA *vIorb; 1521 IORBH FAR16DATA *vNext = NULL; 1522 u8 *port_mmio = port_base(ai, p); 1482 1523 u32 irq_stat; 1483 1524 u32 active_cmds; … … 1489 1530 readl(port_mmio + PORT_IRQ_STAT); /* flush */ 1490 1531 1491 ddprintf("port interrupt for adapter %d port %d stat %lx stack frame %Fp\n", 1492 ad_no(ai), p, irq_stat, (void _far *)&done_queue); 1532 DPRINTF(3,"port interrupt A=%d Port=%d stat=%x\n", ad_no(ai), p, irq_stat); 1493 1533 memset(&done_queue, 0x00, sizeof(done_queue)); 1494 1534 1495 if (irq_stat & PORT_IRQ_ERROR) { 1535 if (irq_stat & PORT_IRQ_ERROR) 1536 { 1496 1537 /* this is an error interrupt; 1497 1538 * disable port interrupts to avoid IRQ storm until error condition … … 1511 1552 * commands have completed, too. 1512 1553 */ 1513 if (ai->ports[p].ncq_cmds != 0) { 1554 if (ai->ports[p].ncq_cmds != 0) 1555 { 1514 1556 active_cmds = readl(port_mmio + PORT_SCR_ACT); 1515 1557 done_mask = ai->ports[p].ncq_cmds ^ active_cmds; 1516 ddprintf("[ncq_cmds]: active_cmds = 0x%08lx, done_mask = 0x%08lx\n", 1517 active_cmds, done_mask); 1518 } else { 1558 DPRINTF(1,"[ncq_cmds]: active_cmds=0x%08x done_mask=0x%08x\n", active_cmds, done_mask); 1559 } 1560 else 1561 { 1519 1562 active_cmds = readl(port_mmio + PORT_CMD_ISSUE); 1520 1563 done_mask = ai->ports[p].reg_cmds ^ active_cmds; 1521 ddprintf("[reg_cmds]: active_cmds = 0x%08lx, done_mask = 0x%08lx\n", 1522 active_cmds, done_mask); 1564 DPRINTF(1,"[reg_cmds]: active_cmds=0x%08x done_mask=0x%08x\n", active_cmds, done_mask); 1523 1565 } 1524 1566 … … 1535 1577 * processed after releasing the spinlock. 1536 1578 */ 1537 for (iorb = ai->ports[p].iorb_queue.root; iorb != NULL; iorb = next) { 1538 ADD_WORKSPACE _far *aws = (ADD_WORKSPACE _far *) &iorb->ADDWorkSpace; 1539 next = iorb->pNxtIORB; 1540 if (aws->queued_hw && (done_mask & (1UL << aws->cmd_slot))) { 1579 for (vIorb = ai->ports[p].iorb_queue.vRoot; vIorb != NULL; vIorb = vNext) 1580 { 1581 IORBH *pIorb = Far16ToFlat(vIorb); 1582 ADD_WORKSPACE *aws = (ADD_WORKSPACE *) &pIorb->ADDWorkSpace; 1583 1584 vNext = pIorb->pNxtIORB; 1585 if (aws->queued_hw && (done_mask & (1UL << aws->cmd_slot))) 1586 { 1541 1587 /* this hardware command has completed */ 1542 1588 ai->ports[p].ncq_cmds &= ~(1UL << aws->cmd_slot); … … 1544 1590 1545 1591 /* call post-processing function, if any */ 1546 if (aws->ppfunc != NULL) { 1547 aws->ppfunc(iorb); 1548 } else { 1549 aws->complete = 1; 1592 if (aws->ppfunc != NULL) aws->ppfunc(vIorb, pIorb); 1593 else aws->complete = 1; 1594 1595 if (aws->complete) 1596 { 1597 /* this IORB is complete; move IORB to our temporary done queue */ 1598 iorb_queue_del(&ai->ports[p].iorb_queue, vIorb); 1599 iorb_queue_add(&done_queue, vIorb, pIorb); 1600 aws_free(add_workspace(pIorb)); 1550 1601 } 1551 1552 if (aws->complete) {1553 /* this IORB is complete; move IORB to our temporary done queue */1554 iorb_queue_del(&ai->ports[p].iorb_queue, iorb);1555 iorb_queue_add(&done_queue, iorb);1556 aws_free(add_workspace(iorb));1557 }1558 1602 } 1559 1603 } … … 1562 1606 1563 1607 /* complete all IORBs in the done queue */ 1564 for (iorb = done_queue.root; iorb != NULL; iorb = next) { 1565 next = iorb->pNxtIORB; 1566 iorb_complete(iorb); 1608 for (vIorb = done_queue.vRoot; vIorb != NULL; vIorb = vNext) 1609 { 1610 IORBH *pIorb = Far16ToFlat(vIorb); 1611 1612 vNext = pIorb->pNxtIORB; 1613 iorb_complete(vIorb, pIorb); 1567 1614 } 1568 1615 } … … 1588 1635 * reset, or worse. 1589 1636 */ 1590 if (irq_stat & PORT_IRQ_UNK_FIS) { 1637 if (irq_stat & PORT_IRQ_UNK_FIS) 1638 { 1591 1639 #ifdef DEBUG 1592 u32 _far *unk = (u32 _far*) (port_dma_base(ai, p)->rx_fis + RX_FIS_UNK);1593 dprintf("warning: unknown FIS %08lx %08lx %08lx %08lx\n", unk[0], unk[1], unk[2], unk[3]);1640 u32 *unk = (u32 *) (port_dma_base(ai, p)->rx_fis + RX_FIS_UNK); 1641 DPRINTF(0,"warning: unknown FIS %08lx %08lx %08lx %08lx\n", unk[0], unk[1], unk[2], unk[3]); 1594 1642 #endif 1595 1643 reset_port = 1; 1596 1644 } 1597 if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { 1598 dprintf("warning: host bus [data] error for port #%d\n", p); 1645 if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) 1646 { 1647 DPRINTF(0,"warning: host bus [data] error for port #%d\n", p); 1599 1648 reset_port = 1; 1600 1649 } 1601 if (irq_stat & PORT_IRQ_IF_ERR && !(ai->flags & AHCI_HFLAG_IGN_IRQ_IF_ERR)) { 1602 dprintf("warning: interface fatal error for port #%d\n", p); 1650 if (irq_stat & PORT_IRQ_IF_ERR && !(ai->flags & AHCI_HFLAG_IGN_IRQ_IF_ERR)) 1651 { 1652 DPRINTF(0,"warning: interface fatal error for port #%d\n", p); 1603 1653 reset_port = 1; 1604 1654 } 1605 if (reset_port) { 1655 if (reset_port) 1656 { 1606 1657 /* need to reset the port; leave this to the reset context hook */ 1607 1658 1608 1659 ports_to_reset[ad_no(ai)] |= 1UL << p; 1609 DevHelp_ArmCtxHook(0, reset_ctxhook_h);1660 KernArmHook(reset_ctxhook_h, 0, 0); 1610 1661 1611 1662 /* no point analyzing device errors after a reset... */ … … 1613 1664 } 1614 1665 1615 dprintf("port #%d interrupt error status: 0x%08lx; restarting port\n", 1616 p, irq_stat); 1666 DPRINTF(0,"port #%d interrupt error status: 0x%08lx; restarting port\n", p, irq_stat); 1617 1667 1618 1668 /* Handle device-specific errors. Those errors typically involve restarting … … 1621 1671 */ 1622 1672 ports_to_restart[ad_no(ai)] |= 1UL << p; 1623 DevHelp_ArmCtxHook(0, restart_ctxhook_h);1673 KernArmHook(restart_ctxhook_h, 0, 0); 1624 1674 } 1625 1675 … … 1628 1678 * the same for non-removable devices. 1629 1679 */ 1630 void ahci_get_geometry(IORBH _far *iorb) 1631 { 1632 dprintf("ahci_get_geometry(%d.%d.%d)\n", (int) iorb_unit_adapter(iorb), 1633 (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb)); 1634 1635 ahci_exec_iorb(iorb, 0, cmd_func(iorb, get_geometry)); 1680 void ahci_get_geometry(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1681 { 1682 #ifdef DEBUG 1683 DPRINTF(2,"ahci_get_geometry(%d.%d.%d)\n", iorb_unit_adapter(pIorb), 1684 iorb_unit_port(pIorb), iorb_unit_device(pIorb)); 1685 #endif 1686 1687 ahci_exec_iorb(vIorb, pIorb, 0, cmd_func(pIorb, get_geometry)); 1636 1688 } 1637 1689 … … 1639 1691 * Test whether unit is ready. 1640 1692 */ 1641 void ahci_unit_ready(IORBH _far *iorb) 1642 { 1643 dprintf("ahci_unit_ready(%d.%d.%d)\n", (int) iorb_unit_adapter(iorb), 1644 (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb)); 1645 1646 ahci_exec_iorb(iorb, 0, cmd_func(iorb, unit_ready)); 1693 void ahci_unit_ready(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1694 { 1695 #ifdef DEBUG 1696 DPRINTF(2,"ahci_unit_ready(%d.%d.%d)\n", iorb_unit_adapter(pIorb), 1697 iorb_unit_port(pIorb), iorb_unit_device(pIorb)); 1698 #endif 1699 1700 ahci_exec_iorb(vIorb, pIorb, 0, cmd_func(pIorb, unit_ready)); 1647 1701 } 1648 1702 … … 1650 1704 * Read sectors from AHCI device. 1651 1705 */ 1652 void ahci_read(IORBH _far *iorb) 1653 { 1654 dprintf("ahci_read(%d.%d.%d, %ld, %ld)\n", (int) iorb_unit_adapter(iorb), 1655 (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb), 1656 (long) ((IORB_EXECUTEIO _far *) iorb)->RBA, 1657 (long) ((IORB_EXECUTEIO _far *) iorb)->BlockCount); 1658 1659 ahci_exec_iorb(iorb, 1, cmd_func(iorb, read)); 1706 void ahci_read(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1707 { 1708 #ifdef DEBUG 1709 DPRINTF(2,"ahci_read(%d.%d.%d, %d, %d)\n", iorb_unit_adapter(vIorb), 1710 iorb_unit_port(pIorb), iorb_unit_device(pIorb), 1711 ((IORB_EXECUTEIO *) pIorb)->RBA, 1712 ((IORB_EXECUTEIO *) pIorb)->BlockCount); 1713 #endif 1714 1715 ahci_exec_iorb(vIorb, pIorb, 1, cmd_func(pIorb, read)); 1660 1716 } 1661 1717 … … 1663 1719 * Verify readability of sectors on AHCI device. 1664 1720 */ 1665 void ahci_verify(IORBH _far *iorb) 1666 { 1667 dprintf("ahci_verify(%d.%d.%d, %ld, %ld)\n", (int) iorb_unit_adapter(iorb), 1668 (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb), 1669 (long) ((IORB_EXECUTEIO _far *) iorb)->RBA, 1670 (long) ((IORB_EXECUTEIO _far *) iorb)->BlockCount); 1671 1672 ahci_exec_iorb(iorb, 0, cmd_func(iorb, verify)); 1721 void ahci_verify(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1722 { 1723 #ifdef DEBUG 1724 DPRINTF(2,"ahci_verify(%d.%d.%d, %d, %d)\n", iorb_unit_adapter(pIorb), 1725 iorb_unit_port(pIorb), iorb_unit_device(pIorb), 1726 ((IORB_EXECUTEIO *)pIorb)->RBA, 1727 ((IORB_EXECUTEIO *)pIorb)->BlockCount); 1728 #endif 1729 1730 ahci_exec_iorb(vIorb, pIorb, 0, cmd_func(pIorb, verify)); 1673 1731 } 1674 1732 … … 1676 1734 * Write sectors to AHCI device. 1677 1735 */ 1678 void ahci_write(IORBH _far *iorb) 1679 { 1680 dprintf("ahci_write(%d.%d.%d, %ld, %ld)\n", (int) iorb_unit_adapter(iorb), 1681 (int) iorb_unit_port(iorb), (int) iorb_unit_device(iorb), 1682 (long) ((IORB_EXECUTEIO _far *) iorb)->RBA, 1683 (long) ((IORB_EXECUTEIO _far *) iorb)->BlockCount); 1684 1685 ahci_exec_iorb(iorb, 1, cmd_func(iorb, write)); 1736 void ahci_write(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1737 { 1738 #ifdef DEBUG 1739 DPRINTF(2,"ahci_write(%d.%d.%d, %d, %d)\n", iorb_unit_adapter(pIorb), 1740 iorb_unit_port(pIorb), iorb_unit_device(pIorb), 1741 ((IORB_EXECUTEIO *)pIorb)->RBA, 1742 ((IORB_EXECUTEIO *)pIorb)->BlockCount); 1743 #endif 1744 1745 ahci_exec_iorb(vIorb, pIorb, 1, cmd_func(pIorb, write)); 1686 1746 } 1687 1747 … … 1689 1749 * Execute SCSI (ATAPI) command. 1690 1750 */ 1691 void ahci_execute_cdb(IORBH _far *iorb)1692 { 1693 int a = iorb_unit_adapter( iorb);1694 int p = iorb_unit_port( iorb);1695 int d = iorb_unit_device( iorb);1696 1697 dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd,1698 ((IORB_ADAPTER_PASSTHRU _far *) iorb)->ControllerCmdLen,1751 void ahci_execute_cdb(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1752 { 1753 int a = iorb_unit_adapter(pIorb); 1754 int p = iorb_unit_port(pIorb); 1755 int d = iorb_unit_device(pIorb); 1756 1757 DHEXDUMP(0,Far16ToFlat(((IORB_ADAPTER_PASSTHRU *)pIorb)->pControllerCmd), 1758 ((IORB_ADAPTER_PASSTHRU *)pIorb)->ControllerCmdLen, 1699 1759 "ahci_execute_cdb(%d.%d.%d): ", a, p, d); 1700 1760 1701 if (ad_infos[a].ports[p].devs[d].atapi) { 1702 ahci_exec_iorb(iorb, 0, atapi_execute_cdb); 1703 } else { 1704 iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED); 1705 iorb_done(iorb); 1761 if (ad_infos[a].ports[p].devs[d].atapi) 1762 { 1763 ahci_exec_iorb(vIorb, pIorb, 0, atapi_execute_cdb); 1764 } 1765 else 1766 { 1767 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 1768 iorb_done(vIorb, pIorb); 1706 1769 } 1707 1770 } … … 1711 1774 * ATAPI devices because ATAPI devices will process some ATA commands as well. 1712 1775 */ 1713 void ahci_execute_ata(IORBH _far *iorb)1776 void ahci_execute_ata(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1714 1777 { 1715 1778 #ifdef DEBUG 1716 int a = iorb_unit_adapter(iorb); 1717 int p = iorb_unit_port(iorb); 1718 int d = iorb_unit_device(iorb); 1779 int a = iorb_unit_adapter(pIorb); 1780 int p = iorb_unit_port(pIorb); 1781 int d = iorb_unit_device(pIorb); 1782 1783 DHEXDUMP(0,Far16ToFlat(((IORB_ADAPTER_PASSTHRU *)pIorb)->pControllerCmd), 1784 ((IORB_ADAPTER_PASSTHRU *)pIorb)->ControllerCmdLen, 1785 "ahci_execute_ata(%d.%d.%d): ", a, p, d); 1719 1786 #endif 1720 1787 1721 dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd, 1722 ((IORB_ADAPTER_PASSTHRU _far *) iorb)->ControllerCmdLen, 1723 "ahci_execute_ata(%d.%d.%d): ", a, p, d); 1724 1725 ahci_exec_iorb(iorb, 0, ata_execute_ata); 1788 ahci_exec_iorb(vIorb, pIorb, 0, ata_execute_ata); 1726 1789 } 1727 1790 … … 1744 1807 if (d >= AHCI_MAX_DEVS) return; 1745 1808 1746 if (ai->port_max < p) { 1747 ai->port_max = p; 1748 } 1749 if (ai->ports[p].dev_max < d) { 1750 ai->ports[p].dev_max = d; 1751 } 1809 if (ai->port_max < p) ai->port_max = p; 1810 if (ai->ports[p].dev_max < d) ai->ports[p].dev_max = d; 1752 1811 memset(ai->ports[p].devs + d, 0x00, sizeof(*ai->ports[p].devs)); 1753 1812 … … 1757 1816 ai->ports[p].devs[d].dev_type = UIB_TYPE_DISK; 1758 1817 1759 if (id_buf[ATA_ID_CONFIG] & 0x8000U) { 1818 if (id_buf[ATA_ID_CONFIG] & 0x8000U) 1819 { 1760 1820 /* this is an ATAPI device; augment device information */ 1761 1821 ai->ports[p].devs[d].atapi = 1; … … 1764 1824 ai->ports[p].devs[d].ncq_max = 1; 1765 1825 1766 } else { 1826 } 1827 else 1828 { 1767 1829 /* complete ATA-specific device information */ 1768 if (enable_ncq[ad_no(ai)][p]) { 1830 if (enable_ncq[ad_no(ai)][p]) 1831 { 1769 1832 ai->ports[p].devs[d].ncq_max = id_buf[ATA_ID_QUEUE_DEPTH] & 0x001fU; 1770 1833 } 1771 if (ai->ports[p].devs[d].ncq_max < 1) { 1834 if (ai->ports[p].devs[d].ncq_max < 1) 1835 { 1772 1836 /* NCQ not enabled for this device, or device doesn't support NCQ */ 1773 1837 ai->ports[p].devs[d].ncq_max = 1; 1774 1838 } 1775 if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x0400U) { 1839 if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x0400U) 1840 { 1776 1841 ai->ports[p].devs[d].lba48 = 1; 1777 1842 } 1778 1843 } 1779 1844 1780 dprintf("found device %d.%d.%d: removable = %d, dev_type = %d, atapi = %d, "1845 DPRINTF(2,"found device %d.%d.%d: removable = %d, dev_type = %d, atapi = %d, " 1781 1846 "ncq_max = %d\n", ad_no(ai), p, d, 1782 1847 ai->ports[p].devs[d].removable, … … 1798 1863 * we distinguish only HDs and CD drives for now 1799 1864 */ 1800 if (ai->ports[p].devs[d].removable) { 1865 if (ai->ports[p].devs[d].removable) 1866 { 1801 1867 sprintf(dev_name, RM_CD_PREFIX "%s", p, d, ata_dev_name(id_buf)); 1802 } else { 1868 } 1869 else 1870 { 1803 1871 sprintf(dev_name, RM_HD_PREFIX "%s", p, d, ata_dev_name(id_buf)); 1804 1872 } … … 1816 1884 /* try to detect virtualbox environment to enable a hack for IRQ routing */ 1817 1885 if (ai == ad_infos && ai->pci_vendor == 0x8086 && ai->pci_device == 0x2829 && 1818 !memcmp(ata_dev_name(id_buf), "VBOX HARDDISK", 13)) { 1886 !memcmp(ata_dev_name(id_buf), "VBOX HARDDISK", 13)) 1887 { 1819 1888 /* running inside virtualbox */ 1820 1889 pci_hack_virtualbox();
Note:
See TracChangeset
for help on using the changeset viewer.