OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [orpmon/] [drivers/] [ata.c] - Diff between revs 921 and 1020

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 921 Rev 1020
Line 65... Line 65...
  unsigned short dev_pio;
  unsigned short dev_pio;
  unsigned long sectors;
  unsigned long sectors;
 
 
  char txt[41];
  char txt[41];
 
 
 
printf( "Checking device-id\n" );
  /* check device-id (MINOR number)                                   */
  /* check device-id (MINOR number)                                   */
  if ( (device = DEVICE(inode)) > 1 )
  if ( (device = DEVICE(inode)) > 1 )
      return EOPENIDEV;
      return EOPENIDEV;
 
 
 
printf( "Searching for hostcontroller: " );
  /* get atahost id                                                   */
  /* get atahost id                                                   */
  atahost = ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_HOST, 0);
  atahost = ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_HOST, 0);
  if (atahost)
  if (atahost)
  {
  {
    printf( "OCIDEC-%1d, revision 0x%02X found at 0x%08lX.\n", TYPE(atahost), REV(atahost), BASE(inode) );
    printf( "OCIDEC-%1d, revision 0x%02X found at 0x%08lX.\n", TYPE(atahost), REV(atahost), BASE(inode) );
Line 85... Line 87...
 
 
 
 
  /* check if the host has been opened already                        */
  /* check if the host has been opened already                        */
  if (!usage[device]++)
  if (!usage[device]++)
  {
  {
 
printf( "Opening device for the first time\n" );
      /* no, take device out of reset                                 */
      /* no, take device out of reset                                 */
      ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_HW_RST);
      ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_HW_RST);
 
      ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_SW_RST);
 
 
      /* program PIO timing registers (set to PIO mode 0)             */
      /* program PIO timing registers (set to PIO mode 0)             */
      ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO0);
      ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO0);
 
 
 
      /* enable host controller (for old OCIDEC cores)                */
 
      ata_ioctl(inode, filp, ATA_IOCTL_ENABLE_HOST, 0);
  }
  }
 
 
  /* select requested device                                          */
  /* select requested device                                          */
  ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, 0);
  ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, 0);
 
 
 
printf( "Executing IdentifyDevice command\n" );
  /* identify requested ata-devices                                   */
  /* identify requested ata-devices                                   */
  ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_DEVICE, (unsigned long) buf);
  ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, IDENTIFY_DEVICE);
 
 
 
  /* read block from ata-device                                 */
 
  buf[0] = 256;
 
  ata_ioctl(inode, filp, ATA_IOCTL_READ, (unsigned long) buf);
 
 
  /* check if a valid device was found                                */
  /* check if a valid device was found                                */
  /* bit 15 in identify_device word0 must be '0',
  /* bit 15 in identify_device word0 must be '0',
     or be equal to 0x848a (CFA feature set)                          */
     or be equal to 0x848a (CFA feature set)                          */
  if ( (buf[0] & 0x8000) && (buf[0] != 0x848a) )
  if ( (buf[0] & 0x8000) && (buf[0] != 0x848a) )
Line 108... Line 120...
    ata_release(inode, filp);
    ata_release(inode, filp);
    return EOPENNODEV;
    return EOPENNODEV;
  }
  }
 
 
  /* Then check specific configuration word                           */
  /* Then check specific configuration word                           */
 
  if (buf[0] == 0x848a)
 
    printf( "Found CompactFLASH device.\n" );
 
  else
  switch(buf[2]) {
  switch(buf[2]) {
     case 0x37c8:
     case 0x37c8:
         /* device does require SET_FEATURES
         /* device does require SET_FEATURES
            IDENTIFY_DEVICE response is incomplete                    */
            IDENTIFY_DEVICE response is incomplete                    */
     case 0x738c:
     case 0x738c:
Line 132... Line 147...
         return EOPENNODEV;
         return EOPENNODEV;
   }
   }
 
 
  /* checks ok                                                        */
  /* checks ok                                                        */
 
 
  /* extract data from device                                         */
 
  printf( "Device%1d: ", device);
 
 
 
  /* display device model, serialnumber, and firmware revision        */
  /* display device model, serialnumber, and firmware revision        */
  memcpy(txt, &buf[27], 40);
  memcpy(txt, &buf[27], 40);
  txt[40] = '\0';
  txt[40] = '\0';
  printf( "%s ", txt );
  printf( "Model       : %s\n", txt );
 
 
  memcpy(txt, &buf[10], 20);
  memcpy(txt, &buf[10], 20);
  txt[20] = '\0';
  txt[20] = '\0';
  printf( "%s ", txt );
  printf( "Serial      : %s\n", txt );
 
 
  memcpy( txt, &buf[23], 8);
  memcpy( txt, &buf[23], 8);
  txt[8] = '\0';
  txt[8] = '\0';
  printf( "%s\n", txt );
  printf( "Firmware rev: %s\n", txt );
 
 
  /* display size in MBytes                                           */
  /* display size in MBytes                                           */
  sectors = (buf[61] << 16) | buf[60];
  sectors = (buf[61] << 16) | buf[60];
  printf( "         %ld MBytes ", sectors >> 11 ); /* assuming 512bytes per sector */
  printf( "         %ld MBytes ", sectors >> 11 ); /* assuming 512bytes per sector */
 
 
Line 194... Line 206...
 
 
  return 0;
  return 0;
}
}
 
 
 
 
 
/*
 
       A T A _ R E A D _ D P O R T
 
 
 
       closes ata device;
 
*/
 
int ata_read_dport(unsigned long base)
 
{
 
  /* device ready to transfer data ?? */
 
  while ( !ata_dev_datrdy(base) );
 
 
 
  return REG32(base + ATA_DR);
 
}
 
 
 
 
/*
/*
        A T A _ I O C T L
        A T A _ I O C T L
*/
*/
int ata_ioctl(struct inode *inode, struct file *filp, unsigned command, unsigned long argument)
int ata_ioctl(struct inode *inode, struct file *filp, unsigned command, unsigned long argument)
{
{
    unsigned long base = BASE(inode);
    unsigned long base = BASE(inode);
 
 
    switch (command)
    switch (command)
    {
    {
        case ATA_IOCTL_IDENTIFY_DEVICE:
        case ATA_IOCTL_ENABLE_HOST:
        /* Reads the identify_device block                            */
        /* enables the ATA host controller (sets IDE_EN bit)          */
        {
        {
            int i;
            REG32(base + ATA_CTRL) |= ATA_IDE_EN;
            unsigned short *buf_ptr = (short *)argument;
            return 0;
 
        }
 
 
 
 
 
        case ATA_IOCTL_EXEC_CMD:
 
        /* sends a command to the ATA device                          */
 
        {
 
          while( ata_dev_busy(base) ); // wait for device ready
 
          ata_cmd(base) = argument & 0xff;
 
          return 0;
 
        }
 
 
            /* send 'identify_device' command                         */
 
            REG32(base + ATA_CR) = IDENTIFY_DEVICE;
 
 
 
            /* read data from devices and store it in buffer          */
        case ATA_IOCTL_READ:
            for (i=0; i < 256; i++)
        {
                *buf_ptr++ = REG32(base + ATA_DR);
          unsigned short *buf_ptr = (short *)argument;
 
          int n, cnt;
 
 
 
          cnt = buf_ptr[0];
 
          for (n=0; n < cnt; n++)
 
          {
 
            while( !ata_dev_datrdy(base) );     // wait for data
 
            *buf_ptr++ = ata_read_dport(base);  // read data
 
          }
 
 
            return 0;
            return 0;
        }
        }
 
 
 
 
Line 227... Line 268...
        /* reads OCIDEC status register configuration bits            */
        /* reads OCIDEC status register configuration bits            */
            return (REG32(base + ATA_STAT) >> 24);
            return (REG32(base + ATA_STAT) >> 24);
 
 
 
 
        case ATA_IOCTL_SELECT_DEVICE:
        case ATA_IOCTL_SELECT_DEVICE:
        /* selects ATA device
        /* selects ATA device                                         */
           sets the DEV bit in the device/head register               */
        {
 
          while( ata_dev_busy(base) ); // wait for device ready
 
 
 
          /* sets the DEV bit in the device/head register             */
          if ( DEVICE(inode) )
          if ( DEVICE(inode) )
            REG32(base + ATA_DHR) |= ATA_DHR_DEV;  /* select device1  */
            REG32(base + ATA_DHR) |= ATA_DHR_DEV;  /* select device1  */
          else
          else
            REG32(base + ATA_DHR) &= ~ATA_DHR_DEV; /* select device0  */
            REG32(base + ATA_DHR) &= ~ATA_DHR_DEV; /* select device0  */
 
 
          return 0;
          return 0;
 
        }
 
 
 
 
        case ATA_IOCTL_SET_FTE:
        case ATA_IOCTL_SET_FTE:
 
        {
        /* set FTE bits                                               */
        /* set FTE bits                                               */
          if ( MINOR(inode->i_rdev) )
          if ( MINOR(inode->i_rdev) )
            if (argument)
            if (argument)
                REG32(base + ATA_CTRL) |= ATA_IORDY_FTE0;
                REG32(base + ATA_CTRL) |= ATA_IORDY_FTE0;
              else
              else
Line 251... Line 297...
                REG32(base + ATA_CTRL) |= ATA_IORDY_FTE1;
                REG32(base + ATA_CTRL) |= ATA_IORDY_FTE1;
              else
              else
                REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE1;
                REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE1;
 
 
          return 0;
          return 0;
 
        }
 
 
 
 
        case ATA_IOCTL_SET_PIO:
        case ATA_IOCTL_SET_PIO:
        /* programs the PIO timing registers                          */
        /* programs the PIO timing registers                          */
        {
        {
          unsigned long timing;
          unsigned long timing;
          unsigned short buf[256];
          unsigned short buf[256];
 
 
          /* do we need to read the identify_device block ??          */
          /* do we need to read the identify_device block ??          */
          if (argument & (ARG_PIO4 | ARG_PIO3) )
          if (argument & (ARG_PIO4 | ARG_PIO3) )
            ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_DEVICE, (unsigned long) buf);
          {
 
            /* identify requested ata-devices                         */
 
            ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, IDENTIFY_DEVICE);
 
 
 
            /* read block from ata-device                             */
 
            buf[0] = 256;
 
            ata_ioctl(inode, filp, ATA_IOCTL_READ, (unsigned long) buf);
 
          }
 
 
          /* program register transfer timing registers               */
          /* program register transfer timing registers               */
          /* set the slowest pio mode for register transfers          */
          /* set the slowest pio mode for register transfers          */
          if (argument < current_pio_mode)
          if (argument < current_pio_mode)
          {
          {
Line 410... Line 464...
            }
            }
          }
          }
 
 
 
 
        default:
        default:
            printf( "FIXME: Unsupported IOCTL call\n" );
            printf( "FIXME: Unsupported IOCTL call %1d\n", command );
            return EINVAL;
            return EINVAL;
    }
    }
}
}
 
 
 
 
Line 486... Line 540...
            buf_ptr = request->buffer;
            buf_ptr = request->buffer;
 
 
            for (n=0; n < request->nr_sectors; n++)
            for (n=0; n < request->nr_sectors; n++)
            for (i=0; i < sector_size; i++)
            for (i=0; i < sector_size; i++)
            {
            {
                rd_data = REG32(base + ATA_DR);
                rd_data = ata_read_dport(base);
 
 
                /* the data is byte reversed, swap high & low bytes   */
                /* the data is byte reversed, swap high & low bytes   */
                *buf_ptr++ = rd_data;
                *buf_ptr++ = rd_data;
                *buf_ptr++ = rd_data >> 8;
                *buf_ptr++ = rd_data >> 8;
            }
            }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.