Changeset 165 for trunk


Ignore:
Timestamp:
Jul 31, 2013, 8:08:59 PM (12 years ago)
Author:
David Azarewicz
Message:

code cleanup - debug messages
fixed defect in smart ioctl

Location:
trunk/src/os2ahci
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/os2ahci/README

    r163 r165  
    1717Copyright (c) 2011 thi.guten Software Development
    1818Copyright (c) 2011-2013 Mensys B.V.
     19Portions copyright (c) 2013 David Azarewicz
    1920
    2021Authors: Christian Mueller, Markus Thielen
     
    8182- Add the following line to CONFIG.SYS:
    8283  BASEDEV=OS2AHCI.ADD
     84
     85
     86Reporting Problems
     87==================
     88
     89If you have problems with this driver, please read the Troubleshooting
     90page at:
     91
     92  http://svn.ecomstation.nl/ahci/wiki/Troubleshooting
     93
     94You can open a ticket at:
     95  http://svn.ecomstation.nl/ahci
    8396
    8497
     
    151164Option                 Description
    152165------------------------------------------------------------------------------
    153 /s                     Enable SCSI emulation for ATAPI units (default = off)
     166/s                     Enable SCSI emulation for ATAPI units (default = on)
    154167                       SCSI emulation is required for tools like cdrecord.
    155168
     
    346359Starting with version 1.22, OS2AHCI supports the IOCTL interface required by
    347360existing SMART monitoring tools. Since those tools are hard-coded to open
    348 the character device named "IBMS506$", OS2AHCI will now register a device
    349 with this name, too.
     361the character device named "IBMS506$", they will not work with OS2AHCI unless
     362modified to open the OS2AHCI$ device. Previous versions of OS2AHCI used to
     363register register a duplicate device with the IBMS506$ name, however since
     364that caused so many unacceptable problems, that is no longer done. You must
     365have a SMART utility that opens the OS2AHCI$ device to access the AHCI driver.
     366
     367A patched version of the smartctl.exe program is included in the OS2AHCI
     368distribution. This patched version simply has the name "IBMS506$" changed
     369to "OS2AHCI$" and is otherwise identical. This patched program has been
     370renamed to smartahci.exe to distinguish it from the unpatched version.
     371The patched smartahci.exe program is provided AS-IS and is completely
     372UNSUPPORTED. Use of this program is at your own risk.
    350373
    351374NOTES:
    352 
    353  - If multiple drivers exporting this character device name are loaded at
    354    the same time, the driver loaded last will receive all [SMART] requests.
    355    This means that if both DANIS506 and OS2AHCI are loaded and SMART support
    356    for OS2AHCI-controlled hard disks is desired, OS2AHCI will have to be
    357    loaded after DANIS506. It also means that DANIS506 may have to be told
    358    to ignore type 2 controllers (i.e. controllers supporting both SATA and
    359    AHCI) using the command line options "/A:x /I".
    360375
    361376 - The IOCTL interface for SMART is based on the idea of IDE controllers
     
    381396Change Log
    382397==========
     398
     399v.1.30 29-Jun-2013 - David Azarewicz
     400  Enhanced debug log output
     401  Removed the IBMS506 header that was causing problems and shouldn't
     402    be there anyway.
     403  Fixed a defect in the SMART IOCtl.
    383404
    384405v.1.29 12-Jun-2013 - David Azarewicz
  • trunk/src/os2ahci/ahci.c

    r164 r165  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
     6 * Portions copyright (c) 2013 David Azarewicz
    67 *
    78 * Authors: Christian Mueller, Markus Thielen
     
    234235
    235236#if 0
     237  /* init_reset is set by default. This code is commented out to allow
     238   * unsetting init_reset by a command line switch
     239   */
    236240  if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 &&
    237241      ai->pci->vendor == PCI_VENDOR_ID_INTEL) {
     
    13431347    dprintf("flushing cache on %d.%d.%d\n", ad_no(ai), p, d);
    13441348    return(ahci_exec_polled_cmd(ai, p, d, 30000,
    1345                                 ai->ports[p].devs[d].lba48 ? ATA_CMD_FLUSH_EXT
    1346                                                            : ATA_CMD_FLUSH,
    1347                                 AP_END));
     1349           ai->ports[p].devs[d].lba48 ? ATA_CMD_FLUSH_EXT : ATA_CMD_FLUSH, AP_END));
    13481350  }
    13491351  return 0;
  • trunk/src/os2ahci/apm.c

    r162 r165  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
     6 * Portions copyright (c) 2013 David Azarewicz
    67 *
    78 * Authors: Christian Mueller, Markus Thielen
     
    123124      for (d = 0; d <= ai->ports[p].dev_max; d++) {
    124125        if (ai->ports[p].devs[d].present) {
    125           ahci_flush_cache(ai, p, d);
    126         }
     126          ahci_flush_cache(ai, p, d);
     127        }
    127128      }
    128129    }
     
    241242
    242243      #if 0
     244      /* cannot flush caches this way */
    243245      ahci_start_port(ai, p, 0);
    244246
     
    246248      for (d = 0; d <= ai->ports[p].dev_max; d++) {
    247249        if (ai->ports[p].devs[d].present) {
    248           ahci_flush_cache(ai, p, d);
    249         }
     250          ahci_flush_cache(ai, p, d);
     251        }
    250252      }
    251253      #endif
  • trunk/src/os2ahci/ata.c

    r162 r165  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
     6 * Portions copyright (c) 2013 David Azarewicz
    67 *
    78 * Authors: Christian Mueller, Markus Thielen
  • trunk/src/os2ahci/init.asm

    r164 r165  
    3636
    3737DEVHDR          SEGMENT WORD PUBLIC 'DATA'
    38 _dev_hdr        dd      _next_hdr               ; next device header
     38_dev_hdr        dd      -1                      ; next device header
    3939                dw      DEVLEV_3 + DEV_CHAR_DEV + DEV_IDC ; flags for ADD drivers
    4040                dw      OFFSET _asm_strat       ; strategy routine
     
    4444                dd      DEV_IOCTL2 + DEV_ADAPTER_DD + DEV_INITCOMPLETE + DEV_SAVERESTORE ; ADD flags
    4545                dw      0
    46 
    47 if 1
    48 ; This is here to support old SMART tools which only look for IBMS506$. This is a
    49 ; really bad thing to do as it will cause problems in the future. The SMART tools
    50 ; should be fixed to be able to open OS2AHCI$ and this header should be removed.
    51 _next_hdr       dd      -1                      ; no headers after this one
    52                 dw      DEVLEV_3 + DEV_CHAR_DEV ; flags for ADD drivers
    53                 dw      OFFSET _asm_strat       ; strategy routine
    54                 dw      0                       ; IDC entry point
    55                 db      "IBMS506$"              ; name of character device
    56                 dq      0                       ; 8 reserved bytes
    57                 dd      0
    58                 dw      0
    59 else
    60 _next_hdr       equ -1
    61 endif
    6246
    6347DEVHDR          ENDS
  • trunk/src/os2ahci/ioctl.c

    r129 r165  
    207207  ic->iorb.iorbh.UnitHandle       = iorb_unit(a, p, d);
    208208  ic->iorb.iorbh.CommandCode      = IOCC_ADAPTER_PASSTHRU;
    209   ic->iorb.iorbh.CommandModifier  = (req->flags & PT_ATAPI) ? IOCM_EXECUTE_CDB
    210                                                             : IOCM_EXECUTE_ATA;
     209  ic->iorb.iorbh.CommandModifier  = (req->flags & PT_ATAPI) ? IOCM_EXECUTE_CDB : IOCM_EXECUTE_ATA;
    211210  ic->iorb.iorbh.RequestControl   = IORB_ASYNC_POST;
    212211  ic->iorb.iorbh.Timeout          = req->timeout;
     
    234233  add_entry(&ic->iorb.iorbh);
    235234
    236   /* Wait for IORB completion. On SMP kernels, ProcBlock will release
    237    * all spinlocks currently held, in addition to re-enabling interrupts,
    238    * so we can use spinlocks to protect the time between checking the
    239    * IORB_DONE flag and calling ProcBlock.
    240    *
    241    * However, if OS2AHCI_SMP is not defined, we're emulating spinlocks
    242    * via disabling interrupts and there's a sanity check in the emulation
    243    * code to catch recursive spinlocks, thus we need to reset the emulated
    244    * spinlock status before calling ProcBlock. Otherwise, the driver will
    245    * will get caught in the sanity checks when processing the next IORB or
    246    * interrupt while we're waiting.
    247    */
     235  /* Wait for IORB completion. */
    248236  spin_lock(drv_lock);
    249237  while (!(ic->iorb.iorbh.Status & IORB_DONE)) {
    250 
    251 #   ifndef OS2AHCI_SMP
    252       drv_lock = 0;
    253 #   endif
    254 
    255238    DevHelp_ProcBlock((ULONG) (void _far *) &ic->iorb.iorbh, 30000, 1);
    256     spin_lock(drv_lock);
    257239  }
    258240  spin_unlock(drv_lock);
     
    355337  USHORT d;
    356338  UCHAR unit;
    357  
     339
    358340  /* verify addressability of parm buffer (DSKSP_CommandParameters) */
    359341  if (DevHelp_VerifyAccess((SEL) ((ULONG) cp >> 16),
     
    499481
    500482  case DSKSP_SMART_ONOFF:
    501     ret = do_smart(unit, (BYTE) ((parm) ? ATA_SMART_ENABLE
    502                                         : ATA_SMART_DISABLE),
    503                    0, 0, NULL);
     483    ret = do_smart(unit, (BYTE) ((parm) ? ATA_SMART_ENABLE : ATA_SMART_DISABLE), 0, 0, NULL);
    504484    break;
    505485
    506486  case DSKSP_SMART_AUTOSAVE_ONOFF:
    507     ret = do_smart(unit, ATA_SMART_AUTOSAVE,
    508                    (BYTE) ((parm) ? (BYTE) 0xf1 : 0), 0, NULL);
     487    ret = do_smart(unit, ATA_SMART_AUTOSAVE, (BYTE) ((parm) ? (BYTE) 0xf1 : 0), 0, NULL);
    509488    break;
    510489
     
    547526 * Perform SMART request. The code has been more or less copied from DANIS506.
    548527 */
    549 static USHORT do_smart(BYTE unit, BYTE sub_func, BYTE cnt, BYTE lba_l,
    550                        void _far *buf)
     528static USHORT do_smart(BYTE unit, BYTE sub_func, BYTE cnt, BYTE lba_l, void _far *buf)
    551529{
    552530  OS2AHCI_PASSTHROUGH pt;
     
    584562  }
    585563
    586   if (((ret = gen_ioctl(&ioctl)) & STERR) == 0 &&
    587       sub_func == ATA_SMART_STATUS) {
     564  if (((ret = gen_ioctl(&ioctl)) & STERR) == 0 && sub_func == ATA_SMART_STATUS) {
    588565
    589566    /* ATA_SMART_STATUS doesn't transfer anything but instead relies on the
  • trunk/src/os2ahci/libc.c

    r160 r165  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
     6 * Portions copyright (c) 2013 David Azarewicz
    67 *
    78 * Authors: Christian Mueller, Markus Thielen
     
    3839#define HEAP_UNIT_CNT         (HEAP_SIZE / HEAP_UNIT)
    3940
    40 /* ------------------------ typedefs and structures ------------------------ */
    41 
    42 #ifdef NOT_USED
    43 /* mdelay() calibration status */
    44 typedef enum {
    45   MD_NOT_CALIBRATED,                  /* delay loop not calibrated */
    46   MD_CALIBRATION_START,               /* calibration run started */
    47   MD_CALIBRATION_END,                 /* calibration run ended */
    48   MD_CALIBRATION_DONE                 /* calibration complete */
    49 } MDCAL;
    50 static void _cdecl _far mdelay_timer_callback  (ULONG timer_handle,
    51                                                 ULONG parm1,
    52                                                 ULONG parm2);
    53 static int              mdelay_cal_end         (void);
    54 #endif
    55 
    5641/* -------------------------- function prototypes -------------------------- */
    5742
    58 static void             long_to_asc            (long val,
    59                                                 char _far *buf,
    60                                                 int base,
    61                                                 int zero, int flen);
     43static void long_to_asc(long val, char _far *buf, int base, int zero, int flen);
    6244
    6345/* ------------------------ global/static variables ------------------------ */
     
    9476};
    9577
    96 #ifdef NOT_USED
    97 /* delay loop calibration data */
    98 volatile MDCAL mdelay_cal_status = 0;     /* delay loop calibration status */
    99 volatile u32   mdelay_loops_per_ms = 0;   /* delay loop counter */
    100 #endif
    101 
    10278/* very small heap for dynamic memory management */
    10379static u8 heap_buf[HEAP_SIZE];
     
    688664}
    689665
    690 #ifdef NOT_USED
    691 /******************************************************************************
    692  * Calibrate 'mdelay()' loop. This is done by setting up a 1 second timer
    693  * with a callback that sets 'mdelay_done' to MD_CALIBRATION_END. Then it
    694  * calls mdelay() with a large milliseond value as initial delay loop counter.
    695  * When the timer triggers, 'mdelay()' will stop and update the delay loop
    696  * counter.
    697  *
    698  * This function needs to be called at device driver init time. Since it uses
    699  * ADD timers, it must be called with interrupts enabled. All this is not very
    700  * precise (we should wait for a clock tick before starting, ...) but we don't
    701  * really need precise timers.
    702  */
    703 void mdelay_cal(void)
    704 {
    705   ULONG timer_handle;
    706 
    707   dprintf("calibrating delay loop... ");
    708 
    709   mdelay_loops_per_ms = 100000;
    710   mdelay_cal_status = MD_CALIBRATION_START;
    711 
    712   ADD_StartTimerMS(&timer_handle, 1000, (PFN) mdelay_timer_callback, 0, 0);
    713   mdelay(999999999);
    714   ADD_CancelTimer(timer_handle);
    715 
    716   dprintf("done (loops per ms = %ld)\n", mdelay_loops_per_ms);
    717 }
    718 
    719 /******************************************************************************
    720  * Wait specified number of milliseconds. This is implemented using a busy
    721  * loop and is only good for delays in the millisecond range but never for more
    722  * than a few milliseconds and only in situations where a proper timer won't do.
    723  * As a rule of thumb, don't call this function and use ADD timers, instead.
    724  *
    725  * NOTES:
    726  *
    727  *  - Timers are problematic on x86 platforms because there's no reliable
    728  *    hardware timer on all architectures and the CPU clock speed may change
    729  *    while executing delay loops (AMD Cool&Quiet and Intel SpeedStep), thus
    730  *    calibration routines won't really be sufficient. But this usually only
    731  *    extends the delay and we don't really need a high precision timer. The
    732  *    exception are things like notebooks that are clocked slower when on
    733  *    battery and which got booted while on battery. Should still be OK,
    734  *    though, because our requirements are not that strict.
    735  *
    736  *  - The code in this function is inefficient by design to make sure it
    737  *    will work with future CPUs which might otherwise be too fast for
    738  *    our loop counters. Part of this design is using volatile variables to
    739  *    force memory operations.
    740  *
    741  *  - Before using this function, call mdelay_calibrate() to determine the
    742  *    number of inner loops required per millisecond.
    743  */
    744 void mdelay(u32 millies)
    745 {
    746   volatile u32 i;
    747   volatile u32 n;
    748 
    749   for (i = 0; i < millies; i++) {
    750     for (n = 0; n < mdelay_loops_per_ms; n++) {
    751       if (mdelay_cal_end()) {
    752         /* this is a calibration run that just ended */
    753         goto complete_calibration;
    754       }
    755     }
    756   }
    757   return;
    758 
    759 complete_calibration:
    760   /* complete calibration cycle */
    761   if (i < 1000) {
    762     /* Initial value for delay loop was too high; interpolate results for
    763      * an assumed initial delay loop divided by 1000.
    764      */
    765     i = i * 1000 + mdelay_loops_per_ms % 1000;
    766     mdelay_loops_per_ms /= 1000;
    767   }
    768   mdelay_loops_per_ms = (mdelay_loops_per_ms * i) / 1000;
    769   mdelay_cal_status = MD_CALIBRATION_DONE;
    770 }
    771 #endif
    772 
    773666/******************************************************************************
    774667 * Setup the millisecond timer. This is implemented by blocking (yielding the
     
    898791}
    899792
    900 #ifdef NOT_USED
    901 /******************************************************************************
    902  * Timer callback handler for 'mdelay_calibrate()'
    903  */
    904 static void _cdecl _far mdelay_timer_callback(ULONG timer_handle,
    905                                               ULONG parm1,
    906                                               ULONG parm2)
    907 {
    908   mdelay_cal_status = MD_CALIBRATION_END;
    909 }
    910 
    911 /******************************************************************************
    912  * Determine whether an mdelay calibration run has just ended. This is in a
    913  * function to prevent overzealous optimizers from removing the whole delay
    914  * loop in mdelay().
    915  */
    916 static int mdelay_cal_end(void)
    917 {
    918   return(mdelay_cal_status == MD_CALIBRATION_END);
    919 }
    920 #endif
  • trunk/src/os2ahci/os2ahci.c

    r163 r165  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
     6 * Portions copyright (c) 2013 David Azarewicz
    67 *
    78 * Authors: Christian Mueller, Markus Thielen
     
    825826      #endif
    826827
    827       if (!TRACE_ACTIVE) build_user_info();
     828      build_user_info();
    828829    }
    829830    iorb_done(iorb);
  • trunk/src/os2ahci/os2ahci.h

    r162 r165  
    175175
    176176/* SMP spinlock compatibility macros for older DDKs using CLI/STI */
    177 #ifndef OS2AHCI_SMP
     177#ifdef SPINLOCK_EMULATION
    178178#define DevHelp_CreateSpinLock(p_sph)  *(p_sph) = 0
    179179#define DevHelp_FreeSpinLock(sph)      0
  • trunk/src/os2ahci/trace.c

    r164 r165  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
     6 * Portions copyright (c) 2013 David Azarewicz
    67 *
    78 * Authors: Christian Mueller, Markus Thielen
     
    188189
    189190  spin_lock(com_lock);
    190   #ifdef NOT_USED
    191   /* block process until data is available in the trace buffer. */
    192   while (ahci_trace_buf.writep == ahci_trace_buf.readp ) { /* buffer is empty */
    193     spin_lock(com_lock);
    194       #ifndef OS2AHCI_SMP
    195       com_lock = 0;
    196       #endif
    197       if (DevHelp_ProcBlock((ULONG) ahci_trace_buf.phys_addr,
    198                             (ULONG) -1, 0) == WAIT_INTERRUPTED) {
    199         /* user pressed Ctrl+C or whatever */
    200         rwrb->NumSectors = 0;
    201         return STDON;
    202       }
    203     spin_lock(com_lock);
    204   }
    205   #endif
    206191
    207192  /* get pointer to caller's buffer */
     
    235220    AD_INFO *ai = ad_infos + a;
    236221
    237     ntprintf("Adapter %d: %d:%d:%d irq=%d addr=0x%lx version=%lx\n", a,
     222    ntprintf("Adapter %d: PCI=%d:%d:%d ID=%x:%x irq=%d addr=0x%lx version=%lx\n", a,
    238223      ai->bus, ai->dev_func>>3, ai->dev_func&7,
     224      ai->pci->vendor, ai->pci->device,
    239225      ai->irq, ai->mmio_phys,
    240226      ai->bios_config[HOST_VERSION / sizeof(u32)]);
Note: See TracChangeset for help on using the changeset viewer.