Commit 48ba6e98 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.6-pre1 IDE clean 14

Most importantly this patch is making ide.c use the
new automagic for module initialization lists and further
preparing the rest of the code in question here for proper
module separation. Despite this the CMOS probe has been removed
as well... *Iff*, which I don't expect, this breaks anything
it can be reintroduced easely. During this effort an actual bug
in the initialization of the main module has been uncovered as well.
a quite serious BUG has been tagged in ide-scsi.c as well, but
as far as now I just didn't get along to actually fixing it.
(The patch is big enough as it is).

Details follow:

- Kill *unused* ide_media_verbose() funciton.

- Remove the unnecessary media and supports_dma fields from
    ide_driver_t.

- Remove the global name field from ide_driver_t struct by pushing it
    down to the places where it's actually used.

- Remove the unused hwif_data field from ide_hwif_t.

- Push the supports_dsc_overlap condition up to the level where it
    belongs: disk type as well.

- Make the initialization of ide main ide.c work with the new module
    initialization auto-magic instead of calling it explicitly in
    ll_rw_block.c This prevents the ide_init() from being called twice. We
    have BTW. renamed it to ata_module_init(), since  ata is more adequate
    then ide and xxx_module_init corresponds better to the naming
    conventions used elsewhere throughout the kernel.

    This BUG was there before any ide-clean.  It was worked around by a
    magic variable preventing the second call to succeed.  We have removed
    this variable in one of the previous patches and thus uncovered it.

- Kill proc_ide_read_driver() and proc_ide_write_driver(). The drivers
    already report on syslog which drives they have taken care of.  (Or
    at least they should). In esp. the proc_ide_write_driver() was just
    too offending for me.  Beleve it or not the purpose of it was to
    *request a particular* driver for a device, by echoing some magic
    values to a magic file...
    More importantly this "back door" was getting in the way of a properly
    done modularization of the IDE stuff.

- Made some not externally used functions static or not EXPORT-ed.

- Provide the start of a proper modularization between the main module
    and drivers for particular device types. Changing the name-space
    polluting DRIVER() macro to ata_ops() showed how inconsistently the
    busy (read: module  busy!) field from ide_driver_t
    is currently used across the    different device type modules.
    This has to be fixed soon.

- Make the ide code use the similar device type ID numbers as the SCSI
    code :-).  This is just tedious, but it will help in a distant
    feature. It helps reading the code anyway.

- Mark repettitive code with /* ATA-PATTERN */ comments for later
    consolidation at places where we did came across it.

- Various comments and notes added where some explanations was missing.
parent b62bbbcb
......@@ -1697,9 +1697,6 @@ int __init blk_dev_init(void)
blk_max_low_pfn = max_low_pfn;
blk_max_pfn = max_pfn;
#if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_IDE)
ide_init(); /* this MUST precede hd_init */
#endif
#if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_HD)
hd_init();
#endif
......
......@@ -48,7 +48,6 @@
static int aec62xx_get_info(char *, char **, off_t, int);
extern int (*aec62xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count)
......@@ -310,8 +309,8 @@ static int config_aec6210_chipset_for_dma (ide_drive_t *drive, byte ultra)
unsigned long dma_base = hwif->dma_base;
byte speed = -1;
if (drive->media != ide_disk)
return ((int) ide_dma_off_quietly);
if (drive->type != ATA_DISK)
return ide_dma_off_quietly;
if (((id->dma_ultra & 0x0010) ||
(id->dma_ultra & 0x0008) ||
......@@ -356,7 +355,7 @@ static int config_aec6260_chipset_for_dma (ide_drive_t *drive, byte ultra)
byte speed = -1;
byte ultra66 = eighty_ninty_three(drive);
if (drive->media != ide_disk)
if (drive->type != ATA_DISK)
return ((int) ide_dma_off_quietly);
if ((id->dma_ultra & 0x0010) && (ultra) && (ultra66)) {
......
......@@ -278,7 +278,7 @@ static void ali15x3_tune_drive (ide_drive_t *drive, byte pio)
* PIO mode => ATA FIFO on, ATAPI FIFO off
*/
pci_read_config_byte(dev, portFIFO, &cd_dma_fifo);
if (drive->media==ide_disk) {
if (drive->type == ATA_DISK) {
if (hwif->index) {
pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50);
} else {
......@@ -424,9 +424,9 @@ static byte ali15x3_can_ultra (ide_drive_t *drive)
} else if ((m5229_revision < 0xC2) &&
#ifndef CONFIG_WDC_ALI15X3
((chip_is_1543c_e && strstr(id->model, "WDC ")) ||
(drive->media!=ide_disk))) {
(drive->type != ATA_DISK))) {
#else /* CONFIG_WDC_ALI15X3 */
(drive->media!=ide_disk)) {
(drive->type != ATA_DISK)) {
#endif /* CONFIG_WDC_ALI15X3 */
return 0;
} else {
......@@ -441,7 +441,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
ide_dma_action_t dma_func = ide_dma_on;
byte can_ultra_dma = ali15x3_can_ultra(drive);
if ((m5229_revision<=0x20) && (drive->media!=ide_disk))
if ((m5229_revision<=0x20) && (drive->type != ATA_DISK))
return hwif->dmaproc(ide_dma_off_quietly, drive);
if ((id != NULL) && ((id->capability & 1) != 0) && hwif->autodma) {
......@@ -494,7 +494,7 @@ static int ali15x3_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_check:
return ali15x3_config_drive_for_dma(drive);
case ide_dma_write:
if ((m5229_revision < 0xC2) && (drive->media != ide_disk))
if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
return 1; /* try PIO instead of DMA */
break;
default:
......
......@@ -34,7 +34,6 @@
static int amd74xx_get_info(char *, char **, off_t, int);
extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
static int amd74xx_get_info (char *buffer, char **addr, off_t offset, int count)
......
......@@ -88,7 +88,6 @@
static int cmd64x_get_info(char *, char **, off_t, int);
static int cmd680_get_info(char *, char **, off_t, int);
extern int (*cmd64x_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
......@@ -448,7 +447,8 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
u8 regU = 0;
u8 regD = 0;
if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) return 1;
if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
return 1;
(void) pci_read_config_byte(dev, pciD, &regD);
(void) pci_read_config_byte(dev, pciU, &regU);
......@@ -641,8 +641,8 @@ static int config_cmd64x_chipset_for_dma (ide_drive_t *drive, unsigned int rev,
break;
}
if (drive->media != ide_disk) {
cmdprintk("CMD64X: drive->media != ide_disk at double check, inital check failed!!\n");
if (drive->type != ATA_DISK) {
cmdprintk("CMD64X: drive is not a disk at double check, inital check failed!!\n");
return ((int) ide_dma_off);
}
......@@ -788,7 +788,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
}
if ((id != NULL) && ((id->capability & 1) != 0) &&
hwif->autodma && (drive->media == ide_disk)) {
hwif->autodma && (drive->type == ATA_DISK)) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive)) {
dma_func = ide_dma_off;
......
......@@ -37,7 +37,6 @@
static int cs5530_get_info(char *, char **, off_t, int);
extern int (*cs5530_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count)
......
......@@ -56,7 +56,6 @@
static int hpt34x_get_info(char *, char **, off_t, int);
extern int (*hpt34x_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count)
......@@ -210,7 +209,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
struct hd_driveid *id = drive->id;
byte speed = 0x00;
if (drive->media != ide_disk)
if (drive->type != ATA_DISK)
return ((int) ide_dma_off_quietly);
hpt34x_clear_chipset(drive);
......@@ -333,7 +332,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
if (drive->type != ATA_DISK)
return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
......
......@@ -355,7 +355,6 @@ extern char *ide_xfer_verbose (byte xfer_rate);
#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
static int hpt366_get_info(char *, char **, off_t, int);
extern int (*hpt366_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count)
{
......@@ -579,7 +578,7 @@ static void hpt370_tune_chipset (ide_drive_t *drive, byte speed)
static int hpt3xx_tune_chipset (ide_drive_t *drive, byte speed)
{
if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))
if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
return -1;
if (!drive->init_speed)
......@@ -664,7 +663,7 @@ static int config_chipset_for_dma (ide_drive_t *drive)
byte ultra66 = eighty_ninty_three(drive);
int rval;
if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))
if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
return ((int) ide_dma_off_quietly);
if ((id->dma_ultra & 0x0020) &&
......
......@@ -143,7 +143,7 @@ static void ht6560b_selectproc (ide_drive_t *drive)
if (select != current_select || timing != current_timing) {
current_select = select;
current_timing = timing;
if (drive->media != ide_disk || !drive->present)
if (drive->type != ATA_DISK || !drive->present)
select |= HT_PREFETCH_MODE;
(void) inb(HT_CONFIG_PORT);
(void) inb(HT_CONFIG_PORT);
......
......@@ -2906,14 +2906,10 @@ int ide_cdrom_cleanup(ide_drive_t *drive)
return 0;
}
int ide_cdrom_reinit (ide_drive_t *drive);
static ide_driver_t ide_cdrom_driver = {
name: "ide-cdrom",
media: ide_cdrom,
busy: 0,
supports_dma: 1,
supports_dsc_overlap: 1,
static int ide_cdrom_reinit (ide_drive_t *drive);
static struct ata_operations ide_cdrom_driver = {
owner: THIS_MODULE,
cleanup: ide_cdrom_cleanup,
standby: NULL,
flushcache: NULL,
......@@ -2937,7 +2933,7 @@ char *ignore = NULL;
MODULE_PARM(ignore, "s");
MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
int ide_cdrom_reinit (ide_drive_t *drive)
static int ide_cdrom_reinit (ide_drive_t *drive)
{
struct cdrom_info *info;
int failed = 0;
......@@ -2955,14 +2951,17 @@ int ide_cdrom_reinit (ide_drive_t *drive)
}
memset (info, 0, sizeof (struct cdrom_info));
drive->driver_data = info;
DRIVER(drive)->busy++;
/* ATA-PATTERN */
ata_ops(drive)->busy++;
if (ide_cdrom_setup (drive)) {
DRIVER(drive)->busy--;
ata_ops(drive)->busy--;
if (ide_cdrom_cleanup (drive))
printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name);
return 1;
}
DRIVER(drive)->busy--;
ata_ops(drive)->busy--;
failed--;
revalidate_drives();
......@@ -2975,7 +2974,7 @@ static void __exit ide_cdrom_exit(void)
ide_drive_t *drive;
int failed = 0;
while ((drive = ide_scan_devices (ide_cdrom, ide_cdrom_driver.name, &ide_cdrom_driver, failed)) != NULL)
while ((drive = ide_scan_devices(ATA_ROM, "ide-cdrom", &ide_cdrom_driver, failed)) != NULL)
if (ide_cdrom_cleanup (drive)) {
printk ("%s: cleanup_module() called while still busy\n", drive->name);
failed++;
......@@ -2989,7 +2988,7 @@ int ide_cdrom_init(void)
int failed = 0;
MOD_INC_USE_COUNT;
while ((drive = ide_scan_devices (ide_cdrom, ide_cdrom_driver.name, NULL, failed++)) != NULL) {
while ((drive = ide_scan_devices (ATA_ROM, "ide-cdrom", NULL, failed++)) != NULL) {
/* skip drives that we were told to ignore */
if (ignore != NULL) {
if (strstr(ignore, drive->name)) {
......@@ -3013,14 +3012,17 @@ int ide_cdrom_init(void)
}
memset (info, 0, sizeof (struct cdrom_info));
drive->driver_data = info;
DRIVER(drive)->busy++;
/* ATA-PATTERN */
ata_ops(drive)->busy++;
if (ide_cdrom_setup (drive)) {
DRIVER(drive)->busy--;
ata_ops(drive)->busy--;
if (ide_cdrom_cleanup (drive))
printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name);
continue;
}
DRIVER(drive)->busy--;
ata_ops(drive)->busy--;
failed--;
}
revalidate_drives();
......
......@@ -1053,17 +1053,13 @@ static int idedisk_cleanup (ide_drive_t *drive)
return ide_unregister_subdriver(drive);
}
int idedisk_reinit(ide_drive_t *drive);
static int idedisk_reinit(ide_drive_t *drive);
/*
* IDE subdriver functions, registered with ide.c
*/
static ide_driver_t idedisk_driver = {
name: "ide-disk",
media: ide_disk,
busy: 0,
supports_dma: 1,
supports_dsc_overlap: 0,
static struct ata_operations idedisk_driver = {
owner: THIS_MODULE,
cleanup: idedisk_cleanup,
standby: do_idedisk_standby,
flushcache: do_idedisk_flushcache,
......@@ -1083,7 +1079,7 @@ static ide_driver_t idedisk_driver = {
MODULE_DESCRIPTION("ATA DISK Driver");
int idedisk_reinit (ide_drive_t *drive)
static int idedisk_reinit(ide_drive_t *drive)
{
int failed = 0;
......@@ -1093,15 +1089,16 @@ int idedisk_reinit (ide_drive_t *drive)
printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name);
return 1;
}
DRIVER(drive)->busy++;
ata_ops(drive)->busy++;
idedisk_setup(drive);
if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", drive->name, drive->head);
(void) idedisk_cleanup(drive);
DRIVER(drive)->busy--;
idedisk_cleanup(drive);
ata_ops(drive)->busy--;
return 1;
}
DRIVER(drive)->busy--;
ata_ops(drive)->busy--;
failed--;
revalidate_drives();
......@@ -1114,7 +1111,7 @@ static void __exit idedisk_exit (void)
ide_drive_t *drive;
int failed = 0;
while ((drive = ide_scan_devices (ide_disk, idedisk_driver.name, &idedisk_driver, failed)) != NULL) {
while ((drive = ide_scan_devices(ATA_DISK, "ide-disk", &idedisk_driver, failed)) != NULL) {
if (idedisk_cleanup (drive)) {
printk (KERN_ERR "%s: cleanup_module() called while still busy\n", drive->name);
failed++;
......@@ -1134,20 +1131,20 @@ int idedisk_init (void)
int failed = 0;
MOD_INC_USE_COUNT;
while ((drive = ide_scan_devices (ide_disk, idedisk_driver.name, NULL, failed++)) != NULL) {
while ((drive = ide_scan_devices(ATA_DISK, "ide-disk", NULL, failed++)) != NULL) {
if (ide_register_subdriver (drive, &idedisk_driver)) {
printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name);
continue;
}
DRIVER(drive)->busy++;
ata_ops(drive)->busy++;
idedisk_setup(drive);
if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", drive->name, drive->head);
(void) idedisk_cleanup(drive);
DRIVER(drive)->busy--;
idedisk_cleanup(drive);
ata_ops(drive)->busy--;
continue;
}
DRIVER(drive)->busy--;
ata_ops(drive)->busy--;
failed--;
}
revalidate_drives();
......
......@@ -470,7 +470,7 @@ static int config_drive_for_dma (ide_drive_t *drive)
ide_hwif_t *hwif = HWIF(drive);
#ifdef CONFIG_IDEDMA_ONLYDISK
if (drive->media != ide_disk)
if (drive->type != ATA_DISK)
config_allows_dma = 0;
#endif
......@@ -555,7 +555,7 @@ static void ide_toggle_bounce(ide_drive_t *drive, int on)
{
u64 addr = BLK_BOUNCE_HIGH;
if (on && drive->media == ide_disk && HWIF(drive)->highmem) {
if (on && drive->type == ATA_DISK && HWIF(drive)->highmem) {
if (!PCI_DMA_BUS_IS_PHYS)
addr = BLK_BOUNCE_ANY;
else
......@@ -613,7 +613,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
if (drive->type != ATA_DISK)
return 0;
#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL); /* issue cmd to drive */
......
......@@ -69,22 +69,6 @@ char *ide_xfer_verbose (byte xfer_rate)
}
}
/*
*
*/
char *ide_media_verbose (ide_drive_t *drive)
{
switch (drive->media) {
case ide_scsi: return("scsi ");
case ide_disk: return("disk ");
case ide_optical: return("optical");
case ide_cdrom: return("cdrom ");
case ide_tape: return("tape ");
case ide_floppy: return("floppy ");
default: return("???????");
}
}
/*
* A Verbose noise maker for debugging on the attempted dmaing calls.
*/
......
......@@ -1826,14 +1826,6 @@ static int idefloppy_media_change (ide_drive_t *drive)
return test_and_clear_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
}
/*
* Revalidate the new media. Should set blk_size[]
*/
static void idefloppy_revalidate (ide_drive_t *drive)
{
ide_revalidate_drive(drive);
}
/*
* Return the current floppy capacity to ide.c.
*/
......@@ -2046,17 +2038,13 @@ static ide_proc_entry_t idefloppy_proc[] = {
#endif /* CONFIG_PROC_FS */
int idefloppy_reinit(ide_drive_t *drive);
static int idefloppy_reinit(ide_drive_t *drive);
/*
* IDE subdriver functions, registered with ide.c
*/
static ide_driver_t idefloppy_driver = {
name: "ide-floppy",
media: ide_floppy,
busy: 0,
supports_dma: 1,
supports_dsc_overlap: 0,
static struct ata_operations idefloppy_driver = {
owner: THIS_MODULE,
cleanup: idefloppy_cleanup,
standby: NULL,
flushcache: NULL,
......@@ -2066,7 +2054,7 @@ static ide_driver_t idefloppy_driver = {
open: idefloppy_open,
release: idefloppy_release,
media_change: idefloppy_media_change,
revalidate: idefloppy_revalidate,
revalidate: ide_revalidate_drive,
pre_reset: NULL,
capacity: idefloppy_capacity,
special: NULL,
......@@ -2074,13 +2062,13 @@ static ide_driver_t idefloppy_driver = {
driver_reinit: idefloppy_reinit,
};
int idefloppy_reinit (ide_drive_t *drive)
static int idefloppy_reinit (ide_drive_t *drive)
{
idefloppy_floppy_t *floppy;
int failed = 0;
MOD_INC_USE_COUNT;
while ((drive = ide_scan_devices (ide_floppy, idefloppy_driver.name, NULL, failed++)) != NULL) {
while ((drive = ide_scan_devices(ATA_FLOPPY, "ide-floppy", NULL, failed++)) != NULL) {
if (!idefloppy_identify_device (drive, drive->id)) {
printk (KERN_ERR "ide-floppy: %s: not supported by this version of ide-floppy\n", drive->name);
continue;
......@@ -2098,9 +2086,12 @@ int idefloppy_reinit (ide_drive_t *drive)
kfree (floppy);
continue;
}
DRIVER(drive)->busy++;
/* ATA-PATTERN */
ata_ops(drive)->busy++;
idefloppy_setup (drive, floppy);
DRIVER(drive)->busy--;
ata_ops(drive)->busy--;
failed--;
}
revalidate_drives();
......@@ -2115,7 +2106,7 @@ static void __exit idefloppy_exit (void)
ide_drive_t *drive;
int failed = 0;
while ((drive = ide_scan_devices (ide_floppy, idefloppy_driver.name, &idefloppy_driver, failed)) != NULL) {
while ((drive = ide_scan_devices(ATA_FLOPPY, "ide-floppy", &idefloppy_driver, failed)) != NULL) {
if (idefloppy_cleanup (drive)) {
printk ("%s: cleanup_module() called while still busy\n", drive->name);
failed++;
......@@ -2141,7 +2132,7 @@ int idefloppy_init (void)
printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
MOD_INC_USE_COUNT;
while ((drive = ide_scan_devices (ide_floppy, idefloppy_driver.name, NULL, failed++)) != NULL) {
while ((drive = ide_scan_devices (ATA_FLOPPY, "ide-floppy", NULL, failed++)) != NULL) {
if (!idefloppy_identify_device (drive, drive->id)) {
printk (KERN_ERR "ide-floppy: %s: not supported by this version of ide-floppy\n", drive->name);
continue;
......@@ -2159,9 +2150,11 @@ int idefloppy_init (void)
kfree (floppy);
continue;
}
DRIVER(drive)->busy++;
/* ATA-PATTERN */
ata_ops(drive)->busy++;
idefloppy_setup (drive, floppy);
DRIVER(drive)->busy--;
ata_ops(drive)->busy--;
failed--;
}
revalidate_drives();
......
/*
* linux/drivers/ide/ide-geometry.c
*
* Sun Feb 24 23:13:03 CET 2002: Patch by Andries Brouwer to remove the
* confused CMOS probe applied. This is solving more problems then it my
* (unexpectedly) introduce.
*/
#include <linux/config.h>
#include <linux/ide.h>
#include <linux/mc146818rtc.h>
#include <asm/io.h>
#ifdef CONFIG_BLK_DEV_IDE
/*
* We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc
* controller that is BIOS compatible with ST-506, and thus showing up in our
* BIOS table, but not register compatible, and therefore not present in CMOS.
*
* Furthermore, we will assume that our ST-506 drives <if any> are the primary
* drives in the system -- the ones reflected as drive 1 or 2. The first
* drive is stored in the high nibble of CMOS byte 0x12, the second in the low
* nibble. This will be either a 4 bit drive type or 0xf indicating use byte
* 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS. A non-zero value
* means we have an AT controller hard disk for that drive.
*
* Of course, there is no guarantee that either drive is actually on the
* "primary" IDE interface, but we don't bother trying to sort that out here.
* If a drive is not actually on the primary interface, then these parameters
* will be ignored. This results in the user having to supply the logical
* drive geometry as a boot parameter for each drive not on the primary i/f.
*/
/*
* The only "perfect" way to handle this would be to modify the setup.[cS] code
* to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info
* for us during initialization. I have the necessary docs -- any takers? -ml
*/
/*
* I did this, but it doesnt work - there is no reasonable way to find the
* correspondence between the BIOS numbering of the disks and the Linux
* numbering. -aeb
*
* The code below is bad. One of the problems is that drives 1 and 2
* may be SCSI disks (even when IDE disks are present), so that
* the geometry we read here from BIOS is attributed to the wrong disks.
* Consequently, also the former "drive->present = 1" below was a mistake.
*
* Eventually the entire routine below should be removed.
*
* 17-OCT-2000 rjohnson@analogic.com Added spin-locks for reading CMOS
* chip.
*/
void probe_cmos_for_drives (ide_hwif_t *hwif)
{
#ifdef __i386__
extern struct drive_info_struct drive_info;
byte cmos_disks, *BIOS = (byte *) &drive_info;
int unit;
unsigned long flags;
#ifdef CONFIG_BLK_DEV_PDC4030
if (hwif->chipset == ide_pdc4030 && hwif->channel != 0)
return;
#endif /* CONFIG_BLK_DEV_PDC4030 */
spin_lock_irqsave(&rtc_lock, flags);
cmos_disks = CMOS_READ(0x12);
spin_unlock_irqrestore(&rtc_lock, flags);
/* Extract drive geometry from CMOS+BIOS if not already setup */
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
if ((cmos_disks & (0xf0 >> (unit*4)))
&& !drive->present && !drive->nobios) {
unsigned short cyl = *(unsigned short *)BIOS;
unsigned char head = *(BIOS+2);
unsigned char sect = *(BIOS+14);
if (cyl > 0 && head > 0 && sect > 0 && sect < 64) {
drive->cyl = drive->bios_cyl = cyl;
drive->head = drive->bios_head = head;
drive->sect = drive->bios_sect = sect;
drive->ctl = *(BIOS+8);
} else {
printk("hd%c: C/H/S=%d/%d/%d from BIOS ignored\n",
unit+'a', cyl, head, sect);
}
}
BIOS += 16;
}
#endif
}
#endif /* CONFIG_BLK_DEV_IDE */
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
extern ide_drive_t * get_info_ptr(kdev_t);
......@@ -105,14 +27,14 @@ ontrack(ide_drive_t *drive, int heads, unsigned int *c, int *h, int *s) {
unsigned long total;
/*
* The specs say: take geometry as obtained from Identify,
* compute total capacity C*H*S from that, and truncate to
* 1024*255*63. Now take S=63, H the first in the sequence
* 4, 8, 16, 32, 64, 128, 255 such that 63*H*1024 >= total.
* [Please tell aeb@cwi.nl in case this computes a
* geometry different from what OnTrack uses.]
* The specs say: take geometry as obtained from Identify, compute
* total capacity C*H*S from that, and truncate to 1024*255*63. Now
* take S=63, H the first in the sequence 4, 8, 16, 32, 64, 128, 255
* such that 63*H*1024 >= total. [Please tell aeb@cwi.nl in case this
* computes a geometry different from what OnTrack uses.]
*/
total = DRIVER(drive)->capacity(drive);
total = ata_ops(drive)->capacity(drive);
*s = 63;
......
......@@ -130,17 +130,17 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
}
#endif /* CONFIG_BLK_DEV_PDC4030 */
switch (type) {
case ide_floppy:
case ATA_FLOPPY:
if (!strstr(id->model, "CD-ROM")) {
if (!strstr(id->model, "oppy") && !strstr(id->model, "poyp") && !strstr(id->model, "ZIP"))
printk("cdrom or floppy?, assuming ");
if (drive->media != ide_cdrom) {
if (drive->type != ATA_ROM) {
printk ("FLOPPY");
break;
}
}
type = ide_cdrom; /* Early cdrom models used zero */
case ide_cdrom:
type = ATA_ROM; /* Early cdrom models used zero */
case ATA_ROM:
drive->removable = 1;
#ifdef CONFIG_PPC
/* kludge for Apple PowerBook internal zip */
......@@ -152,10 +152,10 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
#endif
printk ("CD/DVD-ROM");
break;
case ide_tape:
case ATA_TAPE:
printk ("TAPE");
break;
case ide_optical:
case ATA_MOD:
printk ("OPTICAL");
drive->removable = 1;
break;
......@@ -164,7 +164,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
break;
}
printk (" drive\n");
drive->media = type;
drive->type = type;
return;
}
......@@ -184,7 +184,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
mate->noprobe = 1;
}
}
drive->media = ide_disk;
drive->type = ATA_DISK;
printk("ATA DISK drive\n");
QUIRK_LIST(HWIF(drive),drive);
return;
......@@ -327,12 +327,12 @@ static int do_probe (ide_drive_t *drive, byte cmd)
int rc;
ide_hwif_t *hwif = HWIF(drive);
if (drive->present) { /* avoid waiting for inappropriate probes */
if ((drive->media != ide_disk) && (cmd == WIN_IDENTIFY))
if ((drive->type != ATA_DISK) && (cmd == WIN_IDENTIFY))
return 4;
}
#ifdef DEBUG
printk("probing for %s: present=%d, media=%d, probetype=%s\n",
drive->name, drive->present, drive->media,
printk("probing for %s: present=%d, type=%d, probetype=%s\n",
drive->name, drive->present, drive->type,
(cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI");
#endif
ide_delay_50ms(); /* needed for some systems (e.g. crw9624 as drive0 with disk as slave) */
......@@ -421,10 +421,10 @@ static inline void probe_for_drive (ide_drive_t *drive)
if (!drive->present)
return; /* drive not found */
if (drive->id == NULL) { /* identification failed? */
if (drive->media == ide_disk) {
if (drive->type == ATA_DISK) {
printk ("%s: non-IDE drive, CHS=%d/%d/%d\n",
drive->name, drive->cyl, drive->head, drive->sect);
} else if (drive->media == ide_cdrom) {
} else if (drive->type == ATA_ROM) {
printk("%s: ATAPI cdrom (?)\n", drive->name);
} else {
drive->present = 0; /* nuke it */
......@@ -481,33 +481,31 @@ static void hwif_register (ide_hwif_t *hwif)
((unsigned long)hwif->io_ports[IDE_STATUS_OFFSET])) {
ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 8, hwif->name);
hwif->straight8 = 1;
goto jump_straight8;
}
if (hwif->io_ports[IDE_DATA_OFFSET])
ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_ERROR_OFFSET])
ide_request_region(hwif->io_ports[IDE_ERROR_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_NSECTOR_OFFSET])
ide_request_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_SECTOR_OFFSET])
ide_request_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_LCYL_OFFSET])
ide_request_region(hwif->io_ports[IDE_LCYL_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_HCYL_OFFSET])
ide_request_region(hwif->io_ports[IDE_HCYL_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_SELECT_OFFSET])
ide_request_region(hwif->io_ports[IDE_SELECT_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_STATUS_OFFSET])
ide_request_region(hwif->io_ports[IDE_STATUS_OFFSET], 1, hwif->name);
jump_straight8:
} else {
if (hwif->io_ports[IDE_DATA_OFFSET])
ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_ERROR_OFFSET])
ide_request_region(hwif->io_ports[IDE_ERROR_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_NSECTOR_OFFSET])
ide_request_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_SECTOR_OFFSET])
ide_request_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_LCYL_OFFSET])
ide_request_region(hwif->io_ports[IDE_LCYL_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_HCYL_OFFSET])
ide_request_region(hwif->io_ports[IDE_HCYL_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_SELECT_OFFSET])
ide_request_region(hwif->io_ports[IDE_SELECT_OFFSET], 1, hwif->name);
if (hwif->io_ports[IDE_STATUS_OFFSET])
ide_request_region(hwif->io_ports[IDE_STATUS_OFFSET], 1, hwif->name);
}
if (hwif->io_ports[IDE_CONTROL_OFFSET])
ide_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name);
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
if (hwif->io_ports[IDE_IRQ_OFFSET])
ide_request_region(hwif->io_ports[IDE_IRQ_OFFSET], 1, hwif->name);
#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
#endif
}
/*
......@@ -521,13 +519,6 @@ static void probe_hwif (ide_hwif_t *hwif)
if (hwif->noprobe)
return;
#ifdef CONFIG_BLK_DEV_IDE
if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) {
extern void probe_cmos_for_drives(ide_hwif_t *);
probe_cmos_for_drives (hwif);
}
#endif
if ((hwif->chipset != ide_4drives || !hwif->mate->present) &&
#if CONFIG_BLK_DEV_PDC4030
......@@ -545,7 +536,7 @@ static void probe_hwif (ide_hwif_t *hwif)
}
if (!msgout)
printk("%s: ports already in use, skipping probe\n", hwif->name);
return;
return;
}
__save_flags(flags); /* local CPU only */
......@@ -796,60 +787,51 @@ static int init_irq (ide_hwif_t *hwif)
static void init_gendisk (ide_hwif_t *hwif)
{
struct gendisk *gd;
unsigned int unit, units, minors, i;
unsigned int unit, minors, i;
extern devfs_handle_t ide_devfs_handle;
#if 1
units = MAX_DRIVES;
#else
/* figure out maximum drive number on the interface */
for (units = MAX_DRIVES; units > 0; --units) {
if (hwif->drives[units-1].present)
break;
}
#endif
minors = units * (1<<PARTN_BITS);
minors = MAX_DRIVES * (1 << PARTN_BITS);
gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
if (!gd)
goto err_kmalloc_gd;
gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
if (!gd->sizes)
goto err_kmalloc_gd_sizes;
gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
if (!gd->part)
goto err_kmalloc_gd_part;
memset(gd->part, 0, minors * sizeof(struct hd_struct));
blksize_size[hwif->major] = kmalloc (minors*sizeof(int), GFP_KERNEL);
if (!blksize_size[hwif->major])
goto err_kmalloc_bs;
memset(gd->part, 0, minors * sizeof(struct hd_struct));
for (i = 0; i < minors; ++i)
blksize_size[hwif->major][i] = BLOCK_SIZE;
for (unit = 0; unit < units; ++unit)
for (unit = 0; unit < MAX_DRIVES; ++unit)
hwif->drives[unit].part = &gd->part[unit << PARTN_BITS];
gd->major = hwif->major; /* our major device number */
gd->major_name = IDE_MAJOR_NAME; /* treated special in genhd.c */
gd->minor_shift = PARTN_BITS; /* num bits for partitions */
gd->nr_real = units; /* current num real drives */
gd->nr_real = MAX_DRIVES; /* current num real drives */
gd->next = NULL; /* linked list of major devs */
gd->fops = ide_fops; /* file operations */
gd->de_arr = kmalloc (sizeof *gd->de_arr * units, GFP_KERNEL);
gd->flags = kmalloc (sizeof *gd->flags * units, GFP_KERNEL);
gd->de_arr = kmalloc(sizeof(*gd->de_arr) * MAX_DRIVES, GFP_KERNEL);
gd->flags = kmalloc(sizeof(*gd->flags) * MAX_DRIVES, GFP_KERNEL);
if (gd->de_arr)
memset (gd->de_arr, 0, sizeof *gd->de_arr * units);
memset(gd->de_arr, 0, sizeof(*gd->de_arr) * MAX_DRIVES);
if (gd->flags)
memset (gd->flags, 0, sizeof *gd->flags * units);
memset(gd->flags, 0, sizeof(*gd->flags) * MAX_DRIVES);
hwif->gd = gd;
add_gendisk(gd);
for (unit = 0; unit < units; ++unit) {
#if 1
char name[64];
for (unit = 0; unit < MAX_DRIVES; ++unit) {
char name[80];
ide_add_generic_settings(hwif->drives + unit);
hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit);
sprintf (name, "host%d/bus%d/target%d/lun%d",
......@@ -858,19 +840,6 @@ static void init_gendisk (ide_hwif_t *hwif)
hwif->channel, unit, hwif->drives[unit].lun);
if (hwif->drives[unit].present)
hwif->drives[unit].de = devfs_mk_dir(ide_devfs_handle, name, NULL);
#else
if (hwif->drives[unit].present) {
char name[64];
ide_add_generic_settings(hwif->drives + unit);
hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit);
sprintf (name, "host%d/bus%d/target%d/lun%d",
(hwif->channel && hwif->mate) ? hwif->mate->index : hwif->index,
hwif->channel, unit, hwif->drives[unit].lun);
hwif->drives[unit].de =
devfs_mk_dir (ide_devfs_handle, name, NULL);
}
#endif
}
return;
......@@ -881,7 +850,7 @@ static void init_gendisk (ide_hwif_t *hwif)
err_kmalloc_gd_sizes:
kfree(gd);
err_kmalloc_gd:
printk(KERN_WARNING "(ide::init_gendisk) Out of memory\n");
printk(KERN_CRIT "(ide::init_gendisk) Out of memory\n");
return;
}
......
......@@ -202,7 +202,7 @@ static int proc_ide_get_identify(ide_drive_t *drive, byte *buf)
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.sector_count = 0x01;
taskfile.command = (drive->media == ide_disk) ? WIN_IDENTIFY : WIN_PIDENTIFY ;
taskfile.command = (drive->type == ATA_DISK) ? WIN_IDENTIFY : WIN_PIDENTIFY ;
return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
}
......@@ -346,9 +346,9 @@ static int proc_ide_write_settings
int proc_ide_read_capacity
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = data;
ide_driver_t *driver = drive->driver;
int len;
ide_drive_t *drive = data;
struct ata_operations *driver = drive->driver;
int len;
if (!driver)
len = sprintf(page, "(none)\n");
......@@ -381,58 +381,31 @@ static int proc_ide_read_dmodel
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
static int proc_ide_read_driver
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *) data;
ide_driver_t *driver = drive->driver;
int len;
if (!driver)
len = sprintf(page, "(none)\n");
else
len = sprintf(page, "%s\n", driver->name);
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
static int proc_ide_write_driver
(struct file *file, const char *buffer, unsigned long count, void *data)
{
ide_drive_t *drive = data;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (ide_replace_subdriver(drive, buffer))
return -EINVAL;
return count;
}
static int proc_ide_read_media
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = data;
const char *media;
const char *type;
int len;
switch (drive->media) {
case ide_disk: media = "disk\n";
switch (drive->type) {
case ATA_DISK: type = "disk\n";
break;
case ide_cdrom: media = "cdrom\n";
case ATA_ROM: type = "cdrom\n";
break;
case ide_tape: media = "tape\n";
case ATA_TAPE: type = "tape\n";
break;
case ide_floppy:media = "floppy\n";
case ATA_FLOPPY:type = "floppy\n";
break;
default: media = "UNKNOWN\n";
default: type = "UNKNOWN\n";
break;
}
strcpy(page,media);
len = strlen(media);
strcpy(page,type);
len = strlen(type);
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
static ide_proc_entry_t generic_drive_entries[] = {
{ "driver", S_IFREG|S_IRUGO, proc_ide_read_driver, proc_ide_write_driver },
{ "identify", S_IFREG|S_IRUSR, proc_ide_read_identify, NULL },
{ "media", S_IFREG|S_IRUGO, proc_ide_read_media, NULL },
{ "model", S_IFREG|S_IRUGO, proc_ide_read_dmodel, NULL },
......@@ -476,7 +449,7 @@ static void create_proc_ide_drives(ide_hwif_t *hwif)
for (d = 0; d < MAX_DRIVES; d++) {
ide_drive_t *drive = &hwif->drives[d];
ide_driver_t *driver = drive->driver;
struct ata_operations *driver = drive->driver;
if (!drive->present)
continue;
......@@ -497,35 +470,9 @@ static void create_proc_ide_drives(ide_hwif_t *hwif)
}
}
void recreate_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct proc_dir_entry *ent;
struct proc_dir_entry *parent = hwif->proc;
char name[64];
if (drive->present && !drive->proc) {
drive->proc = proc_mkdir(drive->name, parent);
if (drive->proc)
ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
/*
* assume that we have these already, however, should test FIXME!
* if (driver) {
* ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
* ide_add_proc_entries(drive->proc, driver->proc, drive);
* }
*
*/
sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name);
ent = proc_symlink(drive->name, proc_ide_root, name);
if (!ent)
return;
}
}
void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
static void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_driver_t *driver = drive->driver;
struct ata_operations *driver = drive->driver;
if (drive->proc) {
if (driver)
......
......@@ -6098,8 +6098,11 @@ static int idetape_cleanup (ide_drive_t *drive)
}
idetape_chrdevs[minor].drive = NULL;
restore_flags (flags); /* all CPUs (overkill?) */
DRIVER(drive)->busy = 0;
(void) ide_unregister_subdriver (drive);
/* FIXME: this appears to be totally wrong! */
ata_ops(drive)->busy = 0;
ide_unregister_subdriver (drive);
drive->driver_data = NULL;
devfs_unregister (tape->de_r);
devfs_unregister (tape->de_n);
......@@ -6137,17 +6140,13 @@ static ide_proc_entry_t idetape_proc[] = {
#endif
int idetape_reinit(ide_drive_t *drive);
static int idetape_reinit(ide_drive_t *drive);
/*
* IDE subdriver functions, registered with ide.c
*/
static ide_driver_t idetape_driver = {
name: "ide-tape",
media: ide_tape,
busy: 1,
supports_dma: 1,
supports_dsc_overlap: 1,
static struct ata_operations idetape_driver = {
owner: THIS_MODULE,
cleanup: idetape_cleanup,
standby: NULL,
flushcache: NULL,
......@@ -6176,90 +6175,10 @@ static struct file_operations idetape_fops = {
release: idetape_chrdev_release,
};
int idetape_reinit (ide_drive_t *drive)
/* This will propably just go entierly away... */
static int idetape_reinit (ide_drive_t *drive)
{
#if 0
idetape_tape_t *tape;
int minor, failed = 0, supported = 0;
/* DRIVER(drive)->busy++; */
MOD_INC_USE_COUNT;
#if ONSTREAM_DEBUG
printk(KERN_INFO "ide-tape: MOD_INC_USE_COUNT in idetape_init\n");
#endif
if (!idetape_chrdev_present)
for (minor = 0; minor < MAX_HWIFS * MAX_DRIVES; minor++ )
idetape_chrdevs[minor].drive = NULL;
if ((drive = ide_scan_devices (ide_tape, idetape_driver.name, NULL, failed++)) == NULL) {
revalidate_drives();
MOD_DEC_USE_COUNT;
#if ONSTREAM_DEBUG
printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n");
#endif
return 0;
}
if (!idetape_chrdev_present &&
devfs_register_chrdev (IDETAPE_MAJOR, "ht", &idetape_fops)) {
printk (KERN_ERR "ide-tape: Failed to register character device interface\n");
MOD_DEC_USE_COUNT;
#if ONSTREAM_DEBUG
printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n");
#endif
return -EBUSY;
}
do {
if (!idetape_identify_device (drive, drive->id)) {
printk (KERN_ERR "ide-tape: %s: not supported by this version of ide-tape\n", drive->name);
continue;
}
if (drive->scsi) {
if (strstr(drive->id->model, "OnStream DI-30")) {
printk("ide-tape: ide-scsi emulation is not supported for %s.\n", drive->id->model);
} else {
printk("ide-tape: passing drive %s to ide-scsi emulation.\n", drive->name);
continue;
}
}
tape = (idetape_tape_t *) kmalloc (sizeof (idetape_tape_t), GFP_KERNEL);
if (tape == NULL) {
printk (KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name);
continue;
}
if (ide_register_subdriver (drive, &idetape_driver)) {
printk (KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name);
kfree (tape);
continue;
}
for (minor = 0; idetape_chrdevs[minor].drive != NULL; minor++);
idetape_setup (drive, tape, minor);
idetape_chrdevs[minor].drive = drive;
tape->de_r =
devfs_register (drive->de, "mt", DEVFS_FL_DEFAULT,
HWIF(drive)->major, minor,
S_IFCHR | S_IRUGO | S_IWUGO,
&idetape_fops, NULL);
tape->de_n =
devfs_register (drive->de, "mtn", DEVFS_FL_DEFAULT,
HWIF(drive)->major, minor + 128,
S_IFCHR | S_IRUGO | S_IWUGO,
&idetape_fops, NULL);
devfs_register_tape (tape->de_r);
supported++; failed--;
} while ((drive = ide_scan_devices (ide_tape, idetape_driver.name, NULL, failed++)) != NULL);
if (!idetape_chrdev_present && !supported) {
devfs_unregister_chrdev (IDETAPE_MAJOR, "ht");
} else
idetape_chrdev_present = 1;
revalidate_drives();
MOD_DEC_USE_COUNT;
#if ONSTREAM_DEBUG
printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n");
#endif
return 0;
#else
return 1;
#endif
}
MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
......@@ -6294,7 +6213,7 @@ int idetape_init (void)
for (minor = 0; minor < MAX_HWIFS * MAX_DRIVES; minor++ )
idetape_chrdevs[minor].drive = NULL;
if ((drive = ide_scan_devices (ide_tape, idetape_driver.name, NULL, failed++)) == NULL) {
if ((drive = ide_scan_devices(ATA_TAPE, "ide-tape", NULL, failed++)) == NULL) {
revalidate_drives();
MOD_DEC_USE_COUNT;
#if ONSTREAM_DEBUG
......@@ -6349,7 +6268,7 @@ int idetape_init (void)
&idetape_fops, NULL);
devfs_register_tape (tape->de_r);
supported++; failed--;
} while ((drive = ide_scan_devices (ide_tape, idetape_driver.name, NULL, failed++)) != NULL);
} while ((drive = ide_scan_devices(ATA_TAPE, "ide-tape", NULL, failed++)) != NULL);
if (!idetape_chrdev_present && !supported) {
devfs_unregister_chrdev (IDETAPE_MAJOR, "ht");
} else
......
......@@ -648,7 +648,7 @@ ide_startstop_t taskfile_error (ide_drive_t *drive, const char *msg, byte stat)
if (rq->errors >= ERROR_MAX) {
if (drive->driver != NULL)
DRIVER(drive)->end_request(0, HWGROUP(drive));
ata_ops(drive)->end_request(0, HWGROUP(drive));
else
ide_end_request(drive, 0);
} else {
......
This diff is collapsed.
......@@ -103,7 +103,7 @@ static int ns87415_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
ns87415_prepare_drive(drive, 0); /* DMA failed: select PIO xfer */
return 1;
case ide_dma_check:
if (drive->media != ide_disk)
if (drive->type != ATA_DISK)
return ide_dmaproc(ide_dma_off_quietly, drive);
/* Fallthrough... */
default:
......
......@@ -63,7 +63,6 @@
static int pdc202xx_get_info(char *, char **, off_t, int);
extern int (*pdc202xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
char *pdc202xx_pio_verbose (u32 drive_pci)
......@@ -412,7 +411,8 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed)
default: return -1;
}
if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) return -1;
if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
return -1;
pci_read_config_dword(dev, drive_pci, &drive_conf);
pci_read_config_byte(dev, (drive_pci), &AP);
......@@ -820,7 +820,8 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
}
if (jumpbit) {
if (drive->media != ide_disk) return ide_dma_off_quietly;
if (drive->type != ATA_DISK)
return ide_dma_off_quietly;
if (id->capability & 4) { /* IORDY_EN & PREFETCH_EN */
OUT_BYTE((iordy + adj), indexreg);
OUT_BYTE((IN_BYTE(datareg)|0x03), datareg);
......@@ -869,13 +870,14 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
chipset_is_set:
if (drive->media != ide_disk) return ide_dma_off_quietly;
if (drive->type != ATA_DISK)
return ide_dma_off_quietly;
pci_read_config_byte(dev, (drive_pci), &AP);
if (id->capability & 4) /* IORDY_EN */
pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
pci_read_config_byte(dev, (drive_pci), &AP);
if (drive->media == ide_disk) /* PREFETCH_EN */
if (drive->type == ATA_DISK) /* PREFETCH_EN */
pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
jumpbit_is_set:
......
......@@ -34,7 +34,6 @@
static int pdcadma_get_info(char *, char **, off_t, int);
extern int (*pdcadma_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
static int pdcadma_get_info (char *buffer, char **addr, off_t offset, int count)
......
......@@ -77,7 +77,6 @@
static int piix_get_info(char *, char **, off_t, int);
extern int (*piix_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
......
......@@ -293,7 +293,7 @@ static void qd6580_tune_drive (ide_drive_t *drive, byte pio)
printk(KERN_INFO "%s: PIO mode%d\n",drive->name,pio);
}
if (!HWIF(drive)->channel && drive->media != ide_disk) {
if (!HWIF(drive)->channel && drive->type != ATA_DISK) {
qd_write_reg(0x5f,QD_CONTROL_PORT);
printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO and post-write buffer on %s.\n",drive->name,HWIF(drive)->name);
}
......
......@@ -105,7 +105,6 @@ static byte svwks_revision = 0;
static int svwks_get_info(char *, char **, off_t, int);
extern int (*svwks_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static int svwks_get_info (char *buffer, char **addr, off_t offset, int count)
{
......
......@@ -238,7 +238,7 @@ static void config_drive_art_rwp (ide_drive_t *drive)
byte rw_prefetch = (0x11 << drive->dn);
pci_read_config_byte(dev, 0x4b, &reg4bh);
if (drive->media != ide_disk)
if (drive->type != ATA_DISK)
return;
if ((reg4bh & rw_prefetch) != rw_prefetch)
......
......@@ -60,7 +60,6 @@
static int slc90e66_get_info(char *, char **, off_t, int);
extern int (*slc90e66_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
static int slc90e66_get_info (char *buffer, char **addr, off_t offset, int count)
......
......@@ -192,7 +192,7 @@ static int trm290_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
outl(hwif->dmatable_dma|reading|writing, hwif->dma_base);
drive->waiting_for_dma = 1;
outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
if (drive->media != ide_disk)
if (drive->type != ATA_DISK)
return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
......
......@@ -182,7 +182,7 @@ static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc)
if (!test_bit(PC_TRANSFORM, &pc->flags))
return;
if (drive->media == ide_cdrom || drive->media == ide_optical) {
if (drive->type == ATA_ROM || drive->type == ATA_MOD) {
if (c[0] == READ_6 || c[0] == WRITE_6) {
c[8] = c[4]; c[5] = c[3]; c[4] = c[2];
c[3] = c[1] & 0x1f; c[2] = 0; c[1] &= 0xe0;
......@@ -221,7 +221,7 @@ static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc)
if (!test_bit(PC_TRANSFORM, &pc->flags))
return;
if (drive->media == ide_cdrom || drive->media == ide_optical) {
if (drive->type == ATA_ROM || drive->type == ATA_MOD) {
if (pc->c[0] == MODE_SENSE_10 && sc[0] == MODE_SENSE) {
scsi_buf[0] = atapi_buf[1]; /* Mode data length */
scsi_buf[1] = atapi_buf[2]; /* Medium type */
......@@ -508,7 +508,8 @@ static void idescsi_add_settings(ide_drive_t *drive)
*/
static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id)
{
DRIVER(drive)->busy++;
ata_ops(drive)->busy++;
idescsi_drives[id] = drive;
drive->driver_data = scsi;
drive->ready_stat = 0;
......@@ -535,17 +536,13 @@ static int idescsi_cleanup (ide_drive_t *drive)
return 0;
}
int idescsi_reinit(ide_drive_t *drive);
static int idescsi_reinit(ide_drive_t *drive);
/*
* IDE subdriver functions, registered with ide.c
*/
static ide_driver_t idescsi_driver = {
name: "ide-scsi",
media: ide_scsi,
busy: 0,
supports_dma: 1,
supports_dsc_overlap: 0,
static struct ata_operations idescsi_driver = {
owner: THIS_MODULE,
cleanup: idescsi_cleanup,
standby: NULL,
flushcache: NULL,
......@@ -563,50 +560,20 @@ static ide_driver_t idescsi_driver = {
driver_reinit: idescsi_reinit,
};
int idescsi_reinit (ide_drive_t *drive)
static int idescsi_reinit (ide_drive_t *drive)
{
#if 0
idescsi_scsi_t *scsi;
byte media[] = {TYPE_DISK, TYPE_TAPE, TYPE_PROCESSOR, TYPE_WORM, TYPE_ROM, TYPE_SCANNER, TYPE_MOD, 255};
int i, failed, id;
if (!idescsi_initialized)
return 0;
for (i = 0; i < MAX_HWIFS * MAX_DRIVES; i++)
idescsi_drives[i] = NULL;
MOD_INC_USE_COUNT;
for (i = 0; media[i] != 255; i++) {
failed = 0;
while ((drive = ide_scan_devices (media[i], idescsi_driver.name, NULL, failed++)) != NULL) {
if ((scsi = (idescsi_scsi_t *) kmalloc (sizeof (idescsi_scsi_t), GFP_KERNEL)) == NULL) {
printk (KERN_ERR "ide-scsi: %s: Can't allocate a scsi structure\n", drive->name);
continue;
}
if (ide_register_subdriver (drive, &idescsi_driver)) {
printk (KERN_ERR "ide-scsi: %s: Failed to register the driver with ide.c\n", drive->name);
kfree (scsi);
continue;
}
for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++);
idescsi_setup (drive, scsi, id);
failed--;
}
}
revalidate_drives();
MOD_DEC_USE_COUNT;
#endif
return 0;
}
/*
* idescsi_init will register the driver for each scsi.
*/
int idescsi_init (void)
static int idescsi_init(void)
{
ide_drive_t *drive;
idescsi_scsi_t *scsi;
/* FIXME: The following is just plain wrong, since those are definitely *not* the
* media types supported by the ATA layer */
byte media[] = {TYPE_DISK, TYPE_TAPE, TYPE_PROCESSOR, TYPE_WORM, TYPE_ROM, TYPE_SCANNER, TYPE_MOD, 255};
int i, failed, id;
......@@ -618,7 +585,7 @@ int idescsi_init (void)
MOD_INC_USE_COUNT;
for (i = 0; media[i] != 255; i++) {
failed = 0;
while ((drive = ide_scan_devices (media[i], idescsi_driver.name, NULL, failed++)) != NULL) {
while ((drive = ide_scan_devices (media[i], "ide-scsi", NULL, failed++)) != NULL) {
if ((scsi = (idescsi_scsi_t *) kmalloc (sizeof (idescsi_scsi_t), GFP_KERNEL)) == NULL) {
printk (KERN_ERR "ide-scsi: %s: Can't allocate a scsi structure\n", drive->name);
......@@ -666,7 +633,7 @@ int idescsi_release (struct Scsi_Host *host)
for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
drive = idescsi_drives[id];
if (drive)
DRIVER(drive)->busy--;
ata_ops(drive)->busy--;
}
return 0;
}
......@@ -896,9 +863,17 @@ static void __exit exit_idescsi_module(void)
int i, failed;
scsi_unregister_host(&idescsi_template);
/* FIXME: The media types scanned here have literally nothing to do
* with the media types used by the overall ATA code!
*
* This is basically showing us, that there is something wrong with the
* ide_scan_devices function.
*/
for (i = 0; media[i] != 255; i++) {
failed = 0;
while ((drive = ide_scan_devices (media[i], idescsi_driver.name, &idescsi_driver, failed)) != NULL)
while ((drive = ide_scan_devices (media[i], "ide-scsi", &idescsi_driver, failed)) != NULL)
if (idescsi_cleanup (drive)) {
printk ("%s: exit_idescsi_module() called while still busy\n", drive->name);
failed++;
......
#ifndef _IDE_H
#define _IDE_H
/*
* linux/include/linux/ide.h
*
* Copyright (C) 1994-1998 Linus Torvalds & authors
* Copyright (C) 1994-2002 Linus Torvalds & authors
*/
#include <linux/config.h>
......@@ -350,12 +348,13 @@ void ide_setup_ports( hw_regs_t *hw,
* Now for the data we need to maintain per-drive: ide_drive_t
*/
#define ide_scsi 0x21
#define ide_disk 0x20
#define ide_optical 0x7
#define ide_cdrom 0x5
#define ide_tape 0x1
#define ide_floppy 0x0
#define ATA_DISK 0x20
#define ATA_TAPE 0x01
#define ATA_ROM 0x05 /* CD-ROM */
#define ATA_MOD 0x07 /* optical */
#define ATA_FLOPPY 0x00
#define ATA_SCSI 0x21
#define ATA_NO_LUN 0x7f
typedef union {
unsigned all : 8; /* all of the bits together */
......@@ -371,7 +370,14 @@ typedef union {
struct ide_settings_s;
typedef struct ide_drive_s {
request_queue_t queue; /* request queue */
char type; /* distingiush different devices: disk, cdrom, tape, floppy, ... */
/* NOTE: If we had proper separation between channel and host chip, we
* could move this to the chanell and many sync problems would
* magically just go away.
*/
request_queue_t queue; /* per device request queue */
struct ide_drive_s *next; /* circular list of hwgroup drives */
unsigned long sleep; /* sleep until this time */
unsigned long service_start; /* time we started last request */
......@@ -406,7 +412,6 @@ typedef struct ide_drive_s {
unsigned ata_flash : 1; /* 1=present, 0=default */
unsigned addressing; /* : 2; 0=28-bit, 1=48-bit, 2=64-bit */
byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */
byte media; /* disk, cdrom, tape, floppy, ... */
select_t select; /* basic drive/head select reg value */
byte ctl; /* "normal" value for IDE_CONTROL_REG */
byte ready_stat; /* min status value for drive ready */
......@@ -432,7 +437,7 @@ typedef struct ide_drive_s {
struct hd_driveid *id; /* drive model identification info */
struct hd_struct *part; /* drive partition table */
char name[4]; /* drive name, such as "hda" */
struct ide_driver_s *driver; /* (ide_driver_t *) */
struct ata_operations *driver;
void *driver_data; /* extra driver data */
devfs_handle_t de; /* directory for device */
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
......@@ -570,7 +575,6 @@ typedef struct hwif_s {
unsigned long last_time; /* time when previous rq was done */
#endif
byte straight8; /* Alan's straight 8 check */
void *hwif_data; /* extra hwif data */
ide_busproc_t *busproc; /* driver soft-power interface */
byte bus_state; /* power state of the IDE bus */
struct device device; /* global device tree handle */
......@@ -663,8 +667,6 @@ typedef struct {
#ifdef CONFIG_PROC_FS
void proc_ide_create(void);
void proc_ide_destroy(void);
void recreate_proc_ide_device(ide_hwif_t *, ide_drive_t *);
void destroy_proc_ide_device(ide_hwif_t *, ide_drive_t *);
void destroy_proc_ide_drives(ide_hwif_t *);
void create_proc_ide_interfaces(void);
void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data);
......@@ -692,32 +694,54 @@ read_proc_t proc_ide_read_geometry;
#endif
/*
* Subdrivers support.
* This structure describes the operations possible on a particular device type
* (CD-ROM, tape, DISK and so on).
*
* This is the main hook for device type support submodules.
*/
typedef struct ide_driver_s {
const char *name;
byte media;
unsigned busy : 1;
unsigned supports_dma : 1;
unsigned supports_dsc_overlap : 1;
struct ata_operations {
struct module *owner;
unsigned busy: 1; /* FIXME: this will go soon away... */
int (*cleanup)(ide_drive_t *);
int (*standby)(ide_drive_t *);
int (*flushcache)(ide_drive_t *);
ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long);
int (*end_request)(ide_drive_t *drive, int uptodate);
int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
int (*open)(struct inode *, struct file *, ide_drive_t *);
void (*release)(struct inode *, struct file *, ide_drive_t *);
int (*media_change)(ide_drive_t *);
void (*revalidate)(ide_drive_t *);
void (*pre_reset)(ide_drive_t *);
unsigned long (*capacity)(ide_drive_t *);
ide_startstop_t (*special)(ide_drive_t *);
ide_proc_entry_t *proc;
int (*driver_reinit)(ide_drive_t *);
} ide_driver_t;
};
/* Alas, no aliases. Too much hassle with bringing module.h everywhere */
#define ata_get(ata) \
(((ata) && (ata)->owner) \
? ( try_inc_mod_count((ata)->owner) ? (ata) : NULL ) \
: (ata))
#define ata_put(ata) \
do { \
if ((ata) && (ata)->owner) \
__MOD_DEC_USE_COUNT((ata)->owner); \
} while(0)
#define DRIVER(drive) ((drive)->driver)
/* FIXME: Actually implement and use them as soon as possible! to make the
* ide_scan_devices() go away! */
extern int unregister_ata_driver(unsigned int type, struct ata_operations *driver);
extern int register_ata_driver(unsigned int type, struct ata_operations *driver);
#define ata_ops(drive) ((drive)->driver)
/*
* ide_hwifs[] is the master data structure used to keep track
......@@ -994,30 +1018,24 @@ extern ide_proc_entry_t generic_subdriver_entries[];
extern int ideprobe_init (void);
#endif
#ifdef CONFIG_BLK_DEV_IDEDISK
extern int idedisk_reinit (ide_drive_t *drive);
extern int idedisk_init (void);
#endif /* CONFIG_BLK_DEV_IDEDISK */
#endif
#ifdef CONFIG_BLK_DEV_IDECD
extern int ide_cdrom_reinit (ide_drive_t *drive);
extern int ide_cdrom_init (void);
#endif /* CONFIG_BLK_DEV_IDECD */
#endif
#ifdef CONFIG_BLK_DEV_IDETAPE
extern int idetape_reinit (ide_drive_t *drive);
extern int idetape_init (void);
#endif /* CONFIG_BLK_DEV_IDETAPE */
#endif
#ifdef CONFIG_BLK_DEV_IDEFLOPPY
extern int idefloppy_reinit (ide_drive_t *drive);
extern int idefloppy_init (void);
#endif /* CONFIG_BLK_DEV_IDEFLOPPY */
#endif
#ifdef CONFIG_BLK_DEV_IDESCSI
extern int idescsi_reinit (ide_drive_t *drive);
extern int idescsi_init (void);
#endif /* CONFIG_BLK_DEV_IDESCSI */
#endif
ide_drive_t *ide_scan_devices (byte media, const char *name, ide_driver_t *driver, int n);
extern int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver);
ide_drive_t *ide_scan_devices (byte media, const char *name, struct ata_operations *driver, int n);
extern int ide_register_subdriver(ide_drive_t *drive, struct ata_operations *driver);
extern int ide_unregister_subdriver(ide_drive_t *drive);
extern int ide_replace_subdriver(ide_drive_t *drive, const char *driver);
#ifdef CONFIG_BLK_DEV_IDEPCI
#define ON_BOARD 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment