Changeset 157


Ignore:
Timestamp:
May 8, 2013, 5:10:33 PM (12 years ago)
Author:
David Azarewicz
Message:

Fixed up timer functions

Location:
trunk/src/os2ahci
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/os2ahci/Makefile

    r156 r157  
    9797# Main dependencies
    9898
    99 LIBS = addcalls doscalls rmcalls apmcalls
     99LIBS = addcalls doscalls rmcalls apmcalls os2286p.lib
    100100
    101101SRCS = init.asm math.asm libc.c os2ahci.c pci.c ahci.c ata.c atapi.c &
  • trunk/src/os2ahci/README

    r156 r157  
    405405  Debug output improvements.
    406406  Added /b switch for setting debug baud rate.
     407  Fixed up time delay functions
    407408
    408409v.1.26 26-Mar-2013 - David Azarewicz
  • trunk/src/os2ahci/ahci.c

    r156 r157  
    331331
    332332        /* spec says "leave reset bit on for at least 1ms"; make it 2ms */
    333         mdelay(2);
     333        udelay(2000);
    334334
    335335        writel(port_mmio + PORT_SCR_CTL, tmp);
     
    341341     * least hard disks complete the reset within a few milliseonds)
    342342     */
    343     mdelay(20);
     343    msleep(20);
    344344  }
    345345
     
    448448      return(0);
    449449    }
    450     mdelay(10);
     450    msleep(10);
    451451  }
    452452
     
    459459{
    460460    u32 tmp;
    461     int timeout = 1000;
     461    TIMER Timer;
    462462
    463463    dprintf("controller reset starting on adapter %d\n", ad_no(ai));
     
    480480     * the hardware should be considered fried.
    481481     */
    482     while (((tmp = readl(ai->mmio + HOST_CTL)) & HOST_RESET) == HOST_RESET) {
    483         mdelay(10);
    484         timeout -= 10;
    485         if (timeout <= 0) {
    486           dprintf("controller reset failed (0x%lx)\n", tmp);
    487           return(-1);
    488         }
     482    timer_init(&Timer, 1000);
     483    while (((tmp = readl(ai->mmio + HOST_CTL)) & HOST_RESET) != 0) {
     484      if (timer_check_and_block(&Timer)) {
     485        dprintf("controller reset failed (0x%lx)\n", tmp);
     486        return(-1);
     487      }
    489488    }
    490489
     
    497496    ahci_restore_initial_config(ai);
    498497
    499         if (ai->pci->vendor == PCI_VENDOR_ID_INTEL) {
    500                 u32 tmp16 = 0;
    501 
    502         ddprintf("ahci_reset_controller: intel detected\n");
    503                 /* configure PCS */
    504                 pci_read_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), &tmp16);
    505                 if ((tmp16 & ai->port_map) != ai->port_map) {
    506             ddprintf("ahci_reset_controller: updating PCS %x/%x\n", (u16)tmp16, ai->port_map);
    507                         tmp16 |= ai->port_map;
    508                         pci_write_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), tmp16);
    509                 }
    510         }
     498    if (ai->pci->vendor == PCI_VENDOR_ID_INTEL) {
     499      u32 tmp16 = 0;
     500
     501      ddprintf("ahci_reset_controller: intel detected\n");
     502      /* configure PCS */
     503      pci_read_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), &tmp16);
     504      if ((tmp16 & ai->port_map) != ai->port_map) {
     505        ddprintf("ahci_reset_controller: updating PCS %x/%x\n", (u16)tmp16, ai->port_map);
     506        tmp16 |= ai->port_map;
     507        pci_write_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), tmp16);
     508      }
     509    }
    511510
    512511    return 0;
     
    538537  int p;
    539538  int i;
     539  TIMER Timer;
    540540
    541541  if ((id_buf = malloc(ATA_ID_WORDS * sizeof(u16))) == NULL) {
     
    561561      ddprintf("ahci_scan_ports: Wait till not busy on port %d\n", p);
    562562      /* wait until all active commands have completed on this port */
     563      timer_init(&Timer, 250);
    563564      while (ahci_port_busy(ai, p)) {
    564         msleep(250);
     565        if (timer_check_and_block(&Timer)) break;
    565566      }
    566567
     
    718719  u8 _far *port_mmio = port_base(ai, p);
    719720  u32 tmp;
    720   int timeout;
     721  TIMER Timer;
    721722
    722723  dprintf("ahci_reset_port: resetting port %d.%d\n", ad_no(ai), p);
     
    762763
    763764  /* spec says "leave reset bit on for at least 1ms"; make it 2ms */
    764   mdelay(2);
     765  udelay(2000);
    765766
    766767  writel(port_mmio + PORT_SCR_CTL, tmp);
     
    768769
    769770  /* wait for communication to be re-established after port reset */
    770   timeout = 5000;
     771  dprintf("Wait for communication...\n");
     772  timer_init(&Timer, 500);
    771773  while (((tmp = readl(port_mmio + PORT_SCR_STAT)) & 3) != 3) {
    772     mdelay(10);
    773     timeout -= 10;
    774     if (timeout <= 0) {
    775       dprintf("no device present after resetting port #%d "
    776               "(PORT_SCR_STAT = 0x%lx)\n", p, tmp);
     774    if (timer_check_and_block(&Timer)) {
     775      dprintf("no device present after resetting port #%d (PORT_SCR_STAT = 0x%lx)\n", p, tmp);
    777776      return(-1);
    778777    }
     
    788787
    789788  /* wait for device to be ready ((PxTFD & (BSY | DRQ | ERR)) == 0) */
    790   timeout = 5000;
     789  timer_init(&Timer, 1000);
    791790  while (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) {
    792     mdelay(10);
    793     timeout -= 10;
    794     if (timeout <= 0) {
    795       dprintf("device not ready on port #%d "
    796               "(PORT_TFDATA = 0x%lx)\n", p, tmp);
     791    if (timer_check_and_block(&Timer)) {
     792      dprintf("device not ready on port #%d (PORT_TFDATA = 0x%lx)\n", p, tmp);
    797793      ahci_stop_port(ai, p);
    798794      return(-1);
    799795    }
    800796  }
    801   ddprintf("ahci_reset_port: PORT_TFDATA   = 0x%lx\n", readl(port_mmio + PORT_TFDATA));
     797  ddprintf("ahci_reset_port: PORT_TFDATA = 0x%lx\n", readl(port_mmio + PORT_TFDATA));
    802798
    803799  return(0);
     
    949945{
    950946  u8 _far *port_mmio = port_base(ai, p);
    951   int timeout = 1000;
     947  TIMER Timer;
    952948  u32 tmp;
     949  int status;
    953950
    954951  /* disable FIS reception */
     
    958955
    959956  /* wait for completion, spec says 500ms, give it 1000ms */
    960   while (timeout > 0 && (readl(port_mmio + PORT_CMD) & PORT_CMD_FIS_ON)) {
    961     mdelay(10);
    962     timeout -= 10;
    963   }
    964 
    965   return((timeout <= 0) ? -1 : 0);
     957  status = 0;
     958  timer_init(&Timer, 1000);
     959  while (readl(port_mmio + PORT_CMD) & PORT_CMD_FIS_ON) {
     960    status = timer_check_and_block(&Timer);
     961    if (status) break;
     962  }
     963
     964  return(status ? -1 : 0);
    966965}
    967966
     
    976975{
    977976  u8 _far *port_mmio = port_base(ai, p);
    978   int timeout = 500;
     977  TIMER Timer;
     978  int status;
    979979  u32 tmp;
    980980
     
    991991
    992992  /* wait for engine to stop. This could be as long as 500 msec */
    993   while (timeout > 0 && (readl(port_mmio + PORT_CMD) & PORT_CMD_LIST_ON)) {
    994     mdelay(10);
    995     timeout -= 10;
    996   }
    997 
    998   return((timeout <= 0) ? -1 : 0);
     993  status = 0;
     994  timer_init(&Timer, 500);
     995  while (readl(port_mmio + PORT_CMD) & PORT_CMD_LIST_ON) {
     996    status = timer_check_and_block(&Timer);
     997    if (status) break;
     998  }
     999
     1000  return(status ? -1 : 0);
    9991001}
    10001002
     
    11621164  int p = iorb_unit_port(iorb);
    11631165  u8 _far *port_mmio = port_base(ai, p);
     1166  TIMER Timer;
     1167  int rc;
    11641168
    11651169  /* enable AHCI mode */
     
    12041208    ddprintf("executing polled cmd on slot 0...");
    12051209    writel(port_mmio + PORT_CMD_ISSUE, 1);
    1206     timeout /= 10;
    1207     while (timeout > 0 && (readl(port_mmio + PORT_CMD_ISSUE) & 1)) {
    1208       mdelay(10);
    1209       timeout--;
    1210     }
    1211     ddprintf(" done (time left = %ld)\n", timeout * 10);
    1212 
    1213     if (timeout == 0) {
     1210    timer_init(&Timer, timeout);
     1211    while (readl(port_mmio + PORT_CMD_ISSUE) & 1) {
     1212      rc = timer_check_and_block(&Timer);
     1213      if (rc) break;
     1214    }
     1215
     1216    if (rc) {
    12141217      dprintf("timeout for IORB %Fp\n", iorb);
    12151218      iorb_seterr(iorb, IOERR_ADAPTER_TIMEOUT);
    1216 
    12171219    } else if (readl(port_mmio + PORT_SCR_ERR) != 0 ||
    12181220               readl(port_mmio + PORT_TFDATA) & 0x89) {
     
    12201222      iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC);
    12211223      ahci_reset_port(ai, iorb_unit_port(iorb), 0);
    1222 
    12231224    } else {
    12241225      /* successfully executed command */
     
    12591260  u32 tmp;
    12601261  int rc;
     1262  TIMER Timer;
    12611263
    12621264  /* verify that command slot 0 is idle */
     
    12771279
    12781280  /* wait until command has completed */
    1279   while (timeout > 0 && (readl(port_mmio + PORT_CMD_ISSUE) & 1)) {
    1280     mdelay(10);
    1281     timeout -= 10;
    1282   }
    1283   ddprintf(" done (time left = %d)\n", timeout);
     1281  timer_init(&Timer, timeout);
     1282  rc = 0;
     1283  while (readl(port_mmio + PORT_CMD_ISSUE) & 1) {
     1284    rc = timer_check_and_block(&Timer);
     1285    if (rc) break;
     1286  }
    12841287
    12851288  /* check error condition */
    12861289  if ((tmp = readl(port_mmio + PORT_SCR_ERR)) != 0) {
    12871290    dprintf("SERR = 0x%08lx\n", tmp);
    1288     timeout = 0;
     1291    rc = 1;
    12891292  }
    12901293  if (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) {
    12911294    dprintf("TFDATA = 0x%08lx\n", tmp);
    1292     timeout = 0;
    1293   }
    1294 
    1295   if (timeout <= 0) {
     1295    rc = 1;
     1296  }
     1297
     1298  if (rc) {
    12961299    ahci_reset_port(ai, p, 0);
    12971300    return(-1);
  • trunk/src/os2ahci/apm.c

    r153 r157  
    104104  int p;
    105105  int d;
     106  TIMER Timer;
    106107
    107108  if (suspended) return;
     
    115116    for (p = 0; p <= ai->port_max; p++) {
    116117      /* wait until all active commands have completed on this port */
     118      timer_init(&Timer, 250);
    117119      while (ahci_port_busy(ai, p)) {
    118         msleep(250);
     120        if (timer_check_and_block(&Timer)) break;
    119121      }
    120122
  • trunk/src/os2ahci/ata.c

    r156 r157  
    443443int check_lvm(IORBH _far *iorb, ULONG sector)
    444444{
    445   ADD_WORKSPACE _far *aws = add_workspace(iorb);
     445  DLA_Table_Sector *pDLA = (DLA_Table_Sector*)add_workspace(iorb)->buf;
    446446  AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb);
    447447  GEOMETRY _far *geometry = ((IORB_GEOMETRY _far *) iorb)->pGeometry;
    448   PDLA_Table_Sector pDLA;
    449448  int p = iorb_unit_port(iorb);
    450449  int rc;
     
    453452         AP_SECTOR_28, (u32) sector-1,
    454453         AP_COUNT, (u16) 1,
    455          AP_VADDR, (void _far *) aws->buf, 512,
     454         AP_VADDR, (void _far *) pDLA, 512,
    456455         AP_DEVICE, 0x40,
    457456         AP_END);
    458457  if (rc) return 0;
    459458
    460   pDLA = (PDLA_Table_Sector)aws->buf;
    461459  ddphex(pDLA, sizeof(DLA_Table_Sector), "DLA sector %d:\n", sector-1);
    462460
    463461  if ((pDLA->DLA_Signature1 == DLA_TABLE_SIGNATURE1) && (pDLA->DLA_Signature2 == DLA_TABLE_SIGNATURE2)) {
    464     ddprintf("is_lvm_geometry found at sector %d\n", sector);
     462    ddprintf("is_lvm_geometry found at sector %d\n", sector-1);
    465463    geometry->TotalCylinders = pDLA->Cylinders;
    466464    geometry->NumHeads = pDLA->Heads_Per_Cylinder;
    467465    geometry->SectorsPerTrack = pDLA->Sectors_Per_Track;
     466    geometry->TotalSectors = pDLA->Cylinders * pDLA->Heads_Per_Cylinder * pDLA->Sectors_Per_Track;
    468467    return 1;
    469468  }
     
    605604  if (is_lvm_geometry(iorb)) Method = "LVM";
    606605
    607   if (debug) {
    608     printf("Drive geometry: %d cylinders, %d heads, %d sectors per track (%ldMB) (%s)\n",
    609         (u16) geometry->TotalCylinders, (u16) geometry->NumHeads, (u16) geometry->SectorsPerTrack,
    610         (u32) (geometry->TotalSectors / 2048), Method);
    611   }
     606  dprintf("Drive geometry: %ld cylinders, %d heads, %d sectors per track (%ldMB) (%s)\n",
     607      (u32) geometry->TotalCylinders, (u16) geometry->NumHeads, (u16) geometry->SectorsPerTrack,
     608      (u32) (geometry->TotalSectors / 2048), Method);
    612609
    613610  /* tell interrupt handler that this IORB is complete */
  • trunk/src/os2ahci/init.asm

    r155 r157  
    2929                PUBLIC  _end_of_data         ; end of all data (label)
    3030                PUBLIC  _end_of_code         ; end of all code (label)
     31                PUBLIC  _udelay              ; spin for microseconds
     32                EXTRN   DOSIODELAYCNT:ABS
    3133
    3234; ----------------------------------------------------------------------------
     
    198200                .386
    199201
     202; void udelay(u16 microseconds);
     203_udelay         PROC NEAR
     204                enter   0, 0
     205                mov     cx, word ptr [bp+4]
     206@OuterLoop:
     207                mov     ax, DOSIODELAYCNT
     208                shl     ax, 1
     209@InnerLoop:
     210                dec     ax
     211                jnz     short @InnerLoop               
     212                loop    @OuterLoop
     213
     214                leave
     215                ret
     216_udelay          ENDP
    200217
    201218; Read long value from MMIO address; need to do this here to get real
  • trunk/src/os2ahci/libc.c

    r156 r157  
    4040/* ------------------------ typedefs and structures ------------------------ */
    4141
     42#ifdef NOT_USED
    4243/* mdelay() calibration status */
    4344typedef enum {
     
    4748  MD_CALIBRATION_DONE                 /* calibration complete */
    4849} MDCAL;
     50static void _cdecl _far mdelay_timer_callback  (ULONG timer_handle,
     51                                                ULONG parm1,
     52                                                ULONG parm2);
     53static int              mdelay_cal_end         (void);
     54#endif
    4955
    5056/* -------------------------- function prototypes -------------------------- */
     
    5460                                                int base,
    5561                                                int zero, int flen);
    56 static void _cdecl _far mdelay_timer_callback  (ULONG timer_handle,
    57                                                 ULONG parm1,
    58                                                 ULONG parm2);
    59 static int              mdelay_cal_end         (void);
    6062
    6163/* ------------------------ global/static variables ------------------------ */
     
    9294};
    9395
     96#ifdef NOT_USED
    9497/* delay loop calibration data */
    9598volatile MDCAL mdelay_cal_status = 0;     /* delay loop calibration status */
    9699volatile u32   mdelay_loops_per_ms = 0;   /* delay loop counter */
     100#endif
    97101
    98102/* very small heap for dynamic memory management */
     
    684688}
    685689
     690#ifdef NOT_USED
    686691/******************************************************************************
    687692 * Calibrate 'mdelay()' loop. This is done by setting up a 1 second timer
     
    764769  mdelay_cal_status = MD_CALIBRATION_DONE;
    765770}
    766 
    767 /******************************************************************************
    768  * Sleep specified number of milliseonds. This is implemented by yielding the
    769  * CPU until the system timer value indicates we're done. This function can
     771#endif
     772
     773/******************************************************************************
     774 * Setup the millisecond timer. This is implemented by blocking (yielding the
     775 * CPU) until the system timer value indicates we're done. This function can
    770776 * only be called at task time, or from a context hook.
    771777 *
     
    773779 *       can lead to intervals up to 55ms (18.2 timer interrupts per second).
    774780 */
     781void timer_init(TIMER far *pTimer, u32 Milliseconds)
     782{
     783  pTimer->Start = gis->msecs;
     784  pTimer->End = pTimer->Start + Milliseconds;
     785}
     786
     787/******************************************************************************
     788 * Check the millisecond timer. Block if not done.
     789 */
     790int timer_check_and_block(TIMER far *pTimer)
     791{
     792  u32 current;
     793
     794  current = gis->msecs;
     795  if (pTimer->Start < pTimer->End) {
     796    if ((current >= pTimer->End) || (current < pTimer->Start)) return 1;
     797  } else {
     798    if ((current >= pTimer->End) && (current < pTimer->Start)) return 1;
     799  }
     800  DevHelp_ProcBlock((ULONG)&timer_check_and_block, 1, WAIT_IS_INTERRUPTABLE);
     801  return 0;
     802}
     803
     804/******************************************************************************
     805 * Sleep specified number of milliseonds.
     806 */
    775807void msleep(u32 millies)
    776808{
    777   ULONG start;
    778   ULONG end;
    779   ULONG event_id;
    780 
    781   if (gis == NULL) {
    782     /* no global info segment; use mdelay() */
    783     mdelay(millies);
    784     return;
    785   }
    786 
    787   start = gis->msecs;
    788   end = start + millies;
    789   event_id = (ULONG)&msleep;
    790 
    791   if (end < start) {
    792     /* wrap-around; wait until 'msecs' has wrapped, too */
    793     while (gis->msecs >= start) {
    794       DevHelp_ProcBlock(event_id, 1, WAIT_IS_INTERRUPTABLE);
    795     }
    796   }
    797 
    798   while (gis->msecs <= end) {
    799     DevHelp_ProcBlock(event_id, 1, WAIT_IS_INTERRUPTABLE);
    800   }
     809  TIMER Timer;
     810
     811  timer_init(&Timer, millies);
     812  while (!timer_check_and_block(&Timer));
    801813}
    802814
     
    885897}
    886898
     899#ifdef NOT_USED
    887900/******************************************************************************
    888901 * Timer callback handler for 'mdelay_calibrate()'
     
    904917  return(mdelay_cal_status == MD_CALIBRATION_END);
    905918}
    906 
     919#endif
  • trunk/src/os2ahci/os2ahci.c

    r156 r157  
    417417    /* initialization succeeded and we found at least one AHCI adapter */
    418418    ADD_InitTimer(timer_pool, sizeof(timer_pool));
    419     mdelay_cal();
     419    //NOT_USED mdelay_cal();
    420420
    421421    if (DevHelp_RegisterDeviceClass(drv_name, (PFN) add_entry, 0, 1, &add_handle)) {
     
    14211421void lock_adapter(AD_INFO *ai)
    14221422{
     1423  TIMER Timer;
     1424
    14231425  spin_lock(drv_lock);
    14241426  while (ai->busy) {
    14251427    spin_unlock(drv_lock);
    1426     msleep(250);
     1428    timer_init(&Timer, 250);
     1429    while (!timer_check_and_block(&Timer));
    14271430    spin_lock(drv_lock);
    14281431  }
  • trunk/src/os2ahci/os2ahci.h

    r156 r157  
    283283
    284284typedef unsigned int     size_t;
     285
     286typedef struct {
     287  u32 Start;
     288  u32 End;
     289} TIMER;
    285290
    286291/* PCI device information structure; this is used both for scanning and for
     
    427432extern void _cdecl _far engine_hook   (void);
    428433extern void _cdecl _far asm_krnl_exit (void);
     434extern void _cdecl udelay             (u16 microseconds);
    429435
    430436/* os2ahci.c */
     
    519525extern void        free          (void *ptr);
    520526extern ULONG       virt_to_phys  (void _far *ptr);
    521 extern void        mdelay_cal    (void);
    522 extern void        mdelay        (u32 millies);
     527//NOT_USED extern void        mdelay_cal    (void);
     528//NOT_USED extern void        mdelay        (u32 millies);
    523529extern void        msleep        (u32 millies);
    524530extern void        panic         (char *msg);
    525531extern int         disable       (void);
    526532extern void        enable        (void);
     533extern void timer_init(TIMER far *pTimer, u32 Milliseconds);
     534extern int timer_check_and_block(TIMER far *pTimer);
    527535
    528536/* trace.c */
Note: See TracChangeset for help on using the changeset viewer.