Changeset 211 for trunk


Ignore:
Timestamp:
Jul 24, 2023, 5:51:46 PM (2 years ago)
Author:
David Azarewicz
Message:

Added workaround to help with VirtualBox issues.
Improved diagnostic messages.
Changed how timeouts are reset and how ctx hooks are triggered.
Added quirk for devices with issues executing some standard commands.
Changed to make /N the default.

Location:
trunk
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/os2ahci/Makefile

    r209 r211  
    1717FDEBUG=0x0000
    1818
     19FIXPACK=Test Build
     20
    1921.ERASE
    2022.SUFFIXES
     
    2325# Define default build version if not specified in environment
    2426BLD_MAJOR=2
    25 BLD_MINOR=08 # must be 2 digits
     27BLD_MINOR=09 # must be 2 digits
    2628BLD_REV=0 # not used at this time
    2729
     
    9092!endif
    9193
    92 #DAZ need to find which structures need pack(1) so we can reset this back to -zp4
    9394AFLAGS=-q -6p -bt=os2 -wx -d1
    9495CFLAGS =-q -bt=os2 -6s -olinar -s -ze -zl -zq -zfp -zgp -ms -wx -zp1 -ecs -ei -za99
     
    142143  @%append $^&.lrf option map=$^*.map
    143144  @%append $^&.lrf option stack=0
    144   #  @%append $*.lnk option protmode
    145145  @%append $^&.lrf sort global
    146146  @%append $^&.lrf option osname='ArcaOS'
     
    149149  @for %f in ($(OBJS)) do @%append $^&.lrf file %f
    150150  @for %f in ($(LIBS)) do @%append $^&.lrf library %f
    151   #  @%append $*.lnk segment type DATA SHARED
    152   #  @%append $*.lnk segment type CODE IOPL
    153   #  # Order segments by class
    154   #  @%append $*.lnk order
    155   #  @%append $*.lnk clname 'DATA'
    156   #  @%append $*.lnk clname 'CONST'
    157   #  @%append $*.lnk clname 'BSS'
    158   #  @%append $*.lnk clname 'CODE'
    159151  @wlink @$^&.lrf
    160152  @%erase $^&.lrf
  • trunk/src/os2ahci/ReadMe.txt

    r209 r211  
    1616Copyright (c) 2011 thi.guten Software Development
    1717Copyright (c) 2011 Mensys B.V.
    18 Copyright (c) 2013-2021 David Azarewicz
     18Copyright (c) 2013-2023 David Azarewicz
    1919
    2020Authors: Christian Mueller, Markus Thielen
     
    7272                      (default = -1, all adapters)
    7373
    74 /F                    Force the use of the HW write cache when using NCQ
    75                       commands; see "Native Command Queuing" below for
    76                       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)
    7777
    7878/G:<vendor>:<device>  Add generic PCI ID to list of supported AHCI adapters
     
    9494                      turned off with /!T to perform only a PCI class scan
    9595
    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.
    100103
    101104/V                    Display informational messages during boot.
     
    131134
    132135/N                    Enable NCQ (Native Command Queuing) for hard disks
    133                       (default = off)
     136                      (default = on) Can be turned off with /!N.
    134137
    135138/LS                   Set link speed (default = 0):
     
    145148                        3 = transitions to both partial and slumber states disabled
    146149
    147 /4                    Force track size to be 56 sectors regardless of the
    148                       reported disk geometry to optimize partition boundaries
    149                       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.
    150153
    151154Port-specific options depend on the currently active adapter
     
    185188database servers).
    186189
    187 While we believe NCQ will work with the majority of controllers and hard
    188 disks, it's currently turned off by default until we have more feedback
    189 from OS/2 users. In order to turn on NCQ, just add the command line
    190 option "/N" to OS2AHCI.ADD.
    191 
    192190NCQ and HW Caches
    193191-----------------
     
    195193In NCQ mode, OS2AHCI supports a request flag which allows upstream code
    196194(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.
     195of being buffered in the HW disk cache. The command line option "/F"
     196forces NCQ commands to use the hardware cache, ignoring the request flag.
     197This may result in data loss in case of power failures. When rebooting
     198or shutting down, the HW disk cache is always flushed regardless of any
     199of the command line options.
    218200
    219201
     
    262244 2. Drive HDD via OS2AHCI.ADD and CDROM via DANIS506.ADD
    263245
    264 OS2AHCI.ADD can't drive the CDROM because it's attached to a PATA
    265 IDE controller which doesn't support AHCI.
     246OS2AHCI.ADD can't drive the CDROM because it's attached to an IDE controller
     247which doesn't support AHCI.
    266248
    267249 - If OS2AHCI.ADD comes first in CONFIG.SYS, it will take over the SATA/AHCI
     
    270252 - If DANIS506.ADD comes first in CONFIG.SYS, it will take over both the
    271253   SATA/AHCI and the PATA/IDE controller and OS2AHCI.ADD will silently exit.
    272 
    273 Advantages of AHCI
    274 ------------------
    275 
    276 The interfaces provided by the various [Intel] controllers could be
    277 summarized like this (the term ATA as driver interface being a bit of our
    278 own invention):
    279 
    280  - Intel PIIX: IDE (I/O registers) and ATA (taskfile)
    281  - Intel ICH6: IDE (I/O registers), ATA (taskfile) and SATA
    282    (FIS, vendor-specific)
    283  - Intel ICH7: IDE (I/O registers), ATA (taskfile), SATA
    284    (FIS, vendor-specific) and AHCI (FIS)
    285  - Intel PCH: AHCI (FIS)
    286 
    287 Taskfiles are regions in memory with ATA commands which the IDE/ATA
    288 controller can read and process autonomously. FIS (Frame Information
    289 Structures) are pretty much the same but they are specific to the SATA
    290 communication protocol on the serial link. The most important FIS type
    291 for AHCI drivers is the H2D (host to device) FIS which basically contains
    292 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-generation
    296 drivers like DANIS506 would have to do step by step. For example, in
    297 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 taskfiles
    300     or SATA FIS)
    301   * Wait until device signals via interrupt it's ready for the ATAPI command
    302   * Send ATAPI command to device via PIO
    303   * Wait until device signals via interrupt it's ready to transfer data
    304   * Send/Receive any data that might come along with the ATAPI command via
    305     PIO, or wait for DMA transfer to complete
    306   * Wait until device signals via interrupt that command and data transfer
    307     have completed
    308 
    309 For OS2AHCI, the same operation looks like this:
    310 
    311   * Fill in AHCI command header, FIS with ATA "PACKET" command and the ATAPI
    312     command
    313   * Tell port engine to process the command
    314   * Wait until controller signals via interrupt that command and data
    315     transfer have completed
    316 
    317 The AHCI controller automatically takes care of all underlying bits and
    318 pieces. OS2AHCI doesn't even have to know whether a particular message is
    319 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 controller
    321 and the device -- all transfers between OS2AHCI and the AHCI controller are
    322 always done via DMA.
    323254
    324255
     
    384315Change Log
    385316==========
     317
     318v.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
    386325v.2.08 20-Feb-2021 - David Azarewicz
    387326  Corrected RM ADD handle and unit.
  • trunk/src/os2ahci/ahci.c

    r209 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
     
    3636                              ? atapi_##func : ata_##func
    3737
    38 
    39 /* Initial driver status flags indexed by the board_* constants in os2ahci.h
    40  *
    41  * NOTE: The Linux AHCI driver uses a combination of board-specific quirk
    42  *       flags and overriding certain libata service functions to handle
    43  *       adapter flaws. However, there were only three overrides at the time
    44  *       os2ahci was written, one for hard adapter resets and two for port
    45  *       resets, and we can easily implement those within the corresponding
    46  *       reset handlers. If this becomes more complex, this array of flags
    47  *       should be converted into a structure array which contains function
    48  *       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 
    7138#define MAX_IRQ_HANDLERS 8 /* This is the maximum number of handlers that Dev32Help_SetIRQ can register */
    7239static u16 irq_used[MAX_IRQ_HANDLERS]; /* IRQ level for each used IRQ */
     
    8148  dprintf(0,"AHCI global registers for adapter %d %d:%d:%d irq=%d addr=0x%x\n",
    8249      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);
    8552
    8653  for (i = 0; i <= HOST_CAP2; i += sizeof(u32))
     
    180147  if (readl(ai->mmio + HOST_VERSION) >= 0x00010200L) ai->cap2 = readl(ai->mmio + HOST_CAP2);
    181148
    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];
    188149  ai->hw_ports = (ai->cap & 0x1f) + 1;
    189150
    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))
    191152  {
    192153    /* disable 64-bit support for faulty controllers; OS/2 can't do 64 bits at
     
    200161   * around quirks and faulty hardware is hard to come by...
    201162   */
    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))
    203164  {
    204165    DPRINTF(DBG_INIT, DBG_PREFIX": controller can't do NCQ, turning off CAP_NCQ\n");
     
    206167  }
    207168
    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))
    209170  {
    210171    DPRINTF(DBG_INIT, DBG_PREFIX": controller can do NCQ, turning on CAP_NCQ\n");
     
    212173  }
    213174
    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))
    215176  {
    216177    DPRINTF(DBG_INIT, DBG_PREFIX": controller can't do PMP, turning off CAP_PMP\n");
     
    218179  }
    219180
    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))
    221182  {
    222183    DPRINTF(DBG_INIT, DBG_PREFIX": controller can't do SNTF, turning off CAP_SNTF\n");
     
    224185  }
    225186
    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)
    227188  {
    228189    DPRINTF(DBG_INIT, DBG_PREFIX": JMB361 has only one port, port_map 0x%x -> 0x%x\n", ai->port_map, 1);
     
    276237  DPRINTF(DBG_DETAILED, DBG_PREFIX": BIOS AHCI mode is %d\n", ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN);
    277238
    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)
    279240  {
    280241    /* Adapter is not in AHCI mode and the spec says a COMRESET is
     
    309270  readl(ai->mmio + HOST_CTL);
    310271
    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)
    312273  {
    313274    /* This BIOS apparently accesses the controller via SATA registers and
     
    400361    while (((tmp = readl(ai->mmio + HOST_CTL)) & HOST_RESET) != 0) {
    401362      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);
    403364        return(-1);
    404365      }
     
    411372    ahci_restore_initial_config(ai);
    412373
    413     if (ai->pci_vendor == PCI_VENDOR_ID_INTEL) {
     374    if (ai->PciVendor == PCI_VENDOR_ID_INTEL) {
    414375      u32 tmp16 = 0;
    415376
     
    498459  }
    499460
    500   if (ai->pci_vendor == PCI_VENDOR_ID_INTEL)
     461  if (ai->PciVendor == PCI_VENDOR_ID_INTEL)
    501462  {
    502463    /* Adapter is not in AHCI mode and the spec says a COMRESET is
     
    520481
    521482  /* 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));
    523484  return(1);
    524485}
     
    541502    /* register IRQ handler; each IRQ level is registered only once */
    542503    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 */
    546507      else
    547508      {
     
    569530      if (rc)
    570531      {
    571         dprintf(0,"failed to register interrupt %d\n", ai->irq);
     532        dprintf(0, DBG_PREFIX": failed to register interrupt %d\n", ai->irq);
    572533        return(-1);
    573534      }
     
    612573  readl(ai->mmio + HOST_CTL); /* flush */
    613574
    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 
    617575  DPRINTF(DBG_INIT|DBG_FUNCEND, DBG_PREFIX": END\n");
    618576  return(0);
     
    686644  if (ai->port_max < p) ai->port_max = p;
    687645  if (ai->ports[p].dev_max < d) ai->ports[p].dev_max = d;
    688   memset(ai->ports[p].devs + d, 0x00, sizeof(*ai->ports[p].devs));
     646  memset(ai->ports[p].devs + d, 0, sizeof(*ai->ports[p].devs));
    689647
    690648  /* set generic device information (assuming an ATA disk device for now) */
     
    699657    /* this is an ATAPI device; augment device information */
    700658    ai->ports[p].devs[d].atapi     = 1;
    701     ai->ports[p].devs[d].atapi_16  = (id_buf[ATA_ID_CONFIG] & 0x0001U) != 0;
    702     ai->ports[p].devs[d].dev_type  = (id_buf[ATA_ID_CONFIG] & 0x1f00U) >> 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;
    703661    ai->ports[p].devs[d].ncq_max   = 1;
    704662
     
    709667    if (enable_ncq[ad_no(ai)][p])
    710668    {
    711       ai->ports[p].devs[d].ncq_max = id_buf[ATA_ID_QUEUE_DEPTH] & 0x001fU;
     669      ai->ports[p].devs[d].ncq_max = id_buf[ATA_ID_QUEUE_DEPTH] & 0x001f;
    712670    }
    713671    if (ai->ports[p].devs[d].ncq_max < 1)
     
    716674      ai->ports[p].devs[d].ncq_max = 1;
    717675    }
    718     if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x0400U)
    719     {
    720       ai->ports[p].devs[d].lba48   = 1;
     676    if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x0400)
     677    {
     678      ai->ports[p].devs[d].lba48 = 1;
    721679    }
    722680  }
     
    760718
    761719  /* 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 &&
    763721      !memcmp(pDevName, "VBOX HARDDISK", 13))
    764722  {
     
    933891  /* set link speed and power management options */
    934892  DPRINTF(DBG_DETAILED, DBG_PREFIX": setting link speed and power management options\n");
    935   tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000fffUL;
     893  tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000fff;
    936894  tmp |= (link_speed[ad_no(ai)][p] & 0x0f) << 4;
    937895  tmp |= (link_power[ad_no(ai)][p] & 0x0f) << 8;
     
    10981056  if ((rc = ahci_stop_fis_rx(ai, p)) != 0)
    10991057  {
    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);
    11011059    return(rc);
    11021060  }
     
    11051063  if ((rc = ahci_stop_engine(ai, p)) != 0)
    11061064  {
    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);
    11081066    return(rc);
    11091067  }
     
    14081366    writel(port_mmio + PORT_CMD_ISSUE, 1);
    14091367    TimerInit(&Timer, timeout);
     1368    rc = 0;
    14101369    while (readl(port_mmio + PORT_CMD_ISSUE) & 1)
    14111370    {
     
    14171376    if (rc)
    14181377    {
    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);
    14201379      iorb_seterr(pIorb, IOERR_ADAPTER_TIMEOUT);
    14211380    }
     
    17311690        iorb_queue_del(&ai->ports[p].iorb_queue, vIorb);
    17321691        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;
    17331694        aws_free(add_workspace(pIorb));
    17341695      }
     
    17751736    #ifdef DEBUG
    17761737    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]);
    17781739    #endif
    17791740    reset_port = 1;
     
    17811742  if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR))
    17821743  {
    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);
    17841745    reset_port = 1;
    17851746  }
    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);
    17891750    reset_port = 1;
    17901751  }
     
    17941755
    17951756    ports_to_reset[ad_no(ai)] |= 1UL << p;
    1796     KernArmHook(reset_ctxhook_h, 0, 0);
     1757    SafeArmCtxHook(ResetCtxHook_h, 0);
    17971758
    17981759    /* no point analyzing device errors after a reset... */
     
    18001761  }
    18011762
    1802   #ifdef DEBUG
    1803   dprintf(0,"port #%d interrupt error status: 0x%08x; restarting port\n", p, irq_stat);
    1804   #else
     1763  #ifndef DEBUG
    18051764  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   }
    18091765  #endif
     1766  {
     1767    dprintf(0,DBG_PREFIX": Port=%d status=%08x; restarting port\n", p, irq_stat);
     1768  }
    18101769
    18111770  /* Handle device-specific errors. Those errors typically involve restarting
     
    18141773   */
    18151774  ports_to_restart[ad_no(ai)] |= 1UL << p;
    1816   KernArmHook(restart_ctxhook_h, 0, 0);
     1775  SafeArmCtxHook(RestartCtxHook_h, 0);
    18171776}
    18181777
  • trunk/src/os2ahci/ahci.h

    r205 r211  
    7777#define RX_FIS_SDB              0x58 /* offset of SDB FIS data */
    7878#define RX_FIS_UNK              0x60 /* offset of Unknown FIS data */
    79 
    80 #define board_ahci              0
    81 #define board_ahci_vt8251       1
    82 #define board_ahci_ign_iferr    2
    83 #define board_ahci_sb600        3
    84 #define board_ahci_mv           4
    85 #define board_ahci_sb700        5 /* for SB700 and SB800 */
    86 #define board_ahci_mcp65        6
    87 #define board_ahci_nopmp        7
    88 #define board_ahci_yesncq       8
    89 #define board_ahci_nosntf       9
    9079
    9180/* global controller registers */
     
    156145
    157146/* 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 */
    175164#define PORT_IRQ_FREEZE         (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR   | \
    176165                                 PORT_IRQ_CONNECT  | PORT_IRQ_PHYRDY   | \
  • trunk/src/os2ahci/apm.c

    r209 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
  • trunk/src/os2ahci/ata.c

    r209 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
     
    121121      if (ata_cmd.lba_l & 0xf0000000UL)
    122122      {
    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);
    124124        return(ATA_CMD_INVALID_PARM);
    125125      }
     
    172172
    173173    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);
    175175      return(ATA_CMD_INVALID_PARM);
    176176    }
     
    255255        if (sg_size)
    256256        {
    257           dprintf(0, __func__": unaligned SG element\n");
     257          dprintf(0, DBG_PREFIX": unaligned SG element\n");
    258258          return -1;
    259259        }
    260         dprintf(0, __func__": too many S/G elements\n");
     260        dprintf(0, DBG_PREFIX": too many S/G elements\n");
    261261        return(i - 1);
    262262      }
    263263      if ((sg_addr & 1) || (chunk & 1))
    264264      {
    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");
    266266        return(ATA_CMD_UNALIGNED_ADDR);
    267267      }
     
    278278
    279279  #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);
    281281  dHexDump(0,cmd_hdr, offsetof(AHCI_CMD_HDR, reserved), "cmd_hdr: ");
    282282  dHexDump(0,&ata_cmd, sizeof(ata_cmd), "ata_cmd: ");
     
    549549    {
    550550      /* 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",
    552552              iorb_unit_adapter(pIorb), iorb_unit_port(pIorb),
    553553              iorb_unit_device(pIorb));
     
    651651  int rc;
    652652
    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))
    654654  {
    655655    /* need LBA48 for this command */
  • trunk/src/os2ahci/ata.h

    r207 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
  • trunk/src/os2ahci/atapi.c

    r209 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
  • trunk/src/os2ahci/atapi.h

    r205 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
  • trunk/src/os2ahci/ctxhook.c

    r209 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
     
    3131
    3232/* port restart context hook and input data */
    33 ULONG           restart_ctxhook_h;
     33ULONG           RestartCtxHook_h;
    3434volatile u32    ports_to_restart[MAX_AD];
    3535
    3636/* port reset context hook and input data */
    37 ULONG           reset_ctxhook_h;
    38 ULONG           th_reset_watchdog;
     37ULONG           ResetCtxHook_h;
     38ULONG           th_watchdog;
    3939volatile u32    ports_to_reset[MAX_AD];
    4040IORB_QUEUE      abort_queue;
     
    4242/* trigger engine context hook and input data */
    4343ULONG           engine_ctxhook_h;
     44
     45#define QUEUEDEPTH 8
     46static struct _ctxq_
     47{
     48  ULONG ulHandle;
     49  ULONG ulArg;
     50} CtxQueue[QUEUEDEPTH] = {0};
     51static ULONG ulCtxStatusFlag = 0;
     52
     53void 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
     74void 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}
    4493
    4594/******************************************************************************
     
    78127 * in the interrupt and error handlers.
    79128 */
    80 void _Syscall restart_ctxhook(ULONG parm)
     129void _Syscall RestartCtxHook(ULONG parm)
    81130{
    82131  IORB_QUEUE done_queue;
     
    85134  IORBH FAR16DATA *vIorb;
    86135  IORBH FAR16DATA *vNext;
     136  IORBH *pIorb;
     137  ADD_WORKSPACE *aws;
    87138  u8 *port_mmio;
    88139  int rearm_ctx_hook;
     
    97148  rearm_ctx_hook = 0;
    98149
    99   DPRINTF(DBG_FUNCBEG, DBG_PREFIX": restart_ctxhook() started\n");
     150  AhciStats.ulSoftErrorCount++;
     151  DPRINTF(0, DBG_PREFIX": BEG\n");
    100152  memset(&done_queue, 0x00, sizeof(done_queue));
    101153
    102154  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  }
    103162
    104163  for (a = 0; a < ad_info_cnt; a++)
     
    124183        need_reset = 0;
    125184
    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));
    127186
    128187        /* get "current command slot"; only valid if there are no NCQ cmds */
    129188        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);
    131190
    132191        for (vIorb = ai->ports[p].iorb_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext)
    133192        {
    134           IORBH *pIorb = Far16ToFlat(vIorb);
    135           ADD_WORKSPACE *aws = add_workspace(pIorb);
     193          pIorb = Far16ToFlat(vIorb);
     194          aws = add_workspace(pIorb);
    136195          vNext = pIorb->f16NxtIORB;
    137196
    138197          if (aws->queued_hw)
    139198          {
     199            if (aws->timer != 0)
     200            {
     201              Timer_CancelTimer(aws->timer);
     202              aws->timer = 0;
     203            }
     204
    140205            if (ai->ports[p].ncq_cmds & (1UL << aws->cmd_slot))
    141206            {
     
    144209              aws->no_ncq = 1;
    145210              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
    146215            }
    147216            else
     
    152221              {
    153222                /* 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
    155227                vProblemIorb = vIorb;
    156228              }
     
    179251        if (ai->ports[p].ncq_cmds != 0 || ai->ports[p].reg_cmds != 0)
    180252        {
    181           DPRINTF(0, DBG_PREFIX": warning: commands issued not 0 (%08lx/%08lx); resetting...\n",
     253          DPRINTF(0, DBG_PREFIX": warning: commands issued not 0 (%08x/%08x); resetting...\n",
    182254                  ai->ports[p].ncq_cmds, ai->ports[p].reg_cmds);
    183255          need_reset = 1;
     
    260332  spin_unlock(drv_lock);
    261333
     334  DPRINTF(0, DBG_PREFIX": Resuming\n");
    262335  /* call notification routine on all IORBs which have completed */
    263336  for (vIorb = done_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext)
    264337  {
    265     IORBH *pIorb = Far16ToFlat(vIorb);
     338    pIorb = Far16ToFlat(vIorb);
    266339    vNext = pIorb->f16NxtIORB;
    267340
     
    278351  spin_unlock(drv_lock);
    279352
    280   DPRINTF(DBG_FUNCEND, DBG_PREFIX": restart_ctxhook() completed\n");
     353  DPRINTF(0, DBG_PREFIX": END Rearm=%x\n", rearm_ctx_hook);
    281354
    282355  /* Check whether we have to rearm ourselves because some adapters were busy
     
    285358  if (rearm_ctx_hook)
    286359  {
    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);
    290368  KernThunkStackTo16();
    291369}
     
    317395 * the upstream code might reuse the IORBs before we're done with them.
    318396 */
    319 void _Syscall reset_ctxhook(ULONG parm)
     397void _Syscall ResetCtxHook(ULONG ulArg)
    320398{
    321399  IORB_QUEUE done_queue;
     
    323401  IORBH FAR16DATA *vIorb;
    324402  IORBH FAR16DATA *vNext;
     403  IORBH *pIorb;
     404  ADD_WORKSPACE *aws;
    325405  int rearm_ctx_hook;
    326406  int a;
     
    332412  rearm_ctx_hook = 0;
    333413
    334   DPRINTF(DBG_FUNCBEG, DBG_PREFIX": reset_ctxhook() started\n");
     414  AhciStats.ulHardErrorCount++;
     415  DPRINTF(0, DBG_PREFIX": BEG Arg=%x\n", ulArg);
    335416  memset(&done_queue, 0x00, sizeof(done_queue));
    336417
     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
    337425  spin_lock(drv_lock);
    338426
    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    }
    344445  }
    345446
     
    347448  for (vIorb = abort_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext)
    348449  {
    349     IORBH *pIorb = Far16ToFlat(vIorb);
     450    pIorb = Far16ToFlat(vIorb);
    350451    vNext = pIorb->f16NxtIORB;
    351452    a = iorb_unit_adapter(pIorb);
    352453    p = iorb_unit_port(pIorb);
    353454    ai = ad_infos + a;
     455    aws = add_workspace(pIorb);
    354456
    355457    if (ai->busy)
     
    365467
    366468    /* 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
    369477      /* prepare port reset */
    370478      ports_to_reset[a] |= (1UL << p);
     
    411519        {
    412520          IORBH *pIorb = Far16ToFlat(vIorb);
    413           ADD_WORKSPACE *aws = add_workspace(pIorb);
    414521          vNext = pIorb->f16NxtIORB;
     522
     523          aws = add_workspace(pIorb);
    415524
    416525          if (aws->queued_hw)
     
    421530              /* we can retry this IORB */
    422531              iorb_requeue(pIorb);
    423 
    424532            }
    425533            else
     
    438546  spin_unlock(drv_lock);
    439547
     548  DPRINTF(0, DBG_PREFIX": Resuming\n");
     549
    440550  /* complete all aborted IORBs */
    441551  for (vIorb = done_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext)
    442552  {
    443     IORBH *pIorb = Far16ToFlat(vIorb);
     553    pIorb = Far16ToFlat(vIorb);
    444554    vNext = pIorb->f16NxtIORB;
    445555
     
    457567  spin_unlock(drv_lock);
    458568
    459   DPRINTF(DBG_FUNCEND, DBG_PREFIX": reset_ctxhook() completed\n");
     569  DPRINTF(0, DBG_PREFIX": END Rearm=%x\n", rearm_ctx_hook);
    460570
    461571  /* Check whether we have to rearm ourselves because some adapters were busy
     
    468578     * we set the timer again.
    469579     */
    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);
    475584  KernThunkStackTo16();
    476585}
  • trunk/src/os2ahci/ioctl.c

    r206 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
  • trunk/src/os2ahci/ioctl.h

    r205 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
     
    3030#define OS2AHCI_IOCTL_GET_DEVLIST      0x01
    3131#define OS2AHCI_IOCTL_PASSTHROUGH      0x02
     32#define OS2AHCI_IOCTL_DEBUG            0xd1
    3233
    3334/* IOCTL definitions from s506oem.h (primarily required for SMART calls) */
     
    199200} UnitInformationData;
    200201
    201 
    202202#pragma pack()
    203203
  • trunk/src/os2ahci/os2ahci.c

    r209 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
     
    2626 */
    2727
     28#define INCL_LONGLONG
    2829#include "os2ahci.h"
    2930#include "ioctl.h"
     
    5859int thorough_scan = 1; /* if != 0, perform thorough PCI scan */
    5960int init_reset = 1;    /* if != 0, reset ports during init */
    60 int force_write_cache; /* if != 0, force write cache */
     61int force_write_cache = 0; /* if != 0, force write cache */
    6162int iVerbose = 0;     /* default is quiet. 1=show sign on banner, >1=show adapter info during boot */
    6263int use_mbr_test = 1;
     
    190191  memset(ad_infos, 0, sizeof(ad_infos));
    191192  memset(emulate_scsi, 1, sizeof(emulate_scsi)); /* set default enabled */
     193  memset(enable_ncq, 1, sizeof(enable_ncq)); /* set default enabled */
    192194  UtSetDriverName("OS2AHCI$");
    193195  Header.ulCaps |= DEV_ADAPTER_DD; /* DAZ This flag is not really needed. */
     
    423425  if (iVerbose) iprintf("OS2AHCI.ADD: driver version %d.%02d", DMAJOR, DMINOR);
    424426
    425   #ifdef TESTVER
     427  #if defined(TESTVER) && defined(DEBUG)
    426428  #include "testver.c"
    427429  #endif
     
    443445
    444446    /* 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);
    447449    KernAllocateContextHook(engine_ctxhook, 0, &engine_ctxhook_h);
    448450
     
    481483{
    482484  DPRINTF(DBG_FUNCBEG, DBG_PREFIX": IOCTL 0x%x/0x%x\n", ioctl->ioctl.bCategory, ioctl->ioctl.bFunction);
    483   AhciStats.ulTestCount2++;
    484485
    485486  switch (ioctl->ioctl.bCategory)
     
    599600    memset(&pIorb->ADDWorkSpace, 0x00, sizeof(ADD_WORKSPACE));
    600601
    601     #ifdef DEBUG
    602     DumpIorb(pIorb); /* DAZ TESTING */
    603     #endif
     602    //#ifdef DEBUG
     603    //DumpIorb(pIorb); /* DAZ TESTING */
     604    //#endif
    604605
    605606    if (iorb_driver_level(pIorb))
     
    622623      {
    623624        /* unit handle outside of the allowed range */
    624         dprintf(0,"warning: IORB for %d.%d.%d out 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);
    625626        pIorb->Status = IORB_ERROR;
    626627        pIorb->ErrorCode = IOERR_CMD_SYNTAX;
     
    920921
    921922    /* trigger reset context hook which will finish the abort processing */
    922     KernArmHook(reset_ctxhook_h, 0, 0);
     923    SafeArmCtxHook(ResetCtxHook_h, 0);
    923924    break;
    924925
     
    10711072    if ((u32)(pPtr + 1) - (u32)pDt > pIorb_conf->DeviceTableLen)
    10721073    {
    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");
    10741075      iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
    10751076      goto iocm_device_table_done;
     
    11001101        if (ad_info->busy)
    11011102        {
    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");
    11031104          iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
    11041105          goto iocm_device_table_done;
     
    11121113        if (rc != 0)
    11131114        {
    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);
    11151116          iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
    11161117          goto iocm_device_table_done;
     
    15331534 * separate function which is invoked via a context hook.
    15341535 */
    1535 void __syscall timeout_callback(ULONG timer_handle, ULONG p1)
    1536 {
    1537   IORBH FAR16DATA *vIorb = (IORBH FAR16DATA *)CastULONGToFar16(p1);
     1536void __syscall timeout_callback(ULONG timer_handle, ULONG ulArg)
     1537{
     1538  IORBH FAR16DATA *vIorb = (IORBH FAR16DATA *)CastULONGToFar16(ulArg);
    15381539  IORBH *pIorb = Far16ToFlat(vIorb);
    15391540  int a = iorb_unit_adapter(pIorb);
     
    15411542
    15421543  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);
    15581545
    15591546  /* Trigger abort processing function. We don't really care whether this
     
    15681555   *    will process our IORB as well.
    15691556   */
    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);
    15791558}
    15801559
     
    15901569 * problems during the early boot phase.
    15911570 */
    1592 void __syscall reset_watchdog(ULONG timer_handle, ULONG p1)
     1571void __syscall WatchdogTimer(ULONG timer_handle, ULONG ulArg)
    15931572{
    15941573  /* reset watchdog timer */
    15951574  Timer_CancelTimer(timer_handle);
    1596   th_reset_watchdog = 0;
    1597   dprintf(0,"reset watchdog invoked\n");
    1598 
    1599   /* You cannot call the reset_ctxhook directly because it does things
     1575  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
    16001579   * that are illegal in an interrupt handler.
    16011580   */
    1602 
    1603   KernArmHook(reset_ctxhook_h, 0, 0);
    1604 
    1605   /* call context hook manually */
    1606   //reset_ctxhook(0);
     1581  SafeArmCtxHook(ulArg, 0);
    16071582}
    16081583
     
    16341609  if ((u32)(pUi + 1) - (u32)pDt > pIorb_conf->DeviceTableLen)
    16351610  {
    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");
    16371612    iorb_seterr(&pIorb_conf->iorbh, IOERR_CMD_SW_RESOURCE);
    16381613    return(-1);
  • trunk/src/os2ahci/os2ahci.h

    r209 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
     
    107107  parm nomemory [eax] [bx] value [eax] modify nomemory exact [eax];
    108108
     109ULONG 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
     115ULONG 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
    109122/* stdarg.h macros with explicit far pointers */
    110123typedef char *va_list;
     
    112125#define va_arg(va, type)      ((type *) (va += sizeof(type)))[-1]
    113126#define va_end(va)            va = 0
    114 
    115 /* stddef macros */
    116 #define offsetof(s, e) ((u32)&((s *)0)->e)
    117127
    118128/* shortcut macros */
     
    222232  u32   class;           /* PCI device class */
    223233  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 */
    226236} PCI_ID;
    227237
     
    275285/* adapter information structure */
    276286typedef 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) */
    280301  unsigned      cmd_max : 5;           /*    maximum cmd slot number (0-31) */
    281302  unsigned      port_scan_done : 1;    /*    if != 0, port scan already done */
    282303  unsigned      busy : 1;              /*    if != 0, adapter is busy */
    283304  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 */
    289308
    290309  /* 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 */
    309317} AD_INFO;
    310318
     
    364372  ULONG ulSize;
    365373  ULONG ulVersion;
    366   ULONG ulTestCount3;
    367   ULONG ulTestCount2;
     374  ULONG ulHardErrorCount;
     375  ULONG ulSoftErrorCount;
    368376  ULONG ulTestCount1;
    369377} AHCISTATS;
     
    409417extern void unlock_adapter(AD_INFO *ai);
    410418extern void __syscall timeout_callback(ULONG timer_handle, ULONG p1);
    411 extern void __syscall reset_watchdog(ULONG timer_handle, ULONG p1);
     419extern void __syscall WatchdogTimer(ULONG timer_handle, ULONG p1);
    412420
    413421/* ahci.c */
     
    459467extern int add_pci_id(u16 vendor, u16 device);
    460468extern void scan_pci_bus(void);
    461 extern int pci_enable_int(USHORT BusDevFunc);
    462469extern void pci_hack_virtualbox(void);
    463470extern char *vendor_from_id(u16 vendor);
    464 extern char *device_from_id(u16 device);
    465471
    466472/* ctxhook.c */
    467 extern void _Syscall restart_ctxhook(ULONG parm);
    468 extern void _Syscall reset_ctxhook(ULONG parm);
     473extern void _Syscall RestartCtxHook(ULONG parm);
     474extern void _Syscall ResetCtxHook(ULONG parm);
    469475extern void _Syscall engine_ctxhook(ULONG parm);
     476extern void SafeArmCtxHook(ULONG ulHandle, ULONG armData);
    470477
    471478/* apm.c */
     
    477484extern USHORT ioctl_get_devlist(REQPACKET *ioctl);
    478485extern USHORT ioctl_passthrough(REQPACKET *ioctl);
     486extern USHORT ioctl_debug(REQPACKET *ioctl);
    479487extern USHORT ioctl_gen_dsk(REQPACKET *ioctl);
    480488extern USHORT ioctl_smart(REQPACKET *ioctl);
     
    504512
    505513/* port restart context hook and input data */
    506 extern ULONG restart_ctxhook_h;
     514extern ULONG RestartCtxHook_h;
    507515extern volatile u32 ports_to_restart[MAX_AD];
    508516
    509517/* port reset context hook and input data */
    510 extern ULONG reset_ctxhook_h;
    511 extern ULONG th_reset_watchdog;
     518extern ULONG ResetCtxHook_h;
     519extern ULONG th_watchdog;
    512520extern volatile u32 ports_to_reset[MAX_AD];
    513521extern IORB_QUEUE abort_queue;
     
    525533
    526534#ifdef DEBUG
    527 extern void DumpIorb(IORBH *pIorb);
     535extern void DumpIorb(IORBH *pIorb, IORBH FAR16DATA *vIorb);
    528536#endif
    529537
  • trunk/src/os2ahci/pci.c

    r209 r211  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
    6  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    77 *
    88 * Authors: Christian Mueller, Markus Thielen
     
    2727
    2828#include "os2ahci.h"
     29#include "pci_regs.h"
    2930
    3031/* offset of PCI base address register (BAR) in the PCI config space */
     
    3637
    3738/******************************************************************************
    38  * chipset/controller name strings
    39  */
    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 /******************************************************************************
    6439 * PCI vendor and device IDs for known AHCI adapters. Copied from the Linux
    6540 * AHCI driver.
     
    6944{
    7045  /* 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 */
    11387
    11488  /* JMicron 360/1/3/5/6, match class to avoid IDE function */
    11589  { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
    116     PCI_CLASS_STORAGE_SATA_AHCI, 0xffffffL, board_ahci_ign_iferr, "360" },
     90    PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, "360", AHCI_HFLAG_IGN_IRQ_IF_ERR },
    11791
    11892  /* 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 */
    126100
    127101  /* AMD */
    128   { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
     102  { PCI_VDEVICE(AMD, 0x7800), "Hudson-2", 0 }, /* AMD Hudson-2 */
    129103  /* AMD is using RAID class only for ahci controllers */
    130104  { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
    131     PCI_CLASS_STORAGE_RAID << 8, 0xffffffL, board_ahci, "Hudson2" },
     105    PCI_CLASS_STORAGE_RAID << 8, 0xffffff, "Hudson2", 0 },
    132106
    133107  /* 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 */
    136110
    137111  /* 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 */
    207181
    208182  /* 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 */
    212186
    213187  /* 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 */
    216190
    217191  /* Promise */
    218   { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci,          "PDC42819"  }, /* PDC42819 */
     192  { PCI_VDEVICE(PROMISE, 0x3f20), "PDC42819", 0 }, /* PDC42819 */
    219193
    220194  /* Generic, PCI class code for AHCI */
    221195  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
    222     PCI_CLASS_STORAGE_SATA_AHCI, 0xffffffL, board_ahci, s_generic  },
     196    PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, "Generic", 0 },
    223197
    224198  /* 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 }
    237211};
    238212
     
    255229  pci_ids[i].vendor = vendor;
    256230  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;
    259233  return(0);
    260234}
     
    321295        for (n = 0; n < ad_info_cnt; n++)
    322296        {
    323           if (ad_infos[n].bus_dev_func == BusDevFunc)
     297          if (ad_infos[n].BusDevFunc == BusDevFunc)
    324298          {
    325299            /* this device has already been found (e.g. via thorough scan) */
     
    343317    } while (BusDevFunc != 0xffff);
    344318  }
    345 }
    346 
    347 /******************************************************************************
    348  * Enable interrupt generation. PCI 2.3 added a bit which allows disabling
    349  * interrupt generation for a device. This function clears the corresponding
    350  * 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);
    362319}
    363320
     
    559516   * itself with the OS/2 resource manager
    560517   */
    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;
    565523  ad_info->irq = irq;
    566524  ad_info->irq_pin = pin;
     
    594552  }
    595553
     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  }
    596560  if (ahci_config_caps(ad_info)) goto add_pci_fail;
    597561
     
    738702    }
    739703
    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 "";
    760705}
    761706
  • trunk/src/os2ahci/thunk.asm

    r205 r211  
    11; Thunking for ahci32 driver
    2 ; Copyright (c) 2018-2021 David Azarewicz
     2; Copyright (c) 2018-2023 David Azarewicz
    33; Author: David Azarewicz <david@88watts.net>
    44
  • trunk/src/os2ahci/trace.c

    r209 r211  
    11/**
    22 *
    3  * Copyright (c) 2013-2021 David Azarewicz <david@88watts.net>
     3 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
    44 *
    55 */
     
    2222    AD_INFO *ai = ad_infos + a;
    2323
    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,
    2828      ai->irq, ai->mmio_phys,
    2929      ai->bios_config[HOST_VERSION / sizeof(u32)]);
     
    6363
    6464#ifdef DEBUG
    65 void DumpIorb(IORBH *pIorb)
     65void DumpIorb(IORBH *pIorb, IORBH FAR16DATA *vIorb)
    6666{
    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;
    6969
    7070  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);
    7272  dprintf(0,"  CmdMod=%x ReqCtrl=%x Status=%x ErrorCode=%x\n",
    7373      pIorb->CommandModifier, pIorb->RequestControl, pIorb->Status, pIorb->ErrorCode);
     
    7575      pIorb->Timeout, pIorb->StatusBlockLen, pIorb->pStatusBlock, pIorb->Reserved_1,
    7676      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  }
    7789}
    7890#endif
  • trunk/tools/ahci.wis

    r194 r211  
    33  <TITLE>=("TITLE")</TITLE>
    44  <REXX NAME=TITLE>
     5   Call Rxfuncadd 'SysLoadFuncs','RexxUtil','SysLoadFuncs';
     6   Call SysLoadFuncs;
    57   MyTitle="AHCI Driver for OS/2";
    68
Note: See TracChangeset for help on using the changeset viewer.