Ignore:
Timestamp:
May 30, 2009, 4:49:26 AM (10 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
4.10, 4.11, master
Children:
46a67b19
Parents:
b30c618
Message:

2009-05-30 Chris Johns <chrisj@…>

  • ide/ide.c: Add initialisation code to reset the IDE devices and to probe them and display their model numbers. Also add code to display the probing to aid bring up new hardware.
  • ide/idecfg.c: Add the --ide-show command to show probing type accessing when finding devices on the configured IDE buses.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/pc386/ide/ide.c

    rb30c618 r57be444  
    3030#include <libchip/ide_ctrl_io.h>
    3131
     32bool pc386_ide_show;
     33
    3234/* #define DEBUG_OUT */
    3335
    34 /* Not using this currently */
    35 #if 0
    3636static bool pc386_ide_status_busy (uint32_t port,
    3737                                   uint32_t timeout,
     
    5454  return false;
    5555}
    56 #endif
    5756
    5857static bool pc386_ide_status_data_ready (uint32_t port,
     
    105104}
    106105
     106static void wait(volatile uint32_t loops)
     107{
     108  while (loops)
     109    loops--;
     110}
     111
    107112/*=========================================================================*\
    108113| Function:                                                                 |
     
    123128\*=========================================================================*/
    124129{
     130  uint32_t port = IDE_Controller_Table[minor].port1;
     131  uint8_t  dev = 0;
     132
     133  if (pc386_ide_show)
     134    printk("IDE%d: port base: %04x\n", minor, port);
     135
     136  outport_byte(port+IDE_REGISTER_DEVICE_HEAD,
     137               (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | 0xE0);
     138  wait(10000);
     139  outport_byte(port+IDE_REGISTER_DEVICE_CONTROL,
     140               IDE_REGISTER_DEVICE_CONTROL_SRST | IDE_REGISTER_DEVICE_CONTROL_nIEN);
     141  wait(10000);
     142  outport_byte(port+IDE_REGISTER_DEVICE_CONTROL,
     143               IDE_REGISTER_DEVICE_CONTROL_nIEN);
     144  wait(10000);
     145
     146  for (dev = 0; dev < 2; dev++)
     147  {
     148    uint32_t    byte;
     149    uint8_t     status;
     150    uint8_t     error;
     151    uint8_t     cyllsb;
     152    uint8_t     cylmsb;
     153    const char* label = dev ? " slave" : "master";
     154    char        model_number[41];
     155    char*       p = &model_number[0];
     156
     157    memset(model_number, 0, sizeof(model_number));
     158
     159    outport_byte(port+IDE_REGISTER_DEVICE_HEAD,
     160                 (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | 0xE0);
     161    /*
     162    outport_byte(port+IDE_REGISTER_SECTOR_NUMBER,
     163                 (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | IDE_REGISTER_LBA3_L);
     164    */
     165
     166    outport_byte(port+IDE_REGISTER_COMMAND, 0x00);
     167   
     168    if (!pc386_ide_status_busy (port, 6000, &status))
     169      continue;
     170   
     171    inport_byte(port+IDE_REGISTER_STATUS,        status);
     172    inport_byte(port+IDE_REGISTER_ERROR,         error);
     173    inport_byte(port+IDE_REGISTER_CYLINDER_LOW,  cyllsb);
     174    inport_byte(port+IDE_REGISTER_CYLINDER_HIGH, cylmsb);
     175
     176    if (pc386_ide_show)
     177    {
     178      printk("IDE%d:%s: status=%02x\n", minor, label, status);
     179      printk("IDE%d:%s: error=%02x\n", minor, label, error);
     180      printk("IDE%d:%s: cylinder-low=%02x\n", minor, label, cyllsb);
     181      printk("IDE%d:%s: cylinder-high=%02x\n", minor, label, cylmsb);
     182    }
     183
     184#if 0
     185    /*
     186     * Filter based on the cylinder values and the status.
     187     * Taken from grub's ata.c.
     188     */
     189    if (cyllsb != 0x14 || cylmsb != 0xeb)
     190      if (status == 0 || (cyllsb != 0 && cylmsb != 0 &&
     191                          cyllsb != 0xc3 && cylmsb != 0x3c))
     192      {
     193        if (pc386_ide_show)
     194          printk("IDE%d:%s: bad device\n", minor, label);
     195      }
     196#endif
     197   
     198    outport_byte(port+IDE_REGISTER_COMMAND, 0xec);
     199
     200    if (!pc386_ide_status_busy (port, 6000, &status))
     201    {
     202      if (pc386_ide_show)
     203        printk("IDE%d:%s: device busy: %02x\n", minor, label, status);
     204      continue;
     205    }
     206   
     207    byte = 0;
     208    while (byte < 512)
     209    {
     210      uint16_t word;
     211      bool     data_ready;
     212
     213      if (pc386_ide_show && ((byte % 16) == 0))
     214        printk("\n %04x : ", byte);
     215     
     216      data_ready = pc386_ide_status_data_ready (port, 100, &status);
     217
     218      if (status & IDE_REGISTER_STATUS_ERR)
     219      {
     220        inport_byte(port+IDE_REGISTER_ERROR, error);
     221        if (error != 4)
     222        {
     223          if (pc386_ide_show)
     224            printk("IDE%d:%s: error=%04x\n", minor, label, error);
     225          break;
     226        }
     227        /*
     228         * The device is an ATAPI device.
     229         */
     230        outport_byte(port+IDE_REGISTER_COMMAND, 0xa1);
     231        continue;
     232      }
     233
     234      if (!data_ready)
     235        break;
     236     
     237      inport_word(port+IDE_REGISTER_DATA, word);
     238
     239      if (pc386_ide_show)
     240        printk ("%04x ", word);
     241
     242      if (byte >= 54 && byte < (54 + 40))
     243      {
     244        *p = word >> 8;
     245        p++;
     246        *p = word;
     247        p++;
     248      }
     249       
     250      byte += 2;
     251    }
     252   
     253    if (pc386_ide_show)
     254      printk("\nbytes read = %d\n", byte);
     255
     256    if (p != &model_number[0])
     257      printk("IDE%d:%s: %s\n", minor, label, model_number);
     258  }
     259 
    125260  /*
    126261   * FIXME: enable interrupts, if needed
Note: See TracChangeset for help on using the changeset viewer.