From 49f0c7c7ba5f3cd7157a81d393253391f41736d5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 2 Apr 2005 19:28:52 +0200 Subject: [ide] drive->nice1 fix It is drive's property independent of the driver being used so move drive->nice1 setup from ide_register_subdriver() to probe_hwif() in ide-probe.c. As a result changing a driver which controls the drive no longer affects this flag. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 11 ++++++++--- drivers/ide/ide.c | 1 - 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index cb158558d2012..2b8c8f86edbd0 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -862,6 +862,13 @@ static void probe_hwif(ide_hwif_t *hwif) drive->autotune == IDE_TUNE_AUTO) /* auto-tune PIO mode */ hwif->tuneproc(drive, 255); + + if (drive->autotune != IDE_TUNE_DEFAULT && + drive->autotune != IDE_TUNE_AUTO) + continue; + + drive->nice1 = 1; + /* * MAJOR HACK BARF :-/ * @@ -871,9 +878,7 @@ static void probe_hwif(ide_hwif_t *hwif) * Move here to prevent module loading clashing. */ // drive->autodma = hwif->autodma; - if ((hwif->ide_dma_check) && - ((drive->autotune == IDE_TUNE_DEFAULT) || - (drive->autotune == IDE_TUNE_AUTO))) { + if (hwif->ide_dma_check) { /* * Force DMAing for the beginning of the check. * Some chipsets appear to do interesting diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 20da2d61b200f..f1f1091894cc9 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -2038,7 +2038,6 @@ int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) (drive->autotune == IDE_TUNE_AUTO)) { /* DMA timings and setup moved to ide-probe.c */ drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap); - drive->nice1 = 1; } #ifdef CONFIG_PROC_FS if (drive->driver != &idedefault_driver) -- cgit 1.2.3-korg From 2d10d2f9c037350f1271e64e39f242ec7953a50d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 2 Apr 2005 19:31:35 +0200 Subject: [ide] drive->dsc_overlap fix drive->dsc_overlap is supported only by ide-{cd,tape} drivers. Add missing clearing of ->dsc_overlap to ide_{cd,tape}_release() and move ->dsc_overlap setup from ide_register_subdriver() to ide_cdrom_setup() (ide-tape enables it unconditionally). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 4 ++++ drivers/ide/ide-tape.c | 1 + drivers/ide/ide.c | 5 ----- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 4b96aa193161f..dfa50ef0ad29b 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -3219,6 +3219,9 @@ int ide_cdrom_setup (ide_drive_t *drive) */ blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); + if (drive->autotune == IDE_TUNE_DEFAULT || + drive->autotune == IDE_TUNE_AUTO) + drive->dsc_overlap = (drive->next != drive); #if 0 drive->dsc_overlap = (HWIF(drive)->no_dsc) ? 0 : 1; if (HWIF(drive)->no_dsc) { @@ -3282,6 +3285,7 @@ static void ide_cd_release(struct kref *kref) if (devinfo->handle == drive && unregister_cdrom(devinfo)) printk(KERN_ERR "%s: %s failed to unregister device from the cdrom " "driver.\n", __FUNCTION__, drive->name); + drive->dsc_overlap = 0; drive->driver_data = NULL; blk_queue_prep_rq(drive->queue, NULL); g->private_data = NULL; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 913d762c5220d..8802679c3eff9 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -4698,6 +4698,7 @@ static void ide_tape_release(struct kref *kref) ide_drive_t *drive = tape->drive; struct gendisk *g = drive->disk; + drive->dsc_overlap = 0; drive->driver_data = NULL; devfs_remove("%s/mt", drive->devfs_name); devfs_remove("%s/mtn", drive->devfs_name); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index f1f1091894cc9..9990e2294308f 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -2034,11 +2034,6 @@ int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) list_add_tail(&drive->list, &driver->drives); spin_unlock(&drives_lock); // printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name); - if ((drive->autotune == IDE_TUNE_DEFAULT) || - (drive->autotune == IDE_TUNE_AUTO)) { - /* DMA timings and setup moved to ide-probe.c */ - drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap); - } #ifdef CONFIG_PROC_FS if (drive->driver != &idedefault_driver) ide_add_proc_entries(drive->proc, driver->proc, drive); -- cgit 1.2.3-korg From 2f5930e15a6456602366b04b728c8492b07830bc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 2 Apr 2005 19:33:42 +0200 Subject: [ide] destroy_proc_ide_device() cleanup When this function is called device is already unbinded from a driver so there are no driver /proc entries to remove. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-proc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 30e9611fc728d..14d1658b609fe 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -421,10 +421,7 @@ static void create_proc_ide_drives(ide_hwif_t *hwif) static void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive) { - ide_driver_t *driver = drive->driver; - if (drive->proc) { - ide_remove_proc_entries(drive->proc, driver->proc); ide_remove_proc_entries(drive->proc, generic_drive_entries); remove_proc_entry(drive->name, proc_ide_root); remove_proc_entry(drive->name, hwif->proc); -- cgit 1.2.3-korg From 4de9793a90e10d132275915066194a6bc20895bb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 2 Apr 2005 19:38:19 +0200 Subject: [ide] add ide_{un}register_region() Add ide_{un}register_region() and fix ide-{tape,scsi}.c to register block device number ranges. In ata_probe() only probe for modules. Behavior is unchanged because: * if driver is already loaded and attached to drive ata_probe() is not called et all * if driver is loaded by ata_probe() it will register new number range for a drive and this range will be found by kobj_lookup() If this is not clear please read http://lwn.net/Articles/25711/ and see drivers/base/map.c. This patch makes it possible to move drive->disk allocation from ide-probe.c to device drivers. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 61 +++++++++++++++++++++++++++++++++++-------------- drivers/ide/ide-tape.c | 3 +++ drivers/scsi/ide-scsi.c | 4 ++++ include/linux/ide.h | 3 +++ 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 2b8c8f86edbd0..4f25501bc758b 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1214,8 +1214,6 @@ static int ata_lock(dev_t dev, void *data) return 0; } -extern ide_driver_t idedefault_driver; - static struct kobject *ata_probe(dev_t dev, int *part, void *data) { ide_hwif_t *hwif = data; @@ -1223,24 +1221,53 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data) ide_drive_t *drive = &hwif->drives[unit]; if (!drive->present) return NULL; - if (drive->driver == &idedefault_driver) { - if (drive->media == ide_disk) - (void) request_module("ide-disk"); - if (drive->scsi) - (void) request_module("ide-scsi"); - if (drive->media == ide_cdrom || drive->media == ide_optical) - (void) request_module("ide-cd"); - if (drive->media == ide_tape) - (void) request_module("ide-tape"); - if (drive->media == ide_floppy) - (void) request_module("ide-floppy"); - } - if (drive->driver == &idedefault_driver) - return NULL; + + if (drive->media == ide_disk) + request_module("ide-disk"); + if (drive->scsi) + request_module("ide-scsi"); + if (drive->media == ide_cdrom || drive->media == ide_optical) + request_module("ide-cd"); + if (drive->media == ide_tape) + request_module("ide-tape"); + if (drive->media == ide_floppy) + request_module("ide-floppy"); + + return NULL; +} + +static struct kobject *exact_match(dev_t dev, int *part, void *data) +{ + struct gendisk *p = data; *part &= (1 << PARTN_BITS) - 1; - return get_disk(drive->disk); + return &p->kobj; } +static int exact_lock(dev_t dev, void *data) +{ + struct gendisk *p = data; + + if (!get_disk(p)) + return -1; + return 0; +} + +void ide_register_region(struct gendisk *disk) +{ + blk_register_region(MKDEV(disk->major, disk->first_minor), + disk->minors, NULL, exact_match, exact_lock, disk); +} + +EXPORT_SYMBOL_GPL(ide_register_region); + +void ide_unregister_region(struct gendisk *disk) +{ + blk_unregister_region(MKDEV(disk->major, disk->first_minor), + disk->minors); +} + +EXPORT_SYMBOL_GPL(ide_unregister_region); + static int alloc_disks(ide_hwif_t *hwif) { unsigned int unit; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8802679c3eff9..41513c4b27fe7 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -4687,6 +4687,8 @@ static int idetape_cleanup (ide_drive_t *drive) DRIVER(drive)->busy = 0; (void) ide_unregister_subdriver(drive); + ide_unregister_region(drive->disk); + ide_tape_put(tape); return 0; @@ -4878,6 +4880,7 @@ static int idetape_attach (ide_drive_t *drive) g->number = devfs_register_tape(drive->devfs_name); g->fops = &idetape_block_ops; g->private_data = tape; + ide_register_region(g); return 0; failed: diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 805cccd042b67..fc7e999ec4631 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -723,6 +723,8 @@ static int idescsi_cleanup (ide_drive_t *drive) if (ide_unregister_subdriver(drive)) return 1; + ide_unregister_region(g); + drive->driver_data = NULL; g->private_data = NULL; g->fops = ide_fops; @@ -1120,12 +1122,14 @@ static int idescsi_attach(ide_drive_t *drive) idescsi_setup (drive, idescsi); g->fops = &idescsi_ops; g->private_data = idescsi; + ide_register_region(g); err = scsi_add_host(host, &drive->gendev); if (!err) { scsi_scan_host(host); return 0; } /* fall through on error */ + ide_unregister_region(g); ide_unregister_subdriver(drive); } diff --git a/include/linux/ide.h b/include/linux/ide.h index 58d91a9d53325..329dcc754d868 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1442,6 +1442,9 @@ extern int ide_hwif_request_regions(ide_hwif_t *hwif); extern void ide_hwif_release_regions(ide_hwif_t* hwif); extern void ide_unregister (unsigned int index); +void ide_register_region(struct gendisk *); +void ide_unregister_region(struct gendisk *); + void ide_undecoded_slave(ide_hwif_t *); int probe_hwif_init_with_fixup(ide_hwif_t *, void (*)(ide_hwif_t *)); -- cgit 1.2.3-korg From dbb3dc01862b4121a09a4624d820bbe2e1cc24a0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 2 Apr 2005 19:49:01 +0200 Subject: [ide] kill ide_drive_t->disk * move ->disk from ide_drive_t to driver specific objects * make drivers allocate struct gendisk and setup rq->rq_disk (there is no need to do this for REQ_DRIVE_TASKFILE requests) * add ide_init_disk() helper and kill alloc_disks() in ide-probe.c * kill no longer needed ide_open() and ide_fops[] in ide.c ide_init_disk() fixed by Andrew Morton . Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 60 ++++++++++++++++++++++++++++++------------------ drivers/ide/ide-cd.h | 1 + drivers/ide/ide-disk.c | 22 ++++++++++++++---- drivers/ide/ide-floppy.c | 40 ++++++++++++++++++++++++-------- drivers/ide/ide-io.c | 2 -- drivers/ide/ide-probe.c | 52 +++++++++++------------------------------ drivers/ide/ide-tape.c | 31 ++++++++++++++++++++----- drivers/ide/ide.c | 17 -------------- drivers/scsi/ide-scsi.c | 23 +++++++++++++++---- include/linux/ide.h | 3 +-- 10 files changed, 143 insertions(+), 108 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index dfa50ef0ad29b..df13295189014 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -556,10 +556,13 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, /* * Initialize a ide-cd packet command request */ -static void cdrom_prepare_request(struct request *rq) +static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq) { + struct cdrom_info *cd = drive->driver_data; + ide_init_drive_cmd(rq); rq->flags = REQ_PC; + rq->rq_disk = cd->disk; } static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, @@ -572,7 +575,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, sense = &info->sense_data; /* stuff the sense request in front of our current request */ - cdrom_prepare_request(rq); + cdrom_prepare_request(drive, rq); rq->data = sense; rq->cmd[0] = GPCMD_REQUEST_SENSE; @@ -1856,7 +1859,7 @@ static ide_startstop_t cdrom_start_write_cont(ide_drive_t *drive) static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq) { struct cdrom_info *info = drive->driver_data; - struct gendisk *g = drive->disk; + struct gendisk *g = info->disk; unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; /* @@ -2048,7 +2051,7 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *cdi = &info->devinfo; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.cmd[0] = GPCMD_TEST_UNIT_READY; @@ -2080,7 +2083,7 @@ cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense) if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) { stat = 0; } else { - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; req.cmd[4] = lockflag ? 1 : 0; @@ -2124,7 +2127,7 @@ static int cdrom_eject(ide_drive_t *drive, int ejectflag, if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag) return 0; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); /* only tell drive to close tray if open, if it can do that */ if (ejectflag && !CDROM_CONFIG_FLAGS(drive)->close_tray) @@ -2148,7 +2151,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, int stat; struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.cmd[0] = GPCMD_READ_CDVD_CAPACITY; @@ -2171,7 +2174,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, { struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.data = buf; @@ -2228,7 +2231,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) if (stat) toc->capacity = 0x1fffff; - set_capacity(drive->disk, toc->capacity * sectors_per_frame); + set_capacity(info->disk, toc->capacity * sectors_per_frame); blk_queue_hardsect_size(drive->queue, sectors_per_frame << SECTOR_BITS); @@ -2348,7 +2351,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) stat = cdrom_get_last_written(cdi, &last_written); if (!stat && (last_written > toc->capacity)) { toc->capacity = last_written; - set_capacity(drive->disk, toc->capacity * sectors_per_frame); + set_capacity(info->disk, toc->capacity * sectors_per_frame); } /* Remember that we've read this stuff. */ @@ -2363,7 +2366,7 @@ static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf, { struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.data = buf; @@ -2383,7 +2386,7 @@ static int cdrom_select_speed(ide_drive_t *drive, int speed, struct request_sense *sense) { struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; if (speed == 0) @@ -2413,7 +2416,7 @@ static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end) struct request_sense sense; struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = &sense; req.cmd[0] = GPCMD_PLAY_AUDIO_MSF; @@ -2463,7 +2466,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi, /* here we queue the commands from the uniform CD-ROM layer. the packet must be complete, as we do not touch it at all. */ - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE); if (cgc->sense) memset(cgc->sense, 0, sizeof(struct request_sense)); @@ -2613,7 +2616,7 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi) struct request req; int ret; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.flags = REQ_SPECIAL | REQ_QUIET; ret = ide_do_drive_cmd(drive, &req, ide_wait); @@ -2857,7 +2860,7 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots) if (!CDROM_CONFIG_FLAGS(drive)->mo_drive) devinfo->mask |= CDC_MO_DRIVE; - devinfo->disk = drive->disk; + devinfo->disk = info->disk; return register_cdrom(devinfo); } @@ -3262,7 +3265,7 @@ int ide_cdrom_cleanup(ide_drive_t *drive) return 1; } - del_gendisk(drive->disk); + del_gendisk(info->disk); ide_cd_put(info); @@ -3274,7 +3277,7 @@ static void ide_cd_release(struct kref *kref) struct cdrom_info *info = to_ide_cd(kref); struct cdrom_device_info *devinfo = &info->devinfo; ide_drive_t *drive = info->drive; - struct gendisk *g = drive->disk; + struct gendisk *g = info->disk; if (info->buffer != NULL) kfree(info->buffer); @@ -3289,7 +3292,7 @@ static void ide_cd_release(struct kref *kref) drive->driver_data = NULL; blk_queue_prep_rq(drive->queue, NULL); g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); kfree(info); } @@ -3417,7 +3420,7 @@ MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); static int ide_cdrom_attach (ide_drive_t *drive) { struct cdrom_info *info; - struct gendisk *g = drive->disk; + struct gendisk *g; struct request_sense sense; if (!strstr("ide-cdrom", drive->driver_req)) @@ -3442,17 +3445,25 @@ static int ide_cdrom_attach (ide_drive_t *drive) printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name); goto failed; } + + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_free_cd; + + ide_init_disk(g, drive); + if (ide_register_subdriver(drive, &ide_cdrom_driver)) { printk(KERN_ERR "%s: Failed to register the driver with ide.c\n", drive->name); - kfree(info); - goto failed; + goto out_put_disk; } memset(info, 0, sizeof (struct cdrom_info)); kref_init(&info->kref); info->drive = drive; + info->disk = g; + drive->driver_data = info; DRIVER(drive)->busy++; @@ -3485,6 +3496,11 @@ static int ide_cdrom_attach (ide_drive_t *drive) g->flags |= GENHD_FL_REMOVABLE; add_disk(g); return 0; + +out_put_disk: + put_disk(g); +out_free_cd: + kfree(info); failed: return 1; } diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 171c65eb31385..ee97600a1f312 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -461,6 +461,7 @@ struct atapi_changer_info { /* Extra per-device info for cdrom drives. */ struct cdrom_info { ide_drive_t *drive; + struct gendisk *disk; struct kref kref; /* Buffer for table of contents. NULL if we haven't allocated diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 9636135ee0779..78733d395d665 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -73,6 +73,7 @@ struct ide_disk_obj { ide_drive_t *drive; + struct gendisk *disk; struct kref kref; }; @@ -1024,7 +1025,7 @@ static void ide_cacheflush_p(ide_drive_t *drive) static int idedisk_cleanup (ide_drive_t *drive) { struct ide_disk_obj *idkp = drive->driver_data; - struct gendisk *g = drive->disk; + struct gendisk *g = idkp->disk; ide_cacheflush_p(drive); if (ide_unregister_subdriver(drive)) @@ -1040,12 +1041,12 @@ static void ide_disk_release(struct kref *kref) { struct ide_disk_obj *idkp = to_ide_disk(kref); ide_drive_t *drive = idkp->drive; - struct gendisk *g = drive->disk; + struct gendisk *g = idkp->disk; drive->driver_data = NULL; drive->devfs_name[0] = '\0'; g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); kfree(idkp); } @@ -1199,7 +1200,7 @@ MODULE_DESCRIPTION("ATA DISK Driver"); static int idedisk_attach(ide_drive_t *drive) { struct ide_disk_obj *idkp; - struct gendisk *g = drive->disk; + struct gendisk *g; /* strstr("foo", "") is non-NULL */ if (!strstr("ide-disk", drive->driver_req)) @@ -1213,9 +1214,15 @@ static int idedisk_attach(ide_drive_t *drive) if (!idkp) goto failed; + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_free_idkp; + + ide_init_disk(g, drive); + if (ide_register_subdriver(drive, &idedisk_driver)) { printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name); - goto out_free_idkp; + goto out_put_disk; } memset(idkp, 0, sizeof(*idkp)); @@ -1223,6 +1230,8 @@ static int idedisk_attach(ide_drive_t *drive) kref_init(&idkp->kref); idkp->drive = drive; + idkp->disk = g; + drive->driver_data = idkp; DRIVER(drive)->busy++; @@ -1243,6 +1252,9 @@ static int idedisk_attach(ide_drive_t *drive) g->private_data = idkp; add_disk(g); return 0; + +out_put_disk: + put_disk(g); out_free_idkp: kfree(idkp); failed: diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 0e9421b57cc5a..1b7d172febf73 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -276,6 +276,7 @@ typedef struct { */ typedef struct ide_floppy_obj { ide_drive_t *drive; + struct gendisk *disk; struct kref kref; /* Current packet command */ @@ -680,9 +681,12 @@ static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc) */ static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struct request *rq) { + struct ide_floppy_obj *floppy = drive->driver_data; + ide_init_drive_cmd(rq); rq->buffer = (char *) pc; rq->flags = REQ_SPECIAL; //rq->cmd = IDEFLOPPY_PC_RQ; + rq->rq_disk = floppy->disk; (void) ide_do_drive_cmd(drive, rq, ide_preempt); } @@ -1274,7 +1278,8 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request unsigned long block = (unsigned long)block_s; debug_log(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n", - rq->rq_status, rq->rq_disk->disk_name, + rq->rq_status, + rq->rq_disk ? rq->rq_disk->disk_name ? "?", rq->flags, rq->errors); debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, " "current_nr_sectors: %d\n", (long)rq->sector, @@ -1329,11 +1334,13 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request */ static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc) { + struct ide_floppy_obj *floppy = drive->driver_data; struct request rq; ide_init_drive_cmd (&rq); rq.buffer = (char *) pc; rq.flags = REQ_SPECIAL; // rq.cmd = IDEFLOPPY_PC_RQ; + rq.rq_disk = floppy->disk; return ide_do_drive_cmd(drive, &rq, ide_wait); } @@ -1358,7 +1365,7 @@ static int idefloppy_get_flexible_disk_page (ide_drive_t *drive) } header = (idefloppy_mode_parameter_header_t *) pc.buffer; floppy->wp = header->wp; - set_disk_ro(drive->disk, floppy->wp); + set_disk_ro(floppy->disk, floppy->wp); page = (idefloppy_flexible_disk_page_t *) (header + 1); page->transfer_rate = ntohs(page->transfer_rate); @@ -1424,7 +1431,7 @@ static int idefloppy_get_capacity (ide_drive_t *drive) drive->bios_cyl = 0; drive->bios_head = drive->bios_sect = 0; floppy->blocks = floppy->bs_factor = 0; - set_capacity(drive->disk, 0); + set_capacity(floppy->disk, 0); idefloppy_create_read_capacity_cmd(&pc); if (idefloppy_queue_pc_tail(drive, &pc)) { @@ -1498,7 +1505,7 @@ static int idefloppy_get_capacity (ide_drive_t *drive) (void) idefloppy_get_flexible_disk_page(drive); } - set_capacity(drive->disk, floppy->blocks * floppy->bs_factor); + set_capacity(floppy->disk, floppy->blocks * floppy->bs_factor); return rc; } @@ -1859,7 +1866,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) static int idefloppy_cleanup (ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; - struct gendisk *g = drive->disk; + struct gendisk *g = floppy->disk; if (ide_unregister_subdriver(drive)) return 1; @@ -1875,11 +1882,11 @@ static void ide_floppy_release(struct kref *kref) { struct ide_floppy_obj *floppy = to_ide_floppy(kref); ide_drive_t *drive = floppy->drive; - struct gendisk *g = drive->disk; + struct gendisk *g = floppy->disk; drive->driver_data = NULL; g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); kfree(floppy); } @@ -2116,7 +2123,8 @@ static struct block_device_operations idefloppy_ops = { static int idefloppy_attach (ide_drive_t *drive) { idefloppy_floppy_t *floppy; - struct gendisk *g = drive->disk; + struct gendisk *g; + if (!strstr("ide-floppy", drive->driver_req)) goto failed; if (!drive->present) @@ -2135,10 +2143,16 @@ static int idefloppy_attach (ide_drive_t *drive) printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name); goto failed; } + + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_free_floppy; + + ide_init_disk(g, drive); + if (ide_register_subdriver(drive, &idefloppy_driver)) { printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name); - kfree (floppy); - goto failed; + goto out_put_disk; } memset(floppy, 0, sizeof(*floppy)); @@ -2146,6 +2160,7 @@ static int idefloppy_attach (ide_drive_t *drive) kref_init(&floppy->kref); floppy->drive = drive; + floppy->disk = g; drive->driver_data = floppy; @@ -2161,6 +2176,11 @@ static int idefloppy_attach (ide_drive_t *drive) drive->attach = 1; add_disk(g); return 0; + +out_put_disk: + put_disk(g); +out_free_floppy: + kfree(floppy); failed: return 1; } diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 65f5267992dc9..94f5744c62d74 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1616,8 +1616,6 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio rq->errors = 0; rq->rq_status = RQ_ACTIVE; - rq->rq_disk = drive->disk; - /* * we need to hold an extra reference to request for safe inspection * after completion diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 4f25501bc758b..554473a95cf74 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1011,10 +1011,8 @@ static int ide_init_queue(ide_drive_t *drive) blk_queue_max_hw_segments(q, max_sg_entries); blk_queue_max_phys_segments(q, max_sg_entries); - /* assign drive and gendisk queue */ + /* assign drive queue */ drive->queue = q; - if (drive->disk) - drive->disk->queue = drive->queue; /* needs drive->queue to be set */ ide_toggle_bounce(drive, 1); @@ -1268,34 +1266,19 @@ void ide_unregister_region(struct gendisk *disk) EXPORT_SYMBOL_GPL(ide_unregister_region); -static int alloc_disks(ide_hwif_t *hwif) +void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) { - unsigned int unit; - struct gendisk *disks[MAX_DRIVES]; + ide_hwif_t *hwif = drive->hwif; + unsigned int unit = (drive->select.all >> 4) & 1; - for (unit = 0; unit < MAX_DRIVES; unit++) { - disks[unit] = alloc_disk(1 << PARTN_BITS); - if (!disks[unit]) - goto Enomem; - } - for (unit = 0; unit < MAX_DRIVES; ++unit) { - ide_drive_t *drive = &hwif->drives[unit]; - struct gendisk *disk = disks[unit]; - disk->major = hwif->major; - disk->first_minor = unit << PARTN_BITS; - sprintf(disk->disk_name,"hd%c",'a'+hwif->index*MAX_DRIVES+unit); - disk->fops = ide_fops; - disk->private_data = drive; - drive->disk = disk; - } - return 0; -Enomem: - printk(KERN_WARNING "(ide::init_gendisk) Out of memory\n"); - while (unit--) - put_disk(disks[unit]); - return -ENOMEM; + disk->major = hwif->major; + disk->first_minor = unit << PARTN_BITS; + sprintf(disk->disk_name, "hd%c", 'a' + hwif->index * MAX_DRIVES + unit); + disk->queue = drive->queue; } +EXPORT_SYMBOL_GPL(ide_init_disk); + static void drive_release_dev (struct device *dev) { ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); @@ -1336,7 +1319,7 @@ static void init_gendisk (ide_hwif_t *hwif) static int hwif_init(ide_hwif_t *hwif) { - int old_irq, unit; + int old_irq; /* Return success if no device is connected */ if (!hwif->present) @@ -1372,9 +1355,6 @@ static int hwif_init(ide_hwif_t *hwif) printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name); goto out; } - - if (alloc_disks(hwif) < 0) - goto out; if (init_irq(hwif) == 0) goto done; @@ -1387,12 +1367,12 @@ static int hwif_init(ide_hwif_t *hwif) if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) { printk("%s: Disabled unable to get IRQ %d.\n", hwif->name, old_irq); - goto out_disks; + goto out; } if (init_irq(hwif)) { printk("%s: probed IRQ %d and default IRQ %d failed.\n", hwif->name, old_irq, hwif->irq); - goto out_disks; + goto out; } printk("%s: probed IRQ %d failed, using default.\n", hwif->name, hwif->irq); @@ -1402,12 +1382,6 @@ done: hwif->present = 1; /* success */ return 1; -out_disks: - for (unit = 0; unit < MAX_DRIVES; unit++) { - struct gendisk *disk = hwif->drives[unit].disk; - hwif->drives[unit].disk = NULL; - put_disk(disk); - } out: unregister_blkdev(hwif->major, hwif->name); return 0; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 41513c4b27fe7..a394afa846715 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -783,6 +783,7 @@ typedef struct { */ typedef struct ide_tape_obj { ide_drive_t *drive; + struct gendisk *disk; struct kref kref; /* @@ -1543,6 +1544,7 @@ static void idetape_active_next_stage (ide_drive_t *drive) } #endif /* IDETAPE_DEBUG_BUGS */ + rq->rq_disk = tape->disk; rq->buffer = NULL; rq->special = (void *)stage->bh; tape->active_data_request = rq; @@ -1795,8 +1797,11 @@ static void idetape_init_rq(struct request *rq, u8 cmd) */ static void idetape_queue_pc_head (ide_drive_t *drive, idetape_pc_t *pc,struct request *rq) { + struct ide_tape_obj *tape = drive->driver_data; + idetape_init_rq(rq, REQ_IDETAPE_PC1); rq->buffer = (char *) pc; + rq->rq_disk = tape->disk; (void) ide_do_drive_cmd(drive, rq, ide_preempt); } @@ -2852,10 +2857,12 @@ static void idetape_create_test_unit_ready_cmd(idetape_pc_t *pc) */ static int __idetape_queue_pc_tail (ide_drive_t *drive, idetape_pc_t *pc) { + struct ide_tape_obj *tape = drive->driver_data; struct request rq; idetape_init_rq(&rq, REQ_IDETAPE_PC1); rq.buffer = (char *) pc; + rq.rq_disk = tape->disk; return ide_do_drive_cmd(drive, &rq, ide_wait); } @@ -3079,6 +3086,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct #endif /* IDETAPE_DEBUG_BUGS */ idetape_init_rq(&rq, cmd); + rq.rq_disk = tape->disk; rq.special = (void *)bh; rq.sector = tape->first_frame_position; rq.nr_sectors = rq.current_nr_sectors = blocks; @@ -4687,7 +4695,7 @@ static int idetape_cleanup (ide_drive_t *drive) DRIVER(drive)->busy = 0; (void) ide_unregister_subdriver(drive); - ide_unregister_region(drive->disk); + ide_unregister_region(tape->disk); ide_tape_put(tape); @@ -4698,7 +4706,7 @@ static void ide_tape_release(struct kref *kref) { struct ide_tape_obj *tape = to_ide_tape(kref); ide_drive_t *drive = tape->drive; - struct gendisk *g = drive->disk; + struct gendisk *g = tape->disk; drive->dsc_overlap = 0; drive->driver_data = NULL; @@ -4707,7 +4715,7 @@ static void ide_tape_release(struct kref *kref) devfs_unregister_tape(g->number); idetape_devs[tape->minor] = NULL; g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); kfree(tape); } @@ -4822,7 +4830,7 @@ static struct block_device_operations idetape_block_ops = { static int idetape_attach (ide_drive_t *drive) { idetape_tape_t *tape; - struct gendisk *g = drive->disk; + struct gendisk *g; int minor; if (!strstr("ide-tape", drive->driver_req)) @@ -4848,10 +4856,16 @@ static int idetape_attach (ide_drive_t *drive) printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name); goto failed; } + + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_free_tape; + + ide_init_disk(g, drive); + 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); - goto failed; + goto out_put_disk; } memset(tape, 0, sizeof(*tape)); @@ -4859,6 +4873,7 @@ static int idetape_attach (ide_drive_t *drive) kref_init(&tape->kref); tape->drive = drive; + tape->disk = g; drive->driver_data = tape; @@ -4883,6 +4898,10 @@ static int idetape_attach (ide_drive_t *drive) ide_register_region(g); return 0; +out_put_disk: + put_disk(g); +out_free_tape: + kfree(tape); failed: return 1; } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 9990e2294308f..3087a565e6bbc 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -359,11 +359,6 @@ static int ide_system_bus_speed(void) return system_bus_speed; } -static int ide_open (struct inode * inode, struct file * filp) -{ - return -ENXIO; -} - /* * drives_lock protects the list of drives, drivers_lock the * list of drivers. Currently nobody takes both at once. @@ -763,11 +758,6 @@ void ide_unregister(unsigned int index) * Remove us from the kernel's knowledge */ blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<drives[i].disk; - hwif->drives[i].disk = NULL; - put_disk(disk); - } kfree(hwif->sg_table); unregister_blkdev(hwif->major, hwif->name); spin_lock_irq(&ide_lock); @@ -2164,13 +2154,6 @@ void ide_unregister_driver(ide_driver_t *driver) EXPORT_SYMBOL(ide_unregister_driver); -struct block_device_operations ide_fops[] = {{ - .owner = THIS_MODULE, - .open = ide_open, -}}; - -EXPORT_SYMBOL(ide_fops); - /* * Probe module */ diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index fc7e999ec4631..2fa6834a911b1 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -98,6 +98,7 @@ typedef struct idescsi_pc_s { typedef struct ide_scsi_obj { ide_drive_t *drive; + struct gendisk *disk; struct Scsi_Host *host; idescsi_pc_t *pc; /* Current packet command */ @@ -323,6 +324,7 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co printk ("ide-scsi: %s: queue cmd = ", drive->name); hexdump(pc->c, 6); } + rq->rq_disk = scsi->disk; return ide_do_drive_cmd(drive, rq, ide_preempt); } @@ -718,7 +720,8 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) static int idescsi_cleanup (ide_drive_t *drive) { struct Scsi_Host *scsihost = drive->driver_data; - struct gendisk *g = drive->disk; + struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); + struct gendisk *g = scsi->disk; if (ide_unregister_subdriver(drive)) return 1; @@ -727,10 +730,10 @@ static int idescsi_cleanup (ide_drive_t *drive) drive->driver_data = NULL; g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); scsi_remove_host(scsihost); - ide_scsi_put(scsihost_to_idescsi(scsihost)); + ide_scsi_put(scsi); return 0; } @@ -912,6 +915,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, rq->special = (char *) pc; rq->flags = REQ_SPECIAL; spin_unlock_irq(host->host_lock); + rq->rq_disk = scsi->disk; (void) ide_do_drive_cmd (drive, rq, ide_end); spin_lock_irq(host->host_lock); return 0; @@ -1087,9 +1091,9 @@ static int idescsi_attach(ide_drive_t *drive) { idescsi_scsi_t *idescsi; struct Scsi_Host *host; - struct gendisk *g = drive->disk; + struct gendisk *g; static int warned; - int err; + int err = -ENOMEM; if (!warned && drive->media == ide_cdrom) { printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n"); @@ -1102,6 +1106,12 @@ static int idescsi_attach(ide_drive_t *drive) !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) return 1; + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_host_put; + + ide_init_disk(g, drive); + host->max_id = 1; #if IDESCSI_DEBUG_LOG @@ -1117,6 +1127,7 @@ static int idescsi_attach(ide_drive_t *drive) idescsi = scsihost_to_idescsi(host); idescsi->drive = drive; idescsi->host = host; + idescsi->disk = g; err = ide_register_subdriver(drive, &idescsi_driver); if (!err) { idescsi_setup (drive, idescsi); @@ -1133,6 +1144,8 @@ static int idescsi_attach(ide_drive_t *drive) ide_unregister_subdriver(drive); } + put_disk(g); +out_host_put: scsi_host_put(host); return err; } diff --git a/include/linux/ide.h b/include/linux/ide.h index 329dcc754d868..9cfc0999becba 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -756,7 +756,6 @@ typedef struct ide_drive_s { struct list_head list; struct device gendev; struct semaphore gendev_rel_sem; /* to deal with device release() */ - struct gendisk *disk; } ide_drive_t; #define IDE_CHIPSET_PCI_MASK \ @@ -1327,7 +1326,7 @@ extern irqreturn_t ide_intr(int irq, void *dev_id, struct pt_regs *regs); extern void do_ide_request(request_queue_t *); extern void ide_init_subdrivers(void); -extern struct block_device_operations ide_fops[]; +void ide_init_disk(struct gendisk *, ide_drive_t *); extern int ata_attach(ide_drive_t *); -- cgit 1.2.3-korg From 5cc8d0f5a3e5d9f133cea67c3194cbdc046983ec Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 2 Apr 2005 20:00:50 +0200 Subject: [ide] get driver from rq->rq_disk->private_data * add ide_driver_t * to device drivers objects * set it to point at driver's ide_driver_t * store address of this entry in disk->private_data * fix ide_{cd,disk,floppy,tape,scsi}_g accordingly * use rq->rq_disk->private_data instead of drive->driver to obtain driver (this allows us to kill ide-default) ide_dma_intr() OOPS fixed by Tejun Heo . Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 7 +++++-- drivers/ide/ide-cd.h | 1 + drivers/ide/ide-disk.c | 8 ++++++-- drivers/ide/ide-dma.c | 8 +++++++- drivers/ide/ide-floppy.c | 8 ++++++-- drivers/ide/ide-io.c | 44 ++++++++++++++++++++++++++++++++++++-------- drivers/ide/ide-tape.c | 8 ++++++-- drivers/ide/ide-taskfile.c | 11 ++++++++--- drivers/ide/ide.c | 4 +++- drivers/scsi/ide-scsi.c | 17 +++++++++++++---- 10 files changed, 91 insertions(+), 25 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index df13295189014..33a020faeabde 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -328,7 +328,8 @@ static DECLARE_MUTEX(idecd_ref_sem); #define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) -#define ide_cd_g(disk) ((disk)->private_data) +#define ide_cd_g(disk) \ + container_of((disk)->private_data, struct cdrom_info, driver) static struct cdrom_info *ide_cd_get(struct gendisk *disk) { @@ -3462,8 +3463,11 @@ static int ide_cdrom_attach (ide_drive_t *drive) kref_init(&info->kref); info->drive = drive; + info->driver = &ide_cdrom_driver; info->disk = g; + g->private_data = &info->driver; + drive->driver_data = info; DRIVER(drive)->busy++; @@ -3492,7 +3496,6 @@ static int ide_cdrom_attach (ide_drive_t *drive) cdrom_read_toc(drive, &sense); g->fops = &idecd_ops; - g->private_data = info; g->flags |= GENHD_FL_REMOVABLE; add_disk(g); return 0; diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index ee97600a1f312..7ca3e5afc6655 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -461,6 +461,7 @@ struct atapi_changer_info { /* Extra per-device info for cdrom drives. */ struct cdrom_info { ide_drive_t *drive; + ide_driver_t *driver; struct gendisk *disk; struct kref kref; diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 78733d395d665..5d54f77561007 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -73,6 +73,7 @@ struct ide_disk_obj { ide_drive_t *drive; + ide_driver_t *driver; struct gendisk *disk; struct kref kref; }; @@ -81,7 +82,8 @@ static DECLARE_MUTEX(idedisk_ref_sem); #define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref) -#define ide_disk_g(disk) ((disk)->private_data) +#define ide_disk_g(disk) \ + container_of((disk)->private_data, struct ide_disk_obj, driver) static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) { @@ -1230,8 +1232,11 @@ static int idedisk_attach(ide_drive_t *drive) kref_init(&idkp->kref); idkp->drive = drive; + idkp->driver = &idedisk_driver; idkp->disk = g; + g->private_data = &idkp->driver; + drive->driver_data = idkp; DRIVER(drive)->busy++; @@ -1249,7 +1254,6 @@ static int idedisk_attach(ide_drive_t *drive) g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; set_capacity(g, idedisk_capacity(drive)); g->fops = &idedisk_ops; - g->private_data = idkp; add_disk(g); return 0; diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 1179a31f81405..2d2eefb610dd8 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -176,7 +176,13 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive) if (!dma_stat) { struct request *rq = HWGROUP(drive)->rq; - DRIVER(drive)->end_request(drive, 1, rq->nr_sectors); + if (rq->rq_disk) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data;; + drv->end_request(drive, 1, rq->nr_sectors); + } else + ide_end_request(drive, 1, rq->nr_sectors); return ide_stopped; } printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 1b7d172febf73..36c0b74a4e45b 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -276,6 +276,7 @@ typedef struct { */ typedef struct ide_floppy_obj { ide_drive_t *drive; + ide_driver_t *driver; struct gendisk *disk; struct kref kref; @@ -520,7 +521,8 @@ static DECLARE_MUTEX(idefloppy_ref_sem); #define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref) -#define ide_floppy_g(disk) ((disk)->private_data) +#define ide_floppy_g(disk) \ + container_of((disk)->private_data, struct ide_floppy_obj, driver) static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) { @@ -2160,8 +2162,11 @@ static int idefloppy_attach (ide_drive_t *drive) kref_init(&floppy->kref); floppy->drive = drive; + floppy->driver = &idefloppy_driver; floppy->disk = g; + g->private_data = &floppy->driver; + drive->driver_data = floppy; DRIVER(drive)->busy++; @@ -2172,7 +2177,6 @@ static int idefloppy_attach (ide_drive_t *drive) strcpy(g->devfs_name, drive->devfs_name); g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; g->fops = &idefloppy_ops; - g->private_data = floppy; drive->attach = 1; add_disk(g); return 0; diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 94f5744c62d74..248e3cc8b3527 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -410,6 +410,17 @@ static void try_to_flush_leftover_data (ide_drive_t *drive) } } +static void ide_kill_rq(ide_drive_t *drive, struct request *rq) +{ + if (rq->rq_disk) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + drv->end_request(drive, 0, 0); + } else + ide_end_request(drive, 0, 0); +} + static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) { ide_hwif_t *hwif = drive->hwif; @@ -444,7 +455,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) - drive->driver->end_request(drive, 0, 0); + ide_kill_rq(drive, rq); else { if ((rq->errors & ERROR_RESET) == ERROR_RESET) { ++rq->errors; @@ -473,7 +484,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); if (rq->errors >= ERROR_MAX) { - drive->driver->end_request(drive, 0, 0); + ide_kill_rq(drive, rq); } else { if ((rq->errors & ERROR_RESET) == ERROR_RESET) { ++rq->errors; @@ -525,7 +536,13 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat) return ide_stopped; } - return drive->driver->error(drive, rq, stat, err); + if (rq->rq_disk) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + return drv->error(drive, rq, stat, err); + } else + return __ide_error(drive, rq, stat, err); } EXPORT_SYMBOL_GPL(ide_error); @@ -535,7 +552,8 @@ ide_startstop_t __ide_abort(ide_drive_t *drive, struct request *rq) if (drive->media != ide_disk) rq->errors |= ERROR_RESET; - DRIVER(drive)->end_request(drive, 0, 0); + ide_kill_rq(drive, rq); + return ide_stopped; } @@ -569,7 +587,13 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) return ide_stopped; } - return drive->driver->abort(drive, rq); + if (rq->rq_disk) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + return drv->abort(drive, rq); + } else + return __ide_abort(drive, rq); } /** @@ -622,7 +646,7 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) udelay(100); } - if (!OK_STAT(stat, READY_STAT, BAD_STAT) && DRIVER(drive) != NULL) + if (!OK_STAT(stat, READY_STAT, BAD_STAT)) return ide_error(drive, "drive_cmd", stat); /* calls ide_end_drive_cmd */ ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG)); @@ -922,6 +946,8 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) return startstop; } if (!drive->special.all) { + ide_driver_t *drv; + if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) return execute_drive_cmd(drive, rq); else if (rq->flags & REQ_DRIVE_TASKFILE) @@ -937,11 +963,13 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) ide_complete_pm_request(drive, rq); return startstop; } - return (DRIVER(drive)->do_request(drive, rq, block)); + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + return drv->do_request(drive, rq, block); } return do_special(drive); kill_rq: - DRIVER(drive)->end_request(drive, 0, 0); + ide_kill_rq(drive, rq); return ide_stopped; } diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index a394afa846715..4825448549850 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -783,6 +783,7 @@ typedef struct { */ typedef struct ide_tape_obj { ide_drive_t *drive; + ide_driver_t *driver; struct gendisk *disk; struct kref kref; @@ -1014,7 +1015,8 @@ static DECLARE_MUTEX(idetape_ref_sem); #define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref) -#define ide_tape_g(disk) ((disk)->private_data) +#define ide_tape_g(disk) \ + container_of((disk)->private_data, struct ide_tape_obj, driver) static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) { @@ -4873,8 +4875,11 @@ static int idetape_attach (ide_drive_t *drive) kref_init(&tape->kref); tape->drive = drive; + tape->driver = &idetape_driver; tape->disk = g; + g->private_data = &tape->driver; + drive->driver_data = tape; down(&idetape_ref_sem); @@ -4894,7 +4899,6 @@ static int idetape_attach (ide_drive_t *drive) g->number = devfs_register_tape(drive->devfs_name); g->fops = &idetape_block_ops; - g->private_data = tape; ide_register_region(g); return 0; diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 246a1a1bd4657..d04f62ab5de19 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -354,8 +354,12 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, break; } - if (sectors > 0) - drive->driver->end_request(drive, 1, sectors); + if (sectors > 0) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + drv->end_request(drive, 1, sectors); + } } return ide_error(drive, s, stat); } @@ -371,7 +375,8 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) return; } } - drive->driver->end_request(drive, 1, rq->hard_nr_sectors); + + ide_end_request(drive, 1, rq->hard_nr_sectors); } /* diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 3087a565e6bbc..482a90d2053bb 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1408,6 +1408,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device unsigned int cmd, unsigned long arg) { ide_settings_t *setting; + ide_driver_t *drv; int err = 0; void __user *p = (void __user *)arg; @@ -1507,7 +1508,8 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1)))) return -EPERM; drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1; - if (drive->dsc_overlap && !DRIVER(drive)->supports_dsc_overlap) { + drv = *(ide_driver_t **)bdev->bd_disk->private_data; + if (drive->dsc_overlap && !drv->supports_dsc_overlap) { drive->dsc_overlap = 0; return -EPERM; } diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 2fa6834a911b1..2e2486b035dd9 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -98,6 +98,7 @@ typedef struct idescsi_pc_s { typedef struct ide_scsi_obj { ide_drive_t *drive; + ide_driver_t *driver; struct gendisk *disk; struct Scsi_Host *host; @@ -109,7 +110,8 @@ typedef struct ide_scsi_obj { static DECLARE_MUTEX(idescsi_ref_sem); -#define ide_scsi_g(disk) ((disk)->private_data) +#define ide_scsi_g(disk) \ + container_of((disk)->private_data, struct ide_scsi_obj, driver) static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk) { @@ -328,6 +330,8 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co return ide_do_drive_cmd(drive, rq, ide_preempt); } +static int idescsi_end_request(ide_drive_t *, int, int); + static ide_startstop_t idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) { @@ -336,7 +340,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); rq->errors++; - DRIVER(drive)->end_request(drive, 0, 0); + + idescsi_end_request(drive, 0, 0); + return ide_stopped; } @@ -348,7 +354,9 @@ idescsi_atapi_abort(ide_drive_t *drive, struct request *rq) ((idescsi_pc_t *) rq->special)->scsi_cmd->serial_number); #endif rq->errors |= ERROR_MAX; - DRIVER(drive)->end_request(drive, 0, 0); + + idescsi_end_request(drive, 0, 0); + return ide_stopped; } @@ -1126,13 +1134,14 @@ static int idescsi_attach(ide_drive_t *drive) drive->driver_data = host; idescsi = scsihost_to_idescsi(host); idescsi->drive = drive; + idescsi->driver = &idescsi_driver; idescsi->host = host; idescsi->disk = g; + g->private_data = &idescsi->driver; err = ide_register_subdriver(drive, &idescsi_driver); if (!err) { idescsi_setup (drive, idescsi); g->fops = &idescsi_ops; - g->private_data = idescsi; ide_register_region(g); err = scsi_add_host(host, &drive->gendev); if (!err) { -- cgit 1.2.3-korg From 3a644abc595a21d9e23caf3b4219386e06fd0b7c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 2 Apr 2005 20:03:55 +0200 Subject: [ide] kill ide-default * add ide_drives list to list devices without a driver * add __ide_add_setting() and use it for adding no auto remove entries * kill ide-default pseudo-driver Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Makefile | 3 +- drivers/ide/ide-default.c | 76 ----------------------------------------------- drivers/ide/ide-proc.c | 9 +++--- drivers/ide/ide.c | 59 +++++++++++++++++++----------------- 4 files changed, 37 insertions(+), 110 deletions(-) delete mode 100644 drivers/ide/ide-default.c diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index eb3c808776473..5be8ad6dc9edc 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -13,8 +13,7 @@ EXTRA_CFLAGS += -Idrivers/ide obj-$(CONFIG_BLK_DEV_IDE) += pci/ -ide-core-y += ide.o ide-default.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ - ide-taskfile.o +ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o ide-core-$(CONFIG_BLK_DEV_CMD640) += pci/cmd640.o diff --git a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c deleted file mode 100644 index 8b0c8520f7ce6..0000000000000 --- a/drivers/ide/ide-default.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ide-default - Driver for unbound ide devices - * - * This provides a clean way to bind a device to default operations - * by having an actual driver class that rather than special casing - * "no driver" all over the IDE code - * - * Copyright (C) 2003, Red Hat - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define IDEDEFAULT_VERSION "0.9.newide" -/* - * Driver initialization. - */ - -static int idedefault_attach(ide_drive_t *drive); - -static ide_startstop_t idedefault_do_request(ide_drive_t *drive, struct request *rq, sector_t block) -{ - ide_end_request(drive, 0, 0); - return ide_stopped; -} - -/* - * IDE subdriver functions, registered with ide.c - */ - -ide_driver_t idedefault_driver = { - .name = "ide-default", - .version = IDEDEFAULT_VERSION, - .attach = idedefault_attach, - .cleanup = ide_unregister_subdriver, - .do_request = idedefault_do_request, - .end_request = ide_end_request, - .error = __ide_error, - .abort = __ide_abort, - .drives = LIST_HEAD_INIT(idedefault_driver.drives) -}; - -static int idedefault_attach (ide_drive_t *drive) -{ - if (ide_register_subdriver(drive, &idedefault_driver)) { - printk(KERN_ERR "ide-default: %s: Failed to register the " - "driver with ide.c\n", drive->name); - return 1; - } - - return 0; -} - -MODULE_DESCRIPTION("IDE Default Driver"); - -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 14d1658b609fe..bdff5ac580531 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -107,8 +107,6 @@ static int proc_ide_read_identify if (drive) { unsigned short *val = (unsigned short *) page; - BUG_ON(!drive->driver); - err = taskfile_lib_get_identify(drive, page); if (!err) { char *out = ((char *)page) + (SECTOR_WORDS * 4); @@ -312,8 +310,11 @@ static int proc_ide_read_driver ide_driver_t *driver = drive->driver; int len; - len = sprintf(page, "%s version %s\n", - driver->name, driver->version); + if (driver) { + len = sprintf(page, "%s version %s\n", + driver->name, driver->version); + } else + len = sprintf(page, "ide-default version 0.9.newide\n"); PROC_IDE_READ_RETURN(page,start,off,count,eof,len); } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 482a90d2053bb..973dec799b5c8 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -196,7 +196,7 @@ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ EXPORT_SYMBOL(ide_hwifs); -extern ide_driver_t idedefault_driver; +static struct list_head ide_drives = LIST_HEAD_INIT(ide_drives); /* * Do not even *think* about calling this! @@ -245,7 +245,6 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index) drive->max_failures = IDE_DEFAULT_MAX_FAILURES; drive->using_dma = 0; drive->is_flash = 0; - drive->driver = &idedefault_driver; drive->vdma = 0; INIT_LIST_HEAD(&drive->list); sema_init(&drive->gendev_rel_sem, 0); @@ -921,7 +920,7 @@ EXPORT_SYMBOL(ide_register_hw); DECLARE_MUTEX(ide_setting_sem); /** - * ide_add_setting - add an ide setting option + * __ide_add_setting - add an ide setting option * @drive: drive to use * @name: setting name * @rw: true if the function is read write @@ -934,6 +933,7 @@ DECLARE_MUTEX(ide_setting_sem); * @div_factor: divison scale * @data: private data field * @set: setting + * @auto_remove: setting auto removal flag * * Removes the setting named from the device if it is present. * The function takes the settings_lock to protect against @@ -945,8 +945,8 @@ DECLARE_MUTEX(ide_setting_sem); * a driver is attached we assume the driver settings are auto * remove. */ - -int ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) + +static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set, int auto_remove) { ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL; @@ -971,7 +971,7 @@ int ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioct setting->set = set; setting->next = *p; - if (drive->driver != &idedefault_driver) + if (auto_remove) setting->auto_remove = 1; *p = setting; up(&ide_setting_sem); @@ -983,6 +983,11 @@ abort: return -1; } +int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) +{ + return __ide_add_setting(drive, name, rw, read_ioctl, write_ioctl, data_type, min, max, mul_factor, div_factor, data, set, 1); +} + EXPORT_SYMBOL(ide_add_setting); /** @@ -1272,17 +1277,17 @@ static int set_xfer_rate (ide_drive_t *drive, int arg) void ide_add_generic_settings (ide_drive_t *drive) { /* - * drive setting name read/write access read ioctl write ioctl data type min max mul_factor div_factor data pointer set function + * drive setting name read/write access read ioctl write ioctl data type min max mul_factor div_factor data pointer set function */ - ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, HDIO_GET_32BIT, HDIO_SET_32BIT, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit); - ide_add_setting(drive, "keepsettings", SETTING_RW, HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL); - ide_add_setting(drive, "nice1", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL); - ide_add_setting(drive, "pio_mode", SETTING_WRITE, -1, HDIO_SET_PIO_MODE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode); - ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL); - ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma); - ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL); - ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate); - ide_add_setting(drive, "number", SETTING_RW, -1, -1, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL); + __ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, HDIO_GET_32BIT, HDIO_SET_32BIT, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit, 0); + __ide_add_setting(drive, "keepsettings", SETTING_RW, HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL, 0); + __ide_add_setting(drive, "nice1", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL, 0); + __ide_add_setting(drive, "pio_mode", SETTING_WRITE, -1, HDIO_SET_PIO_MODE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode, 0); + __ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL, 0); + __ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma, 0); + __ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL, 0); + __ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate, 0); + __ide_add_setting(drive, "number", SETTING_RW, -1, -1, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL, 0); } /** @@ -1320,7 +1325,7 @@ int ide_replace_subdriver (ide_drive_t *drive, const char *driver) } else { drive->driver_req[0] = 0; } - if (DRIVER(drive)!= &idedefault_driver && !strcmp(DRIVER(drive)->name, driver)) + if (drive->driver && !strcmp(drive->driver->name, driver)) return 0; abort: return 1; @@ -1359,9 +1364,9 @@ int ata_attach(ide_drive_t *drive) spin_lock(&drivers_lock); module_put(driver->owner); } - drive->gendev.driver = &idedefault_driver.gen_driver; + drive->gendev.driver = NULL; spin_unlock(&drivers_lock); - if(idedefault_driver.attach(drive) != 0) + if (ide_register_subdriver(drive, NULL)) panic("ide: default attach failed"); return 1; } @@ -2012,10 +2017,8 @@ int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) { unsigned long flags; - BUG_ON(!drive->driver); - spin_lock_irqsave(&ide_lock, flags); - if (!drive->present || drive->driver != &idedefault_driver || + if (!drive->present || drive->driver != NULL || drive->usage || drive->dead) { spin_unlock_irqrestore(&ide_lock, flags); return 1; @@ -2023,11 +2026,11 @@ int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) drive->driver = driver; spin_unlock_irqrestore(&ide_lock, flags); spin_lock(&drives_lock); - list_add_tail(&drive->list, &driver->drives); + list_add_tail(&drive->list, driver ? &driver->drives : &ide_drives); spin_unlock(&drives_lock); // printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name); #ifdef CONFIG_PROC_FS - if (drive->driver != &idedefault_driver) + if (driver) ide_add_proc_entries(drive->proc, driver->proc, drive); #endif return 0; @@ -2055,7 +2058,7 @@ int ide_unregister_subdriver (ide_drive_t *drive) down(&ide_setting_sem); spin_lock_irqsave(&ide_lock, flags); - if (drive->usage || drive->driver == &idedefault_driver || DRIVER(drive)->busy) { + if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) { spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); return 1; @@ -2064,13 +2067,13 @@ int ide_unregister_subdriver (ide_drive_t *drive) ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc); #endif auto_remove_settings(drive); - drive->driver = &idedefault_driver; + drive->driver = NULL; spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); spin_lock(&drives_lock); list_del_init(&drive->list); spin_unlock(&drives_lock); - /* drive will be added to &idedefault_driver->drives in ata_attach() */ + /* drive will be added to &ide_drives in ata_attach() */ return 0; } @@ -2106,7 +2109,7 @@ int ide_register_driver(ide_driver_t *driver) INIT_LIST_HEAD(&list); spin_lock(&drives_lock); - list_splice_init(&idedefault_driver.drives, &list); + list_splice_init(&ide_drives, &list); spin_unlock(&drives_lock); list_for_each_safe(list_loop, tmp_storage, &list) { -- cgit 1.2.3-korg From a04780b2d7f0c71486a6c3e4b452ff8b05f2bd59 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 2 Apr 2005 20:09:12 +0200 Subject: [ide] fix via82cxxx resume failure With David Woodhouse . On resume from sleep, via_set_speed() doesn't reinstate the correct mode, because it thinks the drive is already configured correctly. Also kill redundant printk, ide_config_drive_speed() warns about errors. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/via82cxxx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index d90f4d2251ab0..069dbffe21166 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -332,11 +332,8 @@ static int via_set_drive(ide_drive_t *drive, u8 speed) struct ide_timing t, p; unsigned int T, UT; - if (speed != XFER_PIO_SLOW && speed != drive->current_speed) - if (ide_config_drive_speed(drive, speed)) - printk(KERN_WARNING "ide%d: Drive %d didn't " - "accept speed setting. Oh, well.\n", - drive->dn >> 1, drive->dn & 1); + if (speed != XFER_PIO_SLOW) + ide_config_drive_speed(drive, speed); T = 1000000000 / via_clock; -- cgit 1.2.3-korg