[Kos-dev] ATA & LBA : new experimentations
kos-dev@enix.org
kos-dev@enix.org
12 Feb 2002 12:04:06 +0100
--=-=-=
Hi,
I made some experimentations about my problem concerning the use of
LBA.
First experimentation :
-----------------------
Instead of reading sector 0, and then reading sector 64, I did the
following :
* read sector 0
* identify drive (to make sure there is something else in the
controller buffer)
* read sector 64
But read sector 64 still returned the contents of sector 0.
Second experimentation :
------------------------
I tested if the Error bit was set BEFORE sending the command, and it
was set. So I added a software reset BEFORE sending the command. I
don't know why exactly I need to reset the device, but it works much
more better now.
Then, AFTER sending the command (for a LBA read, for any sector,
including sector 0), the Error bit is set, and the Error register is
set to 0x10, which means IDNF : Requested Sector ID Not Found.
That's strange because I have
sector = 0;
cyl_lo = 0;
cyl_hi = 0;
drive_head = 0xA0 | 0x40 | 0 | 0
SETBITS LBA HEAD 0 MASTER
And it returns an error.
Do you have any idea ?
Note that on an other computer, without doing the reset BEFORE sending
the command, it perfectly works.
Thanks a lot,
Thomas
(code included interesting function is still add_ide_op_polled_mode,
and get_partition_table to see the tests I make)
--=-=-=
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=_ide.c
/* ATA driver for KOS
by Thomas Petazzoni, <thomas.petazzoni@enix.org>
with the help of Soren Schmidt, <sos@freebsd.dk>
*/
#include <kos/asm.h>
#include <lib/stdio.h>
#include <scheduler/scheduler.h>
#include <idt/irq.h>
#include <ide/_ide.h>
#include <liblist/liblist.h>
#include <kos/spinlock.h>
#include <lib/string.h>
#include <kmem/kmem.h>
typedef struct ide_op
{
enum { READ, WRITE } type;
enum { IDE_OP_WAITING, IDE_OP_IN_PROGRESS } status;
harddisk_t *harddisk;
int cyl;
int sector;
int head;
char *buffer;
struct ide_op *next, *prev;
} ide_op_t;
ide_op_t *ide_op_list;
controller_t controllers[NB_CONTROLLERS] =
{
{ 0x1F0, 14, ATA_NOT_PRESENT, PRIMARY_CONTROLLER, 0, { NULL, NULL }},
{ 0x170, 15, ATA_NOT_PRESENT, SECONDARY_CONTROLLER, 0, { NULL, NULL }}
};
static int init_ide(controller_t *ctrl)
{
int status0, status1;
int mask = 0;
int timeout;
outb(ATA_D_IBM | ATA_MASTER, ctrl->ioaddr + ATA_DRIVE);
usleep(1);
status0 = inb(ctrl->ioaddr + ATA_STATUS);
outb(ATA_D_IBM | ATA_SLAVE, ctrl->ioaddr + ATA_DRIVE);
usleep(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 0;
/* no device present */
if(!mask)
return 0;
/* select the master */
outb(ATA_D_IBM | ATA_MASTER, ctrl->ioaddr + ATA_DRIVE);
usleep(1);
/* send reset */
outb(ATA_A_nIEN | ATA_A_RESET, ctrl->ioaddr + ATA_ALTPORT);
usleep(1000);
outb(ATA_A_nIEN, ctrl->ioaddr + ATA_ALTPORT);
usleep(1000);
inb(ctrl->ioaddr + ATA_ERROR);
outb(ATA_A_4BIT, ctrl->ioaddr + ATA_ALTPORT);
usleep(1);
/* wait busy */
for(timeout = 0; timeout < 300000; timeout++)
{
/* select master and get status register */
outb(ATA_D_IBM | ATA_MASTER, ctrl->ioaddr + ATA_DRIVE);
usleep(1);
status0 = inb(ctrl->ioaddr + ATA_STATUS);
/* select slave and get status register */
outb(ATA_D_IBM | ATA_SLAVE, ctrl->ioaddr + ATA_DRIVE);
usleep(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;
usleep(100);
}
if(status0 & ATA_S_BSY)
mask &= ~0x01;
if(status1 & ATA_S_BSY)
mask &= ~0x02;
/* no device */
if(!mask)
return 0;
/* there's at least one device, initialize state */
ctrl->state = ATA_IDLE;
/* check what is the type of the device */
outb(ATA_D_IBM | ATA_MASTER, ctrl->ioaddr + ATA_DRIVE);
usleep(10);
if(inb(ctrl->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
inb(ctrl->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
{
ctrl->devices |= ATA_ATAPI_MASTER;
}
outb(ATA_D_IBM | ATA_SLAVE, ctrl->ioaddr + ATA_DRIVE);
usleep(10);
if(inb(ctrl->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
inb(ctrl->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
{
ctrl->devices |= ATA_ATAPI_SLAVE;
}
if(status0 != 0x00 && !(ctrl->devices & ATA_ATAPI_MASTER))
{
outb(ATA_D_IBM | ATA_MASTER, 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 |= ATA_ATA_MASTER;
}
}
if(status1 != 0x00 && !(ctrl->devices & ATA_ATAPI_SLAVE))
{
outb(ATA_D_IBM | ATA_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 |= ATA_ATA_SLAVE;
}
}
return 0;
}
static int convert_to_ascii(char *src, char *dst, int len)
{
int i;
for(i = 0; i < len; i=i+2)
{
dst[i] = (src[i+1] & 0xff);
dst[i+1] = (src[i] & 0xff);
}
dst[len] = '\0';
for(i = len; i > 0; i--)
{
if(dst[i] == 0)
continue;
else if(dst[i] == ' ')
dst[i] = '\0';
else
break;
}
return 0;
}
/* Will be used for IRQ mode */
static int do_op_first_step(ide_op_t *op)
{
controller_t *ctrl;
ctrl = op->harddisk->ctrl;
ctrl->state = ATA_WAIT_INTR;
outb(ATA_A_4BIT, ctrl->ioaddr + ATA_ALTPORT);
/* select drive */
outb(ATA_D_IBM
| (op->harddisk->device == MASTER) ? ATA_MASTER : ATA_SLAVE
| op->head,
ctrl->ioaddr + ATA_DRIVE);
usleep(1);
outb(1, ctrl->ioaddr + ATA_SECTOR_COUNT);
outb(op->sector, ctrl->ioaddr + ATA_SECTOR_NUMBER);
outb((op->cyl & 0xff), ctrl->ioaddr + ATA_CYL_LSB);
outb(((op->cyl & 0xff00) >> 8), ctrl->ioaddr + ATA_CYL_MSB);
/* FOR THE MOMENT WE DON'T CARE ABOUT THE OPERATION TYPE ... ALWAYS
READ ... */
op->status = IDE_OP_IN_PROGRESS;
outb(ATA_C_READ, ctrl->ioaddr + ATA_CMD);
return 0;
}
static int add_ide_op_with_irq(harddisk_t *harddisk, int type, int cyl, int head, int sector, char *buffer)
{
ide_op_t *new;
new = kmalloc(sizeof(ide_op_t));
if(new == NULL)
{
printk("Memory allocation error\n");
return -1;
}
if(type != READ && type != WRITE)
return -1;
new->status = IDE_OP_WAITING;
new->harddisk = harddisk;
new->cyl = cyl;
new->sector = sector;
new->head = head;
new->buffer = buffer;
new->type = type;
list_add_tail(ide_op_list, new);
if(harddisk->ctrl->state == ATA_IDLE)
do_op_first_step(new);
return 0;
}
int add_ide_op_polled_mode(harddisk_t *harddisk,
int type,
k_ui32_t sector_num,
k_ui16_t *buffer)
{
int timeout, status = 0;
int i;
k_ui8_t cyl_lo, cyl_hi, sect, head;
controller_t *ctrl;
k_ui16_t tmp;
__dbg_printk("[add_ide_op_polled_mode] bonjour\n");
ctrl = harddisk->ctrl;
if(type != READ && type != WRITE)
{
printk("Unknown type of operation\n");
return -1;
}
ctrl->state = ATA_IDLE;
__dbg_printk("Converting to correct sector addressing\n");
if(harddisk->flags & HARDDISK_LBA_CAPABLE)
{
sect = (sector_num & 0xff);
cyl_lo = (sector_num >> 8) & 0xff;
cyl_hi = (sector_num >> 16) & 0xff;
head = ((sector_num >> 24) & 0xf) | 0xE0 /* LBA */;
printk("Using LBA mode %d : sect=%d,cyl_lo=%d,cyl_hi=%d,head=%d\n",
sector_num,sect,cyl_lo,cyl_hi,head);
}
else
{
int cylinder = sector_num /
(harddisk->logical_head_nb * harddisk->logical_sector_per_track);
int temp = sector_num %
(harddisk->logical_head_nb * harddisk->logical_sector_per_track);
cyl_lo = cylinder & 0xff;
cyl_hi = (cylinder >> 8) & 0xff;
head = temp / harddisk->logical_sector_per_track;
sect = (temp % harddisk->logical_sector_per_track) + 1;
}
__dbg_printk("conversion done\n");
/*
printk("Going to read cyl_hi=0x%x, cyl_lo=0x%x, head=0x%x, sect=0x%x\n",
cyl_hi, cyl_lo, head, sect);
*/
/* send reset */
outb(ATA_D_IBM | ATA_MASTER, ctrl->ioaddr + ATA_DRIVE);
usleep(1);
outb(ATA_A_nIEN | ATA_A_RESET, ctrl->ioaddr + ATA_ALTPORT);
usleep(1000);
outb(ATA_A_nIEN, ctrl->ioaddr + ATA_ALTPORT);
usleep(1000);
inb(ctrl->ioaddr + ATA_ERROR);
for(timeout = 0; timeout < 30000; timeout++)
{
status = inb(ctrl->ioaddr + ATA_STATUS);
if(!(status & ATA_S_BSY))
break;
usleep(1);
}
if(timeout == 30000)
printk("TIMEOUT");
if(inb(ctrl->ioaddr + ATA_STATUS) & ATA_S_ERROR)
{
printk("Error of type 0x%x\n", inb(ctrl->ioaddr + ATA_ERROR));
}
// outb(ATA_A_nIEN | ATA_A_4BIT, ctrl->ioaddr + ATA_ALTPORT);
// outb(0, ctrl->ioaddr + ATA_ALTPORT);
/* select drive */
outb(ATA_D_IBM
| (harddisk->device == MASTER) ? ATA_MASTER : ATA_SLAVE
| head,
ctrl->ioaddr + ATA_DRIVE);
outb(0, ctrl->ioaddr + ATA_PRECOMP);
outb(1, ctrl->ioaddr + ATA_SECTOR_COUNT);
outb(sect, ctrl->ioaddr + ATA_SECTOR_NUMBER);
outb(cyl_lo, ctrl->ioaddr + ATA_CYL_LSB);
outb(cyl_hi, ctrl->ioaddr + ATA_CYL_MSB);
/* FOR THE MOMENT WE DON'T CARE ABOUT THE OPERATION TYPE ... ALWAYS
READ ... */
outb(ATA_C_READ, ctrl->ioaddr + ATA_CMD);
for(timeout = 0; timeout < 30000; timeout++)
{
status = inb(ctrl->ioaddr + ATA_STATUS);
if(!(status & ATA_S_BSY))
break;
usleep(1);
}
if(timeout >= 30000)
printk("TIMEOUT");
if(inb(ctrl->ioaddr + ATA_STATUS) & ATA_S_ERROR)
{
printk("[after] Error of type 0x%x\n", inb(ctrl->ioaddr + ATA_ERROR));
return -1;
}
if(!(inb(ctrl->ioaddr + ATA_STATUS) & ATA_S_DRQ))
{
printk("Error (0x%x)\n", inb(ctrl->ioaddr + ATA_ERROR));
return -1;
}
for(i = 0; i < 256; i++)
buffer[i] = inw(ctrl->ioaddr);
return 0;
}
/* TEST FUNCTION ONLY */
static int do_identify_drive(harddisk_t *harddisk, k_ui16_t *buffer)
{
controller_t *ctrl;
int timeout;
int status = 0;
int i;
ctrl = harddisk->ctrl;
/* On met nIEN a 1 dans device control */
outb(ATA_A_nIEN | ATA_A_4BIT, ctrl->ioaddr + ATA_DEVICE_CONTROL);
usleep(1);
/* on selectionne le device */
outb(ATA_D_IBM | (harddisk->device == 0) ? ATA_MASTER : ATA_SLAVE,
ctrl->ioaddr + ATA_DRIVE);
/* sencind command */
outb(ATA_C_ATA_IDENTIFY, ctrl->ioaddr + ATA_CMD);
for(timeout = 0; timeout < 30000; timeout++)
{
status = inb(ctrl->ioaddr + ATA_STATUS);
if(!(status & ATA_S_BSY))
break;
usleep(1);
}
if(!(status & ATA_S_DRQ))
{
printk("Error\n");
return -1;
}
for(i = 0; i < 256; i++)
buffer[i] = inw(ctrl->ioaddr);
return 0;
}
static int get_partition_table (harddisk_t *harddisk)
{
int i;
partition_entry_t *p;
partition_t *new;
int extstart = 0;
int extsup = 0;
int partnum = 1;
k_ui8_t buffer[512];
if(add_ide_op_polled_mode(harddisk, READ, 0, (k_ui16_t *) buffer) < 0)
{
printk("Bonjour coucou\n");
return -1;
}
__dbg_printk("Going to dereference harddisk 0x%x.. might explose\n", (unsigned) harddisk);
p = (partition_entry_t *) (buffer+446);
harddisk->partition_list = NULL;
{
k_ui8_t buffer2[512];
k_ui8_t buffer3[512];
do_identify_drive(harddisk, (k_ui16_t *) buffer2);
if(add_ide_op_polled_mode(harddisk, READ, 64, (k_ui16_t *) buffer3) < 0)
printk("*********** EROOOR \n");
printk("buffer1 : ");
for(i = 0; i < 16; i++)
printk("%x ", buffer[446+i]);
printk("\n");
printk("buffer2 : ");
for(i = 0; i < 16; i++)
printk("%c ", buffer2[27*2+i]);
printk("\n");
printk("buffer3 : ");
for(i = 0; i < 16; i++)
printk("%x ", buffer3[446+i]);
}
return 0;
/* Manage primary partitions */
for (i = 0; i < 4; i++)
{
if (p[i].size == 0)
continue;
new = kmalloc(sizeof(partition_t));
if(new == NULL)
{
printk("Couldn't allocate memory\n");
return -1;
}
if(p[i].type != 0x5)
{
new->is_active = (p[i].active == 0) ? 0 : 1;
new->fs_type = p[i].type;
new->start = p[i].lba;
new->size = p[i].size;
new->number = partnum++;
list_add_tail(harddisk->partition_list, new);
}
else
extstart = p[i].lba;
}
/* Manage extended partitions */
while(extstart != 0)
{
if(partnum > 6)
break;
/*
printk("Reading MBR for extended partition : %d\n",
extstart+extsup);
*/
memset(buffer, 0, 512);
if(add_ide_op_polled_mode(harddisk, READ, extstart+extsup,
(k_ui16_t *) buffer) < 0)
{
printk("Error while reading sector %d\n", extstart+extsup);
return -1;
}
p = (partition_entry_t *) (buffer + 446);
new = kmalloc(sizeof(partition_t));
if(new == NULL)
{
printk("Couldn't allocate memory\n");
return -1;
}
new->is_active = (p[0].active == 0) ? 0 : 1;
new->fs_type = p[0].type;
new->start = extstart + extsup + p[0].lba;
new->size = p[0].size;
new->number = partnum++;
/*
printk("First entry : ");
for (i = 0; i < 16; i++)
printk("%x ", (unsigned) buffer[446+i]);
printk("Second entry : ");
for (i = 0; i < 16; i++)
printk("%x ", (unsigned) buffer[446+16+i]);
printk("Extended adding %d (%d %d 0x%x) %x%x\n",
partnum-1, new->start, new->size, new->fs_type,
(unsigned)buffer[510], (unsigned)buffer[511]);
*/
list_add_tail(harddisk->partition_list, new);
extsup = p[1].lba;
if(extsup == 0)
break;
}
return 0;
}
/* this function set the command "Identify Drive". For this command,
we don't wait for an IRQ, we just wait for BSY bit to be
cleared. (polled mode) */
static int get_drv_infos(controller_t *ctrl, int device)
{
int timeout, status=0;
harddisk_t *harddisk;
identify_device_info_t *dinfo;
k_ui16_t buffer[256];
int i;
/* On met nIEN a 1 dans device control */
outb(ATA_A_nIEN | ATA_A_4BIT, ctrl->ioaddr + ATA_DEVICE_CONTROL);
usleep(1);
/* on selectionne le device */
outb(ATA_D_IBM | (device == 0) ? ATA_MASTER : ATA_SLAVE,
ctrl->ioaddr + ATA_DRIVE);
/* sencind command */
outb(ATA_C_ATA_IDENTIFY, ctrl->ioaddr + ATA_CMD);
for(timeout = 0; timeout < 30000; timeout++)
{
status = inb(ctrl->ioaddr + ATA_STATUS);
if(!(status & ATA_S_BSY))
break;
usleep(1);
}
if(!(status & ATA_S_DRQ))
{
printk("Error\n");
return -1;
}
for(i = 0; i < 256; i++)
buffer[i] = inw(ctrl->ioaddr);
dinfo = (identify_device_info_t *) buffer;
harddisk = (harddisk_t *) ctrl->device[device];
harddisk->ctrl = ctrl;
harddisk->device = device;
harddisk->logical_cylinder_nb = dinfo->nb_logical_cylinders;
harddisk->logical_head_nb = dinfo->nb_logical_heads;
harddisk->logical_sector_per_track = dinfo->nb_logical_sectors;
if(harddisk->logical_sector_per_track == 0 ||
harddisk->logical_head_nb == 0 ||
harddisk->logical_cylinder_nb == 0)
{
printk("Y'a un bleme\n");
return -1;
}
harddisk->lba_capacity = dinfo->lba_capacity;
harddisk->flags = 0;
if(dinfo->capabilities & (1<<1) /* LBA bit must be set */
&& dinfo->major_version /* major version must be non 0 */
&& (dinfo->fields_valid & 1) /* lba fields must be valid */
&& (dinfo->lba_capacity)) /* lba capacity must be non 0 */
harddisk->flags |= HARDDISK_LBA_CAPABLE;
if(harddisk->logical_head_nb == 16 &&
harddisk->logical_sector_per_track == 63 &&
harddisk->logical_cylinder_nb == 16383)
{
if(harddisk->flags & HARDDISK_LBA_CAPABLE)
harddisk->size = harddisk->lba_capacity;
else
FAILED_VERBOSE("Large harddisk without LBA ...\n");
}
else
harddisk->size =
harddisk->logical_cylinder_nb *
harddisk->logical_sector_per_track *
harddisk->logical_head_nb;
convert_to_ascii(dinfo->model_number, harddisk->model_number,40);
convert_to_ascii(dinfo->serial_number, harddisk->serial_number,20);
convert_to_ascii(dinfo->firmware_revision, harddisk->firmware_revision,8);
printk("Calling get_partition_table for %d-%d\n",
ctrl->ctrl, device);
if(get_partition_table(harddisk) < 0)
{
printk("Error while getting partition table\n");
return -1;
}
return 0;
}
static void ide_handler(int nb, cpu_state_t *state)
{
UNUSED(state);
if(controllers[PRIMARY_CONTROLLER].state == ATA_WAIT_INTR)
{
printk("Got an IRQ %d !\n", nb);
printk("The job was of type : %d\n", ide_op_list->type);
controllers[PRIMARY_CONTROLLER].state = ATA_IDLE;
}
}
static char *partition_type(int type)
{
switch(type)
{
case 0xe:
case 0x6:
return "FAT16";
case 0xb:
case 0xc:
return "FAT32";
case 0x82:
return "Linux Swap";
case 0x83:
return "Linux";
default:
return "Unknow";
}
}
/****** needs to be updated *********/
partition_t *get_partition_list(void)
{
harddisk_t *hd = (harddisk_t *) controllers[PRIMARY_CONTROLLER].device[MASTER];
if(hd == NULL)
return NULL;
return hd->partition_list;
}
/******** needs to be updated *******/
int ide_read_on_primary_master(k_ui32_t sector_num, k_ui16_t *buffer)
{
harddisk_t *hd = (harddisk_t *) controllers[PRIMARY_CONTROLLER].device[MASTER];
if(hd == NULL)
return -1;
return add_ide_op_polled_mode(hd,READ,sector_num,buffer);
}
static int initialize_devices(int controller)
{
char c;
controller_t *ctrl;
if(controller == PRIMARY_CONTROLLER)
{
c = 'a';
ctrl = &controllers[PRIMARY_CONTROLLER];
}
else if(controller == SECONDARY_CONTROLLER)
{
c = 'c';
ctrl = &controllers[SECONDARY_CONTROLLER];
}
else
{
printk("Unknow controller !\n");
return -1;
}
if(ctrl->state != ATA_NOT_PRESENT)
{
if(ctrl->devices & ATA_ATA_MASTER)
{
harddisk_t *harddisk;
partition_t *p;
int nb_elts;
ctrl->device[MASTER] = kmalloc(sizeof(harddisk_t));
if(ctrl->device[MASTER] == NULL)
{
printk("[test_ide] memory allocation error\n");
return -1;
}
harddisk = (harddisk_t *) ctrl->device[MASTER];
if(get_drv_infos(ctrl, MASTER) < 0)
{
printk("Failure while getting info for master\n");
kfree(ctrl->device[MASTER]);
ctrl->device[MASTER] = NULL;
return -1;
}
printk("hd%c: (%s = %d Mb : C/H/S : %d/%d/%d\n",
c, harddisk->model_number, harddisk->size>>11,
harddisk->logical_cylinder_nb,
harddisk->logical_head_nb,
harddisk->logical_sector_per_track);
list_foreach(harddisk->partition_list, p, nb_elts)
{
printk(" - hd%c%d start=%d size=%d Mb type=%s\n",
c, nb_elts+1, p->start, p->size>>11, partition_type(p->fs_type));
}
}
if(ctrl->devices & ATA_ATA_SLAVE)
{
harddisk_t *harddisk;
partition_t *p;
int nb_elts;
ctrl->device[SLAVE] = kmalloc(sizeof(harddisk_t));
if(ctrl->device[SLAVE] == NULL)
{
printk("[test_ide] memory allocation error\n");
return -1;
}
harddisk = (harddisk_t *) ctrl->device[SLAVE];
if(get_drv_infos(ctrl, SLAVE) < 0)
{
printk("Failure while getting info for slave\n");
kfree(ctrl->device[SLAVE]);
ctrl->device[SLAVE] = NULL;
return -1;
}
printk("hd%c: (%s = %d Mb : C/H/S : %d/%d/%d\n",
c+1, harddisk->model_number, harddisk->size>>11,
harddisk->logical_cylinder_nb,
harddisk->logical_head_nb,
harddisk->logical_sector_per_track);
list_foreach(harddisk->partition_list, p, nb_elts)
{
printk(" - hd%c%d start=%d size=%d Mb type=%s\n",
c+1, nb_elts+1, p->start, p->size>>11, partition_type(p->fs_type));
}
}
if(ctrl->devices & ATA_ATAPI_MASTER)
{
cdrom_t *cdrom;
ctrl->device[MASTER] = kmalloc(sizeof(cdrom_t));
if(ctrl->device[MASTER] == NULL)
{
printk("[test_ide] memory allocation error\n");
return -1;
}
cdrom = (cdrom_t *) ctrl->device[MASTER];
printk("hd%c (CD-ROM) ", c);
}
if(ctrl->devices & ATA_ATAPI_SLAVE)
{
cdrom_t *cdrom;
ctrl->device[SLAVE] = kmalloc(sizeof(cdrom_t));
if(ctrl->device[SLAVE] == NULL)
{
printk("[test_ide] memory allocation error\n");
return -1;
}
cdrom = (cdrom_t *) ctrl->device[SLAVE];
printk("hd%c (CD-ROM) ", c+1);
}
}
else
printk("no controller found");
printk("\n");
return 0;
}
int test_ide(void)
{
/*
if(ide_init_babel_stuff() < 0)
{
__dbg_printk("[ide] error while initializing Babel\n");
return -1;
}
*/
printk("Primary : \n");
init_ide(&controllers[PRIMARY_CONTROLLER]);
initialize_devices(PRIMARY_CONTROLLER);
/*
printk("Secondary : \n");
init_ide(&controllers[SECONDARY_CONTROLLER]);
initialize_devices(SECONDARY_CONTROLLER);
register_irq_handler(14, ide_handler);
*/
return 0;
}
--=-=-=
--
PETAZZONI Thomas - thomas.petazzoni@enix.org - UIN : 34937744
(Perso) http://www.enix.org/~thomas/
(KOS) http://kos.enix.org/
(Club LinUT) http://club-linut.enix.org
--=-=-=--