- Timestamp:
- Jul 24, 2023, 5:51:46 PM (2 years ago)
- Location:
- trunk
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/Makefile
r209 r211 17 17 FDEBUG=0x0000 18 18 19 FIXPACK=Test Build 20 19 21 .ERASE 20 22 .SUFFIXES … … 23 25 # Define default build version if not specified in environment 24 26 BLD_MAJOR=2 25 BLD_MINOR=0 8# must be 2 digits27 BLD_MINOR=09 # must be 2 digits 26 28 BLD_REV=0 # not used at this time 27 29 … … 90 92 !endif 91 93 92 #DAZ need to find which structures need pack(1) so we can reset this back to -zp493 94 AFLAGS=-q -6p -bt=os2 -wx -d1 94 95 CFLAGS =-q -bt=os2 -6s -olinar -s -ze -zl -zq -zfp -zgp -ms -wx -zp1 -ecs -ei -za99 … … 142 143 @%append $^&.lrf option map=$^*.map 143 144 @%append $^&.lrf option stack=0 144 # @%append $*.lnk option protmode145 145 @%append $^&.lrf sort global 146 146 @%append $^&.lrf option osname='ArcaOS' … … 149 149 @for %f in ($(OBJS)) do @%append $^&.lrf file %f 150 150 @for %f in ($(LIBS)) do @%append $^&.lrf library %f 151 # @%append $*.lnk segment type DATA SHARED152 # @%append $*.lnk segment type CODE IOPL153 # # Order segments by class154 # @%append $*.lnk order155 # @%append $*.lnk clname 'DATA'156 # @%append $*.lnk clname 'CONST'157 # @%append $*.lnk clname 'BSS'158 # @%append $*.lnk clname 'CODE'159 151 @wlink @$^&.lrf 160 152 @%erase $^&.lrf -
trunk/src/os2ahci/ReadMe.txt
r209 r211 16 16 Copyright (c) 2011 thi.guten Software Development 17 17 Copyright (c) 2011 Mensys B.V. 18 Copyright (c) 2013-202 1David Azarewicz18 Copyright (c) 2013-2023 David Azarewicz 19 19 20 20 Authors: Christian Mueller, Markus Thielen … … 72 72 (default = -1, all adapters) 73 73 74 /F Force the use of the HW write cache when using NCQ75 commands; see "Native Command Queuing" below for76 further explanation (default =off)74 /F Ignore the request flag and force the use of the HW 75 write cache when using NCQ commands; see "Native Command 76 Queuing" below for further explanation (default=off) 77 77 78 78 /G:<vendor>:<device> Add generic PCI ID to list of supported AHCI adapters … … 94 94 turned off with /!T to perform only a PCI class scan 95 95 96 /U Check for usable disks and mark disks that are not 97 usable as unavailable for normal OS/2 operations. 98 To be usable a disk must be an MBR disk or wiped. 99 (default = on) Can be turned off with /!U. 96 /U Check for usable disks and mark disks that are not usable 97 as unavailable for normal OS/2 operations. To be usable a 98 disk must be an MBR disk or wiped. (default=on) Can be 99 turned off with /!U. Warning: Use /!U with caution and 100 only temporarily if absolutely necessary to reconfigure a 101 disk. Normal operation with /!U is not recommended and 102 can lead to uncorrectable disk problems. 100 103 101 104 /V Display informational messages during boot. … … 131 134 132 135 /N Enable NCQ (Native Command Queuing) for hard disks 133 (default = o ff)136 (default = on) Can be turned off with /!N. 134 137 135 138 /LS Set link speed (default = 0): … … 145 148 3 = transitions to both partial and slumber states disabled 146 149 147 /4 Force track size to be 56 sectors regardless of the148 reported disk geometryto optimize partition boundaries149 for hard disks with 4096 byte sectors. 150 /4 Force reported track size to be 56 sectors regardless of the 151 actual disk geometry. Intended to optimize partition boundaries 152 for hard disks with 4096 byte sectors. May not work with LVM. 150 153 151 154 Port-specific options depend on the currently active adapter … … 185 188 database servers). 186 189 187 While we believe NCQ will work with the majority of controllers and hard188 disks, it's currently turned off by default until we have more feedback189 from OS/2 users. In order to turn on NCQ, just add the command line190 option "/N" to OS2AHCI.ADD.191 192 190 NCQ and HW Caches 193 191 ----------------- … … 195 193 In NCQ mode, OS2AHCI supports a request flag which allows upstream code 196 194 (e.g. file systems) to force writes to go directly to the disk instead 197 of being buffered in the HW disk cache. However, at least JFS doesn't 198 support this flag properly which effectively disables the HW disk cache 199 for write operations across the board, resulting in a substantial 200 performance loss. In order to prevent OS2AHCI from disabling the HW 201 cache when so requested by upstream code, please use the command line 202 option "/F". 203 204 This may, of course, result in data loss in case of power failures but 205 apparently this was the situation with previous IDE drivers as well thus 206 shouldn't make much difference in the field. The JFS code also seems to 207 imply that this flag has never been widely supported by [IDE] drivers; 208 otherwise, the JFS developers should have stumbled over the performance 209 loss a long time ago and fixed the code. 210 211 NOTES: 212 213 - Without NCQ, OS2AHCI behaves like former IDE drivers, i.e. the HW 214 cache will always be enabled (on modern disks). 215 216 - When suspending, rebooting or shutting down, OS2AHCI always flushes 217 the HW disk cache regardless of the "/F" or "/N" command line options. 195 of being buffered in the HW disk cache. The command line option "/F" 196 forces NCQ commands to use the hardware cache, ignoring the request flag. 197 This may result in data loss in case of power failures. When rebooting 198 or shutting down, the HW disk cache is always flushed regardless of any 199 of the command line options. 218 200 219 201 … … 262 244 2. Drive HDD via OS2AHCI.ADD and CDROM via DANIS506.ADD 263 245 264 OS2AHCI.ADD can't drive the CDROM because it's attached to a PATA265 IDE controllerwhich doesn't support AHCI.246 OS2AHCI.ADD can't drive the CDROM because it's attached to an IDE controller 247 which doesn't support AHCI. 266 248 267 249 - If OS2AHCI.ADD comes first in CONFIG.SYS, it will take over the SATA/AHCI … … 270 252 - If DANIS506.ADD comes first in CONFIG.SYS, it will take over both the 271 253 SATA/AHCI and the PATA/IDE controller and OS2AHCI.ADD will silently exit. 272 273 Advantages of AHCI274 ------------------275 276 The interfaces provided by the various [Intel] controllers could be277 summarized like this (the term ATA as driver interface being a bit of our278 own invention):279 280 - Intel PIIX: IDE (I/O registers) and ATA (taskfile)281 - Intel ICH6: IDE (I/O registers), ATA (taskfile) and SATA282 (FIS, vendor-specific)283 - Intel ICH7: IDE (I/O registers), ATA (taskfile), SATA284 (FIS, vendor-specific) and AHCI (FIS)285 - Intel PCH: AHCI (FIS)286 287 Taskfiles are regions in memory with ATA commands which the IDE/ATA288 controller can read and process autonomously. FIS (Frame Information289 Structures) are pretty much the same but they are specific to the SATA290 communication protocol on the serial link. The most important FIS type291 for AHCI drivers is the H2D (host to device) FIS which basically contains292 the ATA command to be executed.293 294 The big advantage of AHCI controllers, apart from being vendor-neutral,295 is that they take care of a lot of things which previous-generation296 drivers like DANIS506 would have to do step by step. For example, in297 order to send an ATAPI command, DANIS506 would have to do the following:298 299 * Send ATA "PACKET" command to device (via IDE registers, ATA taskfiles300 or SATA FIS)301 * Wait until device signals via interrupt it's ready for the ATAPI command302 * Send ATAPI command to device via PIO303 * Wait until device signals via interrupt it's ready to transfer data304 * Send/Receive any data that might come along with the ATAPI command via305 PIO, or wait for DMA transfer to complete306 * Wait until device signals via interrupt that command and data transfer307 have completed308 309 For OS2AHCI, the same operation looks like this:310 311 * Fill in AHCI command header, FIS with ATA "PACKET" command and the ATAPI312 command313 * Tell port engine to process the command314 * Wait until controller signals via interrupt that command and data315 transfer have completed316 317 The AHCI controller automatically takes care of all underlying bits and318 pieces. OS2AHCI doesn't even have to know whether a particular message is319 sent via PIO or DMA because this is handled by the AHCI controller, too.320 And the whole concept of PIO and DMA is only relevant between AHCI controller321 and the device -- all transfers between OS2AHCI and the AHCI controller are322 always done via DMA.323 254 324 255 … … 384 315 Change Log 385 316 ========== 317 318 v.2.09 24-Jun-2023 - David Azarewicz 319 Added workaround to help with VirtualBox issues. 320 Improved diagnostic messages. 321 Changed how timeouts are reset and how ctx hooks are triggered. 322 Added quirk for devices with issues executing some standard commands. 323 Changed to make /N the default. 324 386 325 v.2.08 20-Feb-2021 - David Azarewicz 387 326 Corrected RM ADD handle and unit. -
trunk/src/os2ahci/ahci.c
r209 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 36 36 ? atapi_##func : ata_##func 37 37 38 39 /* Initial driver status flags indexed by the board_* constants in os2ahci.h40 *41 * NOTE: The Linux AHCI driver uses a combination of board-specific quirk42 * flags and overriding certain libata service functions to handle43 * adapter flaws. However, there were only three overrides at the time44 * os2ahci was written, one for hard adapter resets and two for port45 * resets, and we can easily implement those within the corresponding46 * reset handlers. If this becomes more complex, this array of flags47 * should be converted into a structure array which contains function48 * pointers to all handler functions which may need to be overridden.49 */50 u16 initial_flags[] =51 {52 0, /* board_ahci */53 AHCI_HFLAG_NO_NCQ | /* board_ahci_vt8251 */54 AHCI_HFLAG_NO_PMP,55 AHCI_HFLAG_IGN_IRQ_IF_ERR, /* board_ahci_ign_iferr */56 AHCI_HFLAG_IGN_SERR_INTERNAL | /* board_ahci_sb600 */57 AHCI_HFLAG_NO_MSI |58 AHCI_HFLAG_SECT255 |59 AHCI_HFLAG_32BIT_ONLY,60 AHCI_HFLAG_NO_NCQ | /* board_ahci_mv */61 AHCI_HFLAG_NO_MSI |62 AHCI_HFLAG_MV_PATA |63 AHCI_HFLAG_NO_PMP,64 AHCI_HFLAG_IGN_SERR_INTERNAL, /* board_ahci_sb700 */65 AHCI_HFLAG_YES_NCQ, /* board_ahci_mcp65 */66 AHCI_HFLAG_NO_PMP, /* board_ahci_nopmp */67 AHCI_HFLAG_YES_NCQ, /* board_ahci_yesncq */68 AHCI_HFLAG_NO_SNTF, /* board_ahci_nosntf */69 };70 71 38 #define MAX_IRQ_HANDLERS 8 /* This is the maximum number of handlers that Dev32Help_SetIRQ can register */ 72 39 static u16 irq_used[MAX_IRQ_HANDLERS]; /* IRQ level for each used IRQ */ … … 81 48 dprintf(0,"AHCI global registers for adapter %d %d:%d:%d irq=%d addr=0x%x\n", 82 49 ad_no(ai), 83 PCI_BUS_FROM_BDF(ai-> bus_dev_func), PCI_DEV_FROM_BDF(ai->bus_dev_func),84 PCI_FUNC_FROM_BDF(ai-> bus_dev_func), ai->irq, ai->mmio_phys);50 PCI_BUS_FROM_BDF(ai->BusDevFunc), PCI_DEV_FROM_BDF(ai->BusDevFunc), 51 PCI_FUNC_FROM_BDF(ai->BusDevFunc), ai->irq, ai->mmio_phys); 85 52 86 53 for (i = 0; i <= HOST_CAP2; i += sizeof(u32)) … … 180 147 if (readl(ai->mmio + HOST_VERSION) >= 0x00010200L) ai->cap2 = readl(ai->mmio + HOST_CAP2); 181 148 182 if (ai->pci->board >= sizeof(initial_flags) / sizeof(*initial_flags))183 {184 dprintf(0,"error: invalid board index in PCI info\n");185 return(-1);186 }187 ai->flags = initial_flags[ai->pci->board];188 149 ai->hw_ports = (ai->cap & 0x1f) + 1; 189 150 190 if ((ai->cap & HOST_CAP_64) && (ai-> flags & AHCI_HFLAG_32BIT_ONLY))151 if ((ai->cap & HOST_CAP_64) && (ai->quirks & AHCI_HFLAG_32BIT_ONLY)) 191 152 { 192 153 /* disable 64-bit support for faulty controllers; OS/2 can't do 64 bits at … … 200 161 * around quirks and faulty hardware is hard to come by... 201 162 */ 202 if ((ai->cap & HOST_CAP_NCQ) && (ai-> flags & AHCI_HFLAG_NO_NCQ))163 if ((ai->cap & HOST_CAP_NCQ) && (ai->quirks & AHCI_HFLAG_NO_NCQ)) 203 164 { 204 165 DPRINTF(DBG_INIT, DBG_PREFIX": controller can't do NCQ, turning off CAP_NCQ\n"); … … 206 167 } 207 168 208 if (!(ai->cap & HOST_CAP_NCQ) && (ai-> flags & AHCI_HFLAG_YES_NCQ))169 if (!(ai->cap & HOST_CAP_NCQ) && (ai->quirks & AHCI_HFLAG_YES_NCQ)) 209 170 { 210 171 DPRINTF(DBG_INIT, DBG_PREFIX": controller can do NCQ, turning on CAP_NCQ\n"); … … 212 173 } 213 174 214 if ((ai->cap & HOST_CAP_PMP) && (ai-> flags & AHCI_HFLAG_NO_PMP))175 if ((ai->cap & HOST_CAP_PMP) && (ai->quirks & AHCI_HFLAG_NO_PMP)) 215 176 { 216 177 DPRINTF(DBG_INIT, DBG_PREFIX": controller can't do PMP, turning off CAP_PMP\n"); … … 218 179 } 219 180 220 if ((ai->cap & HOST_CAP_SNTF) && (ai-> flags & AHCI_HFLAG_NO_SNTF))181 if ((ai->cap & HOST_CAP_SNTF) && (ai->quirks & AHCI_HFLAG_NO_SNTF)) 221 182 { 222 183 DPRINTF(DBG_INIT, DBG_PREFIX": controller can't do SNTF, turning off CAP_SNTF\n"); … … 224 185 } 225 186 226 if (ai-> pci_vendor == PCI_VENDOR_ID_JMICRON && ai->pci_device == 0x2361 && ai->port_map != 1)187 if (ai->PciVendor == PCI_VENDOR_ID_JMICRON && ai->PciDevice == 0x2361 && ai->port_map != 1) 227 188 { 228 189 DPRINTF(DBG_INIT, DBG_PREFIX": JMB361 has only one port, port_map 0x%x -> 0x%x\n", ai->port_map, 1); … … 276 237 DPRINTF(DBG_DETAILED, DBG_PREFIX": BIOS AHCI mode is %d\n", ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN); 277 238 278 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && ai-> pci_vendor == PCI_VENDOR_ID_INTEL)239 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && ai->PciVendor == PCI_VENDOR_ID_INTEL) 279 240 { 280 241 /* Adapter is not in AHCI mode and the spec says a COMRESET is … … 309 270 readl(ai->mmio + HOST_CTL); 310 271 311 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && ai-> pci_vendor == PCI_VENDOR_ID_INTEL)272 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && ai->PciVendor == PCI_VENDOR_ID_INTEL) 312 273 { 313 274 /* This BIOS apparently accesses the controller via SATA registers and … … 400 361 while (((tmp = readl(ai->mmio + HOST_CTL)) & HOST_RESET) != 0) { 401 362 if (TimerCheckAndBlock(&Timer)) { 402 dprintf(0, "controller reset failed (0x%x)\n", tmp);363 dprintf(0, DBG_PREFIX": controller reset failed (0x%x)\n", tmp); 403 364 return(-1); 404 365 } … … 411 372 ahci_restore_initial_config(ai); 412 373 413 if (ai-> pci_vendor == PCI_VENDOR_ID_INTEL) {374 if (ai->PciVendor == PCI_VENDOR_ID_INTEL) { 414 375 u32 tmp16 = 0; 415 376 … … 498 459 } 499 460 500 if (ai-> pci_vendor == PCI_VENDOR_ID_INTEL)461 if (ai->PciVendor == PCI_VENDOR_ID_INTEL) 501 462 { 502 463 /* Adapter is not in AHCI mode and the spec says a COMRESET is … … 520 481 521 482 /* couldn't enable AHCI mode */ 522 dprintf(0, "failed to enable AHCI mode on adapter %d\n", ad_no(ai));483 dprintf(0, DBG_PREFIX": failed to enable AHCI mode on adapter %d\n", ad_no(ai)); 523 484 return(1); 524 485 } … … 541 502 /* register IRQ handler; each IRQ level is registered only once */ 542 503 p = 1; /* int count */ 543 if (!(ai-> flags & AHCI_HFLAG_NO_MSI))544 { 545 if (PsdMsiAlloc(ai-> bus_dev_func, &p, &ai->irq)) p = 1; /* shared flag */504 if (!(ai->quirks & AHCI_HFLAG_NO_MSI)) 505 { 506 if (PsdMsiAlloc(ai->BusDevFunc, &p, &ai->irq)) p = 1; /* shared flag */ 546 507 else 547 508 { … … 569 530 if (rc) 570 531 { 571 dprintf(0, "failed to register interrupt %d\n", ai->irq);532 dprintf(0, DBG_PREFIX": failed to register interrupt %d\n", ai->irq); 572 533 return(-1); 573 534 } … … 612 573 readl(ai->mmio + HOST_CTL); /* flush */ 613 574 614 /* enable interrupts on PCI-level (PCI 2.3 added a feature to disable INTs) */615 /* pci_enable_int(ai->bus, ai->dev_func); */616 617 575 DPRINTF(DBG_INIT|DBG_FUNCEND, DBG_PREFIX": END\n"); 618 576 return(0); … … 686 644 if (ai->port_max < p) ai->port_max = p; 687 645 if (ai->ports[p].dev_max < d) ai->ports[p].dev_max = d; 688 memset(ai->ports[p].devs + d, 0 x00, sizeof(*ai->ports[p].devs));646 memset(ai->ports[p].devs + d, 0, sizeof(*ai->ports[p].devs)); 689 647 690 648 /* set generic device information (assuming an ATA disk device for now) */ … … 699 657 /* this is an ATAPI device; augment device information */ 700 658 ai->ports[p].devs[d].atapi = 1; 701 ai->ports[p].devs[d].atapi_16 = (id_buf[ATA_ID_CONFIG] & 0x0001 U) != 0;702 ai->ports[p].devs[d].dev_type = (id_buf[ATA_ID_CONFIG] & 0x1f00 U) >> 8;659 ai->ports[p].devs[d].atapi_16 = (id_buf[ATA_ID_CONFIG] & 0x0001) != 0; 660 ai->ports[p].devs[d].dev_type = (id_buf[ATA_ID_CONFIG] & 0x1f00) >> 8; 703 661 ai->ports[p].devs[d].ncq_max = 1; 704 662 … … 709 667 if (enable_ncq[ad_no(ai)][p]) 710 668 { 711 ai->ports[p].devs[d].ncq_max = id_buf[ATA_ID_QUEUE_DEPTH] & 0x001f U;669 ai->ports[p].devs[d].ncq_max = id_buf[ATA_ID_QUEUE_DEPTH] & 0x001f; 712 670 } 713 671 if (ai->ports[p].devs[d].ncq_max < 1) … … 716 674 ai->ports[p].devs[d].ncq_max = 1; 717 675 } 718 if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x0400 U)719 { 720 ai->ports[p].devs[d].lba48 676 if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x0400) 677 { 678 ai->ports[p].devs[d].lba48 = 1; 721 679 } 722 680 } … … 760 718 761 719 /* try to detect virtualbox environment to enable a hack for IRQ routing */ 762 if (ai == ad_infos && ai-> pci_vendor == 0x8086 && ai->pci_device == 0x2829 &&720 if (ai == ad_infos && ai->PciVendor == 0x8086 && ai->PciDevice == 0x2829 && 763 721 !memcmp(pDevName, "VBOX HARDDISK", 13)) 764 722 { … … 933 891 /* set link speed and power management options */ 934 892 DPRINTF(DBG_DETAILED, DBG_PREFIX": setting link speed and power management options\n"); 935 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000fff UL;893 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000fff; 936 894 tmp |= (link_speed[ad_no(ai)][p] & 0x0f) << 4; 937 895 tmp |= (link_power[ad_no(ai)][p] & 0x0f) << 8; … … 1098 1056 if ((rc = ahci_stop_fis_rx(ai, p)) != 0) 1099 1057 { 1100 dprintf(0, __func__": failed to stop FIS receive (%d)\n", rc);1058 dprintf(0, DBG_PREFIX": failed to stop FIS receive (%d)\n", rc); 1101 1059 return(rc); 1102 1060 } … … 1105 1063 if ((rc = ahci_stop_engine(ai, p)) != 0) 1106 1064 { 1107 dprintf(0, __func__": failed to stop port HW engine (%d)\n", rc);1065 dprintf(0, DBG_PREFIX": failed to stop port HW engine (%d)\n", rc); 1108 1066 return(rc); 1109 1067 } … … 1408 1366 writel(port_mmio + PORT_CMD_ISSUE, 1); 1409 1367 TimerInit(&Timer, timeout); 1368 rc = 0; 1410 1369 while (readl(port_mmio + PORT_CMD_ISSUE) & 1) 1411 1370 { … … 1417 1376 if (rc) 1418 1377 { 1419 DPRINTF(DBG_DETAILED, " timeout for IORB %x port=%x", vIorb, p);1378 DPRINTF(DBG_DETAILED, " timeout %x for IORB %x port=%x", timeout, vIorb, p); 1420 1379 iorb_seterr(pIorb, IOERR_ADAPTER_TIMEOUT); 1421 1380 } … … 1731 1690 iorb_queue_del(&ai->ports[p].iorb_queue, vIorb); 1732 1691 iorb_queue_add(&done_queue, vIorb, pIorb); 1692 /* If we failed a NCQ command and then succeeded with a standard command, disable NCQ for this port */ 1693 if (add_workspace(pIorb)->no_ncq) ai->ports[p].devs[iorb_unit_device(pIorb)].ncq_max = 1; 1733 1694 aws_free(add_workspace(pIorb)); 1734 1695 } … … 1775 1736 #ifdef DEBUG 1776 1737 u32 *unk = (u32 *) (port_dma_base(ai, p)->rx_fis + RX_FIS_UNK); 1777 dprintf(0, "warning: unknown FIS %08lx %08lx %08lx %08lx\n", unk[0], unk[1], unk[2], unk[3]);1738 dprintf(0, DBG_PREFIX": warning: unknown FIS %08lx %08lx %08x %08x\n", unk[0], unk[1], unk[2], unk[3]); 1778 1739 #endif 1779 1740 reset_port = 1; … … 1781 1742 if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) 1782 1743 { 1783 dprintf(0, "warning: host bus [data] error for port #%d\n", p);1744 dprintf(0, DBG_PREFIX": warning: host bus [data] error port=%d\n", p); 1784 1745 reset_port = 1; 1785 1746 } 1786 if (irq_stat & PORT_IRQ_IF_ERR && !(ai-> flags & AHCI_HFLAG_IGN_IRQ_IF_ERR))1787 { 1788 dprintf(0, "warning: interface fatal error for port #%d\n", p);1747 if (irq_stat & PORT_IRQ_IF_ERR && !(ai->quirks & AHCI_HFLAG_IGN_IRQ_IF_ERR)) 1748 { 1749 dprintf(0, DBG_PREFIX": warning: interface fatal error port=%d\n", p); 1789 1750 reset_port = 1; 1790 1751 } … … 1794 1755 1795 1756 ports_to_reset[ad_no(ai)] |= 1UL << p; 1796 KernArmHook(reset_ctxhook_h, 0, 0);1757 SafeArmCtxHook(ResetCtxHook_h, 0); 1797 1758 1798 1759 /* no point analyzing device errors after a reset... */ … … 1800 1761 } 1801 1762 1802 #ifdef DEBUG 1803 dprintf(0,"port #%d interrupt error status: 0x%08x; restarting port\n", p, irq_stat); 1804 #else 1763 #ifndef DEBUG 1805 1764 if (!ai->ports[p].devs[0].atapi) 1806 {1807 dprintf(0,"port #%d interrupt error status: 0x%08x; restarting port\n", p, irq_stat);1808 }1809 1765 #endif 1766 { 1767 dprintf(0,DBG_PREFIX": Port=%d status=%08x; restarting port\n", p, irq_stat); 1768 } 1810 1769 1811 1770 /* Handle device-specific errors. Those errors typically involve restarting … … 1814 1773 */ 1815 1774 ports_to_restart[ad_no(ai)] |= 1UL << p; 1816 KernArmHook(restart_ctxhook_h, 0, 0);1775 SafeArmCtxHook(RestartCtxHook_h, 0); 1817 1776 } 1818 1777 -
trunk/src/os2ahci/ahci.h
r205 r211 77 77 #define RX_FIS_SDB 0x58 /* offset of SDB FIS data */ 78 78 #define RX_FIS_UNK 0x60 /* offset of Unknown FIS data */ 79 80 #define board_ahci 081 #define board_ahci_vt8251 182 #define board_ahci_ign_iferr 283 #define board_ahci_sb600 384 #define board_ahci_mv 485 #define board_ahci_sb700 5 /* for SB700 and SB800 */86 #define board_ahci_mcp65 687 #define board_ahci_nopmp 788 #define board_ahci_yesncq 889 #define board_ahci_nosntf 990 79 91 80 /* global controller registers */ … … 156 145 157 146 /* PORT_IRQ_{STAT,MASK} bits */ 158 #define PORT_IRQ_COLD_PRES (1UL << 31) /* cold presence detect */159 #define PORT_IRQ_TF_ERR (1UL << 30) /* task file error */160 #define PORT_IRQ_HBUS_ERR (1UL << 29) /* host bus fatal error */161 #define PORT_IRQ_HBUS_DATA_ERR (1UL << 28) /* host bus data error */162 #define PORT_IRQ_IF_ERR (1UL << 27) /* interface fatal error */163 #define PORT_IRQ_IF_NONFATAL (1UL << 26) /* interface non-fatal error */164 #define PORT_IRQ_OVERFLOW (1UL << 24) /* xfer exhausted available S/G */165 #define PORT_IRQ_BAD_PMP (1UL << 23) /* incorrect port multiplier */166 #define PORT_IRQ_PHYRDY (1UL << 22) /* PhyRdy changed */167 #define PORT_IRQ_DEV_ILCK (1UL << 7) /* device interlock */168 #define PORT_IRQ_CONNECT (1UL << 6) /* port connect change status */169 #define PORT_IRQ_SG_DONE (1UL << 5) /* descriptor processed */170 #define PORT_IRQ_UNK_FIS (1UL << 4) /* unknown FIS rx'd */171 #define PORT_IRQ_SDB_FIS (1UL << 3) /* Set Device Bits FIS rx'd */172 #define PORT_IRQ_DMAS_FIS (1UL << 2) /* DMA Setup FIS rx'd */173 #define PORT_IRQ_PIOS_FIS (1UL << 1) /* PIO Setup FIS rx'd */174 #define PORT_IRQ_D2H_REG_FIS (1UL << 0) /* D2H Register FIS rx'd */147 #define PORT_IRQ_COLD_PRES (1UL << 31) /* 80000000 cold presence detect */ 148 #define PORT_IRQ_TF_ERR (1UL << 30) /* 40000000 task file error */ 149 #define PORT_IRQ_HBUS_ERR (1UL << 29) /* 20000000 host bus fatal error */ 150 #define PORT_IRQ_HBUS_DATA_ERR (1UL << 28) /* 10000000 host bus data error */ 151 #define PORT_IRQ_IF_ERR (1UL << 27) /* 08000000 interface fatal error */ 152 #define PORT_IRQ_IF_NONFATAL (1UL << 26) /* 04000000 interface non-fatal error */ 153 #define PORT_IRQ_OVERFLOW (1UL << 24) /* 01000000 xfer exhausted available S/G */ 154 #define PORT_IRQ_BAD_PMP (1UL << 23) /* 00800000 incorrect port multiplier */ 155 #define PORT_IRQ_PHYRDY (1UL << 22) /* 00400000 PhyRdy changed */ 156 #define PORT_IRQ_DEV_ILCK (1UL << 7) /* 00000080 device interlock */ 157 #define PORT_IRQ_CONNECT (1UL << 6) /* 00000040 port connect change status */ 158 #define PORT_IRQ_SG_DONE (1UL << 5) /* 00000020 descriptor processed */ 159 #define PORT_IRQ_UNK_FIS (1UL << 4) /* 00000010 unknown FIS rx'd */ 160 #define PORT_IRQ_SDB_FIS (1UL << 3) /* 00000008 Set Device Bits FIS rx'd */ 161 #define PORT_IRQ_DMAS_FIS (1UL << 2) /* 00000004 DMA Setup FIS rx'd */ 162 #define PORT_IRQ_PIOS_FIS (1UL << 1) /* 00000002 PIO Setup FIS rx'd */ 163 #define PORT_IRQ_D2H_REG_FIS (1UL << 0) /* 00000001 D2H Register FIS rx'd */ 175 164 #define PORT_IRQ_FREEZE (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR | \ 176 165 PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY | \ -
trunk/src/os2ahci/apm.c
r209 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen -
trunk/src/os2ahci/ata.c
r209 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 121 121 if (ata_cmd.lba_l & 0xf0000000UL) 122 122 { 123 dprintf(0, "error: LBA-28 address %d has more than 28 bits\n", ata_cmd.lba_l);123 dprintf(0, DBG_PREFIX": error: LBA-28 address %d has more than 28 bits\n", ata_cmd.lba_l); 124 124 return(ATA_CMD_INVALID_PARM); 125 125 } … … 172 172 173 173 default: 174 dprintf(0, "error: v_ata_cmd()called with invalid parameter type (%d)\n", (int) ap);174 dprintf(0, DBG_PREFIX": error: called with invalid parameter type (%d)\n", (int) ap); 175 175 return(ATA_CMD_INVALID_PARM); 176 176 } … … 255 255 if (sg_size) 256 256 { 257 dprintf(0, __func__": unaligned SG element\n");257 dprintf(0, DBG_PREFIX": unaligned SG element\n"); 258 258 return -1; 259 259 } 260 dprintf(0, __func__": too many S/G elements\n");260 dprintf(0, DBG_PREFIX": too many S/G elements\n"); 261 261 return(i - 1); 262 262 } 263 263 if ((sg_addr & 1) || (chunk & 1)) 264 264 { 265 DPRINTF(0, DBG_PREFIX": warning: ata_cmd()called with unaligned S/G element(s)\n");265 DPRINTF(0, DBG_PREFIX": warning: called with unaligned S/G element(s)\n"); 266 266 return(ATA_CMD_UNALIGNED_ADDR); 267 267 } … … 278 278 279 279 #if DEBUG & DBG_DETAILED 280 dprintf(0, "ATA command for %d.%d.%d, slot %d:\n", ad_no(ai), p, d, slot);280 dprintf(0, DBG_PREFIX": ATA command for %d.%d.%d, slot %d:\n", ad_no(ai), p, d, slot); 281 281 dHexDump(0,cmd_hdr, offsetof(AHCI_CMD_HDR, reserved), "cmd_hdr: "); 282 282 dHexDump(0,&ata_cmd, sizeof(ata_cmd), "ata_cmd: "); … … 549 549 { 550 550 /* more than 32 bits for number of sectors */ 551 dprintf(0, "warning: limiting disk %d.%d.%d to 2TB\n",551 dprintf(0, DBG_PREFIX": warning: limiting disk %d.%d.%d to 2TB\n", 552 552 iorb_unit_adapter(pIorb), iorb_unit_port(pIorb), 553 553 iorb_unit_device(pIorb)); … … 651 651 int rc; 652 652 653 if ( ullLba >= (1UL << 28) || count > 256 || add_workspace(pIorb)->is_ncq)653 if (add_workspace(pIorb)->is_ncq || ullLba >= (1 << 28) || count > 256 || (ullLba+count) >= (1 << 28)) 654 654 { 655 655 /* need LBA48 for this command */ -
trunk/src/os2ahci/ata.h
r207 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen -
trunk/src/os2ahci/atapi.c
r209 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen -
trunk/src/os2ahci/atapi.h
r205 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen -
trunk/src/os2ahci/ctxhook.c
r209 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 31 31 32 32 /* port restart context hook and input data */ 33 ULONG restart_ctxhook_h;33 ULONG RestartCtxHook_h; 34 34 volatile u32 ports_to_restart[MAX_AD]; 35 35 36 36 /* port reset context hook and input data */ 37 ULONG reset_ctxhook_h;38 ULONG th_ reset_watchdog;37 ULONG ResetCtxHook_h; 38 ULONG th_watchdog; 39 39 volatile u32 ports_to_reset[MAX_AD]; 40 40 IORB_QUEUE abort_queue; … … 42 42 /* trigger engine context hook and input data */ 43 43 ULONG engine_ctxhook_h; 44 45 #define QUEUEDEPTH 8 46 static struct _ctxq_ 47 { 48 ULONG ulHandle; 49 ULONG ulArg; 50 } CtxQueue[QUEUEDEPTH] = {0}; 51 static ULONG ulCtxStatusFlag = 0; 52 53 void SafeArmCtxHook(ULONG ulHandle, ULONG armData) 54 { 55 USHORT i; 56 57 i = LockInc(&ulCtxStatusFlag); 58 59 if (i) 60 { 61 i--; 62 if (i < QUEUEDEPTH) 63 { 64 CtxQueue[i].ulHandle = ulHandle; 65 CtxQueue[i].ulArg = armData; 66 } 67 } 68 else 69 { 70 KernArmHook(ulHandle, armData, 0); 71 } 72 } 73 74 void ClearThreadStatus(ULONG ulHandle) 75 { 76 USHORT i; 77 78 i = LockDec(&ulCtxStatusFlag); 79 80 if (i) 81 { 82 i--; 83 if (i < QUEUEDEPTH) 84 { 85 KernArmHook(CtxQueue[i].ulHandle, CtxQueue[i].ulArg, 0); 86 } 87 else 88 { 89 KernArmHook(ulHandle, 0, 0); 90 } 91 } 92 } 44 93 45 94 /****************************************************************************** … … 78 127 * in the interrupt and error handlers. 79 128 */ 80 void _Syscall restart_ctxhook(ULONG parm)129 void _Syscall RestartCtxHook(ULONG parm) 81 130 { 82 131 IORB_QUEUE done_queue; … … 85 134 IORBH FAR16DATA *vIorb; 86 135 IORBH FAR16DATA *vNext; 136 IORBH *pIorb; 137 ADD_WORKSPACE *aws; 87 138 u8 *port_mmio; 88 139 int rearm_ctx_hook; … … 97 148 rearm_ctx_hook = 0; 98 149 99 DPRINTF(DBG_FUNCBEG, DBG_PREFIX": restart_ctxhook() started\n"); 150 AhciStats.ulSoftErrorCount++; 151 DPRINTF(0, DBG_PREFIX": BEG\n"); 100 152 memset(&done_queue, 0x00, sizeof(done_queue)); 101 153 102 154 spin_lock(drv_lock); 155 156 if (th_watchdog != 0) 157 { 158 /* watchdog timer still active -- just reset it */ 159 Timer_CancelTimer(th_watchdog); 160 th_watchdog = 0; 161 } 103 162 104 163 for (a = 0; a < ad_info_cnt; a++) … … 124 183 need_reset = 0; 125 184 126 DPRINTF(DBG_DETAILED, DBG_PREFIX": port %d, TF_DATA:0x%x\n", p, readl(port_mmio + PORT_TFDATA));185 DPRINTF(DBG_DETAILED, DBG_PREFIX": port=%d TF_DATA=0x%x\n", p, readl(port_mmio + PORT_TFDATA)); 127 186 128 187 /* get "current command slot"; only valid if there are no NCQ cmds */ 129 188 ccs = (int) ((readl(port_mmio + PORT_CMD) >> 8) & 0x1f); 130 DPRINTF(DBG_DETAILED, DBG_PREFIX": PORT_CMD =0x%x\n", ccs);189 DPRINTF(DBG_DETAILED, DBG_PREFIX": PORT_CMD=0x%x\n", ccs); 131 190 132 191 for (vIorb = ai->ports[p].iorb_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext) 133 192 { 134 IORBH *pIorb = Far16ToFlat(vIorb);135 ADD_WORKSPACE *aws = add_workspace(pIorb);193 pIorb = Far16ToFlat(vIorb); 194 aws = add_workspace(pIorb); 136 195 vNext = pIorb->f16NxtIORB; 137 196 138 197 if (aws->queued_hw) 139 198 { 199 if (aws->timer != 0) 200 { 201 Timer_CancelTimer(aws->timer); 202 aws->timer = 0; 203 } 204 140 205 if (ai->ports[p].ncq_cmds & (1UL << aws->cmd_slot)) 141 206 { … … 144 209 aws->no_ncq = 1; 145 210 need_reset = 1; 211 DPRINTF(0, DBG_PREFIX": failing IORB: %x NCQ slot=%x\n", vIorb, aws->cmd_slot); 212 #ifdef DEBUG 213 DumpIorb(pIorb, vIorb); 214 #endif 146 215 } 147 216 else … … 152 221 { 153 222 /* this is the non-NCQ command that failed */ 154 DPRINTF(0, DBG_PREFIX": failing IORB: %x\n", vIorb); 223 DPRINTF(0, DBG_PREFIX": failing IORB: %x slot=%x\n", vIorb, aws->cmd_slot); 224 #ifdef DEBUG 225 DumpIorb(pIorb, vIorb); 226 #endif 155 227 vProblemIorb = vIorb; 156 228 } … … 179 251 if (ai->ports[p].ncq_cmds != 0 || ai->ports[p].reg_cmds != 0) 180 252 { 181 DPRINTF(0, DBG_PREFIX": warning: commands issued not 0 (%08 lx/%08lx); resetting...\n",253 DPRINTF(0, DBG_PREFIX": warning: commands issued not 0 (%08x/%08x); resetting...\n", 182 254 ai->ports[p].ncq_cmds, ai->ports[p].reg_cmds); 183 255 need_reset = 1; … … 260 332 spin_unlock(drv_lock); 261 333 334 DPRINTF(0, DBG_PREFIX": Resuming\n"); 262 335 /* call notification routine on all IORBs which have completed */ 263 336 for (vIorb = done_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext) 264 337 { 265 IORBH *pIorb = Far16ToFlat(vIorb);338 pIorb = Far16ToFlat(vIorb); 266 339 vNext = pIorb->f16NxtIORB; 267 340 … … 278 351 spin_unlock(drv_lock); 279 352 280 DPRINTF( DBG_FUNCEND, DBG_PREFIX": restart_ctxhook() completed\n");353 DPRINTF(0, DBG_PREFIX": END Rearm=%x\n", rearm_ctx_hook); 281 354 282 355 /* Check whether we have to rearm ourselves because some adapters were busy … … 285 358 if (rearm_ctx_hook) 286 359 { 287 msleep(250); 288 KernArmHook(restart_ctxhook_h, 0, 0); 289 } 360 /* we cannot rearm ourself because we will execute immediately leaving 361 * no time to process and clear the reason we need to rearm. Therefore 362 * we set the timer again. 363 */ 364 Timer_StartTimerMS(&th_watchdog, 250, WatchdogTimer, RestartCtxHook_h); 365 } 366 367 ClearThreadStatus(RestartCtxHook_h); 290 368 KernThunkStackTo16(); 291 369 } … … 317 395 * the upstream code might reuse the IORBs before we're done with them. 318 396 */ 319 void _Syscall reset_ctxhook(ULONG parm)397 void _Syscall ResetCtxHook(ULONG ulArg) 320 398 { 321 399 IORB_QUEUE done_queue; … … 323 401 IORBH FAR16DATA *vIorb; 324 402 IORBH FAR16DATA *vNext; 403 IORBH *pIorb; 404 ADD_WORKSPACE *aws; 325 405 int rearm_ctx_hook; 326 406 int a; … … 332 412 rearm_ctx_hook = 0; 333 413 334 DPRINTF(DBG_FUNCBEG, DBG_PREFIX": reset_ctxhook() started\n"); 414 AhciStats.ulHardErrorCount++; 415 DPRINTF(0, DBG_PREFIX": BEG Arg=%x\n", ulArg); 335 416 memset(&done_queue, 0x00, sizeof(done_queue)); 336 417 418 if (th_watchdog != 0) 419 { 420 /* watchdog timer still active -- just reset it */ 421 Timer_CancelTimer(th_watchdog); 422 th_watchdog = 0; 423 } 424 337 425 spin_lock(drv_lock); 338 426 339 if (th_reset_watchdog != 0) 340 { 341 /* watchdog timer still active -- just reset it */ 342 Timer_CancelTimer(th_reset_watchdog); 343 th_reset_watchdog = 0; 427 if (ulArg) 428 { 429 /* Move the timed-out IORB to the abort queue. Since it's possible that the 430 * IORB has completed after the timeout has expired but before we got to 431 * this line of code, we'll check the return code of iorb_queue_del(): If it 432 * returns an error, the IORB must have completed a few microseconds ago and 433 * there is no timeout. 434 */ 435 vIorb = (IORBH FAR16DATA *)CastULONGToFar16(ulArg); 436 pIorb = Far16ToFlat(vIorb); 437 a = iorb_unit_adapter(pIorb); 438 p = iorb_unit_port(pIorb); 439 if (iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, vIorb) == 0) 440 { 441 pIorb = Far16ToFlat(vIorb); 442 iorb_queue_add(&abort_queue, vIorb, pIorb); 443 pIorb->ErrorCode = IOERR_ADAPTER_TIMEOUT; 444 } 344 445 } 345 446 … … 347 448 for (vIorb = abort_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext) 348 449 { 349 IORBH *pIorb = Far16ToFlat(vIorb);450 pIorb = Far16ToFlat(vIorb); 350 451 vNext = pIorb->f16NxtIORB; 351 452 a = iorb_unit_adapter(pIorb); 352 453 p = iorb_unit_port(pIorb); 353 454 ai = ad_infos + a; 455 aws = add_workspace(pIorb); 354 456 355 457 if (ai->busy) … … 365 467 366 468 /* reset port if the IORB has already been queued to hardware */ 367 if (add_workspace(pIorb)->queued_hw) 368 { 469 if (aws->queued_hw) 470 { 471 if (aws->timer != 0) 472 { 473 Timer_CancelTimer(aws->timer); 474 aws->timer = 0; 475 } 476 369 477 /* prepare port reset */ 370 478 ports_to_reset[a] |= (1UL << p); … … 411 519 { 412 520 IORBH *pIorb = Far16ToFlat(vIorb); 413 ADD_WORKSPACE *aws = add_workspace(pIorb);414 521 vNext = pIorb->f16NxtIORB; 522 523 aws = add_workspace(pIorb); 415 524 416 525 if (aws->queued_hw) … … 421 530 /* we can retry this IORB */ 422 531 iorb_requeue(pIorb); 423 424 532 } 425 533 else … … 438 546 spin_unlock(drv_lock); 439 547 548 DPRINTF(0, DBG_PREFIX": Resuming\n"); 549 440 550 /* complete all aborted IORBs */ 441 551 for (vIorb = done_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext) 442 552 { 443 IORBH *pIorb = Far16ToFlat(vIorb);553 pIorb = Far16ToFlat(vIorb); 444 554 vNext = pIorb->f16NxtIORB; 445 555 … … 457 567 spin_unlock(drv_lock); 458 568 459 DPRINTF( DBG_FUNCEND, DBG_PREFIX": reset_ctxhook() completed\n");569 DPRINTF(0, DBG_PREFIX": END Rearm=%x\n", rearm_ctx_hook); 460 570 461 571 /* Check whether we have to rearm ourselves because some adapters were busy … … 468 578 * we set the timer again. 469 579 */ 470 //msleep(250); 471 //KernArmHook(reset_ctxhook_h, 0, 0); 472 Timer_StartTimerMS(&th_reset_watchdog, 250, reset_watchdog, 0); 473 } 474 580 Timer_StartTimerMS(&th_watchdog, 250, WatchdogTimer, ResetCtxHook_h); 581 } 582 583 ClearThreadStatus(ResetCtxHook_h); 475 584 KernThunkStackTo16(); 476 585 } -
trunk/src/os2ahci/ioctl.c
r206 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen -
trunk/src/os2ahci/ioctl.h
r205 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 30 30 #define OS2AHCI_IOCTL_GET_DEVLIST 0x01 31 31 #define OS2AHCI_IOCTL_PASSTHROUGH 0x02 32 #define OS2AHCI_IOCTL_DEBUG 0xd1 32 33 33 34 /* IOCTL definitions from s506oem.h (primarily required for SMART calls) */ … … 199 200 } UnitInformationData; 200 201 201 202 202 #pragma pack() 203 203 -
trunk/src/os2ahci/os2ahci.c
r209 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 26 26 */ 27 27 28 #define INCL_LONGLONG 28 29 #include "os2ahci.h" 29 30 #include "ioctl.h" … … 58 59 int thorough_scan = 1; /* if != 0, perform thorough PCI scan */ 59 60 int init_reset = 1; /* if != 0, reset ports during init */ 60 int force_write_cache ; /* if != 0, force write cache */61 int force_write_cache = 0; /* if != 0, force write cache */ 61 62 int iVerbose = 0; /* default is quiet. 1=show sign on banner, >1=show adapter info during boot */ 62 63 int use_mbr_test = 1; … … 190 191 memset(ad_infos, 0, sizeof(ad_infos)); 191 192 memset(emulate_scsi, 1, sizeof(emulate_scsi)); /* set default enabled */ 193 memset(enable_ncq, 1, sizeof(enable_ncq)); /* set default enabled */ 192 194 UtSetDriverName("OS2AHCI$"); 193 195 Header.ulCaps |= DEV_ADAPTER_DD; /* DAZ This flag is not really needed. */ … … 423 425 if (iVerbose) iprintf("OS2AHCI.ADD: driver version %d.%02d", DMAJOR, DMINOR); 424 426 425 #if def TESTVER427 #if defined(TESTVER) && defined(DEBUG) 426 428 #include "testver.c" 427 429 #endif … … 443 445 444 446 /* allocate context hooks */ 445 KernAllocateContextHook( restart_ctxhook, 0, &restart_ctxhook_h);446 KernAllocateContextHook( reset_ctxhook, 0, &reset_ctxhook_h);447 KernAllocateContextHook(RestartCtxHook, 0, &RestartCtxHook_h); 448 KernAllocateContextHook(ResetCtxHook, 0, &ResetCtxHook_h); 447 449 KernAllocateContextHook(engine_ctxhook, 0, &engine_ctxhook_h); 448 450 … … 481 483 { 482 484 DPRINTF(DBG_FUNCBEG, DBG_PREFIX": IOCTL 0x%x/0x%x\n", ioctl->ioctl.bCategory, ioctl->ioctl.bFunction); 483 AhciStats.ulTestCount2++;484 485 485 486 switch (ioctl->ioctl.bCategory) … … 599 600 memset(&pIorb->ADDWorkSpace, 0x00, sizeof(ADD_WORKSPACE)); 600 601 601 #ifdef DEBUG602 DumpIorb(pIorb); /* DAZ TESTING */603 #endif602 //#ifdef DEBUG 603 //DumpIorb(pIorb); /* DAZ TESTING */ 604 //#endif 604 605 605 606 if (iorb_driver_level(pIorb)) … … 622 623 { 623 624 /* unit handle outside of the allowed range */ 624 dprintf(0, "warning: IORB for %d.%d.%dout of range\n", a, p, d);625 dprintf(0, DBG_PREFIX": ERROR: IORB for %d.%d.%d is out of range\n", a, p, d); 625 626 pIorb->Status = IORB_ERROR; 626 627 pIorb->ErrorCode = IOERR_CMD_SYNTAX; … … 920 921 921 922 /* trigger reset context hook which will finish the abort processing */ 922 KernArmHook(reset_ctxhook_h, 0, 0);923 SafeArmCtxHook(ResetCtxHook_h, 0); 923 924 break; 924 925 … … 1071 1072 if ((u32)(pPtr + 1) - (u32)pDt > pIorb_conf->DeviceTableLen) 1072 1073 { 1073 dprintf(0, "error: device table provided by DASD too small\n");1074 dprintf(0, DBG_PREFIX": error: device table provided by DASD too small\n"); 1074 1075 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE); 1075 1076 goto iocm_device_table_done; … … 1100 1101 if (ad_info->busy) 1101 1102 { 1102 dprintf(0, "error: port scan requested while adapter was busy\n");1103 dprintf(0, DBG_PREFIX": error: port scan requested while adapter was busy\n"); 1103 1104 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE); 1104 1105 goto iocm_device_table_done; … … 1112 1113 if (rc != 0) 1113 1114 { 1114 dprintf(0, "error: port scan failed on adapter #%d\n", dta);1115 dprintf(0, DBG_PREFIX": error: port scan failed on adapter #%d\n", dta); 1115 1116 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE); 1116 1117 goto iocm_device_table_done; … … 1533 1534 * separate function which is invoked via a context hook. 1534 1535 */ 1535 void __syscall timeout_callback(ULONG timer_handle, ULONG p1)1536 { 1537 IORBH FAR16DATA *vIorb = (IORBH FAR16DATA *)CastULONGToFar16( p1);1536 void __syscall timeout_callback(ULONG timer_handle, ULONG ulArg) 1537 { 1538 IORBH FAR16DATA *vIorb = (IORBH FAR16DATA *)CastULONGToFar16(ulArg); 1538 1539 IORBH *pIorb = Far16ToFlat(vIorb); 1539 1540 int a = iorb_unit_adapter(pIorb); … … 1541 1542 1542 1543 Timer_CancelTimer(timer_handle); 1543 dprintf(0,"timeout for IORB %x port=%x\n", vIorb, p); 1544 1545 /* Move the timed-out IORB to the abort queue. Since it's possible that the 1546 * IORB has completed after the timeout has expired but before we got to 1547 * this line of code, we'll check the return code of iorb_queue_del(): If it 1548 * returns an error, the IORB must have completed a few microseconds ago and 1549 * there is no timeout. 1550 */ 1551 spin_lock(drv_lock); 1552 if (iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, vIorb) == 0) 1553 { 1554 iorb_queue_add(&abort_queue, vIorb, pIorb); 1555 pIorb->ErrorCode = IOERR_ADAPTER_TIMEOUT; 1556 } 1557 spin_unlock(drv_lock); 1544 dprintf(0, DBG_PREFIX": timeout for IORB %x port=%x.%x\n", ulArg, a, p); 1558 1545 1559 1546 /* Trigger abort processing function. We don't really care whether this … … 1568 1555 * will process our IORB as well. 1569 1556 */ 1570 KernArmHook(reset_ctxhook_h, 0, 0); 1571 1572 /* Set up a watchdog timer which calls the context hook manually in case 1573 * some kernel thread is looping around the IORB_COMPLETE status bit 1574 * without yielding the CPU (kernel threads don't preempt). This shouldn't 1575 * happen per design because kernel threads are supposed to yield but it 1576 * does in the early boot phase. 1577 */ 1578 Timer_StartTimerMS(&th_reset_watchdog, 5000, reset_watchdog, 0); 1557 SafeArmCtxHook(ResetCtxHook_h, ulArg); 1579 1558 } 1580 1559 … … 1590 1569 * problems during the early boot phase. 1591 1570 */ 1592 void __syscall reset_watchdog(ULONG timer_handle, ULONG p1)1571 void __syscall WatchdogTimer(ULONG timer_handle, ULONG ulArg) 1593 1572 { 1594 1573 /* reset watchdog timer */ 1595 1574 Timer_CancelTimer(timer_handle); 1596 th_ reset_watchdog = 0;1597 dprintf(0, "reset watchdog invoked\n");1598 1599 /* You cannot call the reset_ctxhookdirectly because it does things1575 th_watchdog = 0; 1576 dprintf(0, DBG_PREFIX": BEG %s\n", ulArg==ResetCtxHook_h?"Reset":"Restart"); 1577 1578 /* The ctxhook cannot be called directly because it does things 1600 1579 * that are illegal in an interrupt handler. 1601 1580 */ 1602 1603 KernArmHook(reset_ctxhook_h, 0, 0); 1604 1605 /* call context hook manually */ 1606 //reset_ctxhook(0); 1581 SafeArmCtxHook(ulArg, 0); 1607 1582 } 1608 1583 … … 1634 1609 if ((u32)(pUi + 1) - (u32)pDt > pIorb_conf->DeviceTableLen) 1635 1610 { 1636 dprintf(0, "error: device table provided by DASD too small\n");1611 dprintf(0, DBG_PREFIX": error: device table provided by DASD too small\n"); 1637 1612 iorb_seterr(&pIorb_conf->iorbh, IOERR_CMD_SW_RESOURCE); 1638 1613 return(-1); -
trunk/src/os2ahci/os2ahci.h
r209 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 107 107 parm nomemory [eax] [bx] value [eax] modify nomemory exact [eax]; 108 108 109 ULONG LockInc(ULONG *ulCounter); 110 #pragma aux LockInc = \ 111 "mov eax, 1" \ 112 "lock xadd [ebx],eax" \ 113 parm [ebx] value [eax] modify exact [eax]; 114 115 ULONG LockDec(ULONG *ulCounter); 116 #pragma aux LockDec = \ 117 "mov eax, -1" \ 118 "lock xadd [ebx],eax" \ 119 "dec eax" \ 120 parm [ebx] value [eax] modify exact [eax]; 121 109 122 /* stdarg.h macros with explicit far pointers */ 110 123 typedef char *va_list; … … 112 125 #define va_arg(va, type) ((type *) (va += sizeof(type)))[-1] 113 126 #define va_end(va) va = 0 114 115 /* stddef macros */116 #define offsetof(s, e) ((u32)&((s *)0)->e)117 127 118 128 /* shortcut macros */ … … 222 232 u32 class; /* PCI device class */ 223 233 u32 class_mask; /* bits to match when scanning for 'class' */ 224 u32 board; /* AHCI controller board type (board_* constants)*/225 char *chipname; /* human readable chip ID string*/234 char *pChipName; /* human readable chip ID string */ 235 u32 quirks; /* AHCI controller quirks */ 226 236 } PCI_ID; 227 237 … … 275 285 /* adapter information structure */ 276 286 typedef struct { 277 PCI_ID *pci; /* 00 pointer to corresponding PCI ID */ 278 279 unsigned port_max : 5; /* 04 maximum port number (0..AHCI_MAX_PORTS-1) */ 287 u16 BusDevFunc; /* 00 PCI bus number PCI device and function number */ 288 u16 PciVendor; /* 02 */ 289 u16 PciDevice; /* 04 */ 290 u8 irq; /* 06 interrupt number */ 291 u8 irq_pin; /* 07 irq pin */ 292 293 u32 cap; /* 08 working copy of CAP register */ 294 u32 cap2; /* 0c working copy of CAP2 register */ 295 HRESOURCE rm_bars[6]; /* 10 resource handle for MMIO and I/O BARs */ 296 HRESOURCE rm_adh; /* 28 resource handle for adapter */ 297 char *pChipName; /* 2c pointer to chip name */ 298 u32 quirks; /* 30 adapter quirks */ 299 300 unsigned port_max : 5; /* 34 maximum port number (0..AHCI_MAX_PORTS-1) */ 280 301 unsigned cmd_max : 5; /* maximum cmd slot number (0-31) */ 281 302 unsigned port_scan_done : 1; /* if != 0, port scan already done */ 282 303 unsigned busy : 1; /* if != 0, adapter is busy */ 283 304 unsigned hw_ports : 6; /* number of ports as reported by the hardware */ 284 unsigned int_set:1; /* interrupt has been set */ 285 286 u32 port_map; /* 08 bitmap of active ports */ 287 u16 pci_vendor; /* 0c */ 288 u16 pci_device; /* 0e */ 305 unsigned int_set:1; /* interrupt has been set */ 306 307 u32 port_map; /* 38 bitmap of active ports */ 289 308 290 309 /* initial adapter configuration from BIOS */ 291 u32 bios_config[HOST_CAP2 / sizeof(u32) + 1]; /* 10 0x24 / 4 + 1 = 0x0a dwords = 0x28 bytes*/ 292 293 u32 cap; /* 38 working copy of CAP register */ 294 u32 cap2; /* 3c working copy of CAP2 register */ 295 u32 flags; /* 40 adapter flags */ 296 297 HRESOURCE rm_adh; /* 44 resource handle for adapter */ 298 HRESOURCE rm_bars[6]; /* 48 resource handle for MMIO and I/O BARs */ 299 300 u16 bus_dev_func; /* 64 PCI bus number PCI device and function number */ 301 u8 irq; /* 66 interrupt number */ 302 u8 irq_pin; /* 67 irq pin */ 303 304 u32 mmio_phys; /* 68 physical address of MMIO region */ 305 u32 mmio_size; /* 6c size of MMIO region */ 306 u8 *mmio; /* 70 pointer to this adapter's MMIO region */ 307 308 P_INFO ports[AHCI_MAX_PORTS]; /* 74 SATA ports on this adapter */ 310 u32 bios_config[HOST_CAP2 / sizeof(u32) + 1]; /* 3c 0x24 / 4 + 1 = 0x0a dwords = 0x28 bytes*/ 311 312 u32 mmio_phys; /* 64 physical address of MMIO region */ 313 u32 mmio_size; /* 68 size of MMIO region */ 314 u8 *mmio; /* 6c pointer to this adapter's MMIO region */ 315 316 P_INFO ports[AHCI_MAX_PORTS]; /* 70 SATA ports on this adapter */ 309 317 } AD_INFO; 310 318 … … 364 372 ULONG ulSize; 365 373 ULONG ulVersion; 366 ULONG ul TestCount3;367 ULONG ul TestCount2;374 ULONG ulHardErrorCount; 375 ULONG ulSoftErrorCount; 368 376 ULONG ulTestCount1; 369 377 } AHCISTATS; … … 409 417 extern void unlock_adapter(AD_INFO *ai); 410 418 extern void __syscall timeout_callback(ULONG timer_handle, ULONG p1); 411 extern void __syscall reset_watchdog(ULONG timer_handle, ULONG p1);419 extern void __syscall WatchdogTimer(ULONG timer_handle, ULONG p1); 412 420 413 421 /* ahci.c */ … … 459 467 extern int add_pci_id(u16 vendor, u16 device); 460 468 extern void scan_pci_bus(void); 461 extern int pci_enable_int(USHORT BusDevFunc);462 469 extern void pci_hack_virtualbox(void); 463 470 extern char *vendor_from_id(u16 vendor); 464 extern char *device_from_id(u16 device);465 471 466 472 /* ctxhook.c */ 467 extern void _Syscall restart_ctxhook(ULONG parm);468 extern void _Syscall reset_ctxhook(ULONG parm);473 extern void _Syscall RestartCtxHook(ULONG parm); 474 extern void _Syscall ResetCtxHook(ULONG parm); 469 475 extern void _Syscall engine_ctxhook(ULONG parm); 476 extern void SafeArmCtxHook(ULONG ulHandle, ULONG armData); 470 477 471 478 /* apm.c */ … … 477 484 extern USHORT ioctl_get_devlist(REQPACKET *ioctl); 478 485 extern USHORT ioctl_passthrough(REQPACKET *ioctl); 486 extern USHORT ioctl_debug(REQPACKET *ioctl); 479 487 extern USHORT ioctl_gen_dsk(REQPACKET *ioctl); 480 488 extern USHORT ioctl_smart(REQPACKET *ioctl); … … 504 512 505 513 /* port restart context hook and input data */ 506 extern ULONG restart_ctxhook_h;514 extern ULONG RestartCtxHook_h; 507 515 extern volatile u32 ports_to_restart[MAX_AD]; 508 516 509 517 /* port reset context hook and input data */ 510 extern ULONG reset_ctxhook_h;511 extern ULONG th_ reset_watchdog;518 extern ULONG ResetCtxHook_h; 519 extern ULONG th_watchdog; 512 520 extern volatile u32 ports_to_reset[MAX_AD]; 513 521 extern IORB_QUEUE abort_queue; … … 525 533 526 534 #ifdef DEBUG 527 extern void DumpIorb(IORBH *pIorb );535 extern void DumpIorb(IORBH *pIorb, IORBH FAR16DATA *vIorb); 528 536 #endif 529 537 -
trunk/src/os2ahci/pci.c
r209 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 27 27 28 28 #include "os2ahci.h" 29 #include "pci_regs.h" 29 30 30 31 /* offset of PCI base address register (BAR) in the PCI config space */ … … 36 37 37 38 /****************************************************************************** 38 * chipset/controller name strings39 */40 static char chip_esb2[] = "ESB2";41 static char chip_ich8[] = "ICH8";42 static char chip_ich8m[] = "ICH8M";43 static char chip_ich9[] = "ICH9";44 static char chip_ich9m[] = "ICH9M";45 static char chip_ich10[] = "ICH10";46 static char chip_pchahci[] = "PCH AHCI";47 static char chip_pchraid[] = "PCH RAID";48 static char chip_tolapai[] = "Tolapai";49 static char chip_sb600[] = "SB600";50 static char chip_sb700[] = "SB700/800";51 static char chip_vt8251[] = "VT8251";52 static char chip_mcp65[] = "MCP65";53 static char chip_mcp67[] = "MCP67";54 static char chip_mcp73[] = "MCP73";55 static char chip_mcp77[] = "MCP77";56 static char chip_mcp79[] = "MCP79";57 static char chip_mcp89[] = "MCP689";58 static char chip_sis968[] = "968";59 60 static char s_generic[] = "Generic";61 62 63 /******************************************************************************64 39 * PCI vendor and device IDs for known AHCI adapters. Copied from the Linux 65 40 * AHCI driver. … … 69 44 { 70 45 /* Intel 71 * NOTE: ICH5 controller does NOT support AHCI, so we do 72 * not add it here! */ 73 { PCI_VDEVICE(INTEL, 0x2652), board_ahci, "ICH6" }, /* ICH6 */ 74 { PCI_VDEVICE(INTEL, 0x2653), board_ahci, "ICH6M" }, /* ICH6M */ 75 { PCI_VDEVICE(INTEL, 0x27c1), board_ahci, "ICH7" }, /* ICH7 */ 76 { PCI_VDEVICE(INTEL, 0x27c5), board_ahci, "ICH7M" }, /* ICH7M */ 77 { PCI_VDEVICE(INTEL, 0x27c3), board_ahci, "ICH7R" }, /* ICH7R */ 78 { PCI_VDEVICE(AL, 0x5288), board_ahci_ign_iferr, "ULiM5288" }, /* ULi M5288 */ 79 { PCI_VDEVICE(INTEL, 0x2681), board_ahci, chip_esb2 }, /* ESB2 */ 80 { PCI_VDEVICE(INTEL, 0x2682), board_ahci, chip_esb2 }, /* ESB2 */ 81 { PCI_VDEVICE(INTEL, 0x2683), board_ahci, chip_esb2 }, /* ESB2 */ 82 { PCI_VDEVICE(INTEL, 0x27c6), board_ahci, "ICH7MDH" }, /* ICH7-M DH */ 83 { PCI_VDEVICE(INTEL, 0x2821), board_ahci, chip_ich8 }, /* ICH8 */ 84 { PCI_VDEVICE(INTEL, 0x2822), board_ahci_nosntf, chip_ich8 }, /* ICH8 */ 85 { PCI_VDEVICE(INTEL, 0x2824), board_ahci, chip_ich8 }, /* ICH8 */ 86 { PCI_VDEVICE(INTEL, 0x2829), board_ahci, chip_ich8m }, /* ICH8M */ 87 { PCI_VDEVICE(INTEL, 0x282a), board_ahci, chip_ich8m }, /* ICH8M */ 88 { PCI_VDEVICE(INTEL, 0x2922), board_ahci, chip_ich9 }, /* ICH9 */ 89 { PCI_VDEVICE(INTEL, 0x2923), board_ahci, chip_ich9 }, /* ICH9 */ 90 { PCI_VDEVICE(INTEL, 0x2924), board_ahci, chip_ich9 }, /* ICH9 */ 91 { PCI_VDEVICE(INTEL, 0x2925), board_ahci, chip_ich9 }, /* ICH9 */ 92 { PCI_VDEVICE(INTEL, 0x2927), board_ahci, chip_ich9 }, /* ICH9 */ 93 { PCI_VDEVICE(INTEL, 0x2929), board_ahci, chip_ich9m }, /* ICH9M */ 94 { PCI_VDEVICE(INTEL, 0x292a), board_ahci, chip_ich9m }, /* ICH9M */ 95 { PCI_VDEVICE(INTEL, 0x292b), board_ahci, chip_ich9m }, /* ICH9M */ 96 { PCI_VDEVICE(INTEL, 0x292c), board_ahci, chip_ich9m }, /* ICH9M */ 97 { PCI_VDEVICE(INTEL, 0x292f), board_ahci, chip_ich9m }, /* ICH9M */ 98 { PCI_VDEVICE(INTEL, 0x294d), board_ahci, chip_ich9 }, /* ICH9 */ 99 { PCI_VDEVICE(INTEL, 0x294e), board_ahci, chip_ich9m }, /* ICH9M */ 100 { PCI_VDEVICE(INTEL, 0x502a), board_ahci, chip_tolapai }, /* Tolapai */ 101 { PCI_VDEVICE(INTEL, 0x502b), board_ahci, chip_tolapai }, /* Tolapai */ 102 { PCI_VDEVICE(INTEL, 0x3a05), board_ahci, chip_ich10 }, /* ICH10 */ 103 { PCI_VDEVICE(INTEL, 0x3a22), board_ahci, chip_ich10 }, /* ICH10 */ 104 { PCI_VDEVICE(INTEL, 0x3a25), board_ahci, chip_ich10 }, /* ICH10 */ 105 { PCI_VDEVICE(INTEL, 0x3b22), board_ahci, chip_pchahci }, /* PCH AHCI */ 106 { PCI_VDEVICE(INTEL, 0x3b23), board_ahci, chip_pchahci }, /* PCH AHCI */ 107 { PCI_VDEVICE(INTEL, 0x3b24), board_ahci, chip_pchraid }, /* PCH RAID */ 108 { PCI_VDEVICE(INTEL, 0x3b25), board_ahci, chip_pchraid }, /* PCH RAID */ 109 { PCI_VDEVICE(INTEL, 0x3b29), board_ahci, chip_pchahci }, /* PCH AHCI */ 110 { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci, chip_pchraid }, /* PCH RAID */ 111 { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci, chip_pchraid }, /* PCH RAID */ 112 { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci, chip_pchahci }, /* PCH AHCI */ 46 * NOTE: ICH5 controller does NOT support AHCI, so we do not add it here! */ 47 { PCI_VDEVICE(INTEL, 0x2652), "ICH6" , 0 }, /* ICH6 */ 48 { PCI_VDEVICE(INTEL, 0x2653), "ICH6M", 0 }, /* ICH6M */ 49 { PCI_VDEVICE(INTEL, 0x27c1), "ICH7" , 0 }, /* ICH7 */ 50 { PCI_VDEVICE(INTEL, 0x27c5), "ICH7M", 0 }, /* ICH7M */ 51 { PCI_VDEVICE(INTEL, 0x27c3), "ICH7R", 0 }, /* ICH7R */ 52 { PCI_VDEVICE(AL, 0x5288), "ULiM5288", AHCI_HFLAG_IGN_IRQ_IF_ERR }, /* ULi M5288 */ 53 { PCI_VDEVICE(INTEL, 0x2681), "ESB2" , 0 }, /* ESB2 */ 54 { PCI_VDEVICE(INTEL, 0x2682), "ESB2" , 0 }, /* ESB2 */ 55 { PCI_VDEVICE(INTEL, 0x2683), "ESB2" , 0 }, /* ESB2 */ 56 { PCI_VDEVICE(INTEL, 0x27c6), "ICH7MDH", 0 }, /* ICH7-M DH */ 57 { PCI_VDEVICE(INTEL, 0x2821), "ICH8" , 0 }, /* ICH8 */ 58 { PCI_VDEVICE(INTEL, 0x2822), "ICH8", AHCI_HFLAG_NO_SNTF }, /* ICH8 */ 59 { PCI_VDEVICE(INTEL, 0x2824), "ICH8" , 0 }, /* ICH8 */ 60 { PCI_VDEVICE(INTEL, 0x2829), "ICH8M" , 0 }, /* ICH8M */ 61 { PCI_VDEVICE(INTEL, 0x282a), "ICH8M" , 0 }, /* ICH8M */ 62 { PCI_VDEVICE(INTEL, 0x2922), "ICH9" , 0 }, /* ICH9 */ 63 { PCI_VDEVICE(INTEL, 0x2923), "ICH9" , 0 }, /* ICH9 */ 64 { PCI_VDEVICE(INTEL, 0x2924), "ICH9" , 0 }, /* ICH9 */ 65 { PCI_VDEVICE(INTEL, 0x2925), "ICH9" , 0 }, /* ICH9 */ 66 { PCI_VDEVICE(INTEL, 0x2927), "ICH9" , 0 }, /* ICH9 */ 67 { PCI_VDEVICE(INTEL, 0x2929), "ICH9M" , 0 }, /* ICH9M */ 68 { PCI_VDEVICE(INTEL, 0x292a), "ICH9M" , 0 }, /* ICH9M */ 69 { PCI_VDEVICE(INTEL, 0x292b), "ICH9M" , 0 }, /* ICH9M */ 70 { PCI_VDEVICE(INTEL, 0x292c), "ICH9M" , 0 }, /* ICH9M */ 71 { PCI_VDEVICE(INTEL, 0x292f), "ICH9M" , 0 }, /* ICH9M */ 72 { PCI_VDEVICE(INTEL, 0x294d), "ICH9" , 0 }, /* ICH9 */ 73 { PCI_VDEVICE(INTEL, 0x294e), "ICH9M" , 0 }, /* ICH9M */ 74 { PCI_VDEVICE(INTEL, 0x502a), "Tolapai" , 0 }, /* Tolapai */ 75 { PCI_VDEVICE(INTEL, 0x502b), "Tolapai" , 0 }, /* Tolapai */ 76 { PCI_VDEVICE(INTEL, 0x3a05), "ICH10" , 0 }, /* ICH10 */ 77 { PCI_VDEVICE(INTEL, 0x3a22), "ICH10" , 0 }, /* ICH10 */ 78 { PCI_VDEVICE(INTEL, 0x3a25), "ICH10" , 0 }, /* ICH10 */ 79 { PCI_VDEVICE(INTEL, 0x3b22), "PCH AHCI", 0 }, /* PCH AHCI */ 80 { PCI_VDEVICE(INTEL, 0x3b23), "PCH AHCI", 0 }, /* PCH AHCI */ 81 { PCI_VDEVICE(INTEL, 0x3b24), "PCH RAID", 0 }, /* PCH RAID */ 82 { PCI_VDEVICE(INTEL, 0x3b25), "PCH RAID", 0 }, /* PCH RAID */ 83 { PCI_VDEVICE(INTEL, 0x3b29), "PCH AHCI", 0 }, /* PCH AHCI */ 84 { PCI_VDEVICE(INTEL, 0x3b2b), "PCH RAID", 0 }, /* PCH RAID */ 85 { PCI_VDEVICE(INTEL, 0x3b2c), "PCH RAID", 0 }, /* PCH RAID */ 86 { PCI_VDEVICE(INTEL, 0x3b2f), "PCH AHCI", 0 }, /* PCH AHCI */ 113 87 114 88 /* JMicron 360/1/3/5/6, match class to avoid IDE function */ 115 89 { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 116 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff L, board_ahci_ign_iferr, "360"},90 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, "360", AHCI_HFLAG_IGN_IRQ_IF_ERR }, 117 91 118 92 /* ATI */ 119 { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600, chip_sb600}, /* ATI SB600 */120 { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb700, chip_sb700}, /* ATI SB700/800 */121 { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb700, chip_sb700}, /* ATI SB700/800 */122 { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb700, chip_sb700}, /* ATI SB700/800 */123 { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb700, chip_sb700}, /* ATI SB700/800 */124 { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb700, chip_sb700}, /* ATI SB700/800 */125 { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700, chip_sb700}, /* ATI SB700/800 */93 { PCI_VDEVICE(ATI, 0x4380), "SB600", AHCI_HFLAG_IGN_SERR_INTERNAL | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255 | AHCI_HFLAG_32BIT_ONLY }, /* ATI SB600 */ 94 { PCI_VDEVICE(ATI, 0x4390), "SB700/800", AHCI_HFLAG_IGN_SERR_INTERNAL }, /* ATI SB700/800 */ 95 { PCI_VDEVICE(ATI, 0x4391), "SB700/800", AHCI_HFLAG_IGN_SERR_INTERNAL }, /* ATI SB700/800 */ 96 { PCI_VDEVICE(ATI, 0x4392), "SB700/800", AHCI_HFLAG_IGN_SERR_INTERNAL }, /* ATI SB700/800 */ 97 { PCI_VDEVICE(ATI, 0x4393), "SB700/800", AHCI_HFLAG_IGN_SERR_INTERNAL }, /* ATI SB700/800 */ 98 { PCI_VDEVICE(ATI, 0x4394), "SB700/800", AHCI_HFLAG_IGN_SERR_INTERNAL }, /* ATI SB700/800 */ 99 { PCI_VDEVICE(ATI, 0x4395), "SB700/800", AHCI_HFLAG_IGN_SERR_INTERNAL }, /* ATI SB700/800 */ 126 100 127 101 /* AMD */ 128 { PCI_VDEVICE(AMD, 0x7800), board_ahci}, /* AMD Hudson-2 */102 { PCI_VDEVICE(AMD, 0x7800), "Hudson-2", 0 }, /* AMD Hudson-2 */ 129 103 /* AMD is using RAID class only for ahci controllers */ 130 104 { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 131 PCI_CLASS_STORAGE_RAID << 8, 0xffffff L, board_ahci, "Hudson2"},105 PCI_CLASS_STORAGE_RAID << 8, 0xffffff, "Hudson2", 0 }, 132 106 133 107 /* VIA */ 134 { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251, chip_vt8251}, /* VIA VT8251 */135 { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251, chip_vt8251}, /* VIA VT8251 */108 { PCI_VDEVICE(VIA, 0x3349), "VT8251", AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP }, /* VIA VT8251 */ 109 { PCI_VDEVICE(VIA, 0x6287), "VT8251", AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP }, /* VIA VT8251 */ 136 110 137 111 /* NVIDIA */ 138 { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci_mcp65, chip_mcp65}, /* MCP65 */139 { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci_mcp65, chip_mcp65}, /* MCP65 */140 { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci_mcp65, chip_mcp65}, /* MCP65 */141 { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci_mcp65, chip_mcp65}, /* MCP65 */142 { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci_mcp65, chip_mcp65}, /* MCP65 */143 { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65, chip_mcp65}, /* MCP65 */144 { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65, chip_mcp65}, /* MCP65 */145 { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65, chip_mcp65}, /* MCP65 */146 { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci_yesncq, chip_mcp67}, /* MCP67 */147 { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci_yesncq, chip_mcp67}, /* MCP67 */148 { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci_yesncq, chip_mcp67}, /* MCP67 */149 { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci_yesncq, chip_mcp67}, /* MCP67 */150 { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci_yesncq, chip_mcp67}, /* MCP67 */151 { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci_yesncq, chip_mcp67}, /* MCP67 */152 { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci_yesncq, chip_mcp67}, /* MCP67 */153 { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci_yesncq, chip_mcp67}, /* MCP67 */154 { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci_yesncq, chip_mcp67}, /* MCP67 */155 { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci_yesncq, chip_mcp67}, /* MCP67 */156 { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq, chip_mcp67}, /* MCP67 */157 { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq, chip_mcp67}, /* MCP67 */158 { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq, chip_mcp67}, /* Linux ID */159 { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq, chip_mcp73}, /* MCP73 */160 { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq, chip_mcp73}, /* MCP73 */161 { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq, chip_mcp73}, /* MCP73 */162 { PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci_yesncq, chip_mcp73}, /* MCP73 */163 { PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci_yesncq, chip_mcp73}, /* MCP73 */164 { PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci_yesncq, chip_mcp73}, /* MCP73 */165 { PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci_yesncq, chip_mcp73}, /* MCP73 */166 { PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci_yesncq, chip_mcp73}, /* MCP73 */167 { PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci_yesncq, chip_mcp73}, /* MCP73 */168 { PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci_yesncq, chip_mcp73}, /* MCP73 */169 { PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci_yesncq, chip_mcp73}, /* MCP73 */170 { PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci_yesncq, chip_mcp73}, /* MCP73 */171 { PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci, chip_mcp77}, /* MCP77 */172 { PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci, chip_mcp77}, /* MCP77 */173 { PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci, chip_mcp77}, /* MCP77 */174 { PCI_VDEVICE(NVIDIA, 0x0ad3), board_ahci, chip_mcp77}, /* MCP77 */175 { PCI_VDEVICE(NVIDIA, 0x0ad4), board_ahci, chip_mcp77}, /* MCP77 */176 { PCI_VDEVICE(NVIDIA, 0x0ad5), board_ahci, chip_mcp77}, /* MCP77 */177 { PCI_VDEVICE(NVIDIA, 0x0ad6), board_ahci, chip_mcp77}, /* MCP77 */178 { PCI_VDEVICE(NVIDIA, 0x0ad7), board_ahci, chip_mcp77}, /* MCP77 */179 { PCI_VDEVICE(NVIDIA, 0x0ad8), board_ahci, chip_mcp77}, /* MCP77 */180 { PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci, chip_mcp77}, /* MCP77 */181 { PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci, chip_mcp77}, /* MCP77 */182 { PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci, chip_mcp77}, /* MCP77 */183 { PCI_VDEVICE(NVIDIA, 0x0ab4), board_ahci, chip_mcp79}, /* MCP79 */184 { PCI_VDEVICE(NVIDIA, 0x0ab5), board_ahci, chip_mcp79}, /* MCP79 */185 { PCI_VDEVICE(NVIDIA, 0x0ab6), board_ahci, chip_mcp79}, /* MCP79 */186 { PCI_VDEVICE(NVIDIA, 0x0ab7), board_ahci, chip_mcp79}, /* MCP79 */187 { PCI_VDEVICE(NVIDIA, 0x0ab8), board_ahci, chip_mcp79}, /* MCP79 */188 { PCI_VDEVICE(NVIDIA, 0x0ab9), board_ahci, chip_mcp79}, /* MCP79 */189 { PCI_VDEVICE(NVIDIA, 0x0aba), board_ahci, chip_mcp79}, /* MCP79 */190 { PCI_VDEVICE(NVIDIA, 0x0abb), board_ahci, chip_mcp79}, /* MCP79 */191 { PCI_VDEVICE(NVIDIA, 0x0abc), board_ahci, chip_mcp79}, /* MCP79 */192 { PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci, chip_mcp79}, /* MCP79 */193 { PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci, chip_mcp79}, /* MCP79 */194 { PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci, chip_mcp79}, /* MCP79 */195 { PCI_VDEVICE(NVIDIA, 0x0d84), board_ahci, chip_mcp89}, /* MCP89 */196 { PCI_VDEVICE(NVIDIA, 0x0d85), board_ahci, chip_mcp89}, /* MCP89 */197 { PCI_VDEVICE(NVIDIA, 0x0d86), board_ahci, chip_mcp89}, /* MCP89 */198 { PCI_VDEVICE(NVIDIA, 0x0d87), board_ahci, chip_mcp89}, /* MCP89 */199 { PCI_VDEVICE(NVIDIA, 0x0d88), board_ahci, chip_mcp89}, /* MCP89 */200 { PCI_VDEVICE(NVIDIA, 0x0d89), board_ahci, chip_mcp89}, /* MCP89 */201 { PCI_VDEVICE(NVIDIA, 0x0d8a), board_ahci, chip_mcp89}, /* MCP89 */202 { PCI_VDEVICE(NVIDIA, 0x0d8b), board_ahci, chip_mcp89}, /* MCP89 */203 { PCI_VDEVICE(NVIDIA, 0x0d8c), board_ahci, chip_mcp89}, /* MCP89 */204 { PCI_VDEVICE(NVIDIA, 0x0d8d), board_ahci, chip_mcp89}, /* MCP89 */205 { PCI_VDEVICE(NVIDIA, 0x0d8e), board_ahci, chip_mcp89}, /* MCP89 */206 { PCI_VDEVICE(NVIDIA, 0x0d8f), board_ahci, chip_mcp89}, /* MCP89 */112 { PCI_VDEVICE(NVIDIA, 0x044c), "MCP65", AHCI_HFLAG_YES_NCQ }, /* MCP65 */ 113 { PCI_VDEVICE(NVIDIA, 0x044d), "MCB65", AHCI_HFLAG_YES_NCQ }, /* MCP65 */ 114 { PCI_VDEVICE(NVIDIA, 0x044e), "MCP65", AHCI_HFLAG_YES_NCQ }, /* MCP65 */ 115 { PCI_VDEVICE(NVIDIA, 0x044f), "MCP65", AHCI_HFLAG_YES_NCQ }, /* MCP65 */ 116 { PCI_VDEVICE(NVIDIA, 0x045c), "MCP65", AHCI_HFLAG_YES_NCQ }, /* MCP65 */ 117 { PCI_VDEVICE(NVIDIA, 0x045d), "MCP65", AHCI_HFLAG_YES_NCQ }, /* MCP65 */ 118 { PCI_VDEVICE(NVIDIA, 0x045e), "MCP65", AHCI_HFLAG_YES_NCQ }, /* MCP65 */ 119 { PCI_VDEVICE(NVIDIA, 0x045f), "MCP65", AHCI_HFLAG_YES_NCQ }, /* MCP65 */ 120 { PCI_VDEVICE(NVIDIA, 0x0550), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 121 { PCI_VDEVICE(NVIDIA, 0x0551), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 122 { PCI_VDEVICE(NVIDIA, 0x0552), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 123 { PCI_VDEVICE(NVIDIA, 0x0553), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 124 { PCI_VDEVICE(NVIDIA, 0x0554), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 125 { PCI_VDEVICE(NVIDIA, 0x0555), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 126 { PCI_VDEVICE(NVIDIA, 0x0556), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 127 { PCI_VDEVICE(NVIDIA, 0x0557), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 128 { PCI_VDEVICE(NVIDIA, 0x0558), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 129 { PCI_VDEVICE(NVIDIA, 0x0559), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 130 { PCI_VDEVICE(NVIDIA, 0x055a), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 131 { PCI_VDEVICE(NVIDIA, 0x055b), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* MCP67 */ 132 { PCI_VDEVICE(NVIDIA, 0x0580), "MCP67" , AHCI_HFLAG_YES_NCQ }, /* Linux ID */ 133 { PCI_VDEVICE(NVIDIA, 0x07f0), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 134 { PCI_VDEVICE(NVIDIA, 0x07f1), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 135 { PCI_VDEVICE(NVIDIA, 0x07f2), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 136 { PCI_VDEVICE(NVIDIA, 0x07f3), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 137 { PCI_VDEVICE(NVIDIA, 0x07f4), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 138 { PCI_VDEVICE(NVIDIA, 0x07f5), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 139 { PCI_VDEVICE(NVIDIA, 0x07f6), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 140 { PCI_VDEVICE(NVIDIA, 0x07f7), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 141 { PCI_VDEVICE(NVIDIA, 0x07f8), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 142 { PCI_VDEVICE(NVIDIA, 0x07f9), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 143 { PCI_VDEVICE(NVIDIA, 0x07fa), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 144 { PCI_VDEVICE(NVIDIA, 0x07fb), "MCP73" , AHCI_HFLAG_YES_NCQ }, /* MCP73 */ 145 { PCI_VDEVICE(NVIDIA, 0x0ad0), "MCP77", 0 }, /* MCP77 */ 146 { PCI_VDEVICE(NVIDIA, 0x0ad1), "MCP77", 0 }, /* MCP77 */ 147 { PCI_VDEVICE(NVIDIA, 0x0ad2), "MCP77", 0 }, /* MCP77 */ 148 { PCI_VDEVICE(NVIDIA, 0x0ad3), "MCP77", 0 }, /* MCP77 */ 149 { PCI_VDEVICE(NVIDIA, 0x0ad4), "MCP77", 0 }, /* MCP77 */ 150 { PCI_VDEVICE(NVIDIA, 0x0ad5), "MCP77", 0 }, /* MCP77 */ 151 { PCI_VDEVICE(NVIDIA, 0x0ad6), "MCP77", 0 }, /* MCP77 */ 152 { PCI_VDEVICE(NVIDIA, 0x0ad7), "MCP77", 0 }, /* MCP77 */ 153 { PCI_VDEVICE(NVIDIA, 0x0ad8), "MCP77", 0 }, /* MCP77 */ 154 { PCI_VDEVICE(NVIDIA, 0x0ad9), "MCP77", 0 }, /* MCP77 */ 155 { PCI_VDEVICE(NVIDIA, 0x0ada), "MCP77", 0 }, /* MCP77 */ 156 { PCI_VDEVICE(NVIDIA, 0x0adb), "MCP77", 0 }, /* MCP77 */ 157 { PCI_VDEVICE(NVIDIA, 0x0ab4), "MCP79", 0 }, /* MCP79 */ 158 { PCI_VDEVICE(NVIDIA, 0x0ab5), "MCP79", 0 }, /* MCP79 */ 159 { PCI_VDEVICE(NVIDIA, 0x0ab6), "MCP79", 0 }, /* MCP79 */ 160 { PCI_VDEVICE(NVIDIA, 0x0ab7), "MCP79", 0 }, /* MCP79 */ 161 { PCI_VDEVICE(NVIDIA, 0x0ab8), "MCP79", 0 }, /* MCP79 */ 162 { PCI_VDEVICE(NVIDIA, 0x0ab9), "MCP79", 0 }, /* MCP79 */ 163 { PCI_VDEVICE(NVIDIA, 0x0aba), "MCP79", 0 }, /* MCP79 */ 164 { PCI_VDEVICE(NVIDIA, 0x0abb), "MCP79", 0 }, /* MCP79 */ 165 { PCI_VDEVICE(NVIDIA, 0x0abc), "MCP79", 0 }, /* MCP79 */ 166 { PCI_VDEVICE(NVIDIA, 0x0abd), "MCP79", 0 }, /* MCP79 */ 167 { PCI_VDEVICE(NVIDIA, 0x0abe), "MCP79", 0 }, /* MCP79 */ 168 { PCI_VDEVICE(NVIDIA, 0x0abf), "MCP79", 0 }, /* MCP79 */ 169 { PCI_VDEVICE(NVIDIA, 0x0d84), "MCP89", 0 }, /* MCP89 */ 170 { PCI_VDEVICE(NVIDIA, 0x0d85), "MCP89", 0 }, /* MCP89 */ 171 { PCI_VDEVICE(NVIDIA, 0x0d86), "MCP89", 0 }, /* MCP89 */ 172 { PCI_VDEVICE(NVIDIA, 0x0d87), "MCP89", 0 }, /* MCP89 */ 173 { PCI_VDEVICE(NVIDIA, 0x0d88), "MCP89", 0 }, /* MCP89 */ 174 { PCI_VDEVICE(NVIDIA, 0x0d89), "MCP89", 0 }, /* MCP89 */ 175 { PCI_VDEVICE(NVIDIA, 0x0d8a), "MCP89", 0 }, /* MCP89 */ 176 { PCI_VDEVICE(NVIDIA, 0x0d8b), "MCP89", 0 }, /* MCP89 */ 177 { PCI_VDEVICE(NVIDIA, 0x0d8c), "MCP89", 0 }, /* MCP89 */ 178 { PCI_VDEVICE(NVIDIA, 0x0d8d), "MCP89", 0 }, /* MCP89 */ 179 { PCI_VDEVICE(NVIDIA, 0x0d8e), "MCP89", 0 }, /* MCP89 */ 180 { PCI_VDEVICE(NVIDIA, 0x0d8f), "MCP89", 0 }, /* MCP89 */ 207 181 208 182 /* SiS */ 209 { PCI_VDEVICE(SI, 0x1184), board_ahci, "966"}, /* SiS 966 */210 { PCI_VDEVICE(SI, 0x1185), board_ahci, chip_sis968}, /* SiS 968 */211 { PCI_VDEVICE(SI, 0x0186), board_ahci, chip_sis968}, /* SiS 968 */183 { PCI_VDEVICE(SI, 0x1184), "966", 0 }, /* SiS 966 */ 184 { PCI_VDEVICE(SI, 0x1185), "968", 0 }, /* SiS 968 */ 185 { PCI_VDEVICE(SI, 0x0186), "968", 0 }, /* SiS 968 */ 212 186 213 187 /* Marvell */ 214 { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv, "6145"}, /* 6145 */215 { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv, "6121"}, /* 6121 */188 { PCI_VDEVICE(MARVELL, 0x6145), "6145", AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP }, /* 6145 */ 189 { PCI_VDEVICE(MARVELL, 0x6121), "6121", AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP }, /* 6121 */ 216 190 217 191 /* Promise */ 218 { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci, "PDC42819"}, /* PDC42819 */192 { PCI_VDEVICE(PROMISE, 0x3f20), "PDC42819", 0 }, /* PDC42819 */ 219 193 220 194 /* Generic, PCI class code for AHCI */ 221 195 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 222 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff L, board_ahci, s_generic},196 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, "Generic", 0 }, 223 197 224 198 /* end of list, including a few slots to define custom adapters (10) */ 225 { 0, 0, 0, 0, 0, 0, 0, NULL},226 { 0, 0, 0, 0, 0, 0, 0, NULL},227 { 0, 0, 0, 0, 0, 0, 0, NULL},228 { 0, 0, 0, 0, 0, 0, 0, NULL},229 { 0, 0, 0, 0, 0, 0, 0, NULL},230 { 0, 0, 0, 0, 0, 0, 0, NULL},231 { 0, 0, 0, 0, 0, 0, 0, NULL},232 { 0, 0, 0, 0, 0, 0, 0, NULL},233 { 0, 0, 0, 0, 0, 0, 0, NULL},234 { 0, 0, 0, 0, 0, 0, 0, NULL},235 236 { 0, 0, 0, 0, 0, 0, 0, NULL}199 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 200 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 201 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 202 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 203 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 204 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 205 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 206 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 207 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 208 { 0, 0, 0, 0, 0, 0, NULL, 0 }, 209 210 { 0, 0, 0, 0, 0, 0, NULL, 0 } 237 211 }; 238 212 … … 255 229 pci_ids[i].vendor = vendor; 256 230 pci_ids[i].device = device; 257 pci_ids[i]. board = board_ahci;258 pci_ids[i]. chipname = s_generic;231 pci_ids[i].pChipName = "Specified"; 232 pci_ids[i].quirks = 0; 259 233 return(0); 260 234 } … … 321 295 for (n = 0; n < ad_info_cnt; n++) 322 296 { 323 if (ad_infos[n]. bus_dev_func == BusDevFunc)297 if (ad_infos[n].BusDevFunc == BusDevFunc) 324 298 { 325 299 /* this device has already been found (e.g. via thorough scan) */ … … 343 317 } while (BusDevFunc != 0xffff); 344 318 } 345 }346 347 /******************************************************************************348 * Enable interrupt generation. PCI 2.3 added a bit which allows disabling349 * interrupt generation for a device. This function clears the corresponding350 * bit in the configuration space command register.351 */352 int pci_enable_int(USHORT BusDevFunc)353 {354 ULONG tmp;355 356 if (PciReadConfig(BusDevFunc, 4, sizeof(tmp), &tmp) ||357 PciWriteConfig(BusDevFunc, 4, sizeof(tmp), tmp & ~(1UL << 10)))358 {359 return(-1);360 }361 return(0);362 319 } 363 320 … … 559 516 * itself with the OS/2 resource manager 560 517 */ 561 ad_info->pci = pci_id; 562 ad_info->pci_vendor = vendor; 563 ad_info->pci_device = device; 564 ad_info->bus_dev_func = BusDevFunc; 518 ad_info->pChipName = pci_id->pChipName; 519 ad_info->quirks = pci_id->quirks; 520 ad_info->PciVendor = vendor; 521 ad_info->PciDevice = device; 522 ad_info->BusDevFunc = BusDevFunc; 565 523 ad_info->irq = irq; 566 524 ad_info->irq_pin = pin; … … 594 552 } 595 553 554 if (!PciReadConfig(BusDevFunc, PCI_COMMAND, 2, &val)) 555 { 556 val |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); 557 val &= ~PCI_COMMAND_INTX_DISABLE; 558 PciWriteConfig(BusDevFunc, PCI_COMMAND, 2, val); 559 } 596 560 if (ahci_config_caps(ad_info)) goto add_pci_fail; 597 561 … … 738 702 } 739 703 740 return "Generic"; 741 } 742 743 /****************************************************************************** 744 * return a device name for a PCI device id 745 * NOTE: this is as simple as can be, so don't call it twice in one statement. 746 */ 747 char *device_from_id(u16 device) 748 { 749 int i; 750 751 for (i = 0; pci_ids[i].vendor != 0; i++) 752 { 753 if (pci_ids[i].device == device) 754 { 755 return pci_ids[i].chipname; 756 } 757 } 758 759 return s_generic; 704 return ""; 760 705 } 761 706 -
trunk/src/os2ahci/thunk.asm
r205 r211 1 1 ; Thunking for ahci32 driver 2 ; Copyright (c) 2018-202 1David Azarewicz2 ; Copyright (c) 2018-2023 David Azarewicz 3 3 ; Author: David Azarewicz <david@88watts.net> 4 4 -
trunk/src/os2ahci/trace.c
r209 r211 1 1 /** 2 2 * 3 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>3 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 4 4 * 5 5 */ … … 22 22 AD_INFO *ai = ad_infos + a; 23 23 24 dprintf(0,"Adapter %d: PCI=%d:%d:%d ID=%04x:%04x %s %s irq=%d addr=0x%x version=%x\n", a,25 PCI_BUS_FROM_BDF(ai-> bus_dev_func), PCI_DEV_FROM_BDF(ai->bus_dev_func),26 PCI_FUNC_FROM_BDF(ai-> bus_dev_func),27 ai-> pci_vendor, ai->pci_device, vendor_from_id(ai->pci_vendor), ai->pci->chipname,24 dprintf(0,"Adapter %d: %d:%d:%d ID=%04x:%04x %s %s irq=%d adr=%x version=%x\n", a, 25 PCI_BUS_FROM_BDF(ai->BusDevFunc), PCI_DEV_FROM_BDF(ai->BusDevFunc), 26 PCI_FUNC_FROM_BDF(ai->BusDevFunc), 27 ai->PciVendor, ai->PciDevice, vendor_from_id(ai->PciVendor), ai->pChipName, 28 28 ai->irq, ai->mmio_phys, 29 29 ai->bios_config[HOST_VERSION / sizeof(u32)]); … … 63 63 64 64 #ifdef DEBUG 65 void DumpIorb(IORBH *pIorb )65 void DumpIorb(IORBH *pIorb, IORBH FAR16DATA *vIorb) 66 66 { 67 if (!(D32g_DbgLevel & DBG_DETAILED)) return;68 if ( !ad_infos[iorb_unit_adapter(pIorb)].ports[iorb_unit_port(pIorb)].devs[iorb_unit_device(pIorb)].atapi) return;67 //if (!(D32g_DbgLevel & DBG_DETAILED)) return; 68 if (ad_infos[iorb_unit_adapter(pIorb)].ports[iorb_unit_port(pIorb)].devs[iorb_unit_device(pIorb)].atapi) return; 69 69 70 70 dprintf(0,"IORB %x: Size=%x Len=%x Handle=%x CmdCode=%x\n", 71 pIorb, sizeof(IORBH), pIorb->Length, pIorb->UnitHandle, pIorb->CommandCode);71 vIorb, sizeof(IORBH), pIorb->Length, pIorb->UnitHandle, pIorb->CommandCode); 72 72 dprintf(0," CmdMod=%x ReqCtrl=%x Status=%x ErrorCode=%x\n", 73 73 pIorb->CommandModifier, pIorb->RequestControl, pIorb->Status, pIorb->ErrorCode); … … 75 75 pIorb->Timeout, pIorb->StatusBlockLen, pIorb->pStatusBlock, pIorb->Reserved_1, 76 76 pIorb->f16NxtIORB); 77 78 if (pIorb->CommandCode == IOCC_EXECUTE_IO || pIorb->CommandCode == IOCC_EXECUTE_IO_64) 79 { 80 IORB_EXECUTEIO64 *pIo = (IORB_EXECUTEIO64*)pIorb; 81 ULONGLONG ullLba; 82 83 ullLba = pIo->RBA; 84 if (pIorb->CommandCode == IOCC_EXECUTE_IO_64) ullLba = pIo->ullRBA; 85 86 dprintf(0," I/O: Block=%llx Count=%x Xferred=%x Size=%x Flags=%x\n", 87 ullLba, pIo->BlockCount, pIo->BlocksXferred, pIo->BlockSize, pIo->Flags); 88 } 77 89 } 78 90 #endif -
trunk/tools/ahci.wis
r194 r211 3 3 <TITLE>=("TITLE")</TITLE> 4 4 <REXX NAME=TITLE> 5 Call Rxfuncadd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'; 6 Call SysLoadFuncs; 5 7 MyTitle="AHCI Driver for OS/2"; 6 8
Note:
See TracChangeset
for help on using the changeset viewer.