patch-2.3.99-pre9 linux/drivers/ide/ide.c
Next file: linux/drivers/ide/pdc202xx.c
Previous file: linux/drivers/ide/ide-probe.c
Back to the patch index
Back to the overall index
- Lines: 407
- Date:
Mon May 15 11:03:48 2000
- Orig file:
v2.3.99-pre8/linux/drivers/ide/ide.c
- Orig date:
Thu May 11 15:30:07 2000
diff -u --recursive --new-file v2.3.99-pre8/linux/drivers/ide/ide.c linux/drivers/ide/ide.c
@@ -321,6 +321,7 @@
|| !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */
|| !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */
|| !strncmp(id->model, "HAGIWARA HPC", 12) /* Hagiwara */
+ || !strncmp(id->model, "LEXAR ATA_FLASH", 15) /* Lexar */
|| !strncmp(id->model, "ATA_FLASH", 9)) /* Simple Tech */
{
return 1; /* yes, it is a flash memory card */
@@ -767,6 +768,18 @@
args[1] = err;
args[2] = IN_BYTE(IDE_NSECTOR_REG);
}
+ } else if (rq->cmd == IDE_DRIVE_TASK) {
+ byte *args = (byte *) rq->buffer;
+ rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+ if (args) {
+ args[0] = stat;
+ args[1] = err;
+ args[2] = IN_BYTE(IDE_NSECTOR_REG);
+ args[3] = IN_BYTE(IDE_SECTOR_REG);
+ args[4] = IN_BYTE(IDE_LCYL_REG);
+ args[5] = IN_BYTE(IDE_HCYL_REG);
+ args[6] = IN_BYTE(IDE_SELECT_REG);
+ }
}
spin_lock_irqsave(&io_request_lock, flags);
blkdev_dequeue_request(rq);
@@ -876,7 +889,7 @@
if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;
/* retry only "normal" I/O: */
- if (rq->cmd == IDE_DRIVE_CMD) {
+ if (rq->cmd == IDE_DRIVE_CMD || rq->cmd == IDE_DRIVE_TASK) {
rq->errors = 1;
ide_end_drive_cmd(drive, stat, err);
return ide_stopped;
@@ -1036,7 +1049,20 @@
static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
{
byte *args = rq->buffer;
- if (args) {
+ if (args && rq->cmd == IDE_DRIVE_TASK) {
+
+#ifdef DEBUG
+ printk("%s: DRIVE_TASK_CMD data=x%02x cmd=0x%02x fr=0x%02x ns=0x%02x sc=0x%02x lcyl=0x%02x hcyl=0x%02x sel=0x%02x\n",
+ drive->name, args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
+#endif
+ OUT_BYTE(args[1], IDE_FEATURE_REG);
+ OUT_BYTE(args[3], IDE_SECTOR_REG);
+ OUT_BYTE(args[4], IDE_LCYL_REG);
+ OUT_BYTE(args[5], IDE_HCYL_REG);
+ OUT_BYTE(args[6], IDE_SELECT_REG);
+ ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
+ return ide_started;
+ } else if (args) {
#ifdef DEBUG
printk("%s: DRIVE_CMD cmd=0x%02x sc=0x%02x fr=0x%02x xx=0x%02x\n",
drive->name, args[0], args[1], args[2], args[3]);
@@ -1116,7 +1142,7 @@
return startstop;
}
if (!drive->special.all) {
- if (rq->cmd == IDE_DRIVE_CMD) {
+ if (rq->cmd == IDE_DRIVE_CMD || rq->cmd == IDE_DRIVE_TASK) {
return execute_drive_cmd(drive, rq);
}
if (drive->driver != NULL) {
@@ -1225,7 +1251,7 @@
* the driver. This makes the driver much more friendlier to shared IRQs
* than previous designs, while remaining 100% (?) SMP safe and capable.
*/
-static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
+static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq)
{
ide_drive_t *drive;
ide_hwif_t *hwif;
@@ -1313,73 +1339,13 @@
return &hwif->drives[DEVICE_NR(dev) & 1].queue;
}
-void do_ide0_request (request_queue_t *q)
-{
- ide_do_request (ide_hwifs[0].hwgroup, 0);
-}
-
-#if MAX_HWIFS > 1
-void do_ide1_request (request_queue_t *q)
-{
- ide_do_request (ide_hwifs[1].hwgroup, 0);
-}
-#endif /* MAX_HWIFS > 1 */
-
-#if MAX_HWIFS > 2
-void do_ide2_request (request_queue_t *q)
-{
- ide_do_request (ide_hwifs[2].hwgroup, 0);
-}
-#endif /* MAX_HWIFS > 2 */
-
-#if MAX_HWIFS > 3
-void do_ide3_request (request_queue_t *q)
-{
- ide_do_request (ide_hwifs[3].hwgroup, 0);
-}
-#endif /* MAX_HWIFS > 3 */
-
-#if MAX_HWIFS > 4
-void do_ide4_request (request_queue_t *q)
-{
- ide_do_request (ide_hwifs[4].hwgroup, 0);
-}
-#endif /* MAX_HWIFS > 4 */
-
-#if MAX_HWIFS > 5
-void do_ide5_request (request_queue_t *q)
-{
- ide_do_request (ide_hwifs[5].hwgroup, 0);
-}
-#endif /* MAX_HWIFS > 5 */
-
-#if MAX_HWIFS > 6
-void do_ide6_request (request_queue_t *q)
-{
- ide_do_request (ide_hwifs[6].hwgroup, 0);
-}
-#endif /* MAX_HWIFS > 6 */
-
-#if MAX_HWIFS > 7
-void do_ide7_request (request_queue_t *q)
-{
- ide_do_request (ide_hwifs[7].hwgroup, 0);
-}
-#endif /* MAX_HWIFS > 7 */
-
-#if MAX_HWIFS > 8
-void do_ide8_request (request_queue_t *q)
-{
- ide_do_request (ide_hwifs[8].hwgroup, 0);
-}
-#endif /* MAX_HWIFS > 8 */
-
-#if MAX_HWIFS > 9
-void do_ide9_request (request_queue_t *q)
+/*
+ * Passes the stuff to ide_do_request
+ */
+void do_ide_request(request_queue_t *q)
{
- ide_do_request (ide_hwifs[9].hwgroup, 0);
+ ide_do_request(q->queuedata, 0);
}
-#endif /* MAX_HWIFS > 9 */
/*
* ide_timer_expiry() is our timeout function for all drive operations.
@@ -1656,16 +1622,8 @@
*/
void ide_init_drive_cmd (struct request *rq)
{
- rq->buffer = NULL;
+ memset(rq, 0, sizeof(*rq));
rq->cmd = IDE_DRIVE_CMD;
- rq->sector = 0;
- rq->nr_sectors = 0;
- rq->nr_segments = 0;
- rq->current_nr_sectors = 0;
- rq->sem = NULL;
- rq->bh = NULL;
- rq->bhtail = NULL;
- rq->q = NULL;
}
/*
@@ -2049,8 +2007,10 @@
hwgroup->hwif = HWIF(hwgroup->drive);
#ifdef CONFIG_BLK_DEV_IDEDMA
- if (hwif->dma_base)
+ if (hwif->dma_base) {
(void) ide_release_dma(hwif);
+ hwif->dma_base = 0;
+ }
#endif /* CONFIG_BLK_DEV_IDEDMA */
/*
@@ -2083,6 +2043,7 @@
init_hwif_data (index); /* restore hwif data to pristine status */
hwif->hwgroup = old_hwif.hwgroup;
hwif->tuneproc = old_hwif.tuneproc;
+ hwif->speedproc = old_hwif.speedproc;
hwif->selectproc = old_hwif.selectproc;
hwif->resetproc = old_hwif.resetproc;
hwif->dmaproc = old_hwif.dmaproc;
@@ -2103,7 +2064,7 @@
hwif->pci_devid = old_hwif.pci_devid;
#endif /* CONFIG_BLK_DEV_IDEPCI */
hwif->straight8 = old_hwif.straight8;
-
+ hwif->hwif_data = old_hwif.hwif_data;
abort:
restore_flags(flags); /* all CPUs */
}
@@ -2304,24 +2265,24 @@
return val;
}
-int ide_spin_wait_hwgroup (ide_drive_t *drive, unsigned long *flags)
+int ide_spin_wait_hwgroup (ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
unsigned long timeout = jiffies + (3 * HZ);
- spin_lock_irqsave(&io_request_lock, *flags);
+ spin_lock_irq(&io_request_lock);
while (hwgroup->busy) {
- unsigned long lflags;
- spin_unlock_irqrestore(&io_request_lock, *flags);
- __save_flags(lflags); /* local CPU only */
+ unsigned long flags;
+ spin_unlock_irq(&io_request_lock);
+ __save_flags(flags); /* local CPU only */
__sti(); /* local CPU only; needed for jiffies */
if (0 < (signed long)(jiffies - timeout)) {
- __restore_flags(lflags); /* local CPU only */
+ __restore_flags(flags);
printk("%s: channel busy\n", drive->name);
return -EBUSY;
}
- __restore_flags(lflags); /* local CPU only */
- spin_lock_irqsave(&io_request_lock, *flags);
+ __restore_flags(flags); /* local CPU only */
+ spin_lock_irq(&io_request_lock);
}
return 0;
}
@@ -2333,7 +2294,6 @@
*/
int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
{
- unsigned long flags;
int i;
u32 *p;
@@ -2345,7 +2305,7 @@
return -EINVAL;
if (setting->set)
return setting->set(drive, val);
- if (ide_spin_wait_hwgroup(drive, &flags))
+ if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
switch (setting->data_type) {
case TYPE_BYTE:
@@ -2363,7 +2323,7 @@
*p = val;
break;
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irq(&io_request_lock);
return 0;
}
@@ -2416,6 +2376,9 @@
ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL);
ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma);
ide_add_setting(drive, "ide_scsi", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->scsi, NULL);
+ ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->init_speed, NULL);
+ ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->current_speed, NULL);
+ ide_add_setting(drive, "number", SETTING_RW, -1, -1, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL);
}
int ide_wait_cmd (ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *buf)
@@ -2435,6 +2398,16 @@
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
+int ide_wait_cmd_task (ide_drive_t *drive, byte *buf)
+{
+ struct request rq;
+
+ ide_init_drive_cmd(&rq);
+ rq.cmd = IDE_DRIVE_TASK;
+ rq.buffer = buf;
+ return ide_do_drive_cmd(drive, &rq, ide_wait);
+}
+
/*
* Delay for *at least* 50ms. As we don't know how much time is left
* until the next tick occurs, we wait an extra tick to be safe.
@@ -2551,6 +2524,7 @@
case HDIO_DRIVE_CMD:
{
byte args[4], *argbuf = args;
+ byte xfer_rate = 0;
int argsize = 4;
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
if (NULL == (void *) arg)
@@ -2564,18 +2538,22 @@
return -ENOMEM;
memcpy(argbuf, args, 4);
}
- if (ide_ata66_check(drive, args[0], args[1], args[2]))
- goto abort;
+
+ if (set_transfer(drive, args[0], args[1], args[2])) {
+ xfer_rate = args[1];
+ if (ide_ata66_check(drive, args[0], args[1], args[2]))
+ goto abort;
+ }
err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
- if (!err && set_transfer(drive, args[0], args[1], args[2])) {
-#if 0
+ if (!err && xfer_rate) {
/* active-retuning-calls future */
- if (HWIF(drive)->tune2proc)
- HWIF(drive)->tune2proc(drive, args[1]);
-#endif
+ if ((HWIF(drive)->speedproc) != NULL)
+ HWIF(drive)->speedproc(drive, xfer_rate);
ide_driveid_update(drive);
+ } else {
+ printk("%s: \n", drive->name);
}
abort:
if (copy_to_user((void *)arg, argbuf, argsize))
@@ -2584,6 +2562,18 @@
kfree(argbuf);
return err;
}
+ case HDIO_DRIVE_TASK:
+ {
+ byte args[7], *argbuf = args;
+ int argsize = 7;
+ if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+ if (copy_from_user(args, (void *)arg, 7))
+ return -EFAULT;
+ err = ide_wait_cmd_task(drive, argbuf);
+ if (copy_to_user((void *)arg, argbuf, argsize))
+ err = -EFAULT;
+ return err;
+ }
case HDIO_SCAN_HWIF:
{
@@ -3512,37 +3502,9 @@
EXPORT_SYMBOL(ide_intr);
EXPORT_SYMBOL(ide_fops);
EXPORT_SYMBOL(ide_get_queue);
-EXPORT_SYMBOL(do_ide0_request);
EXPORT_SYMBOL(ide_add_generic_settings);
EXPORT_SYMBOL(ide_devfs_handle);
-#if MAX_HWIFS > 1
-EXPORT_SYMBOL(do_ide1_request);
-#endif /* MAX_HWIFS > 1 */
-#if MAX_HWIFS > 2
-EXPORT_SYMBOL(do_ide2_request);
-#endif /* MAX_HWIFS > 2 */
-#if MAX_HWIFS > 3
-EXPORT_SYMBOL(do_ide3_request);
-#endif /* MAX_HWIFS > 3 */
-#if MAX_HWIFS > 4
-EXPORT_SYMBOL(do_ide4_request);
-#endif /* MAX_HWIFS > 4 */
-#if MAX_HWIFS > 5
-EXPORT_SYMBOL(do_ide5_request);
-#endif /* MAX_HWIFS > 5 */
-#if MAX_HWIFS > 6
-EXPORT_SYMBOL(do_ide6_request);
-#endif /* MAX_HWIFS > 6 */
-#if MAX_HWIFS > 7
-EXPORT_SYMBOL(do_ide7_request);
-#endif /* MAX_HWIFS > 7 */
-#if MAX_HWIFS > 8
-EXPORT_SYMBOL(do_ide8_request);
-#endif /* MAX_HWIFS > 8 */
-#if MAX_HWIFS > 9
-EXPORT_SYMBOL(do_ide9_request);
-#endif /* MAX_HWIFS > 9 */
-
+EXPORT_SYMBOL(do_ide_request);
/*
* Driver module
*/
@@ -3567,6 +3529,7 @@
EXPORT_SYMBOL(ide_revalidate_disk);
EXPORT_SYMBOL(ide_cmd);
EXPORT_SYMBOL(ide_wait_cmd);
+EXPORT_SYMBOL(ide_wait_cmd_task);
EXPORT_SYMBOL(ide_delay_50ms);
EXPORT_SYMBOL(ide_stall_queue);
#ifdef CONFIG_PROC_FS
@@ -3652,8 +3615,13 @@
{
int index;
- for (index = 0; index < MAX_HWIFS; ++index)
+ for (index = 0; index < MAX_HWIFS; ++index) {
ide_unregister(index);
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ if (ide_hwifs[index].dma_base)
+ (void) ide_release_dma(&ide_hwifs[index]);
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+ }
#ifdef CONFIG_PROC_FS
proc_ide_destroy();
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)