summaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Kconfig16
-rw-r--r--drivers/ide/Makefile2
-rw-r--r--drivers/ide/ide-cd.c48
-rw-r--r--drivers/ide/ide-cd.h1
-rw-r--r--drivers/ide/ide-disk.c182
-rw-r--r--drivers/ide/ide-dma.c15
-rw-r--r--drivers/ide/ide-floppy.c34
-rw-r--r--drivers/ide/ide-io.c26
-rw-r--r--drivers/ide/ide-lib.c8
-rw-r--r--drivers/ide/ide-probe.c4
-rw-r--r--drivers/ide/ide-tape.c26
-rw-r--r--drivers/ide/ide-taskfile.c29
-rw-r--r--drivers/ide/ide.c112
-rw-r--r--drivers/ide/legacy/hd.c24
-rw-r--r--drivers/ide/legacy/ide-cs.c132
-rw-r--r--drivers/ide/mips/Makefile4
-rw-r--r--drivers/ide/mips/au1xxx-ide.c1498
-rw-r--r--drivers/ide/mips/swarm.c201
-rw-r--r--drivers/ide/pci/aec62xx.c47
-rw-r--r--drivers/ide/pci/alim15x3.c9
-rw-r--r--drivers/ide/pci/cs5520.c5
-rw-r--r--drivers/ide/pci/pdc202xx_new.c2
-rw-r--r--drivers/ide/pci/serverworks.c2
-rw-r--r--drivers/ide/pci/sgiioc4.c8
-rw-r--r--drivers/ide/pci/siimage.c8
-rw-r--r--drivers/ide/pci/sis5513.c1
-rw-r--r--drivers/ide/pci/sl82c105.c83
-rw-r--r--drivers/ide/pci/via82cxxx.c410
-rw-r--r--drivers/ide/ppc/pmac.c31
-rw-r--r--drivers/ide/setup-pci.c2
30 files changed, 1258 insertions, 1712 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 42e5b8175cb..1c81174595b 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -625,7 +625,7 @@ config BLK_DEV_NS87415
tristate "NS87415 chipset support"
help
This driver adds detection and support for the NS87415 chip
- (used in SPARC64, among others).
+ (used mainly on SPARC64 and PA-RISC machines).
Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
@@ -787,6 +787,10 @@ config BLK_DEV_IDE_PMAC_BLINK
This option enables the use of the sleep LED as a hard drive
activity LED.
+config BLK_DEV_IDE_SWARM
+ tristate "IDE for Sibyte evaluation boards"
+ depends on SIBYTE_SB1xxx_SOC
+
config BLK_DEV_IDE_AU1XXX
bool "IDE for AMD Alchemy Au1200"
depends on SOC_AU1200
@@ -803,14 +807,6 @@ config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
endchoice
-config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
- bool "Enable burstable Mode on DbDMA"
- default false
- depends BLK_DEV_IDE_AU1XXX
- help
- This option enable the burstable Flag on DbDMA controller
- (cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY").
-
config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
int "Maximum transfer size (KB) per request (up to 128)"
default "128"
@@ -936,7 +932,7 @@ config BLK_DEV_Q40IDE
config BLK_DEV_MPC8xx_IDE
bool "MPC8xx IDE support"
- depends on 8xx
+ depends on 8xx && IDE=y && BLK_DEV_IDE=y
help
This option provides support for IDE on Motorola MPC8xx Systems.
Please see 'Type of MPC8xx IDE interface' for details.
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index cca9c075966..569fae71750 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -48,6 +48,6 @@ obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o
-obj-$(CONFIG_BLK_DEV_IDE) += legacy/ arm/
+obj-$(CONFIG_BLK_DEV_IDE) += legacy/ arm/ mips/
obj-$(CONFIG_BLK_DEV_HD) += legacy/
obj-$(CONFIG_ETRAX_IDE) += cris/
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index c2f47923d17..3325660f724 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -614,7 +614,7 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate)
*/
spin_lock_irqsave(&ide_lock, flags);
end_that_request_chunk(failed, 0, failed->data_len);
- end_that_request_last(failed);
+ end_that_request_last(failed, 0);
spin_unlock_irqrestore(&ide_lock, flags);
}
@@ -980,7 +980,7 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
* and attempt to recover if there are problems. Returns 0 if everything's
* ok; nonzero if the request has been terminated.
*/
-static inline
+static
int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
{
if (ireason == 2)
@@ -1292,7 +1292,6 @@ static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
struct cdrom_info *info = drive->driver_data;
info->dma = 0;
- info->cmd = 0;
info->start_seek = jiffies;
return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
}
@@ -1333,8 +1332,6 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
if (cdrom_read_from_buffer(drive))
return ide_stopped;
- blk_attempt_remerge(drive->queue, rq);
-
/* Clear the local sector buffer. */
info->nsectors_buffered = 0;
@@ -1344,8 +1341,6 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
(rq->nr_sectors & (sectors_per_frame - 1)))
info->dma = 0;
- info->cmd = READ;
-
/* Start sending the read request to the drive. */
return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation);
}
@@ -1484,7 +1479,6 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
struct cdrom_info *info = drive->driver_data;
info->dma = 0;
- info->cmd = 0;
rq->flags &= ~REQ_FAILED;
len = rq->data_len;
@@ -1545,7 +1539,7 @@ int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
/*
* Write handling
*/
-static inline int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
+static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
{
/* Two notes about IDE interrupt reason here - 0 means that
* the drive wants to receive data from us, 2 means that
@@ -1739,7 +1733,7 @@ end_request:
spin_lock_irqsave(&ide_lock, flags);
blkdev_dequeue_request(rq);
- end_that_request_last(rq);
+ end_that_request_last(rq, 1);
HWGROUP(drive)->rq = NULL;
spin_unlock_irqrestore(&ide_lock, flags);
return ide_stopped;
@@ -1878,20 +1872,11 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
return ide_stopped;
}
- /*
- * for dvd-ram and such media, it's a really big deal to get
- * big writes all the time. so scour the queue and attempt to
- * remerge requests, often the plugging will not have had time
- * to do this properly
- */
- blk_attempt_remerge(drive->queue, rq);
-
info->nsectors_buffered = 0;
/* use dma, if possible. we don't need to check more, since we
* know that the transfer is always (at least!) frame aligned */
info->dma = drive->using_dma ? 1 : 0;
- info->cmd = WRITE;
info->devinfo.media_written = 1;
@@ -1916,7 +1901,6 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
rq->flags |= REQ_QUIET;
info->dma = 0;
- info->cmd = 0;
/*
* sg request
@@ -1925,7 +1909,6 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
int mask = drive->queue->dma_alignment;
unsigned long addr = (unsigned long) page_address(bio_page(rq->bio));
- info->cmd = rq_data_dir(rq);
info->dma = drive->using_dma;
/*
@@ -2912,6 +2895,8 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
devinfo->mask |= CDC_CLOSE_TRAY;
if (!CDROM_CONFIG_FLAGS(drive)->mo_drive)
devinfo->mask |= CDC_MO_DRIVE;
+ if (!CDROM_CONFIG_FLAGS(drive)->ram)
+ devinfo->mask |= CDC_RAM;
devinfo->disk = info->disk;
return register_cdrom(devinfo);
@@ -3271,9 +3256,8 @@ sector_t ide_cdrom_capacity (ide_drive_t *drive)
}
#endif
-static int ide_cd_remove(struct device *dev)
+static void ide_cd_remove(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
struct cdrom_info *info = drive->driver_data;
ide_unregister_subdriver(drive, info->driver);
@@ -3281,8 +3265,6 @@ static int ide_cd_remove(struct device *dev)
del_gendisk(info->disk);
ide_cd_put(info);
-
- return 0;
}
static void ide_cd_release(struct kref *kref)
@@ -3306,7 +3288,7 @@ static void ide_cd_release(struct kref *kref)
kfree(info);
}
-static int ide_cd_probe(struct device *);
+static int ide_cd_probe(ide_drive_t *);
#ifdef CONFIG_PROC_FS
static int proc_idecd_read_capacity
@@ -3328,13 +3310,13 @@ static ide_proc_entry_t idecd_proc[] = {
#endif
static ide_driver_t ide_cdrom_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-cdrom",
.bus = &ide_bus_type,
- .probe = ide_cd_probe,
- .remove = ide_cd_remove,
},
+ .probe = ide_cd_probe,
+ .remove = ide_cd_remove,
.version = IDECD_VERSION,
.media = ide_cdrom,
.supports_dsc_overlap = 1,
@@ -3428,9 +3410,8 @@ static char *ignore = NULL;
module_param(ignore, charp, 0400);
MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
-static int ide_cd_probe(struct device *dev)
+static int ide_cd_probe(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
struct cdrom_info *info;
struct gendisk *g;
struct request_sense sense;
@@ -3510,12 +3491,13 @@ static void __exit ide_cdrom_exit(void)
{
driver_unregister(&ide_cdrom_driver.gen_driver);
}
-
-static int ide_cdrom_init(void)
+
+static int __init ide_cdrom_init(void)
{
return driver_register(&ide_cdrom_driver.gen_driver);
}
+MODULE_ALIAS("ide:*m-cdrom*");
module_init(ide_cdrom_init);
module_exit(ide_cdrom_exit);
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 7ca3e5afc66..ad1f2ed14a3 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -480,7 +480,6 @@ struct cdrom_info {
struct request request_sense_request;
int dma;
- int cmd;
unsigned long last_block;
unsigned long start_seek;
/* Buffer to hold mechanism status and changer slot table. */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index e827b39e4b3..ca25f9e3d0f 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -477,7 +477,7 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id)
&& id->lba_capacity_2;
}
-static inline void idedisk_check_hpa(ide_drive_t *drive)
+static void idedisk_check_hpa(ide_drive_t *drive)
{
unsigned long long capacity, set_max;
int lba48 = idedisk_supports_lba48(drive->id);
@@ -681,50 +681,9 @@ static ide_proc_entry_t idedisk_proc[] = {
#endif /* CONFIG_PROC_FS */
-static void idedisk_end_flush(request_queue_t *q, struct request *flush_rq)
+static void idedisk_prepare_flush(request_queue_t *q, struct request *rq)
{
ide_drive_t *drive = q->queuedata;
- struct request *rq = flush_rq->end_io_data;
- int good_sectors = rq->hard_nr_sectors;
- int bad_sectors;
- sector_t sector;
-
- if (flush_rq->errors & ABRT_ERR) {
- printk(KERN_ERR "%s: barrier support doesn't work\n", drive->name);
- blk_queue_ordered(drive->queue, QUEUE_ORDERED_NONE);
- blk_queue_issue_flush_fn(drive->queue, NULL);
- good_sectors = 0;
- } else if (flush_rq->errors) {
- good_sectors = 0;
- if (blk_barrier_preflush(rq)) {
- sector = ide_get_error_location(drive,flush_rq->buffer);
- if ((sector >= rq->hard_sector) &&
- (sector < rq->hard_sector + rq->hard_nr_sectors))
- good_sectors = sector - rq->hard_sector;
- }
- }
-
- if (flush_rq->errors)
- printk(KERN_ERR "%s: failed barrier write: "
- "sector=%Lx(good=%d/bad=%d)\n",
- drive->name, (unsigned long long)rq->sector,
- good_sectors,
- (int) (rq->hard_nr_sectors-good_sectors));
-
- bad_sectors = rq->hard_nr_sectors - good_sectors;
-
- if (good_sectors)
- __ide_end_request(drive, rq, 1, good_sectors);
- if (bad_sectors)
- __ide_end_request(drive, rq, 0, bad_sectors);
-}
-
-static int idedisk_prepare_flush(request_queue_t *q, struct request *rq)
-{
- ide_drive_t *drive = q->queuedata;
-
- if (!drive->wcache)
- return 0;
memset(rq->cmd, 0, sizeof(rq->cmd));
@@ -735,9 +694,8 @@ static int idedisk_prepare_flush(request_queue_t *q, struct request *rq)
rq->cmd[0] = WIN_FLUSH_CACHE;
- rq->flags |= REQ_DRIVE_TASK | REQ_SOFTBARRIER;
+ rq->flags |= REQ_DRIVE_TASK;
rq->buffer = rq->cmd;
- return 1;
}
static int idedisk_issue_flush(request_queue_t *q, struct gendisk *disk,
@@ -794,27 +752,64 @@ static int set_nowerr(ide_drive_t *drive, int arg)
return 0;
}
+static void update_ordered(ide_drive_t *drive)
+{
+ struct hd_driveid *id = drive->id;
+ unsigned ordered = QUEUE_ORDERED_NONE;
+ prepare_flush_fn *prep_fn = NULL;
+ issue_flush_fn *issue_fn = NULL;
+
+ if (drive->wcache) {
+ unsigned long long capacity;
+ int barrier;
+ /*
+ * We must avoid issuing commands a drive does not
+ * understand or we may crash it. We check flush cache
+ * is supported. We also check we have the LBA48 flush
+ * cache if the drive capacity is too large. By this
+ * time we have trimmed the drive capacity if LBA48 is
+ * not available so we don't need to recheck that.
+ */
+ capacity = idedisk_capacity(drive);
+ barrier = ide_id_has_flush_cache(id) &&
+ (drive->addressing == 0 || capacity <= (1ULL << 28) ||
+ ide_id_has_flush_cache_ext(id));
+
+ printk(KERN_INFO "%s: cache flushes %ssupported\n",
+ drive->name, barrier ? "" : "not");
+
+ if (barrier) {
+ ordered = QUEUE_ORDERED_DRAIN_FLUSH;
+ prep_fn = idedisk_prepare_flush;
+ issue_fn = idedisk_issue_flush;
+ }
+ } else
+ ordered = QUEUE_ORDERED_DRAIN;
+
+ blk_queue_ordered(drive->queue, ordered, prep_fn);
+ blk_queue_issue_flush_fn(drive->queue, issue_fn);
+}
+
static int write_cache(ide_drive_t *drive, int arg)
{
ide_task_t args;
- int err;
-
- if (!ide_id_has_flush_cache(drive->id))
- return 1;
+ int err = 1;
- memset(&args, 0, sizeof(ide_task_t));
- args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ?
+ if (ide_id_has_flush_cache(drive->id)) {
+ memset(&args, 0, sizeof(ide_task_t));
+ args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ?
SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
- args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
- args.handler = &task_no_data_intr;
+ args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.handler = &task_no_data_intr;
+ err = ide_raw_taskfile(drive, &args, NULL);
+ if (err == 0)
+ drive->wcache = arg;
+ }
- err = ide_raw_taskfile(drive, &args, NULL);
- if (err)
- return err;
+ update_ordered(drive);
- drive->wcache = arg;
- return 0;
+ return err;
}
static int do_idedisk_flushcache (ide_drive_t *drive)
@@ -888,7 +883,6 @@ static void idedisk_setup (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
unsigned long long capacity;
- int barrier;
idedisk_add_settings(drive);
@@ -992,31 +986,6 @@ static void idedisk_setup (ide_drive_t *drive)
drive->wcache = 1;
write_cache(drive, 1);
-
- /*
- * We must avoid issuing commands a drive does not understand
- * or we may crash it. We check flush cache is supported. We also
- * check we have the LBA48 flush cache if the drive capacity is
- * too large. By this time we have trimmed the drive capacity if
- * LBA48 is not available so we don't need to recheck that.
- */
- barrier = 0;
- if (ide_id_has_flush_cache(id))
- barrier = 1;
- if (drive->addressing == 1) {
- /* Can't issue the correct flush ? */
- if (capacity > (1ULL << 28) && !ide_id_has_flush_cache_ext(id))
- barrier = 0;
- }
-
- printk(KERN_INFO "%s: cache flushes %ssupported\n",
- drive->name, barrier ? "" : "not ");
- if (barrier) {
- blk_queue_ordered(drive->queue, QUEUE_ORDERED_FLUSH);
- drive->queue->prepare_flush_fn = idedisk_prepare_flush;
- drive->queue->end_flush_fn = idedisk_end_flush;
- blk_queue_issue_flush_fn(drive->queue, idedisk_issue_flush);
- }
}
static void ide_cacheflush_p(ide_drive_t *drive)
@@ -1028,21 +997,18 @@ static void ide_cacheflush_p(ide_drive_t *drive)
printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
}
-static int ide_disk_remove(struct device *dev)
+static void ide_disk_remove(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
struct ide_disk_obj *idkp = drive->driver_data;
struct gendisk *g = idkp->disk;
- ide_cacheflush_p(drive);
-
ide_unregister_subdriver(drive, idkp->driver);
del_gendisk(g);
- ide_disk_put(idkp);
+ ide_cacheflush_p(drive);
- return 0;
+ ide_disk_put(idkp);
}
static void ide_disk_release(struct kref *kref)
@@ -1058,12 +1024,10 @@ static void ide_disk_release(struct kref *kref)
kfree(idkp);
}
-static int ide_disk_probe(struct device *dev);
+static int ide_disk_probe(ide_drive_t *drive);
-static void ide_device_shutdown(struct device *dev)
+static void ide_device_shutdown(ide_drive_t *drive)
{
- ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
-
#ifdef CONFIG_ALPHA
/* On Alpha, halt(8) doesn't actually turn the machine off,
it puts you into the sort of firmware monitor. Typically,
@@ -1085,18 +1049,18 @@ static void ide_device_shutdown(struct device *dev)
}
printk("Shutdown: %s\n", drive->name);
- dev->bus->suspend(dev, PMSG_SUSPEND);
+ drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
}
static ide_driver_t idedisk_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-disk",
.bus = &ide_bus_type,
- .probe = ide_disk_probe,
- .remove = ide_disk_remove,
- .shutdown = ide_device_shutdown,
},
+ .probe = ide_disk_probe,
+ .remove = ide_disk_remove,
+ .shutdown = ide_device_shutdown,
.version = IDEDISK_VERSION,
.media = ide_disk,
.supports_dsc_overlap = 0,
@@ -1161,6 +1125,17 @@ static int idedisk_release(struct inode *inode, struct file *filp)
return 0;
}
+static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
+ ide_drive_t *drive = idkp->drive;
+
+ geo->heads = drive->bios_head;
+ geo->sectors = drive->bios_sect;
+ geo->cylinders = (u16)drive->bios_cyl; /* truncate */
+ return 0;
+}
+
static int idedisk_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -1195,15 +1170,15 @@ static struct block_device_operations idedisk_ops = {
.open = idedisk_open,
.release = idedisk_release,
.ioctl = idedisk_ioctl,
+ .getgeo = idedisk_getgeo,
.media_changed = idedisk_media_changed,
.revalidate_disk= idedisk_revalidate_disk
};
MODULE_DESCRIPTION("ATA DISK Driver");
-static int ide_disk_probe(struct device *dev)
+static int ide_disk_probe(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
struct ide_disk_obj *idkp;
struct gendisk *g;
@@ -1266,11 +1241,12 @@ static void __exit idedisk_exit (void)
driver_unregister(&idedisk_driver.gen_driver);
}
-static int idedisk_init (void)
+static int __init idedisk_init(void)
{
return driver_register(&idedisk_driver.gen_driver);
}
+MODULE_ALIAS("ide:*m-disk*");
module_init(idedisk_init);
module_exit(idedisk_exit);
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 1e1531334c2..0523da77425 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -90,11 +90,6 @@
#include <asm/io.h>
#include <asm/irq.h>
-struct drive_list_entry {
- const char *id_model;
- const char *id_firmware;
-};
-
static const struct drive_list_entry drive_whitelist [] = {
{ "Micropolis 2112A" , "ALL" },
@@ -139,7 +134,7 @@ static const struct drive_list_entry drive_blacklist [] = {
};
/**
- * in_drive_list - look for drive in black/white list
+ * ide_in_drive_list - look for drive in black/white list
* @id: drive identifier
* @drive_table: list to inspect
*
@@ -147,7 +142,7 @@ static const struct drive_list_entry drive_blacklist [] = {
* Returns 1 if the drive is found in the table.
*/
-static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
+int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
{
for ( ; drive_table->id_model ; drive_table++)
if ((!strcmp(drive_table->id_model, id->model)) &&
@@ -157,6 +152,8 @@ static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *d
return 0;
}
+EXPORT_SYMBOL_GPL(ide_in_drive_list);
+
/**
* ide_dma_intr - IDE DMA interrupt handler
* @drive: the drive the interrupt is for
@@ -663,7 +660,7 @@ int __ide_dma_bad_drive (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- int blacklist = in_drive_list(id, drive_blacklist);
+ int blacklist = ide_in_drive_list(id, drive_blacklist);
if (blacklist) {
printk(KERN_WARNING "%s: Disabling (U)DMA for %s (blacklisted)\n",
drive->name, id->model);
@@ -677,7 +674,7 @@ EXPORT_SYMBOL(__ide_dma_bad_drive);
int __ide_dma_good_drive (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- return in_drive_list(id, drive_whitelist);
+ return ide_in_drive_list(id, drive_whitelist);
}
EXPORT_SYMBOL(__ide_dma_good_drive);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index f615ab75996..1f8db9ac05d 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -1871,9 +1871,8 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
idefloppy_add_settings(drive);
}
-static int ide_floppy_remove(struct device *dev)
+static void ide_floppy_remove(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
idefloppy_floppy_t *floppy = drive->driver_data;
struct gendisk *g = floppy->disk;
@@ -1882,8 +1881,6 @@ static int ide_floppy_remove(struct device *dev)
del_gendisk(g);
ide_floppy_put(floppy);
-
- return 0;
}
static void ide_floppy_release(struct kref *kref)
@@ -1922,16 +1919,16 @@ static ide_proc_entry_t idefloppy_proc[] = {
#endif /* CONFIG_PROC_FS */
-static int ide_floppy_probe(struct device *);
+static int ide_floppy_probe(ide_drive_t *);
static ide_driver_t idefloppy_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-floppy",
.bus = &ide_bus_type,
- .probe = ide_floppy_probe,
- .remove = ide_floppy_remove,
},
+ .probe = ide_floppy_probe,
+ .remove = ide_floppy_remove,
.version = IDEFLOPPY_VERSION,
.media = ide_floppy,
.supports_dsc_overlap = 0,
@@ -2031,6 +2028,17 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
return 0;
}
+static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
+ ide_drive_t *drive = floppy->drive;
+
+ geo->heads = drive->bios_head;
+ geo->sectors = drive->bios_sect;
+ geo->cylinders = (u16)drive->bios_cyl; /* truncate */
+ return 0;
+}
+
static int idefloppy_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -2120,13 +2128,13 @@ static struct block_device_operations idefloppy_ops = {
.open = idefloppy_open,
.release = idefloppy_release,
.ioctl = idefloppy_ioctl,
+ .getgeo = idefloppy_getgeo,
.media_changed = idefloppy_media_changed,
.revalidate_disk= idefloppy_revalidate_disk
};
-static int ide_floppy_probe(struct device *dev)
+static int ide_floppy_probe(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
idefloppy_floppy_t *floppy;
struct gendisk *g;
@@ -2191,15 +2199,13 @@ static void __exit idefloppy_exit (void)
driver_unregister(&idefloppy_driver.gen_driver);
}
-/*
- * idefloppy_init will register the driver for each floppy.
- */
-static int idefloppy_init (void)
+static int __init idefloppy_init(void)
{
printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
return driver_register(&idefloppy_driver.gen_driver);
}
+MODULE_ALIAS("ide:*m-floppy*");
module_init(idefloppy_init);
module_exit(idefloppy_exit);
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 5275cbb1afe..8d50df4526a 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -83,15 +83,12 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
if (!end_that_request_first(rq, uptodate, nr_sectors)) {
add_disk_randomness(rq->rq_disk);
-
- if (blk_rq_tagged(rq))
- blk_queue_end_tag(drive->queue, rq);
-
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
- end_that_request_last(rq);
+ end_that_request_last(rq, uptodate);
ret = 0;
}
+
return ret;
}
EXPORT_SYMBOL(__ide_end_request);
@@ -113,16 +110,17 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
unsigned long flags;
int ret = 1;
+ /*
+ * room for locking improvements here, the calls below don't
+ * need the queue lock held at all
+ */
spin_lock_irqsave(&ide_lock, flags);
rq = HWGROUP(drive)->rq;
if (!nr_sectors)
nr_sectors = rq->hard_cur_sectors;
- if (blk_complete_barrier_rq_locked(drive->queue, rq, nr_sectors))
- ret = rq->nr_sectors != 0;
- else
- ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
+ ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
spin_unlock_irqrestore(&ide_lock, flags);
return ret;
@@ -247,7 +245,7 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
}
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
- end_that_request_last(rq);
+ end_that_request_last(rq, 1);
spin_unlock_irqrestore(&ide_lock, flags);
}
@@ -379,7 +377,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
rq->errors = err;
- end_that_request_last(rq);
+ end_that_request_last(rq, !rq->errors);
spin_unlock_irqrestore(&ide_lock, flags);
}
@@ -1629,12 +1627,6 @@ EXPORT_SYMBOL(ide_init_drive_cmd);
* for the new rq to be completed. This is VERY DANGEROUS, and is
* intended for careful use by the ATAPI tape/cdrom driver code.
*
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed. As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
* If action is ide_end, then the rq is queued at the end of the
* request queue, and the function returns immediately without waiting
* for the new rq to be completed. This is again intended for careful
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index b09a6537c7a..41d46dbe6c2 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
{
u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */
- if (on && drive->media == ide_disk) {
- if (!PCI_DMA_BUS_IS_PHYS)
- addr = BLK_BOUNCE_ANY;
- else if (HWIF(drive)->pci_dev)
+ if (!PCI_DMA_BUS_IS_PHYS) {
+ addr = BLK_BOUNCE_ANY;
+ } else if (on && drive->media == ide_disk) {
+ if (HWIF(drive)->pci_dev)
addr = HWIF(drive)->pci_dev->dma_mask;
}
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 02167a5b751..e7425546b4b 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -655,7 +655,7 @@ static void hwif_release_dev (struct device *dev)
{
ide_hwif_t *hwif = container_of(dev, ide_hwif_t, gendev);
- up(&hwif->gendev_rel_sem);
+ complete(&hwif->gendev_rel_comp);
}
static void hwif_register (ide_hwif_t *hwif)
@@ -1325,7 +1325,7 @@ static void drive_release_dev (struct device *dev)
drive->queue = NULL;
spin_unlock_irq(&ide_lock);
- up(&drive->gendev_rel_sem);
+ complete(&drive->gendev_rel_comp);
}
/*
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 0ac7eb8f40d..0101d0def7c 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -4682,9 +4682,8 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
idetape_add_settings(drive);
}
-static int ide_tape_remove(struct device *dev)
+static void ide_tape_remove(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
idetape_tape_t *tape = drive->driver_data;
ide_unregister_subdriver(drive, tape->driver);
@@ -4692,8 +4691,6 @@ static int ide_tape_remove(struct device *dev)
ide_unregister_region(tape->disk);
ide_tape_put(tape);
-
- return 0;
}
static void ide_tape_release(struct kref *kref)
@@ -4745,16 +4742,16 @@ static ide_proc_entry_t idetape_proc[] = {
#endif
-static int ide_tape_probe(struct device *);
+static int ide_tape_probe(ide_drive_t *);
static ide_driver_t idetape_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-tape",
.bus = &ide_bus_type,
- .probe = ide_tape_probe,
- .remove = ide_tape_remove,
},
+ .probe = ide_tape_probe,
+ .remove = ide_tape_remove,
.version = IDETAPE_VERSION,
.media = ide_tape,
.supports_dsc_overlap = 1,
@@ -4825,9 +4822,8 @@ static struct block_device_operations idetape_block_ops = {
.ioctl = idetape_ioctl,
};
-static int ide_tape_probe(struct device *dev)
+static int ide_tape_probe(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
idetape_tape_t *tape;
struct gendisk *g;
int minor;
@@ -4883,9 +4879,9 @@ static int ide_tape_probe(struct device *dev)
idetape_setup(drive, tape, minor);
class_device_create(idetape_sysfs_class, NULL,
- MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name);
+ MKDEV(IDETAPE_MAJOR, minor), &drive->gendev, "%s", tape->name);
class_device_create(idetape_sysfs_class, NULL,
- MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name);
+ MKDEV(IDETAPE_MAJOR, minor + 128), &drive->gendev, "n%s", tape->name);
devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
S_IFCHR | S_IRUGO | S_IWUGO,
@@ -4916,10 +4912,7 @@ static void __exit idetape_exit (void)
unregister_chrdev(IDETAPE_MAJOR, "ht");
}
-/*
- * idetape_init will register the driver for each tape.
- */
-static int idetape_init (void)
+static int __init idetape_init(void)
{
int error = 1;
idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
@@ -4950,6 +4943,7 @@ out:
return error;
}
+MODULE_ALIAS("ide:*m-tape*");
module_init(idetape_init);
module_exit(idetape_exit);
MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 54f9639c2a8..9834dce4e20 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -51,8 +51,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-#define DEBUG_TASKFILE 0 /* unset when fixed */
-
static void ata_bswap_data (void *buffer, int wcount)
{
u16 *p = buffer;
@@ -310,7 +308,7 @@ static void ide_pio_multi(ide_drive_t *drive, unsigned int write)
ide_pio_sector(drive, write);
}
-static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
+static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
unsigned int write)
{
if (rq->bio) /* fs request */
@@ -765,9 +763,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
ide_hwif_t *hwif = HWIF(drive);
task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
-#if DEBUG_TASKFILE
- u8 status;
-#endif
if (task->data_phase == TASKFILE_MULTI_IN ||
task->data_phase == TASKFILE_MULTI_OUT) {
@@ -778,19 +773,13 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
}
/*
- * (ks) Check taskfile in/out flags.
+ * (ks) Check taskfile in flags.
* If set, then execute as it is defined.
* If not set, then define default settings.
* The default values are:
- * write and read all taskfile registers (except data)
- * write and read the hob registers (sector,nsector,lcyl,hcyl)
+ * read all taskfile registers (except data)
+ * read the hob registers (sector, nsector, lcyl, hcyl)
*/
- if (task->tf_out_flags.all == 0) {
- task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
- if (drive->addressing == 1)
- task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
- }
-
if (task->tf_in_flags.all == 0) {
task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
if (drive->addressing == 1)
@@ -803,16 +792,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
SELECT_MASK(drive, 0);
-#if DEBUG_TASKFILE
- status = hwif->INB(IDE_STATUS_REG);
- if (status & 0x80) {
- printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status);
- udelay(100);
- status = hwif->INB(IDE_STATUS_REG);
- printk("flagged_taskfile -> Status = %02x\n", status);
- }
-#endif
-
if (task->tf_out_flags.b.data) {
u16 data = taskfile->data + (hobfile->data << 8);
hwif->OUTW(data, IDE_DATA_REG);
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 8af179b531c..afeb02bbb72 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -222,7 +222,7 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
hwif->mwdma_mask = 0x80; /* disable all mwdma */
hwif->swdma_mask = 0x80; /* disable all swdma */
- sema_init(&hwif->gendev_rel_sem, 0);
+ init_completion(&hwif->gendev_rel_comp);
default_hwif_iops(hwif);
default_hwif_transport(hwif);
@@ -245,7 +245,7 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
drive->is_flash = 0;
drive->vdma = 0;
INIT_LIST_HEAD(&drive->list);
- sema_init(&drive->gendev_rel_sem, 0);
+ init_completion(&drive->gendev_rel_comp);
}
}
@@ -602,7 +602,7 @@ void ide_unregister(unsigned int index)
}
spin_unlock_irq(&ide_lock);
device_unregister(&drive->gendev);
- down(&drive->gendev_rel_sem);
+ wait_for_completion(&drive->gendev_rel_comp);
spin_lock_irq(&ide_lock);
}
hwif->present = 0;
@@ -662,7 +662,7 @@ void ide_unregister(unsigned int index)
/* More messed up locking ... */
spin_unlock_irq(&ide_lock);
device_unregister(&hwif->gendev);
- down(&hwif->gendev_rel_sem);
+ wait_for_completion(&hwif->gendev_rel_comp);
/*
* Remove us from the kernel's knowledge
@@ -1278,19 +1278,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
up(&ide_setting_sem);
switch (cmd) {
- case HDIO_GETGEO:
- {
- struct hd_geometry geom;
- if (!p || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL;
- geom.heads = drive->bios_head;
- geom.sectors = drive->bios_sect;
- geom.cylinders = (u16)drive->bios_cyl; /* truncate */
- geom.start = get_start_sect(bdev);
- if (copy_to_user(p, &geom, sizeof(struct hd_geometry)))
- return -EFAULT;
- return 0;
- }
-
case HDIO_OBSOLETE_IDENTITY:
case HDIO_GET_IDENTITY:
if (bdev != bdev->bd_contains)
@@ -1904,9 +1891,100 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv)
return 1;
}
+static char *media_string(ide_drive_t *drive)
+{
+ switch (drive->media) {
+ case ide_disk:
+ return "disk";
+ case ide_cdrom:
+ return "cdrom";
+ case ide_tape:
+ return "tape";
+ case ide_floppy:
+ return "floppy";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ide_drive_t *drive = to_ide_device(dev);
+ return sprintf(buf, "%s\n", media_string(drive));
+}
+
+static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ide_drive_t *drive = to_ide_device(dev);
+ return sprintf(buf, "%s\n", drive->name);
+}
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ide_drive_t *drive = to_ide_device(dev);
+ return sprintf(buf, "ide:m-%s\n", media_string(drive));
+}
+
+static struct device_attribute ide_dev_attrs[] = {
+ __ATTR_RO(media),
+ __ATTR_RO(drivename),
+ __ATTR_RO(modalias),
+ __ATTR_NULL
+};
+
+static int ide_uevent(struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
+{
+ ide_drive_t *drive = to_ide_device(dev);
+ int i = 0;
+ int length = 0;
+
+ add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+ "MEDIA=%s", media_string(drive));
+ add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+ "DRIVENAME=%s", drive->name);
+ add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+ "MODALIAS=ide:m-%s", media_string(drive));
+ envp[i] = NULL;
+ return 0;
+}
+
+static int generic_ide_probe(struct device *dev)
+{
+ ide_drive_t *drive = to_ide_device(dev);
+ ide_driver_t *drv = to_ide_driver(dev->driver);
+
+ return drv->probe ? drv->probe(drive) : -ENODEV;
+}
+
+static int generic_ide_remove(struct device *dev)
+{
+ ide_drive_t *drive = to_ide_device(dev);
+ ide_driver_t *drv = to_ide_driver(dev->driver);
+
+ if (drv->remove)
+ drv->remove(drive);
+
+ return 0;
+}
+
+static void generic_ide_shutdown(struct device *dev)
+{
+ ide_drive_t *drive = to_ide_device(dev);
+ ide_driver_t *drv = to_ide_driver(dev->driver);
+
+ if (dev->driver && drv->shutdown)
+ drv->shutdown(drive);
+}
+
struct bus_type ide_bus_type = {
.name = "ide",
.match = ide_bus_match,
+ .uevent = ide_uevent,
+ .probe = generic_ide_probe,
+ .remove = generic_ide_remove,
+ .shutdown = generic_ide_shutdown,
+ .dev_attrs = ide_dev_attrs,
.suspend = generic_ide_suspend,
.resume = generic_ide_resume,
};
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 242029c9c0c..6439dec6688 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -658,22 +658,14 @@ static void do_hd_request (request_queue_t * q)
enable_irq(HD_IRQ);
}
-static int hd_ioctl(struct inode * inode, struct file * file,
- unsigned int cmd, unsigned long arg)
+static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
- struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data;
- struct hd_geometry __user *loc = (struct hd_geometry __user *) arg;
- struct hd_geometry g;
-
- if (cmd != HDIO_GETGEO)
- return -EINVAL;
- if (!loc)
- return -EINVAL;
- g.heads = disk->head;
- g.sectors = disk->sect;
- g.cylinders = disk->cyl;
- g.start = get_start_sect(inode->i_bdev);
- return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0;
+ struct hd_i_struct *disk = bdev->bd_disk->private_data;
+
+ geo->heads = disk->head;
+ geo->sectors = disk->sect;
+ geo->cylinders = disk->cyl;
+ return 0;
}
/*
@@ -695,7 +687,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
static struct block_device_operations hd_fops = {
- .ioctl = hd_ioctl,
+ .getgeo = hd_getgeo,
};
/*
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index ef79805218e..4c2af902090 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -88,15 +88,12 @@ typedef struct ide_info_t {
} ide_info_t;
static void ide_release(dev_link_t *);
-static int ide_event(event_t event, int priority,
- event_callback_args_t *args);
+static void ide_config(dev_link_t *);
+
+static void ide_detach(struct pcmcia_device *p_dev);
-static dev_info_t dev_info = "ide-cs";
-static dev_link_t *ide_attach(void);
-static void ide_detach(dev_link_t *);
-static dev_link_t *dev_list = NULL;
/*======================================================================
@@ -106,18 +103,17 @@ static dev_link_t *dev_list = NULL;
======================================================================*/
-static dev_link_t *ide_attach(void)
+static int ide_attach(struct pcmcia_device *p_dev)
{
ide_info_t *info;
dev_link_t *link;
- client_reg_t client_reg;
- int ret;
-
+
DEBUG(0, "ide_attach()\n");
/* Create new ide device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info) return NULL;
+ if (!info)
+ return -ENOMEM;
link = &info->link; link->priv = info;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -128,21 +124,14 @@ static dev_link_t *ide_attach(void)
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
-
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != CS_SUCCESS) {
- cs_error(link->handle, RegisterClient, ret);
- ide_detach(link);
- return NULL;
- }
-
- return link;
+
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ ide_config(link);
+
+ return 0;
} /* ide_attach */
/*======================================================================
@@ -154,32 +143,16 @@ static dev_link_t *ide_attach(void)
======================================================================*/
-static void ide_detach(dev_link_t *link)
+static void ide_detach(struct pcmcia_device *p_dev)
{
- dev_link_t **linkp;
- int ret;
+ dev_link_t *link = dev_to_instance(p_dev);
DEBUG(0, "ide_detach(0x%p)\n", link);
-
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
if (link->state & DEV_CONFIG)
ide_release(link);
-
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
-
- /* Unlink, free device structure */
- *linkp = link->next;
+
kfree(link->priv);
-
} /* ide_detach */
static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
@@ -406,6 +379,28 @@ void ide_release(dev_link_t *link)
} /* ide_release */
+static int ide_suspend(struct pcmcia_device *dev)
+{
+ dev_link_t *link = dev_to_instance(dev);
+
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+
+ return 0;
+}
+
+static int ide_resume(struct pcmcia_device *dev)
+{
+ dev_link_t *link = dev_to_instance(dev);
+
+ link->state &= ~DEV_SUSPEND;
+ if (DEV_OK(link))
+ pcmcia_request_configuration(link->handle, &link->conf);
+
+ return 0;
+}
+
/*======================================================================
The card status event handler. Mostly, this schedules other
@@ -415,48 +410,15 @@ void ide_release(dev_link_t *link)
======================================================================*/
-int ide_event(event_t event, int priority,
- event_callback_args_t *args)
-{
- dev_link_t *link = args->client_data;
-
- DEBUG(1, "ide_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- ide_release(link);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- ide_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (DEV_OK(link))
- pcmcia_request_configuration(link->handle, &link->conf);
- break;
- }
- return 0;
-} /* ide_event */
-
static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_FUNC_ID(4),
+ PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
+ PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */
PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
@@ -471,6 +433,8 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
+ PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
+ PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -494,10 +458,11 @@ static struct pcmcia_driver ide_cs_driver = {
.drv = {
.name = "ide-cs",
},
- .attach = ide_attach,
- .event = ide_event,
- .detach = ide_detach,
+ .probe = ide_attach,
+ .remove = ide_detach,
.id_table = ide_ids,
+ .suspend = ide_suspend,
+ .resume = ide_resume,
};
static int __init init_ide_cs(void)
@@ -508,7 +473,6 @@ static int __init init_ide_cs(void)
static void __exit exit_ide_cs(void)
{
pcmcia_unregister_driver(&ide_cs_driver);
- BUG_ON(dev_list != NULL);
}
late_initcall(init_ide_cs);
diff --git a/drivers/ide/mips/Makefile b/drivers/ide/mips/Makefile
new file mode 100644
index 00000000000..677c7b2bac9
--- /dev/null
+++ b/drivers/ide/mips/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o
+obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o
+
+EXTRA_CFLAGS := -Idrivers/ide
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 2b6327c576b..32431dcf5d8 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -31,865 +31,638 @@
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
-#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
+#include <linux/platform_device.h>
+
#include <linux/init.h>
#include <linux/ide.h>
#include <linux/sysdev.h>
#include <linux/dma-mapping.h>
+#include "ide-timing.h"
+
#include <asm/io.h>
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
-#if CONFIG_PM
-#include <asm/mach-au1x00/au1xxx_pm.h>
-#endif
-
#include <asm/mach-au1x00/au1xxx_ide.h>
#define DRV_NAME "au1200-ide"
#define DRV_VERSION "1.0"
-#define DRV_AUTHOR "AMD PCS / Pete Popov <ppopov@embeddedalley.com>"
-#define DRV_DESC "Au1200 IDE"
-
-static _auide_hwif auide_hwif;
-static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED;
-static int dbdma_init_done = 0;
-
-/*
- * local I/O functions
- */
-u8 auide_inb(unsigned long port)
-{
- return (au_readb(port));
-}
+#define DRV_AUTHOR "Enrico Walther <enrico.walther@amd.com> / Pete Popov <ppopov@embeddedalley.com>"
-u16 auide_inw(unsigned long port)
-{
- return (au_readw(port));
-}
+/* enable the burstmode in the dbdma */
+#define IDE_AU1XXX_BURSTMODE 1
-u32 auide_inl(unsigned long port)
-{
- return (au_readl(port));
-}
+static _auide_hwif auide_hwif;
+static int dbdma_init_done;
-void auide_insw(unsigned long port, void *addr, u32 count)
-{
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
- _auide_hwif *ahwif = &auide_hwif;
- chan_tab_t *ctp;
- au1x_ddma_desc_t *dp;
-
- if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
- DDMA_FLAGS_NOIE)) {
- printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
- return;
- }
- ctp = *((chan_tab_t **)ahwif->rx_chan);
- dp = ctp->cur_ptr;
- while (dp->dscr_cmd0 & DSCR_CMD0_V)
- ;
- ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
-#else
- while (count--)
- {
- *(u16 *)addr = au_readw(port);
- addr +=2 ;
- }
-#endif
-}
-
-void auide_insl(unsigned long port, void *addr, u32 count)
-{
- while (count--)
- {
- *(u32 *)addr = au_readl(port);
- /* NOTE: For IDE interfaces over PCMCIA,
- * 32-bit access does not work
- */
- addr += 4;
- }
-}
-
-void auide_outb(u8 addr, unsigned long port)
+void auide_insw(unsigned long port, void *addr, u32 count)
{
- return (au_writeb(addr, port));
-}
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
-void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
-{
- return (au_writeb(addr, port));
+ if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
+ DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->rx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-void auide_outw(u16 addr, unsigned long port)
+void auide_outsw(unsigned long port, void *addr, u32 count)
{
- return (au_writew(addr, port));
-}
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
-void auide_outl(u32 addr, unsigned long port)
-{
- return (au_writel(addr, port));
+ if(!put_source_flags(ahwif->tx_chan, (void*)addr,
+ count << 1, DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->tx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-void auide_outsw(unsigned long port, void *addr, u32 count)
-{
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
- _auide_hwif *ahwif = &auide_hwif;
- chan_tab_t *ctp;
- au1x_ddma_desc_t *dp;
-
- if(!put_source_flags(ahwif->tx_chan, (void*)addr,
- count << 1, DDMA_FLAGS_NOIE)) {
- printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
- return;
- }
- ctp = *((chan_tab_t **)ahwif->tx_chan);
- dp = ctp->cur_ptr;
- while (dp->dscr_cmd0 & DSCR_CMD0_V)
- ;
- ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
-#else
- while (count--)
- {
- au_writew(*(u16 *)addr, port);
- addr += 2;
- }
#endif
-}
-
-void auide_outsl(unsigned long port, void *addr, u32 count)
-{
- while (count--)
- {
- au_writel(*(u32 *)addr, port);
- /* NOTE: For IDE interfaces over PCMCIA,
- * 32-bit access does not work
- */
- addr += 4;
- }
-}
static void auide_tune_drive(ide_drive_t *drive, byte pio)
{
- int mem_sttime;
- int mem_stcfg;
- unsigned long flags;
- u8 speed;
-
- /* get the best pio mode for the drive */
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-
- printk("%s: setting Au1XXX IDE to PIO mode%d\n",
- drive->name, pio);
-
- spin_lock_irqsave(&ide_tune_drive_spin_lock, flags);
-
- mem_sttime = 0;
- mem_stcfg = au_readl(MEM_STCFG2);
-
- /* set pio mode! */
- switch(pio) {
- case 0:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO0_TWCS
- | SBC_IDE_PIO0_TCSH
- | SBC_IDE_PIO0_TCSOFF
- | SBC_IDE_PIO0_TWP
- | SBC_IDE_PIO0_TCSW
- | SBC_IDE_PIO0_TPM
- | SBC_IDE_PIO0_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
-
- au_writel(mem_sttime,MEM_STTIME2);
- au_writel(mem_stcfg,MEM_STCFG2);
- break;
-
- case 1:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO1_TWCS
- | SBC_IDE_PIO1_TCSH
- | SBC_IDE_PIO1_TCSOFF
- | SBC_IDE_PIO1_TWP
- | SBC_IDE_PIO1_TCSW
- | SBC_IDE_PIO1_TPM
- | SBC_IDE_PIO1_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
- break;
-
- case 2:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO2_TWCS
- | SBC_IDE_PIO2_TCSH
- | SBC_IDE_PIO2_TCSOFF
- | SBC_IDE_PIO2_TWP
- | SBC_IDE_PIO2_TCSW
- | SBC_IDE_PIO2_TPM
- | SBC_IDE_PIO2_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
- break;
-
- case 3:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO3_TWCS
- | SBC_IDE_PIO3_TCSH
- | SBC_IDE_PIO3_TCSOFF
- | SBC_IDE_PIO3_TWP
- | SBC_IDE_PIO3_TCSW
- | SBC_IDE_PIO3_TPM
- | SBC_IDE_PIO3_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
-
- break;
-
- case 4:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO4_TWCS
- | SBC_IDE_PIO4_TCSH
- | SBC_IDE_PIO4_TCSOFF
- | SBC_IDE_PIO4_TWP
- | SBC_IDE_PIO4_TCSW
- | SBC_IDE_PIO4_TPM
- | SBC_IDE_PIO4_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
- break;
- }
-
- au_writel(mem_sttime,MEM_STTIME2);
- au_writel(mem_stcfg,MEM_STCFG2);
-
- spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags);
-
- speed = pio + XFER_PIO_0;
- ide_config_drive_speed(drive, speed);
+ int mem_sttime;
+ int mem_stcfg;
+ u8 speed;
+
+ /* get the best pio mode for the drive */
+ pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+
+ printk(KERN_INFO "%s: setting Au1XXX IDE to PIO mode%d\n",
+ drive->name, pio);
+
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
+
+ /* set pio mode! */
+ switch(pio) {
+ case 0:
+ mem_sttime = SBC_IDE_TIMING(PIO0);
+
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
+ break;
+
+ case 1:
+ mem_sttime = SBC_IDE_TIMING(PIO1);
+
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
+ break;
+
+ case 2:
+ mem_sttime = SBC_IDE_TIMING(PIO2);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
+ break;
+
+ case 3:
+ mem_sttime = SBC_IDE_TIMING(PIO3);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
+
+ break;
+
+ case 4:
+ mem_sttime = SBC_IDE_TIMING(PIO4);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
+ break;
+ }
+
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
+
+ speed = pio + XFER_PIO_0;
+ ide_config_drive_speed(drive, speed);
}
static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
{
- u8 mode = 0;
- int mem_sttime;
- int mem_stcfg;
- unsigned long flags;
+ int mem_sttime;
+ int mem_stcfg;
+ unsigned long mode;
+
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- struct hd_driveid *id = drive->id;
-
- /*
- * Now see what the current drive is capable of,
- * selecting UDMA only if the mate said it was ok.
- */
- if (id && (id->capability & 1) && drive->autodma &&
- !__ide_dma_bad_drive(drive)) {
- if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
- if (id->dma_mword & 4)
- mode = XFER_MW_DMA_2;
- else if (id->dma_mword & 2)
- mode = XFER_MW_DMA_1;
- else if (id->dma_mword & 1)
- mode = XFER_MW_DMA_0;
- }
- }
+ if (ide_use_dma(drive))
+ mode = ide_dma_speed(drive, 0);
#endif
- spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags);
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
- mem_sttime = 0;
- mem_stcfg = au_readl(MEM_STCFG2);
-
- switch(speed) {
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- auide_tune_drive(drive, (speed - XFER_PIO_0));
- break;
+ if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
+ auide_tune_drive(drive, speed - XFER_PIO_0);
+ return 0;
+ }
+
+ switch(speed) {
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- case XFER_MW_DMA_2:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_MDMA2_TWCS
- | SBC_IDE_MDMA2_TCSH
- | SBC_IDE_MDMA2_TCSOFF
- | SBC_IDE_MDMA2_TWP
- | SBC_IDE_MDMA2_TCSW
- | SBC_IDE_MDMA2_TPM
- | SBC_IDE_MDMA2_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
-
- mode = XFER_MW_DMA_2;
- break;
- case XFER_MW_DMA_1:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_MDMA1_TWCS
- | SBC_IDE_MDMA1_TCSH
- | SBC_IDE_MDMA1_TCSOFF
- | SBC_IDE_MDMA1_TWP
- | SBC_IDE_MDMA1_TCSW
- | SBC_IDE_MDMA1_TPM
- | SBC_IDE_MDMA1_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
-
- mode = XFER_MW_DMA_1;
- break;
- case XFER_MW_DMA_0:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_MDMA0_TWCS
- | SBC_IDE_MDMA0_TCSH
- | SBC_IDE_MDMA0_TCSOFF
- | SBC_IDE_MDMA0_TWP
- | SBC_IDE_MDMA0_TCSW
- | SBC_IDE_MDMA0_TPM
- | SBC_IDE_MDMA0_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
-
- mode = XFER_MW_DMA_0;
- break;
+ case XFER_MW_DMA_2:
+ mem_sttime = SBC_IDE_TIMING(MDMA2);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
+
+ mode = XFER_MW_DMA_2;
+ break;
+ case XFER_MW_DMA_1:
+ mem_sttime = SBC_IDE_TIMING(MDMA1);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
+
+ mode = XFER_MW_DMA_1;
+ break;
+ case XFER_MW_DMA_0:
+ mem_sttime = SBC_IDE_TIMING(MDMA0);
+
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
+
+ mode = XFER_MW_DMA_0;
+ break;
#endif
- default:
- return 1;
- }
-
- /*
- * Tell the drive to switch to the new mode; abort on failure.
- */
- if (!mode || ide_config_drive_speed(drive, mode))
- {
- return 1; /* failure */
- }
-
-
- au_writel(mem_sttime,MEM_STTIME2);
- au_writel(mem_stcfg,MEM_STCFG2);
+ default:
+ return 1;
+ }
+
+ if (ide_config_drive_speed(drive, mode))
+ return 1;
- spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags);
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
- return 0;
+ return 0;
}
/*
* Multi-Word DMA + DbDMA functions
*/
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-static int in_drive_list(struct hd_driveid *id,
- const struct drive_list_entry *drive_table)
-{
- for ( ; drive_table->id_model ; drive_table++){
- if ((!strcmp(drive_table->id_model, id->model)) &&
- ((strstr(drive_table->id_firmware, id->fw_rev)) ||
- (!strcmp(drive_table->id_firmware, "ALL")))
- )
- return 1;
- }
- return 0;
-}
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
static int auide_build_sglist(ide_drive_t *drive, struct request *rq)
{
- ide_hwif_t *hwif = drive->hwif;
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
- struct scatterlist *sg = hwif->sg_table;
+ ide_hwif_t *hwif = drive->hwif;
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg = hwif->sg_table;
- ide_map_sg(drive, rq);
+ ide_map_sg(drive, rq);
- if (rq_data_dir(rq) == READ)
- hwif->sg_dma_direction = DMA_FROM_DEVICE;
- else
- hwif->sg_dma_direction = DMA_TO_DEVICE;
+ if (rq_data_dir(rq) == READ)
+ hwif->sg_dma_direction = DMA_FROM_DEVICE;
+ else
+ hwif->sg_dma_direction = DMA_TO_DEVICE;
- return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
- hwif->sg_dma_direction);
+ return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
+ hwif->sg_dma_direction);
}
static int auide_build_dmatable(ide_drive_t *drive)
{
- int i, iswrite, count = 0;
- ide_hwif_t *hwif = HWIF(drive);
-
- struct request *rq = HWGROUP(drive)->rq;
-
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
- struct scatterlist *sg;
-
- iswrite = (rq_data_dir(rq) == WRITE);
- /* Save for interrupt context */
- ahwif->drive = drive;
-
- /* Build sglist */
- hwif->sg_nents = i = auide_build_sglist(drive, rq);
-
- if (!i)
- return 0;
-
- /* fill the descriptors */
- sg = hwif->sg_table;
- while (i && sg_dma_len(sg)) {
- u32 cur_addr;
- u32 cur_len;
-
- cur_addr = sg_dma_address(sg);
- cur_len = sg_dma_len(sg);
-
- while (cur_len) {
- u32 flags = DDMA_FLAGS_NOIE;
- unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
-
- if (++count >= PRD_ENTRIES) {
- printk(KERN_WARNING "%s: DMA table too small\n",
- drive->name);
- goto use_pio_instead;
- }
-
- /* Lets enable intr for the last descriptor only */
- if (1==i)
- flags = DDMA_FLAGS_IE;
- else
- flags = DDMA_FLAGS_NOIE;
-
- if (iswrite) {
- if(!put_source_flags(ahwif->tx_chan,
- (void*)(page_address(sg->page)
- + sg->offset),
- tc, flags)) {
- printk(KERN_ERR "%s failed %d\n",
- __FUNCTION__, __LINE__);
+ int i, iswrite, count = 0;
+ ide_hwif_t *hwif = HWIF(drive);
+
+ struct request *rq = HWGROUP(drive)->rq;
+
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg;
+
+ iswrite = (rq_data_dir(rq) == WRITE);
+ /* Save for interrupt context */
+ ahwif->drive = drive;
+
+ /* Build sglist */
+ hwif->sg_nents = i = auide_build_sglist(drive, rq);
+
+ if (!i)
+ return 0;
+
+ /* fill the descriptors */
+ sg = hwif->sg_table;
+ while (i && sg_dma_len(sg)) {
+ u32 cur_addr;
+ u32 cur_len;
+
+ cur_addr = sg_dma_address(sg);
+ cur_len = sg_dma_len(sg);
+
+ while (cur_len) {
+ u32 flags = DDMA_FLAGS_NOIE;
+ unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
+
+ if (++count >= PRD_ENTRIES) {
+ printk(KERN_WARNING "%s: DMA table too small\n",
+ drive->name);
+ goto use_pio_instead;
+ }
+
+ /* Lets enable intr for the last descriptor only */
+ if (1==i)
+ flags = DDMA_FLAGS_IE;
+ else
+ flags = DDMA_FLAGS_NOIE;
+
+ if (iswrite) {
+ if(!put_source_flags(ahwif->tx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
}
- } else
+ } else
{
- if(!put_dest_flags(ahwif->rx_chan,
- (void*)(page_address(sg->page)
- + sg->offset),
- tc, flags)) {
- printk(KERN_ERR "%s failed %d\n",
- __FUNCTION__, __LINE__);
+ if(!put_dest_flags(ahwif->rx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
}
- }
+ }
- cur_addr += tc;
- cur_len -= tc;
- }
- sg++;
- i--;
- }
+ cur_addr += tc;
+ cur_len -= tc;
+ }
+ sg++;
+ i--;
+ }
- if (count)
- return 1;
+ if (count)
+ return 1;
-use_pio_instead:
- dma_unmap_sg(ahwif->dev,
- hwif->sg_table,
- hwif->sg_nents,
- hwif->sg_dma_direction);
+ use_pio_instead:
+ dma_unmap_sg(ahwif->dev,
+ hwif->sg_table,
+ hwif->sg_nents,
+ hwif->sg_dma_direction);
- return 0; /* revert to PIO for this request */
+ return 0; /* revert to PIO for this request */
}
static int auide_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ ide_hwif_t *hwif = HWIF(drive);
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
- if (hwif->sg_nents) {
- dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
- hwif->sg_dma_direction);
- hwif->sg_nents = 0;
- }
+ if (hwif->sg_nents) {
+ dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
+ hwif->sg_dma_direction);
+ hwif->sg_nents = 0;
+ }
- return 0;
+ return 0;
}
static void auide_dma_start(ide_drive_t *drive )
{
-// printk("%s\n", __FUNCTION__);
}
-ide_startstop_t auide_dma_intr(ide_drive_t *drive)
-{
- //printk("%s\n", __FUNCTION__);
-
- u8 stat = 0, dma_stat = 0;
-
- dma_stat = HWIF(drive)->ide_dma_end(drive);
- stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */
- if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
- if (!dma_stat) {
- struct request *rq = HWGROUP(drive)->rq;
-
- ide_end_request(drive, 1, rq->nr_sectors);
- return ide_stopped;
- }
- printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
- drive->name, dma_stat);
- }
- return ide_error(drive, "dma_intr", stat);
-}
static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
{
- //printk("%s\n", __FUNCTION__);
-
- /* issue cmd to drive */
- ide_execute_command(drive, command, &auide_dma_intr,
- (2*WAIT_CMD), NULL);
+ /* issue cmd to drive */
+ ide_execute_command(drive, command, &ide_dma_intr,
+ (2*WAIT_CMD), NULL);
}
static int auide_dma_setup(ide_drive_t *drive)
-{
-// printk("%s\n", __FUNCTION__);
-
- if (drive->media != ide_disk)
- return 1;
-
- if (!auide_build_dmatable(drive))
- /* try PIO instead of DMA */
- return 1;
+{
+ struct request *rq = HWGROUP(drive)->rq;
- drive->waiting_for_dma = 1;
+ if (!auide_build_dmatable(drive)) {
+ ide_map_sg(drive, rq);
+ return 1;
+ }
- return 0;
+ drive->waiting_for_dma = 1;
+ return 0;
}
static int auide_dma_check(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
+ u8 speed;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- if( !dbdma_init_done ){
- auide_hwif.white_list = in_drive_list(drive->id,
- dma_white_list);
- auide_hwif.black_list = in_drive_list(drive->id,
- dma_black_list);
- auide_hwif.drive = drive;
- auide_ddma_init(&auide_hwif);
- dbdma_init_done = 1;
- }
+
+ if( dbdma_init_done == 0 ){
+ auide_hwif.white_list = ide_in_drive_list(drive->id,
+ dma_white_list);
+ auide_hwif.black_list = ide_in_drive_list(drive->id,
+ dma_black_list);
+ auide_hwif.drive = drive;
+ auide_ddma_init(&auide_hwif);
+ dbdma_init_done = 1;
+ }
#endif
- /* Is the drive in our DMA black list? */
- if ( auide_hwif.black_list ) {
- drive->using_dma = 0;
- printk("%s found in dma_blacklist[]! Disabling DMA.\n",
- drive->id->model);
- }
- else
- drive->using_dma = 1;
+ /* Is the drive in our DMA black list? */
+
+ if ( auide_hwif.black_list ) {
+ drive->using_dma = 0;
+
+ /* Borrowed the warning message from ide-dma.c */
- return HWIF(drive)->ide_dma_host_on(drive);
+ printk(KERN_WARNING "%s: Disabling DMA for %s (blacklisted)\n",
+ drive->name, drive->id->model);
+ }
+ else
+ drive->using_dma = 1;
+
+ speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
+
+ if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+ return HWIF(drive)->ide_dma_on(drive);
+
+ return HWIF(drive)->ide_dma_off_quietly(drive);
}
static int auide_dma_test_irq(ide_drive_t *drive)
-{
-// printk("%s\n", __FUNCTION__);
-
- if (!drive->waiting_for_dma)
- printk(KERN_WARNING "%s: ide_dma_test_irq \
+{
+ if (drive->waiting_for_dma == 0)
+ printk(KERN_WARNING "%s: ide_dma_test_irq \
called while not waiting\n", drive->name);
- /* If dbdma didn't execute the STOP command yet, the
- * active bit is still set
+ /* If dbdma didn't execute the STOP command yet, the
+ * active bit is still set
*/
- drive->waiting_for_dma++;
- if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
- printk(KERN_WARNING "%s: timeout waiting for ddma to \
+ drive->waiting_for_dma++;
+ if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
+ printk(KERN_WARNING "%s: timeout waiting for ddma to \
complete\n", drive->name);
- return 1;
- }
- udelay(10);
- return 0;
+ return 1;
+ }
+ udelay(10);
+ return 0;
}
static int auide_dma_host_on(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
- return 0;
+ return 0;
}
static int auide_dma_on(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
- drive->using_dma = 1;
- return auide_dma_host_on(drive);
+ drive->using_dma = 1;
+ return auide_dma_host_on(drive);
}
static int auide_dma_host_off(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
- return 0;
+ return 0;
}
static int auide_dma_off_quietly(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
- drive->using_dma = 0;
- return auide_dma_host_off(drive);
+ drive->using_dma = 0;
+ return auide_dma_host_off(drive);
}
static int auide_dma_lostirq(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
-
- printk(KERN_ERR "%s: IRQ lost\n", drive->name);
- return 0;
+ printk(KERN_ERR "%s: IRQ lost\n", drive->name);
+ return 0;
}
static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs)
{
-// printk("%s\n", __FUNCTION__);
-
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
- return;
+ _auide_hwif *ahwif = (_auide_hwif*)param;
+ ahwif->drive->waiting_for_dma = 0;
}
static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs)
{
-// printk("%s\n", __FUNCTION__);
+ _auide_hwif *ahwif = (_auide_hwif*)param;
+ ahwif->drive->waiting_for_dma = 0;
+}
+
+#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
- return;
+static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
+{
+ dev->dev_id = dev_id;
+ dev->dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ dev->dev_intlevel = 0;
+ dev->dev_intpolarity = 0;
+ dev->dev_tsize = tsize;
+ dev->dev_devwidth = devwidth;
+ dev->dev_flags = flags;
}
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
static int auide_dma_timeout(ide_drive_t *drive)
{
// printk("%s\n", __FUNCTION__);
- printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
+ printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
- if (HWIF(drive)->ide_dma_test_irq(drive))
- return 0;
+ if (HWIF(drive)->ide_dma_test_irq(drive))
+ return 0;
- return HWIF(drive)->ide_dma_end(drive);
+ return HWIF(drive)->ide_dma_end(drive);
}
-#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+
+static int auide_ddma_init(_auide_hwif *auide) {
+
+ dbdev_tab_t source_dev_tab, target_dev_tab;
+ u32 dev_id, tsize, devwidth, flags;
+ ide_hwif_t *hwif = auide->hwif;
-static int auide_ddma_init( _auide_hwif *auide )
-{
-// printk("%s\n", __FUNCTION__);
+ dev_id = AU1XXX_ATA_DDMA_REQ;
- dbdev_tab_t source_dev_tab;
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
- dbdev_tab_t target_dev_tab;
- ide_hwif_t *hwif = auide->hwif;
- char warning_output [2][80];
- int i;
-#endif
+ if (auide->white_list || auide->black_list) {
+ tsize = 8;
+ devwidth = 32;
+ }
+ else {
+ tsize = 1;
+ devwidth = 16;
+
+ printk(KERN_ERR "au1xxx-ide: %s is not on ide driver whitelist.\n",auide_hwif.drive->id->model);
+ printk(KERN_ERR " please read 'Documentation/mips/AU1xxx_IDE.README'");
+ }
- /* Add our custom device to DDMA device table */
- /* Create our new device entries in the table */
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
- source_dev_tab.dev_id = AU1XXX_ATA_DDMA_REQ;
-
- if( auide->white_list || auide->black_list ){
- source_dev_tab.dev_tsize = 8;
- source_dev_tab.dev_devwidth = 32;
- source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- source_dev_tab.dev_intlevel = 0;
- source_dev_tab.dev_intpolarity = 0;
-
- /* init device table for target - static bus controller - */
- target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
- target_dev_tab.dev_tsize = 8;
- target_dev_tab.dev_devwidth = 32;
- target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- target_dev_tab.dev_intlevel = 0;
- target_dev_tab.dev_intpolarity = 0;
- target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
- }
- else{
- source_dev_tab.dev_tsize = 1;
- source_dev_tab.dev_devwidth = 16;
- source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- source_dev_tab.dev_intlevel = 0;
- source_dev_tab.dev_intpolarity = 0;
-
- /* init device table for target - static bus controller - */
- target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
- target_dev_tab.dev_tsize = 1;
- target_dev_tab.dev_devwidth = 16;
- target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- target_dev_tab.dev_intlevel = 0;
- target_dev_tab.dev_intpolarity = 0;
- target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
-
- sprintf(&warning_output[0][0],
- "%s is not on ide driver white list.",
- auide_hwif.drive->id->model);
- for ( i=strlen(&warning_output[0][0]) ; i<76; i++ ){
- sprintf(&warning_output[0][i]," ");
- }
-
- sprintf(&warning_output[1][0],
- "To add %s please read 'Documentation/mips/AU1xxx_IDE.README'.",
- auide_hwif.drive->id->model);
- for ( i=strlen(&warning_output[1][0]) ; i<76; i++ ){
- sprintf(&warning_output[1][i]," ");
- }
-
- printk("\n****************************************");
- printk("****************************************\n");
- printk("* %s *\n",&warning_output[0][0]);
- printk("* Switch to safe MWDMA Mode! ");
- printk(" *\n");
- printk("* %s *\n",&warning_output[1][0]);
- printk("****************************************");
- printk("****************************************\n\n");
- }
+#ifdef IDE_AU1XXX_BURSTMODE
+ flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
#else
- source_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
- source_dev_tab.dev_tsize = 8;
- source_dev_tab.dev_devwidth = 32;
- source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- source_dev_tab.dev_intlevel = 0;
- source_dev_tab.dev_intpolarity = 0;
+ flags = DEV_FLAGS_SYNC;
#endif
-#if CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
- /* set flags for tx channel */
- source_dev_tab.dev_flags = DEV_FLAGS_OUT
- | DEV_FLAGS_SYNC
- | DEV_FLAGS_BURSTABLE;
- auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
- /* set flags for rx channel */
- source_dev_tab.dev_flags = DEV_FLAGS_IN
- | DEV_FLAGS_SYNC
- | DEV_FLAGS_BURSTABLE;
- auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+ /* setup dev_tab for tx channel */
+ auide_init_dbdma_dev( &source_dev_tab,
+ dev_id,
+ tsize, devwidth, DEV_FLAGS_OUT | flags);
+ auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+
+ auide_init_dbdma_dev( &source_dev_tab,
+ dev_id,
+ tsize, devwidth, DEV_FLAGS_IN | flags);
+ auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+
+ /* We also need to add a target device for the DMA */
+ auide_init_dbdma_dev( &target_dev_tab,
+ (u32)DSCR_CMD0_ALWAYS,
+ tsize, devwidth, DEV_FLAGS_ANYUSE);
+ auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);
+
+ /* Get a channel for TX */
+ auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
+ auide->tx_dev_id,
+ auide_ddma_tx_callback,
+ (void*)auide);
+
+ /* Get a channel for RX */
+ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+ auide->target_dev_id,
+ auide_ddma_rx_callback,
+ (void*)auide);
+
+ auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
+ NUM_DESCRIPTORS);
+ auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
+ NUM_DESCRIPTORS);
+
+ hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
+ PRD_ENTRIES * PRD_BYTES, /* 1 Page */
+ &hwif->dmatable_dma, GFP_KERNEL);
+
+ au1xxx_dbdma_start( auide->tx_chan );
+ au1xxx_dbdma_start( auide->rx_chan );
+
+ return 0;
+}
#else
- /* set flags for tx channel */
- source_dev_tab.dev_flags = DEV_FLAGS_OUT | DEV_FLAGS_SYNC;
- auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
- /* set flags for rx channel */
- source_dev_tab.dev_flags = DEV_FLAGS_IN | DEV_FLAGS_SYNC;
- auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
-#endif
+
+static int auide_ddma_init( _auide_hwif *auide )
+{
+ dbdev_tab_t source_dev_tab;
+ int flags;
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
-
- auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);
-
- /* Get a channel for TX */
- auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
- auide->tx_dev_id,
- auide_ddma_tx_callback,
- (void*)auide);
- /* Get a channel for RX */
- auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
- auide->target_dev_id,
- auide_ddma_rx_callback,
- (void*)auide);
-#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
- /*
- * Note: if call back is not enabled, update ctp->cur_ptr manually
- */
- auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
- auide->tx_dev_id,
- NULL,
- (void*)auide);
- auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
- DSCR_CMD0_ALWAYS,
- NULL,
- (void*)auide);
+#ifdef IDE_AU1XXX_BURSTMODE
+ flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
+#else
+ flags = DEV_FLAGS_SYNC;
#endif
- auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
- NUM_DESCRIPTORS);
- auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
- NUM_DESCRIPTORS);
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
- hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
- PRD_ENTRIES * PRD_BYTES, /* 1 Page */
- &hwif->dmatable_dma, GFP_KERNEL);
-
- auide->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
- GFP_KERNEL|GFP_DMA);
- if (auide->sg_table == NULL) {
- return -ENOMEM;
- }
-#endif
- au1xxx_dbdma_start( auide->tx_chan );
- au1xxx_dbdma_start( auide->rx_chan );
- return 0;
+ /* setup dev_tab for tx channel */
+ auide_init_dbdma_dev( &source_dev_tab,
+ (u32)DSCR_CMD0_ALWAYS,
+ 8, 32, DEV_FLAGS_OUT | flags);
+ auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+
+ auide_init_dbdma_dev( &source_dev_tab,
+ (u32)DSCR_CMD0_ALWAYS,
+ 8, 32, DEV_FLAGS_IN | flags);
+ auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+
+ /* Get a channel for TX */
+ auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
+ auide->tx_dev_id,
+ NULL,
+ (void*)auide);
+
+ /* Get a channel for RX */
+ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+ DSCR_CMD0_ALWAYS,
+ NULL,
+ (void*)auide);
+
+ auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
+ NUM_DESCRIPTORS);
+ auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
+ NUM_DESCRIPTORS);
+
+ au1xxx_dbdma_start( auide->tx_chan );
+ au1xxx_dbdma_start( auide->rx_chan );
+
+ return 0;
}
+#endif
static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
{
- int i;
-#define ide_ioreg_t unsigned long
- ide_ioreg_t *ata_regs = hw->io_ports;
-
- /* fixme */
- for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
- *ata_regs++ = (ide_ioreg_t) ahwif->regbase
- + (ide_ioreg_t)(i << AU1XXX_ATA_REG_OFFSET);
- }
-
- /* set the Alternative Status register */
- *ata_regs = (ide_ioreg_t) ahwif->regbase
- + (ide_ioreg_t)(14 << AU1XXX_ATA_REG_OFFSET);
+ int i;
+ unsigned long *ata_regs = hw->io_ports;
+
+ /* FIXME? */
+ for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
+ *ata_regs++ = ahwif->regbase + (i << AU1XXX_ATA_REG_OFFSET);
+ }
+
+ /* set the Alternative Status register */
+ *ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET);
}
static int au_ide_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
- _auide_hwif *ahwif = &auide_hwif;
- ide_hwif_t *hwif;
+ _auide_hwif *ahwif = &auide_hwif;
+ ide_hwif_t *hwif;
struct resource *res;
int ret = 0;
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
- char *mode = "MWDMA2";
+ char *mode = "MWDMA2";
#elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
- char *mode = "PIO+DDMA(offload)";
+ char *mode = "PIO+DDMA(offload)";
#endif
- memset(&auide_hwif, 0, sizeof(_auide_hwif));
- auide_hwif.dev = 0;
+ memset(&auide_hwif, 0, sizeof(_auide_hwif));
+ auide_hwif.dev = 0;
ahwif->dev = dev;
ahwif->irq = platform_get_irq(pdev, 0);
@@ -902,11 +675,11 @@ static int au_ide_probe(struct device *dev)
goto out;
}
- if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
+ if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
pr_debug("%s: request_mem_region failed\n", DRV_NAME);
- ret = -EBUSY;
+ ret = -EBUSY;
goto out;
- }
+ }
ahwif->regbase = (u32)ioremap(res->start, res->end-res->start);
if (ahwif->regbase == 0) {
@@ -914,130 +687,92 @@ static int au_ide_probe(struct device *dev)
goto out;
}
- hwif = &ide_hwifs[pdev->id];
+ /* FIXME: This might possibly break PCMCIA IDE devices */
+
+ hwif = &ide_hwifs[pdev->id];
hw_regs_t *hw = &hwif->hw;
- hwif->irq = hw->irq = ahwif->irq;
- hwif->chipset = ide_au1xxx;
+ hwif->irq = hw->irq = ahwif->irq;
+ hwif->chipset = ide_au1xxx;
- auide_setup_ports(hw, ahwif);
+ auide_setup_ports(hw, ahwif);
memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
- hwif->rqsize = CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ;
- hwif->rqsize = ((hwif->rqsize > AU1XXX_ATA_RQSIZE)
- || (hwif->rqsize < 32)) ? AU1XXX_ATA_RQSIZE : hwif->rqsize;
-#else /* if kernel config is not set */
- hwif->rqsize = AU1XXX_ATA_RQSIZE;
-#endif
-
- hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
+ hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */
- hwif->swdma_mask = 0x07;
+ hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */
+ hwif->swdma_mask = 0x00;
#else
- hwif->mwdma_mask = 0x0;
- hwif->swdma_mask = 0x0;
+ hwif->mwdma_mask = 0x0;
+ hwif->swdma_mask = 0x0;
+#endif
+
+ hwif->noprobe = 0;
+ hwif->drives[0].unmask = 1;
+ hwif->drives[1].unmask = 1;
+
+ /* hold should be on in all cases */
+ hwif->hold = 1;
+ hwif->mmio = 2;
+
+ /* If the user has selected DDMA assisted copies,
+ then set up a few local I/O function entry points
+ */
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ hwif->INSW = auide_insw;
+ hwif->OUTSW = auide_outsw;
#endif
- //hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
- hwif->noprobe = 0;
- hwif->drives[0].unmask = 1;
- hwif->drives[1].unmask = 1;
-
- /* hold should be on in all cases */
- hwif->hold = 1;
- hwif->mmio = 2;
-
- /* set up local I/O function entry points */
- hwif->INB = auide_inb;
- hwif->INW = auide_inw;
- hwif->INL = auide_inl;
- hwif->INSW = auide_insw;
- hwif->INSL = auide_insl;
- hwif->OUTB = auide_outb;
- hwif->OUTBSYNC = auide_outbsync;
- hwif->OUTW = auide_outw;
- hwif->OUTL = auide_outl;
- hwif->OUTSW = auide_outsw;
- hwif->OUTSL = auide_outsl;
-
- hwif->tuneproc = &auide_tune_drive;
- hwif->speedproc = &auide_tune_chipset;
+
+ hwif->tuneproc = &auide_tune_drive;
+ hwif->speedproc = &auide_tune_chipset;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- hwif->ide_dma_off_quietly = &auide_dma_off_quietly;
- hwif->ide_dma_timeout = &auide_dma_timeout;
-
- hwif->ide_dma_check = &auide_dma_check;
- hwif->dma_exec_cmd = &auide_dma_exec_cmd;
- hwif->dma_start = &auide_dma_start;
- hwif->ide_dma_end = &auide_dma_end;
- hwif->dma_setup = &auide_dma_setup;
- hwif->ide_dma_test_irq = &auide_dma_test_irq;
- hwif->ide_dma_host_off = &auide_dma_host_off;
- hwif->ide_dma_host_on = &auide_dma_host_on;
- hwif->ide_dma_lostirq = &auide_dma_lostirq;
- hwif->ide_dma_on = &auide_dma_on;
-
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
- hwif->atapi_dma = 1;
- hwif->drives[0].using_dma = 1;
- hwif->drives[1].using_dma = 1;
+ hwif->ide_dma_off_quietly = &auide_dma_off_quietly;
+ hwif->ide_dma_timeout = &auide_dma_timeout;
+
+ hwif->ide_dma_check = &auide_dma_check;
+ hwif->dma_exec_cmd = &auide_dma_exec_cmd;
+ hwif->dma_start = &auide_dma_start;
+ hwif->ide_dma_end = &auide_dma_end;
+ hwif->dma_setup = &auide_dma_setup;
+ hwif->ide_dma_test_irq = &auide_dma_test_irq;
+ hwif->ide_dma_host_off = &auide_dma_host_off;
+ hwif->ide_dma_host_on = &auide_dma_host_on;
+ hwif->ide_dma_lostirq = &auide_dma_lostirq;
+ hwif->ide_dma_on = &auide_dma_on;
+
+ hwif->autodma = 1;
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+ hwif->atapi_dma = 1;
+
#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
- hwif->autodma = 0;
- hwif->channel = 0;
- hwif->hold = 1;
- hwif->select_data = 0; /* no chipset-specific code */
- hwif->config_data = 0; /* no chipset-specific code */
-
- hwif->drives[0].autodma = 0;
- hwif->drives[0].drive_data = 0; /* no drive data */
- hwif->drives[0].using_dma = 0;
- hwif->drives[0].waiting_for_dma = 0;
- hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
- /* secondary hdd not supported */
- hwif->drives[1].autodma = 0;
-
- hwif->drives[1].drive_data = 0;
- hwif->drives[1].using_dma = 0;
- hwif->drives[1].waiting_for_dma = 0;
- hwif->drives[1].autotune = 2; /* 1=autotune, 2=noautotune, 0=default */
-#endif
- hwif->drives[0].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
- hwif->drives[1].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
-
- /*Register Driver with PM Framework*/
-#ifdef CONFIG_PM
- auide_hwif.pm.lock = SPIN_LOCK_UNLOCKED;
- auide_hwif.pm.stopped = 0;
-
- auide_hwif.pm.dev = new_au1xxx_power_device( "ide",
- &au1200ide_pm_callback,
- NULL);
- if ( auide_hwif.pm.dev == NULL )
- printk(KERN_INFO "Unable to create a power management \
- device entry for the au1200-IDE.\n");
- else
- printk(KERN_INFO "Power management device entry for the \
- au1200-IDE loaded.\n");
+ hwif->autodma = 0;
+ hwif->channel = 0;
+ hwif->hold = 1;
+ hwif->select_data = 0; /* no chipset-specific code */
+ hwif->config_data = 0; /* no chipset-specific code */
+
+ hwif->drives[0].autodma = 0;
+ hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
#endif
+ hwif->drives[0].no_io_32bit = 1;
- auide_hwif.hwif = hwif;
- hwif->hwif_data = &auide_hwif;
+ auide_hwif.hwif = hwif;
+ hwif->hwif_data = &auide_hwif;
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
- auide_ddma_init(&auide_hwif);
- dbdma_init_done = 1;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ auide_ddma_init(&auide_hwif);
+ dbdma_init_done = 1;
#endif
probe_hwif_init(hwif);
dev_set_drvdata(dev, hwif);
- printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
+ printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
-out:
- return ret;
+ out:
+ return ret;
}
static int au_ide_remove(struct device *dev)
@@ -1045,7 +780,7 @@ static int au_ide_remove(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
ide_hwif_t *hwif = dev_get_drvdata(dev);
- _auide_hwif *ahwif = &auide_hwif;
+ _auide_hwif *ahwif = &auide_hwif;
ide_unregister(hwif - ide_hwifs);
@@ -1069,180 +804,11 @@ static int __init au_ide_init(void)
return driver_register(&au1200_ide_driver);
}
-static void __init au_ide_exit(void)
+static void __exit au_ide_exit(void)
{
driver_unregister(&au1200_ide_driver);
}
-#ifdef CONFIG_PM
-int au1200ide_pm_callback( au1xxx_power_dev_t *dev,\
- au1xxx_request_t request, void *data) {
-
- unsigned int d, err = 0;
- unsigned long flags;
-
- spin_lock_irqsave(auide_hwif.pm.lock, flags);
-
- switch (request){
- case AU1XXX_PM_SLEEP:
- err = au1xxxide_pm_sleep(dev);
- break;
- case AU1XXX_PM_WAKEUP:
- d = *((unsigned int*)data);
- if ( d > 0 && d <= 99) {
- err = au1xxxide_pm_standby(dev);
- }
- else {
- err = au1xxxide_pm_resume(dev);
- }
- break;
- case AU1XXX_PM_GETSTATUS:
- err = au1xxxide_pm_getstatus(dev);
- break;
- case AU1XXX_PM_ACCESS:
- err = au1xxxide_pm_access(dev);
- break;
- case AU1XXX_PM_IDLE:
- err = au1xxxide_pm_idle(dev);
- break;
- case AU1XXX_PM_CLEANUP:
- err = au1xxxide_pm_cleanup(dev);
- break;
- default:
- err = -1;
- break;
- }
-
- spin_unlock_irqrestore(auide_hwif.pm.lock, flags);
-
- return err;
-}
-
-static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ) {
- return 0;
-}
-
-static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ) {
-
- int retval;
- ide_hwif_t *hwif = auide_hwif.hwif;
- struct request rq;
- struct request_pm_state rqpm;
- ide_task_t args;
-
- if(auide_hwif.pm.stopped)
- return -1;
-
- /*
- * wait until hard disc is ready
- */
- if ( wait_for_ready(&hwif->drives[0], 35000) ) {
- printk("Wait for drive sleep timeout!\n");
- retval = -1;
- }
-
- /*
- * sequenz to tell the high level ide driver that pm is resuming
- */
- memset(&rq, 0, sizeof(rq));
- memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
- rq.flags = REQ_PM_SUSPEND;
- rq.special = &args;
- rq.pm = &rqpm;
- rqpm.pm_step = ide_pm_state_start_suspend;
- rqpm.pm_state = PMSG_SUSPEND;
-
- retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_wait);
-
- if (wait_for_ready (&hwif->drives[0], 35000)) {
- printk("Wait for drive sleep timeout!\n");
- retval = -1;
- }
-
- /*
- * stop dbdma channels
- */
- au1xxx_dbdma_reset(auide_hwif.tx_chan);
- au1xxx_dbdma_reset(auide_hwif.rx_chan);
-
- auide_hwif.pm.stopped = 1;
-
- return retval;
-}
-
-static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ) {
-
- int retval;
- ide_hwif_t *hwif = auide_hwif.hwif;
- struct request rq;
- struct request_pm_state rqpm;
- ide_task_t args;
-
- if(!auide_hwif.pm.stopped)
- return -1;
-
- /*
- * start dbdma channels
- */
- au1xxx_dbdma_start(auide_hwif.tx_chan);
- au1xxx_dbdma_start(auide_hwif.rx_chan);
-
- /*
- * wait until hard disc is ready
- */
- if (wait_for_ready ( &hwif->drives[0], 35000)) {
- printk("Wait for drive wake up timeout!\n");
- retval = -1;
- }
-
- /*
- * sequenz to tell the high level ide driver that pm is resuming
- */
- memset(&rq, 0, sizeof(rq));
- memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
- rq.flags = REQ_PM_RESUME;
- rq.special = &args;
- rq.pm = &rqpm;
- rqpm.pm_step = ide_pm_state_start_resume;
- rqpm.pm_state = PMSG_ON;
-
- retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_head_wait);
-
- /*
- * wait for hard disc
- */
- if ( wait_for_ready(&hwif->drives[0], 35000) ) {
- printk("Wait for drive wake up timeout!\n");
- retval = -1;
- }
-
- auide_hwif.pm.stopped = 0;
-
- return retval;
-}
-
-static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ) {
- return dev->cur_state;
-}
-
-static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ) {
- if (dev->cur_state != AWAKE_STATE)
- return 0;
- else
- return -1;
-}
-
-static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ) {
- return 0;
-}
-
-static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ) {
- return 0;
-}
-#endif /* CONFIG_PM */
-
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AU1200 IDE driver");
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
new file mode 100644
index 00000000000..66f6064f464
--- /dev/null
+++ b/drivers/ide/mips/swarm.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Derived loosely from ide-pmac.c, so:
+ * Copyright (C) 1998 Paul Mackerras.
+ * Copyright (C) 1995-1998 Mark Lord
+ */
+
+/*
+ * Boards with SiByte processors so far have supported IDE devices via
+ * the Generic Bus, PCI bus, and built-in PCMCIA interface. In all
+ * cases, byte-swapping must be avoided for these devices (whereas
+ * other PCI devices, for example, will require swapping). Any
+ * SiByte-targetted kernel including IDE support will include this
+ * file. Probing of a Generic Bus for an IDE device is controlled by
+ * the definition of "SIBYTE_HAVE_IDE", which is provided by
+ * <asm/sibyte/board.h> for Broadcom boards.
+ */
+
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+
+#include <asm/sibyte/board.h>
+#include <asm/sibyte/sb1250_genbus.h>
+#include <asm/sibyte/sb1250_regs.h>
+
+#define DRV_NAME "ide-swarm"
+
+static char swarm_ide_string[] = DRV_NAME;
+
+static struct resource swarm_ide_resource = {
+ .name = "SWARM GenBus IDE",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device *swarm_ide_dev;
+
+/*
+ * swarm_ide_probe - if the board header indicates the existence of
+ * Generic Bus IDE, allocate a HWIF for it.
+ */
+static int __devinit swarm_ide_probe(struct device *dev)
+{
+ ide_hwif_t *hwif;
+ u8 __iomem *base;
+ phys_t offset, size;
+ int i;
+
+ if (!SIBYTE_HAVE_IDE)
+ return -ENODEV;
+
+ /* Find an empty slot. */
+ for (i = 0; i < MAX_HWIFS; i++)
+ if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET])
+ break;
+ if (i >= MAX_HWIFS) {
+ printk(KERN_ERR DRV_NAME ": no free slot for interface\n");
+ return -ENOMEM;
+ }
+
+ hwif = ide_hwifs + i;
+
+ base = ioremap(A_IO_EXT_BASE, 0x800);
+ offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
+ size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
+ iounmap(base);
+
+ offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE;
+ size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE;
+ if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) {
+ printk(KERN_INFO DRV_NAME
+ ": IDE interface at GenBus disabled\n");
+ return -EBUSY;
+ }
+
+ printk(KERN_INFO DRV_NAME ": IDE interface at GenBus slot %i\n",
+ IDE_CS);
+
+ swarm_ide_resource.start = offset;
+ swarm_ide_resource.end = offset + size - 1;
+ if (request_resource(&iomem_resource, &swarm_ide_resource)) {
+ printk(KERN_ERR DRV_NAME
+ ": can't request I/O memory resource\n");
+ return -EBUSY;
+ }
+
+ base = ioremap(offset, size);
+
+ /* Setup MMIO ops. */
+ default_hwif_mmiops(hwif);
+ /* Prevent resource map manipulation. */
+ hwif->mmio = 2;
+ hwif->noprobe = 0;
+
+ for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
+ hwif->hw.io_ports[i] =
+ (unsigned long)(base + ((0x1f0 + i) << 5));
+ hwif->hw.io_ports[IDE_CONTROL_OFFSET] =
+ (unsigned long)(base + (0x3f6 << 5));
+ hwif->hw.irq = K_INT_GB_IDE;
+
+ memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+ hwif->irq = hwif->hw.irq;
+
+ dev_set_drvdata(dev, hwif);
+
+ return 0;
+}
+
+static struct device_driver swarm_ide_driver = {
+ .name = swarm_ide_string,
+ .bus = &platform_bus_type,
+ .probe = swarm_ide_probe,
+};
+
+static void swarm_ide_platform_release(struct device *device)
+{
+ struct platform_device *pldev;
+
+ /* free device */
+ pldev = to_platform_device(device);
+ kfree(pldev);
+}
+
+static int __devinit swarm_ide_init_module(void)
+{
+ struct platform_device *pldev;
+ int err;
+
+ printk(KERN_INFO "SWARM IDE driver\n");
+
+ if (driver_register(&swarm_ide_driver)) {
+ printk(KERN_ERR "Driver registration failed\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ if (!(pldev = kmalloc(sizeof (*pldev), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto out_unregister_driver;
+ }
+
+ memset (pldev, 0, sizeof (*pldev));
+ pldev->name = swarm_ide_string;
+ pldev->id = 0;
+ pldev->dev.release = swarm_ide_platform_release;
+
+ if (platform_device_register(pldev)) {
+ err = -ENODEV;
+ goto out_free_pldev;
+ }
+
+ if (!pldev->dev.driver) {
+ /*
+ * The driver was not bound to this device, there was
+ * no hardware at this address. Unregister it, as the
+ * release fuction will take care of freeing the
+ * allocated structure
+ */
+ platform_device_unregister (pldev);
+ }
+
+ swarm_ide_dev = pldev;
+
+ return 0;
+
+out_free_pldev:
+ kfree(pldev);
+
+out_unregister_driver:
+ driver_unregister(&swarm_ide_driver);
+out:
+ return err;
+}
+
+module_init(swarm_ide_init_module);
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index 52cadc005d7..a21b1e11eef 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -65,23 +65,6 @@ static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
#define BUSCLOCK(D) \
((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))
-#if 0
- if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
- (void) pci_read_config_byte(dev, 0x54, &art);
- p += sprintf(p, "DMA Mode: %s(%s)",
- (c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO",
- (art&0x02)?"2":(art&0x01)?"1":"0");
- p += sprintf(p, " %s(%s)",
- (c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO",
- (art&0x08)?"2":(art&0x04)?"1":"0");
- p += sprintf(p, " %s(%s)",
- (c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO",
- (art&0x20)?"2":(art&0x10)?"1":"0");
- p += sprintf(p, " %s(%s)\n",
- (c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO",
- (art&0x80)?"2":(art&0x40)?"1":"0");
- } else {
-#endif
/*
* TO DO: active tuning and correction of cards without a bios.
@@ -112,13 +95,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive)
switch(hwif->pci_dev->device) {
case PCI_DEVICE_ID_ARTOP_ATP865:
case PCI_DEVICE_ID_ARTOP_ATP865R:
-#if 0
- mode = (hwif->INB(hwif->dma_master) & 0x10) ? 4 : 3;
-#else
mode = (hwif->INB(((hwif->channel) ?
hwif->mate->dma_status :
hwif->dma_status)) & 0x10) ? 4 : 3;
-#endif
break;
case PCI_DEVICE_ID_ARTOP_ATP860:
case PCI_DEVICE_ID_ARTOP_ATP860R:
@@ -263,35 +242,9 @@ static int aec62xx_irq_timeout (ide_drive_t *drive)
case PCI_DEVICE_ID_ARTOP_ATP865:
case PCI_DEVICE_ID_ARTOP_ATP865R:
printk(" AEC62XX time out ");
-#if 0
- {
- int i = 0;
- u8 reg49h = 0;
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, &reg49h);
- for (i=0;i<256;i++)
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10);
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10);
- }
- return 0;
-#endif
default:
break;
}
-#if 0
- {
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = hwif->pci_dev;
- u8 tmp1 = 0, tmp2 = 0, mode6 = 0;
-
- pci_read_config_byte(dev, 0x44, &tmp1);
- pci_read_config_byte(dev, 0x45, &tmp2);
- printk(" AEC6280 r44=%x r45=%x ",tmp1,tmp2);
- mode6 = HWIF(drive)->INB(((hwif->channel) ?
- hwif->mate->dma_status :
- hwif->dma_status));
- printk(" AEC6280 133=%x ", (mode6 & 0x10));
- }
-#endif
return 0;
}
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 6cf49394a80..cf84350efc5 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -876,10 +876,15 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = {
static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
+ static struct pci_device_id ati_rs100[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) },
+ { },
+ };
+
ide_pci_device_t *d = &ali15x3_chipset;
- if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL))
- printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n");
+ if (pci_dev_present(ati_rs100))
+ printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
#if defined(CONFIG_SPARC64)
d->init_hwif = init_hwif_common_ali15x3;
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index 7dc24682d19..ea3c52cc8ac 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -222,10 +222,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
/* We must not grab the entire device, it has 'ISA' space in its
BARS too and we will freak out other bits of the kernel */
- if(pci_enable_device_bars(dev, 1<<2))
- {
+ if (pci_enable_device_bars(dev, 1<<2)) {
printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
- return 1;
+ return -ENODEV;
}
pci_set_master(dev);
if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 211641a5439..fe06ebb0e5b 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -39,7 +39,7 @@
#define PDC202_DEBUG_CABLE 0
-const static char *pdc_quirk_drives[] = {
+static const char *pdc_quirk_drives[] = {
"QUANTUM FIREBALLlct08 08",
"QUANTUM FIREBALLP KA6.4",
"QUANTUM FIREBALLP KA9.1",
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index ff2e217a8c8..0d3073f4eab 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -69,7 +69,7 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list)
static u8 svwks_ratemask (ide_drive_t *drive)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
- u8 mode;
+ u8 mode = 0;
if (!svwks_revision)
pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index af526b671c4..4ee597d0879 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -622,12 +622,18 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
ide_hwif_t *hwif;
int h;
+ /*
+ * Find an empty HWIF; if none available, return -ENOMEM.
+ */
for (h = 0; h < MAX_HWIFS; ++h) {
hwif = &ide_hwifs[h];
- /* Find an empty HWIF */
if (hwif->chipset == ide_unknown)
break;
}
+ if (h == MAX_HWIFS) {
+ printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name);
+ return -ENOMEM;
+ }
/* Get the CmdBlk and CtrlBlk Base Registers */
base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET;
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 022d244f2eb..f1ca154dd52 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -6,7 +6,13 @@
*
* May be copied or modified under the terms of the GNU General Public License
*
- * Documentation available under NDA only
+ * Documentation for CMD680:
+ * http://gkernel.sourceforge.net/specs/sii/sii-0680a-v1.31.pdf.bz2
+ *
+ * Documentation for SiI 3112:
+ * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
+ *
+ * Errata and other documentation only available under NDA.
*
*
* FAQ Items:
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 16b3e2d8bfb..75a2253a3e6 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -87,6 +87,7 @@ static const struct {
u8 chipset_family;
u8 flags;
} SiSHostChipInfo[] = {
+ { "SiS965", PCI_DEVICE_ID_SI_965, ATA_133 },
{ "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 },
{ "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 },
{ "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 },
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index ea0806c82be..8a5c7b286b2 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -399,34 +399,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
return dev->irq;
}
-static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
-{
- unsigned int rev;
- u8 dma_state;
-
- DBG(("init_dma_sl82c105(hwif: ide%d, dma_base: 0x%08x)\n", hwif->index, dma_base));
-
- hwif->autodma = 0;
-
- if (!dma_base)
- return;
-
- dma_state = hwif->INB(dma_base + 2);
- rev = sl82c105_bridge_revision(hwif->pci_dev);
- if (rev <= 5) {
- printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
- hwif->name, rev);
- dma_state &= ~0x60;
- } else {
- dma_state |= 0x60;
- if (!noautodma)
- hwif->autodma = 1;
- }
- hwif->OUTB(dma_state, dma_base + 2);
-
- ide_setup_dma(hwif, dma_base, 8);
-}
-
/*
* Initialise the chip
*/
@@ -434,6 +406,8 @@ static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base
static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
+ unsigned int rev;
+ u8 dma_state;
u32 val;
DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
@@ -455,33 +429,54 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
pci_read_config_dword(dev, 0x40, &val);
*((u32 *)&hwif->hwif_data) = val;
+ hwif->atapi_dma = 0;
+ hwif->mwdma_mask = 0;
+ hwif->swdma_mask = 0;
+ hwif->autodma = 0;
+
if (!hwif->dma_base)
return;
- hwif->atapi_dma = 1;
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
-
+ dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60;
+ rev = sl82c105_bridge_revision(hwif->pci_dev);
+ if (rev <= 5) {
+ /*
+ * Never ever EVER under any circumstances enable
+ * DMA when the bridge is this old.
+ */
+ printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
+ hwif->name, rev);
+ } else {
#ifdef CONFIG_BLK_DEV_IDEDMA
- hwif->ide_dma_check = &sl82c105_check_drive;
- hwif->ide_dma_on = &sl82c105_ide_dma_on;
- hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
- hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
- hwif->dma_start = &sl82c105_ide_dma_start;
- hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
+ dma_state |= 0x60;
+
+ hwif->atapi_dma = 1;
+ hwif->mwdma_mask = 0x07;
+ hwif->swdma_mask = 0x07;
+
+ hwif->ide_dma_check = &sl82c105_check_drive;
+ hwif->ide_dma_on = &sl82c105_ide_dma_on;
+ hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
+ hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
+ hwif->dma_start = &sl82c105_ide_dma_start;
+ hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
+
+ if (!noautodma)
+ hwif->autodma = 1;
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+
+ if (hwif->mate)
+ hwif->serialized = hwif->mate->serialized = 1;
#endif /* CONFIG_BLK_DEV_IDEDMA */
+ }
+ hwif->OUTB(dma_state, hwif->dma_base + 2);
}
static ide_pci_device_t sl82c105_chipset __devinitdata = {
.name = "W82C105",
.init_chipset = init_chipset_sl82c105,
.init_hwif = init_hwif_sl82c105,
- .init_dma = init_dma_sl82c105,
.channels = 2,
.autodma = NOAUTODMA,
.enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index a4d099c937f..c85b87cb59d 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -79,6 +79,8 @@ static struct via_isa_bridge {
u8 rev_max;
u16 flags;
} via_isa_bridges[] = {
+ { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+ { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -100,185 +102,14 @@ static struct via_isa_bridge {
{ NULL }
};
-static struct via_isa_bridge *via_config;
-static unsigned int via_80w;
static unsigned int via_clock;
static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
-/*
- * VIA /proc entry.
- */
-
-#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
-
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 via_proc = 0;
-static unsigned long via_base;
-static struct pci_dev *bmide_dev, *isa_dev;
-
-static char *via_control3[] = { "No limit", "64", "128", "192" };
-
-#define via_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
-#define via_print_drive(name, format, arg...)\
- p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
-
-
-/**
- * via_get_info - generate via /proc file
- * @buffer: buffer for data
- * @addr: set to start of data to use
- * @offset: current file offset
- * @count: size of read
- *
- * Fills in buffer with the debugging/configuration information for
- * the VIA chipset tuning and attached drives
- */
-
-static int via_get_info(char *buffer, char **addr, off_t offset, int count)
+struct via82cxxx_dev
{
- int speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
- uen[4], udma[4], umul[4], active8b[4], recover8b[4];
- struct pci_dev *dev = bmide_dev;
- unsigned int v, u, i;
- int len;
- u16 c, w;
- u8 t, x;
- char *p = buffer;
-
- via_print("----------VIA BusMastering IDE Configuration"
- "----------------");
-
- via_print("Driver Version: 3.38");
- via_print("South Bridge: VIA %s",
- via_config->name);
-
- pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
- pci_read_config_byte(dev, PCI_REVISION_ID, &x);
- via_print("Revision: ISA %#x IDE %#x", t, x);
- via_print("Highest DMA rate: %s",
- via_dma[via_config->flags & VIA_UDMA]);
-
- via_print("BM-DMA base: %#lx", via_base);
- via_print("PCI clock: %d.%dMHz",
- via_clock / 1000, via_clock / 100 % 10);
-
- pci_read_config_byte(dev, VIA_MISC_1, &t);
- via_print("Master Read Cycle IRDY: %dws",
- (t & 64) >> 6);
- via_print("Master Write Cycle IRDY: %dws",
- (t & 32) >> 5);
- via_print("BM IDE Status Register Read Retry: %s",
- (t & 8) ? "yes" : "no");
-
- pci_read_config_byte(dev, VIA_MISC_3, &t);
- via_print("Max DRDY Pulse Width: %s%s",
- via_control3[(t & 0x03)], (t & 0x03) ? " PCI clocks" : "");
-
- via_print("-----------------------Primary IDE"
- "-------Secondary IDE------");
- via_print("Read DMA FIFO flush: %10s%20s",
- (t & 0x80) ? "yes" : "no", (t & 0x40) ? "yes" : "no");
- via_print("End Sector FIFO flush: %10s%20s",
- (t & 0x20) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
-
- pci_read_config_byte(dev, VIA_IDE_CONFIG, &t);
- via_print("Prefetch Buffer: %10s%20s",
- (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no");
- via_print("Post Write Buffer: %10s%20s",
- (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
-
- pci_read_config_byte(dev, VIA_IDE_ENABLE, &t);
- via_print("Enabled: %10s%20s",
- (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no");
-
- c = inb(via_base + 0x02) | (inb(via_base + 0x0a) << 8);
- via_print("Simplex only: %10s%20s",
- (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
-
- via_print("Cable Type: %10s%20s",
- (via_80w & 1) ? "80w" : "40w", (via_80w & 2) ? "80w" : "40w");
-
- via_print("-------------------drive0----drive1"
- "----drive2----drive3-----");
-
- pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
- pci_read_config_dword(dev, VIA_DRIVE_TIMING, &v);
- pci_read_config_word(dev, VIA_8BIT_TIMING, &w);
-
- if (via_config->flags & VIA_UDMA)
- pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
- else u = 0;
-
- for (i = 0; i < 4; i++) {
-
- setup[i] = ((t >> ((3 - i) << 1)) & 0x3) + 1;
- recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1;
- active8b[i] = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1;
- active[i] = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1;
- recover[i] = ((v >> ((3 - i) << 3)) & 0xf) + 1;
- udma[i] = ((u >> ((3 - i) << 3)) & 0x7) + 2;
- umul[i] = ((u >> (((3 - i) & 2) << 3)) & 0x8) ? 1 : 2;
- uen[i] = ((u >> ((3 - i) << 3)) & 0x20);
- den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
-
- speed[i] = 2 * via_clock / (active[i] + recover[i]);
- cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock;
-
- if (!uen[i] || !den[i])
- continue;
-
- switch (via_config->flags & VIA_UDMA) {
-
- case VIA_UDMA_33:
- speed[i] = 2 * via_clock / udma[i];
- cycle[i] = 1000000 * udma[i] / via_clock;
- break;
-
- case VIA_UDMA_66:
- speed[i] = 4 * via_clock / (udma[i] * umul[i]);
- cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock;
- break;
-
- case VIA_UDMA_100:
- speed[i] = 6 * via_clock / udma[i];
- cycle[i] = 333333 * udma[i] / via_clock;
- break;
-
- case VIA_UDMA_133:
- speed[i] = 8 * via_clock / udma[i];
- cycle[i] = 250000 * udma[i] / via_clock;
- break;
- }
- }
-
- via_print_drive("Transfer Mode: ", "%10s",
- den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
-
- via_print_drive("Address Setup: ", "%8dns",
- 1000000 * setup[i] / via_clock);
- via_print_drive("Cmd Active: ", "%8dns",
- 1000000 * active8b[i] / via_clock);
- via_print_drive("Cmd Recovery: ", "%8dns",
- 1000000 * recover8b[i] / via_clock);
- via_print_drive("Data Active: ", "%8dns",
- 1000000 * active[i] / via_clock);
- via_print_drive("Data Recovery: ", "%8dns",
- 1000000 * recover[i] / via_clock);
- via_print_drive("Cycle Time: ", "%8dns",
- cycle[i]);
- via_print_drive("Transfer Rate: ", "%4d.%dMB/s",
- speed[i] / 1000, speed[i] / 100 % 10);
-
- /* hoping it is less than 4K... */
- len = (p - buffer) - offset;
- *addr = buffer + offset;
-
- return len > count ? count : len;
-}
-
-#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
+ struct via_isa_bridge *via_config;
+ unsigned int via_80w;
+};
/**
* via_set_speed - write timing registers
@@ -289,11 +120,13 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
* via_set_speed writes timing values to the chipset registers
*/
-static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
+static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
{
+ struct pci_dev *dev = hwif->pci_dev;
+ struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
u8 t;
- if (~via_config->flags & VIA_BAD_AST) {
+ if (~vdev->via_config->flags & VIA_BAD_AST) {
pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
@@ -305,7 +138,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
- switch (via_config->flags & VIA_UDMA) {
+ switch (vdev->via_config->flags & VIA_UDMA) {
case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
@@ -329,6 +162,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
static int via_set_drive(ide_drive_t *drive, u8 speed)
{
ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
+ struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif);
struct ide_timing t, p;
unsigned int T, UT;
@@ -337,7 +171,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
T = 1000000000 / via_clock;
- switch (via_config->flags & VIA_UDMA) {
+ switch (vdev->via_config->flags & VIA_UDMA) {
case VIA_UDMA_33: UT = T; break;
case VIA_UDMA_66: UT = T/2; break;
case VIA_UDMA_100: UT = T/3; break;
@@ -352,7 +186,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
}
- via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
+ via_set_speed(HWIF(drive), drive->dn, &t);
if (!drive->init_speed)
drive->init_speed = speed;
@@ -390,20 +224,41 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
static int via82cxxx_ide_dma_check (ide_drive_t *drive)
{
- u16 w80 = HWIF(drive)->udma_four;
+ ide_hwif_t *hwif = HWIF(drive);
+ struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
+ u16 w80 = hwif->udma_four;
u16 speed = ide_find_best_mode(drive,
XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
- (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
- (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
- (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
- (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
+ (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
+ (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
+ (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
+ (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
via_set_drive(drive, speed);
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
- return HWIF(drive)->ide_dma_on(drive);
- return HWIF(drive)->ide_dma_off_quietly(drive);
+ return hwif->ide_dma_on(drive);
+ return hwif->ide_dma_off_quietly(drive);
+}
+
+static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
+{
+ struct via_isa_bridge *via_config;
+ u8 t;
+
+ for (via_config = via_isa_bridges; via_config->id; via_config++)
+ if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA +
+ !!(via_config->flags & VIA_BAD_ID),
+ via_config->id, NULL))) {
+
+ pci_read_config_byte(*isa, PCI_REVISION_ID, &t);
+ if (t >= via_config->rev_min &&
+ t <= via_config->rev_max)
+ break;
+ }
+
+ return via_config;
}
/**
@@ -418,82 +273,28 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
{
struct pci_dev *isa = NULL;
+ struct via_isa_bridge *via_config;
u8 t, v;
unsigned int u;
- int i;
/*
* Find the ISA bridge to see how good the IDE is.
*/
-
- for (via_config = via_isa_bridges; via_config->id; via_config++)
- if ((isa = pci_find_device(PCI_VENDOR_ID_VIA +
- !!(via_config->flags & VIA_BAD_ID),
- via_config->id, NULL))) {
-
- pci_read_config_byte(isa, PCI_REVISION_ID, &t);
- if (t >= via_config->rev_min &&
- t <= via_config->rev_max)
- break;
- }
-
+ via_config = via_config_find(&isa);
if (!via_config->id) {
printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
return -ENODEV;
}
/*
- * Check 80-wire cable presence and setup Clk66.
+ * Setup or disable Clk66 if appropriate
*/
- switch (via_config->flags & VIA_UDMA) {
-
- case VIA_UDMA_66:
- /* Enable Clk66 */
- pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
- pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
- for (i = 24; i >= 0; i -= 8)
- if (((u >> (i & 16)) & 8) &&
- ((u >> i) & 0x20) &&
- (((u >> i) & 7) < 2)) {
- /*
- * 2x PCI clock and
- * UDMA w/ < 3T/cycle
- */
- via_80w |= (1 << (1 - (i >> 4)));
- }
- break;
-
- case VIA_UDMA_100:
- pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
- for (i = 24; i >= 0; i -= 8)
- if (((u >> i) & 0x10) ||
- (((u >> i) & 0x20) &&
- (((u >> i) & 7) < 4))) {
- /* BIOS 80-wire bit or
- * UDMA w/ < 60ns/cycle
- */
- via_80w |= (1 << (1 - (i >> 4)));
- }
- break;
-
- case VIA_UDMA_133:
- pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
- for (i = 24; i >= 0; i -= 8)
- if (((u >> i) & 0x10) ||
- (((u >> i) & 0x20) &&
- (((u >> i) & 7) < 6))) {
- /* BIOS 80-wire bit or
- * UDMA w/ < 60ns/cycle
- */
- via_80w |= (1 << (1 - (i >> 4)));
- }
- break;
-
- }
-
- /* Disable Clk66 */
- if (via_config->flags & VIA_BAD_CLK66) {
+ if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) {
+ /* Enable Clk66 */
+ pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+ pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
+ } else if (via_config->flags & VIA_BAD_CLK66) {
/* Would cause trouble on 596a and 686 */
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008);
@@ -560,33 +361,85 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
via_dma[via_config->flags & VIA_UDMA],
pci_name(dev));
- /*
- * Setup /proc/ide/via entry.
- */
+ return 0;
+}
+
+/*
+ * Check and handle 80-wire cable presence
+ */
+static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev)
+{
+ unsigned int u;
+ int i;
+ pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+
+ switch (vdev->via_config->flags & VIA_UDMA) {
+
+ case VIA_UDMA_66:
+ for (i = 24; i >= 0; i -= 8)
+ if (((u >> (i & 16)) & 8) &&
+ ((u >> i) & 0x20) &&
+ (((u >> i) & 7) < 2)) {
+ /*
+ * 2x PCI clock and
+ * UDMA w/ < 3T/cycle
+ */
+ vdev->via_80w |= (1 << (1 - (i >> 4)));
+ }
+ break;
+
+ case VIA_UDMA_100:
+ for (i = 24; i >= 0; i -= 8)
+ if (((u >> i) & 0x10) ||
+ (((u >> i) & 0x20) &&
+ (((u >> i) & 7) < 4))) {
+ /* BIOS 80-wire bit or
+ * UDMA w/ < 60ns/cycle
+ */
+ vdev->via_80w |= (1 << (1 - (i >> 4)));
+ }
+ break;
+
+ case VIA_UDMA_133:
+ for (i = 24; i >= 0; i -= 8)
+ if (((u >> i) & 0x10) ||
+ (((u >> i) & 0x20) &&
+ (((u >> i) & 7) < 6))) {
+ /* BIOS 80-wire bit or
+ * UDMA w/ < 60ns/cycle
+ */
+ vdev->via_80w |= (1 << (1 - (i >> 4)));
+ }
+ break;
-#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
- if (!via_proc) {
- via_base = pci_resource_start(dev, 4);
- bmide_dev = dev;
- isa_dev = isa;
- ide_pci_create_host_proc("via", via_get_info);
- via_proc = 1;
}
-#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
- return 0;
}
static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
{
+ struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev),
+ GFP_KERNEL);
+ struct pci_dev *isa = NULL;
int i;
+ if (vdev == NULL) {
+ printk(KERN_ERR "VP_IDE: out of memory :(\n");
+ return;
+ }
+
+ memset(vdev, 0, sizeof(struct via82cxxx_dev));
+ ide_set_hwifdata(hwif, vdev);
+
+ vdev->via_config = via_config_find(&isa);
+ via_cable_detect(hwif->pci_dev, vdev);
+
hwif->autodma = 0;
hwif->tuneproc = &via82cxxx_tune_drive;
hwif->speedproc = &via_set_drive;
-#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32)
+#if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32)
if(_machine == _MACH_chrp && _chrp_type == _CHRP_Pegasos) {
hwif->irq = hwif->channel ? 15 : 14;
}
@@ -594,7 +447,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
for (i = 0; i < 2; i++) {
hwif->drives[i].io_32bit = 1;
- hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
+ hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
hwif->drives[i].autotune = 1;
hwif->drives[i].dn = hwif->channel * 2 + i;
}
@@ -608,7 +461,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->swdma_mask = 0x07;
if (!hwif->udma_four)
- hwif->udma_four = (via_80w >> hwif->channel) & 1;
+ hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1;
hwif->ide_dma_check = &via82cxxx_ide_dma_check;
if (!noautodma)
hwif->autodma = 1;
@@ -616,24 +469,35 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->drives[1].autodma = hwif->autodma;
}
-static ide_pci_device_t via82cxxx_chipset __devinitdata = {
- .name = "VP_IDE",
- .init_chipset = init_chipset_via82cxxx,
- .init_hwif = init_hwif_via82cxxx,
- .channels = 2,
- .autodma = NOAUTODMA,
- .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
- .bootable = ON_BOARD,
+static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "VP_IDE",
+ .init_chipset = init_chipset_via82cxxx,
+ .init_hwif = init_hwif_via82cxxx,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+ .bootable = ON_BOARD
+ },{ /* 1 */
+ .name = "VP_IDE",
+ .init_chipset = init_chipset_via82cxxx,
+ .init_hwif = init_hwif_via82cxxx,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+ .bootable = ON_BOARD,
+ }
};
static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- return ide_setup_pci_device(dev, &via82cxxx_chipset);
+ return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
}
static struct pci_device_id via_pci_tbl[] = {
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, via_pci_tbl);
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index b3e65a65d20..5013b1285e2 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1271,7 +1271,7 @@ static int
pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
{
struct device_node *np = pmif->node;
- int *bidp, i;
+ int *bidp;
pmif->cable_80 = 0;
pmif->broken_dma = pmif->broken_dma_warn = 0;
@@ -1401,20 +1401,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
/* We probe the hwif now */
probe_hwif_init(hwif);
- /* The code IDE code will have set hwif->present if we have devices attached,
- * if we don't, the discard the interface except if we are on a media bay slot
- */
- if (!hwif->present && !pmif->mediabay) {
- printk(KERN_INFO "ide%d: Bus empty, interface released.\n",
- hwif->index);
- default_hwif_iops(hwif);
- for (i = IDE_DATA_OFFSET; i <= IDE_CONTROL_OFFSET; ++i)
- hwif->io_ports[i] = 0;
- hwif->chipset = ide_unknown;
- hwif->noprobe = 1;
- return -ENODEV;
- }
-
return 0;
}
@@ -1444,7 +1430,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
pmif = &pmac_ide[i];
hwif = &ide_hwifs[i];
- if (mdev->ofdev.node->n_addrs == 0) {
+ if (macio_resource_count(mdev) == 0) {
printk(KERN_WARNING "ide%d: no address for %s\n",
i, mdev->ofdev.node->full_name);
return -ENXIO;
@@ -1667,11 +1653,16 @@ static struct macio_driver pmac_ide_macio_driver =
};
static struct pci_device_id pmac_ide_pci_match[] = {
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
};
static struct pci_driver pmac_ide_pci_driver = {
@@ -1695,7 +1686,7 @@ pmac_ide_probe(void)
#else
macio_register_driver(&pmac_ide_macio_driver);
pci_register_driver(&pmac_ide_pci_driver);
-#endif
+#endif
}
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index d4f2111d436..7ebf992e8c2 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -787,7 +787,7 @@ static int pre_init = 1; /* Before first ordered IDE scan */
static LIST_HEAD(ide_pci_drivers);
/*
- * __ide_register_pci_driver - attach IDE driver
+ * __ide_pci_register_driver - attach IDE driver
* @driver: pci driver
* @module: owner module of the driver
*