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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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);
Note: See TracChangeset for help on using the changeset viewer.