[Kos-dev] IDE Eclairage :)

Laurent pelat_a at epita.fr
Thu Apr 28 17:45:00 CEST 2005


Salut a tous, j'ai pas mal regarde vos sources et plus particulierement
la partie IDE qui m'interesse vraiment.

Y'a plusieurs trucs que je ne comprends pas, peut etre que vous pouvez m'eclairer ;)
Bon mon post va etre long... desole pour les petits joueurs ;)


Voici le morceau de code que j'ai du mal a cerner.
J'ai mis des commentaires pour que vous puissiez me suivre ;)

static result_t _ide_init_controller(ide_controller_t *ctrl)
{
  int status0, status1;
  int mask = 0;
  int timeout;

  /* COMMENTAIRE
  ** 1 ere Partie, On recupere le status des devices (disques durs)
  ** Si les devices sont occupes ou non presents on retourne :)
  */


  /* Get status of controllers */
  outb(ATA_D_IBM | ATA_D_MASTER, ctrl->ioaddr + ATA_DRIVE);
  udelay(1);
  status0 = inb(ctrl->ioaddr + ATA_STATUS);

  outb(ATA_D_IBM | ATA_D_SLAVE, ctrl->ioaddr + ATA_DRIVE);
  udelay(1);
  status1 = inb(ctrl->ioaddr + ATA_STATUS);

  if((status0 & 0xf8) != 0xf8)
    mask |= 0x01;
  if((status1 & 0xf8) != 0xf8)
    mask |= 0x02;

  /* If both BSY bit are set => leave */
  if((status0 & ATA_S_BSY) && (status1 & ATA_S_BSY))
    return ESUCCESS;

  /* no device present */
  if(!mask)
    return ESUCCESS;

  /* COMMENTAIRE
  ** 2eme Partie, on reset le controleur, on desactive les interruptions
  ** On recupere le status des devices (disques durs)
  ** Si les devices sont occupes ou non presents on retourne :)
  */

  /* select the master */
  outb(ATA_D_IBM | ATA_D_MASTER, ctrl->ioaddr + ATA_DRIVE);
  usleep(1);
  /* send reset */
  outb(ATA_A_nIEN | ATA_A_RESET, ctrl->ioaddr + ATA_DEVICE_CONTROL);
  udelay(1);
  outb(ATA_A_nIEN, ctrl->ioaddr + ATA_DEVICE_CONTROL);
  udelay(1);
  inb(ctrl->ioaddr + ATA_ERROR);
  outb(ATA_A_4BIT, ctrl->ioaddr + ATA_DEVICE_CONTROL);
  udelay(1);

  /* wait busy */
  for(timeout = 0; timeout < 300000; timeout++)
    {
      /* select master and get status register */
      outb(ATA_D_IBM | ATA_D_MASTER, ctrl->ioaddr + ATA_DRIVE);
      udelay(1);
      status0 = inb(ctrl->ioaddr + ATA_STATUS);

      /* select slave and get status register */
      outb(ATA_D_IBM | ATA_D_SLAVE, ctrl->ioaddr + ATA_DRIVE);
      udelay(1);
      status1 = inb(ctrl->ioaddr + ATA_STATUS);

      if(mask == 0x01)
        if(!(status0 & ATA_S_BSY))
          break;
      if(mask == 0x02)
        if(!(status1 & ATA_S_BSY))
          break;
      if(mask == 0x03)
        if(!(status0 & ATA_S_BSY) && !(status1 & ATA_S_BSY))
          break;
      udelay(1);
    }

  if(status0 & ATA_S_BSY)
    mask &= ~0x01;
  if(status1 & ATA_S_BSY)
    mask &= ~0x02;

  /* no device */
  if(!mask)
    return ESUCCESS;


Question 1:
-----------

Pourquoi est on oblige de passer par la partie 1?
Pourquoi ne pas "reseter" directement le controleur
et regarder le status des devices?

Question 2:
-----------

/* send reset */
outb(ATA_A_nIEN | ATA_A_RESET, ctrl->ioaddr + ATA_DEVICE_CONTROL);
udelay(1);
outb(ATA_A_nIEN, ctrl->ioaddr + ATA_DEVICE_CONTROL);
udelay(1);

Quel interet de desactiver 2 fois a la suite les interruptions?


Question 3:
-----------
outb(ATA_A_nIEN, ctrl->ioaddr + ATA_DEVICE_CONTROL);
udelay(1);
inb(ctrl->ioaddr + ATA_ERROR);

Quel est l'interet de ce inb? vu qu'on ne recupere aucune valeur?


Voila c'est des petits bugs? ou quelque chose m'echappe?


Bug:
----

Sinon en passant un petit bug:

  if((status1 != 0x00) &&
     (ctrl->devices[IDE_SLAVE].type == IDE_DEV_NOT_PRESENT))
    {
      outb(ATA_D_IBM | ATA_D_SLAVE, ctrl->ioaddr + ATA_DRIVE);
      usleep(1);
      outb(0x58, ctrl->ioaddr + ATA_ERROR);
      outb(0xa5, ctrl->ioaddr + ATA_CYL_LSB);
      if(inb(ctrl->ioaddr + ATA_ERROR) != 0x58 &&
         inb(ctrl->ioaddr + ATA_CYL_LSB) == 0xa5)
        {
          ctrl->devices[IDE_MASTER].type = IDE_DEV_ATA;  <--------- Oops ;)
        }
    }

A remplacer par ctrl->devices[IDE_SLAVE].type = IDE_DEV_ATA;




Merci d'avance pour vos reponses
Encore bravo pour votre OS.
Il est clair et assez abouti, tres agreable a lire.


--
Laurent



More information about the Kos-dev mailing list