- Timestamp:
- Jul 31, 2013, 8:08:59 PM (12 years ago)
- Location:
- trunk/src/os2ahci
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/README
r163 r165 17 17 Copyright (c) 2011 thi.guten Software Development 18 18 Copyright (c) 2011-2013 Mensys B.V. 19 Portions copyright (c) 2013 David Azarewicz 19 20 20 21 Authors: Christian Mueller, Markus Thielen … … 81 82 - Add the following line to CONFIG.SYS: 82 83 BASEDEV=OS2AHCI.ADD 84 85 86 Reporting Problems 87 ================== 88 89 If you have problems with this driver, please read the Troubleshooting 90 page at: 91 92 http://svn.ecomstation.nl/ahci/wiki/Troubleshooting 93 94 You can open a ticket at: 95 http://svn.ecomstation.nl/ahci 83 96 84 97 … … 151 164 Option Description 152 165 ------------------------------------------------------------------------------ 153 /s Enable SCSI emulation for ATAPI units (default = o ff)166 /s Enable SCSI emulation for ATAPI units (default = on) 154 167 SCSI emulation is required for tools like cdrecord. 155 168 … … 346 359 Starting with version 1.22, OS2AHCI supports the IOCTL interface required by 347 360 existing 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. 361 the character device named "IBMS506$", they will not work with OS2AHCI unless 362 modified to open the OS2AHCI$ device. Previous versions of OS2AHCI used to 363 register register a duplicate device with the IBMS506$ name, however since 364 that caused so many unacceptable problems, that is no longer done. You must 365 have a SMART utility that opens the OS2AHCI$ device to access the AHCI driver. 366 367 A patched version of the smartctl.exe program is included in the OS2AHCI 368 distribution. This patched version simply has the name "IBMS506$" changed 369 to "OS2AHCI$" and is otherwise identical. This patched program has been 370 renamed to smartahci.exe to distinguish it from the unpatched version. 371 The patched smartahci.exe program is provided AS-IS and is completely 372 UNSUPPORTED. Use of this program is at your own risk. 350 373 351 374 NOTES: 352 353 - If multiple drivers exporting this character device name are loaded at354 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 support356 for OS2AHCI-controlled hard disks is desired, OS2AHCI will have to be357 loaded after DANIS506. It also means that DANIS506 may have to be told358 to ignore type 2 controllers (i.e. controllers supporting both SATA and359 AHCI) using the command line options "/A:x /I".360 375 361 376 - The IOCTL interface for SMART is based on the idea of IDE controllers … … 381 396 Change Log 382 397 ========== 398 399 v.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. 383 404 384 405 v.1.29 12-Jun-2013 - David Azarewicz -
trunk/src/os2ahci/ahci.c
r164 r165 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Portions copyright (c) 2013 David Azarewicz 6 7 * 7 8 * Authors: Christian Mueller, Markus Thielen … … 234 235 235 236 #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 */ 236 240 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && 237 241 ai->pci->vendor == PCI_VENDOR_ID_INTEL) { … … 1343 1347 dprintf("flushing cache on %d.%d.%d\n", ad_no(ai), p, d); 1344 1348 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)); 1348 1350 } 1349 1351 return 0; -
trunk/src/os2ahci/apm.c
r162 r165 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Portions copyright (c) 2013 David Azarewicz 6 7 * 7 8 * Authors: Christian Mueller, Markus Thielen … … 123 124 for (d = 0; d <= ai->ports[p].dev_max; d++) { 124 125 if (ai->ports[p].devs[d].present) { 125 126 126 ahci_flush_cache(ai, p, d); 127 } 127 128 } 128 129 } … … 241 242 242 243 #if 0 244 /* cannot flush caches this way */ 243 245 ahci_start_port(ai, p, 0); 244 246 … … 246 248 for (d = 0; d <= ai->ports[p].dev_max; d++) { 247 249 if (ai->ports[p].devs[d].present) { 248 249 250 ahci_flush_cache(ai, p, d); 251 } 250 252 } 251 253 #endif -
trunk/src/os2ahci/ata.c
r162 r165 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Portions copyright (c) 2013 David Azarewicz 6 7 * 7 8 * Authors: Christian Mueller, Markus Thielen -
trunk/src/os2ahci/init.asm
r164 r165 36 36 37 37 DEVHDR SEGMENT WORD PUBLIC 'DATA' 38 _dev_hdr dd _next_hdr; next device header38 _dev_hdr dd -1 ; next device header 39 39 dw DEVLEV_3 + DEV_CHAR_DEV + DEV_IDC ; flags for ADD drivers 40 40 dw OFFSET _asm_strat ; strategy routine … … 44 44 dd DEV_IOCTL2 + DEV_ADAPTER_DD + DEV_INITCOMPLETE + DEV_SAVERESTORE ; ADD flags 45 45 dw 0 46 47 if 148 ; This is here to support old SMART tools which only look for IBMS506$. This is a49 ; really bad thing to do as it will cause problems in the future. The SMART tools50 ; should be fixed to be able to open OS2AHCI$ and this header should be removed.51 _next_hdr dd -1 ; no headers after this one52 dw DEVLEV_3 + DEV_CHAR_DEV ; flags for ADD drivers53 dw OFFSET _asm_strat ; strategy routine54 dw 0 ; IDC entry point55 db "IBMS506$" ; name of character device56 dq 0 ; 8 reserved bytes57 dd 058 dw 059 else60 _next_hdr equ -161 endif62 46 63 47 DEVHDR ENDS -
trunk/src/os2ahci/ioctl.c
r129 r165 207 207 ic->iorb.iorbh.UnitHandle = iorb_unit(a, p, d); 208 208 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; 211 210 ic->iorb.iorbh.RequestControl = IORB_ASYNC_POST; 212 211 ic->iorb.iorbh.Timeout = req->timeout; … … 234 233 add_entry(&ic->iorb.iorbh); 235 234 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. */ 248 236 spin_lock(drv_lock); 249 237 while (!(ic->iorb.iorbh.Status & IORB_DONE)) { 250 251 # ifndef OS2AHCI_SMP252 drv_lock = 0;253 # endif254 255 238 DevHelp_ProcBlock((ULONG) (void _far *) &ic->iorb.iorbh, 30000, 1); 256 spin_lock(drv_lock);257 239 } 258 240 spin_unlock(drv_lock); … … 355 337 USHORT d; 356 338 UCHAR unit; 357 339 358 340 /* verify addressability of parm buffer (DSKSP_CommandParameters) */ 359 341 if (DevHelp_VerifyAccess((SEL) ((ULONG) cp >> 16), … … 499 481 500 482 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); 504 484 break; 505 485 506 486 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); 509 488 break; 510 489 … … 547 526 * Perform SMART request. The code has been more or less copied from DANIS506. 548 527 */ 549 static USHORT do_smart(BYTE unit, BYTE sub_func, BYTE cnt, BYTE lba_l, 550 void _far *buf) 528 static USHORT do_smart(BYTE unit, BYTE sub_func, BYTE cnt, BYTE lba_l, void _far *buf) 551 529 { 552 530 OS2AHCI_PASSTHROUGH pt; … … 584 562 } 585 563 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) { 588 565 589 566 /* ATA_SMART_STATUS doesn't transfer anything but instead relies on the -
trunk/src/os2ahci/libc.c
r160 r165 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Portions copyright (c) 2013 David Azarewicz 6 7 * 7 8 * Authors: Christian Mueller, Markus Thielen … … 38 39 #define HEAP_UNIT_CNT (HEAP_SIZE / HEAP_UNIT) 39 40 40 /* ------------------------ typedefs and structures ------------------------ */41 42 #ifdef NOT_USED43 /* 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 #endif55 56 41 /* -------------------------- function prototypes -------------------------- */ 57 42 58 static void long_to_asc (long val, 59 char _far *buf, 60 int base, 61 int zero, int flen); 43 static void long_to_asc(long val, char _far *buf, int base, int zero, int flen); 62 44 63 45 /* ------------------------ global/static variables ------------------------ */ … … 94 76 }; 95 77 96 #ifdef NOT_USED97 /* 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 #endif101 102 78 /* very small heap for dynamic memory management */ 103 79 static u8 heap_buf[HEAP_SIZE]; … … 688 664 } 689 665 690 #ifdef NOT_USED691 /******************************************************************************692 * Calibrate 'mdelay()' loop. This is done by setting up a 1 second timer693 * with a callback that sets 'mdelay_done' to MD_CALIBRATION_END. Then it694 * calls mdelay() with a large milliseond value as initial delay loop counter.695 * When the timer triggers, 'mdelay()' will stop and update the delay loop696 * counter.697 *698 * This function needs to be called at device driver init time. Since it uses699 * ADD timers, it must be called with interrupts enabled. All this is not very700 * precise (we should wait for a clock tick before starting, ...) but we don't701 * 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 busy721 * loop and is only good for delays in the millisecond range but never for more722 * 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 reliable728 * hardware timer on all architectures and the CPU clock speed may change729 * while executing delay loops (AMD Cool&Quiet and Intel SpeedStep), thus730 * calibration routines won't really be sufficient. But this usually only731 * extends the delay and we don't really need a high precision timer. The732 * exception are things like notebooks that are clocked slower when on733 * 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 it737 * will work with future CPUs which might otherwise be too fast for738 * our loop counters. Part of this design is using volatile variables to739 * force memory operations.740 *741 * - Before using this function, call mdelay_calibrate() to determine the742 * 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 for763 * 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 #endif772 773 666 /****************************************************************************** 774 667 * Setup the millisecond timer. This is implemented by blocking (yielding the … … 898 791 } 899 792 900 #ifdef NOT_USED901 /******************************************************************************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 a913 * function to prevent overzealous optimizers from removing the whole delay914 * 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 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Portions copyright (c) 2013 David Azarewicz 6 7 * 7 8 * Authors: Christian Mueller, Markus Thielen … … 825 826 #endif 826 827 827 if (!TRACE_ACTIVE)build_user_info();828 build_user_info(); 828 829 } 829 830 iorb_done(iorb); -
trunk/src/os2ahci/os2ahci.h
r162 r165 175 175 176 176 /* SMP spinlock compatibility macros for older DDKs using CLI/STI */ 177 #if ndef OS2AHCI_SMP177 #ifdef SPINLOCK_EMULATION 178 178 #define DevHelp_CreateSpinLock(p_sph) *(p_sph) = 0 179 179 #define DevHelp_FreeSpinLock(sph) 0 -
trunk/src/os2ahci/trace.c
r164 r165 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Portions copyright (c) 2013 David Azarewicz 6 7 * 7 8 * Authors: Christian Mueller, Markus Thielen … … 188 189 189 190 spin_lock(com_lock); 190 #ifdef NOT_USED191 /* 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_SMP195 com_lock = 0;196 #endif197 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 #endif206 191 207 192 /* get pointer to caller's buffer */ … … 235 220 AD_INFO *ai = ad_infos + a; 236 221 237 ntprintf("Adapter %d: %d:%d:%dirq=%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, 238 223 ai->bus, ai->dev_func>>3, ai->dev_func&7, 224 ai->pci->vendor, ai->pci->device, 239 225 ai->irq, ai->mmio_phys, 240 226 ai->bios_config[HOST_VERSION / sizeof(u32)]);
Note:
See TracChangeset
for help on using the changeset viewer.