patch-2.2.18 linux/drivers/block/ide-floppy.c
Next file: linux/drivers/block/ide-pci.c
Previous file: linux/drivers/block/ide-dma.c
Back to the patch index
Back to the overall index
- Lines: 436
- Date:
Sat Oct 28 11:31:51 2000
- Orig file:
v2.2.17/drivers/block/ide-floppy.c
- Orig date:
Sat Sep 9 18:42:34 2000
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c
@@ -1,7 +1,8 @@
/*
- * linux/drivers/block/ide-floppy.c Version 0.9 Jul 4, 1999
+ * linux/drivers/block/ide-floppy.c Version 0.94 Oct 27, 2000
*
* Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
+ * Copyright (C) 2000 Paul Bristow <paul@paulbristow.net>
*/
/*
@@ -10,6 +11,12 @@
* The driver currently doesn't have any fancy features, just the bare
* minimum read/write support.
*
+ * This driver supports the following IDE floppy drives:
+ *
+ * LS-120 SuperDisk
+ * Iomega Zip 100/250
+ * Iomega PC Card Clik!/PocketZip
+ *
* Many thanks to Lode Leroy <Lode.Leroy@www.ibase.be>, who tested so many
* ALPHA patches to this driver on an EASYSTOR LS-120 ATAPI floppy drive.
*
@@ -29,9 +36,17 @@
* Ver 0.9 Jul 4 99 Fix a bug which might have caused the number of
* bytes requested on each interrupt to be zero.
* Thanks to <shanos@es.co.nz> for pointing this out.
+ * Ver 0.91 Dec 11 99 Added IOMEGA Clik! drive support by
+ * <paul@paulbristow.net>
+ * Ver 0.92 Oct 22 00 Paul Bristow became official maintainer for this
+ * driver. Included Powerbook internal zip kludge.
+ * Ver 0.93 Oct 24 00 Fixed bugs for Clik! drive
+ * no disk on insert and disk change now works
+ * Ver 0.94 Oct 27 00 Tidied up to remove strstr(Clik) everywhere
+ *
*/
-#define IDEFLOPPY_VERSION "0.9"
+#define IDEFLOPPY_VERSION "0.94"
#include <linux/config.h>
#include <linux/module.h>
@@ -60,12 +75,14 @@
*/
#include "ide.h"
+
/*
* The following are used to debug the driver.
*/
-#define IDEFLOPPY_DEBUG_LOG 0
#define IDEFLOPPY_DEBUG_INFO 0
#define IDEFLOPPY_DEBUG_BUGS 1
+/* #define IDEFLOPPY_DEBUG(fmt, args...) printk(KERN_INFO fmt, ## args) */
+#define IDEFLOPPY_DEBUG( fmt, args... )
/*
* Some drives require a longer irq timeout.
@@ -185,6 +202,7 @@
u8 reserved30[2];
} idefloppy_flexible_disk_page_t;
+
/*
* Format capacity
*/
@@ -250,6 +268,8 @@
#define IDEFLOPPY_DRQ_INTERRUPT 0 /* DRQ interrupt device */
#define IDEFLOPPY_MEDIA_CHANGED 1 /* Media may have changed */
#define IDEFLOPPY_USE_READ12 2 /* Use READ12/WRITE12 or READ10/WRITE10 */
+#define IDEFLOPPY_CLIK_DRIVE 3 /* Avoid commands not supported in Clik drive */
+#define IDEFLOPPY_POWERBOOK_ZIP 4 /* Kludge for Apple Powerbook Zip drive */
/*
* ATAPI floppy drive packet commands
@@ -625,9 +645,7 @@
struct request *rq = hwgroup->rq;
int error;
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "Reached idefloppy_end_request\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "Reached idefloppy_end_request\n");
switch (uptodate) {
case 0: error = IDEFLOPPY_ERROR_GENERAL; break;
@@ -750,21 +768,19 @@
idefloppy_floppy_t *floppy = drive->driver_data;
floppy->sense_key = result->sense_key; floppy->asc = result->asc; floppy->ascq = result->ascq;
-#if IDEFLOPPY_DEBUG_LOG
- if (floppy->failed_pc)
- printk (KERN_INFO "ide-floppy: pc = %x, sense key = %x, asc = %x, ascq = %x\n",floppy->failed_pc->c[0],result->sense_key,result->asc,result->ascq);
- else
- printk (KERN_INFO "ide-floppy: sense key = %x, asc = %x, ascq = %x\n",result->sense_key,result->asc,result->ascq);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ if (floppy->failed_pc) {
+ IDEFLOPPY_DEBUG("ide-floppy: pc = %x, sense key = %x, asc = %x, ascq = %x\n",floppy->failed_pc->c[0],result->sense_key,result->asc,result->ascq);
+ }
+ else {
+ IDEFLOPPY_DEBUG("ide-floppy: sense key = %x, asc = %x, ascq = %x\n",result->sense_key,result->asc,result->ascq);
+ }
}
static void idefloppy_request_sense_callback (ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: Reached idefloppy_request_sense_callback\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "ide-floppy: Reached idefloppy_request_sense_callback\n");
if (!floppy->pc->error) {
idefloppy_analyze_error (drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer);
idefloppy_end_request (1,HWGROUP (drive));
@@ -781,9 +797,7 @@
{
idefloppy_floppy_t *floppy = drive->driver_data;
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: Reached idefloppy_pc_callback\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "ide-floppy: Reached idefloppy_pc_callback\n");
idefloppy_end_request (floppy->pc->error ? 0:1, HWGROUP(drive));
}
@@ -844,9 +858,7 @@
struct request *rq = pc->rq;
unsigned int temp;
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: Reached idefloppy_pc_intr interrupt handler\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "ide-floppy: Reached idefloppy_pc_intr interrupt handler\n");
#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
@@ -856,26 +868,20 @@
pc->actually_transferred=pc->request_transfer;
idefloppy_update_buffers (drive, pc);
}
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: DMA finished\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "ide-floppy: DMA finished\n");
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
status.all = GET_STAT(); /* Clear the interrupt */
if (!status.b.drq) { /* No more interrupts */
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "Packet command completed, %d bytes transferred\n", pc->actually_transferred);
clear_bit (PC_DMA_IN_PROGRESS, &pc->flags);
ide__sti(); /* local CPU only */
if (status.b.check || test_bit (PC_DMA_ERROR, &pc->flags)) { /* Error detected */
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: %s: I/O error\n",drive->name);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "ide-floppy: %s: I/O error\n",drive->name);
rq->errors++;
if (pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
printk (KERN_ERR "ide-floppy: I/O error in request sense command\n");
@@ -919,9 +925,7 @@
ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD,NULL);
return ide_started;
}
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_NOTICE "ide-floppy: The floppy wants to send us more data than expected - allowing transfer\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "ide-floppy: The floppy wants to send us more data than expected - allowing transfer\n");
}
}
if (test_bit (PC_WRITING, &pc->flags)) {
@@ -987,7 +991,7 @@
* a legitimate error code was received.
*/
if (!test_bit (PC_ABORT, &pc->flags)) {
- printk (KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
+ IDEFLOPPY_DEBUG( "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);
pc->error = IDEFLOPPY_ERROR_GENERAL; /* Giving up */
}
@@ -995,9 +999,7 @@
pc->callback(drive);
return ide_stopped;
}
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "Retry number - %d\n",pc->retries);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "Retry number - %d\n",pc->retries);
pc->retries++;
pc->actually_transferred=0; /* We haven't transferred any data yet */
@@ -1037,9 +1039,7 @@
static void idefloppy_rw_callback (ide_drive_t *drive)
{
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "ide-floppy: Reached idefloppy_rw_callback\n");
idefloppy_end_request(1, HWGROUP(drive));
return;
@@ -1047,9 +1047,7 @@
static void idefloppy_create_prevent_cmd (idefloppy_pc_t *pc, int prevent)
{
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: creating prevent removal command, prevent = %d\n", prevent);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "ide-floppy: creating prevent removal command, prevent = %d\n", prevent);
idefloppy_init_pc (pc);
pc->c[0] = IDEFLOPPY_PREVENT_REMOVAL_CMD;
@@ -1109,10 +1107,8 @@
int block = sector / floppy->bs_factor;
int blocks = rq->nr_sectors / floppy->bs_factor;
-#if IDEFLOPPY_DEBUG_LOG
- printk ("create_rw1%d_cmd: block == %d, blocks == %d\n",
+ IDEFLOPPY_DEBUG( "create_rw1%d_cmd: block == %d, blocks == %d\n",
2 * test_bit (IDEFLOPPY_USE_READ12, &floppy->flags), block, blocks);
-#endif /* IDEFLOPPY_DEBUG_LOG */
idefloppy_init_pc (pc);
if (test_bit (IDEFLOPPY_USE_READ12, &floppy->flags)) {
@@ -1142,10 +1138,8 @@
idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t *pc;
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);
- printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);
+ IDEFLOPPY_DEBUG( "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
if (rq->errors >= ERROR_MAX) {
if (floppy->failed_pc != NULL)
@@ -1238,6 +1232,7 @@
return 0;
}
+
/*
* Determine if a media is present in the floppy drive, and if so,
* its LBA capacity.
@@ -1266,7 +1261,12 @@
for (i = 0; i < descriptors; i++, descriptor++) {
blocks = descriptor->blocks = ntohl (descriptor->blocks);
length = descriptor->length = ntohs (descriptor->length);
- if (!i && descriptor->dc == CAPACITY_CURRENT) {
+ if (!i) {
+ switch (descriptor->dc) {
+ case CAPACITY_UNFORMATTED: /* Clik! drive returns this instead of CAPACITY_CURRENT */
+ if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags))
+ break; /* If it is not a clik drive, break out (maintains previous driver behaviour) */
+ case CAPACITY_CURRENT: /* Normal Zip/LS-120 disks */
if (memcmp (descriptor, &floppy->capacity, sizeof (idefloppy_capacity_descriptor_t)))
printk (KERN_INFO "%s: %dkB, %d blocks, %d sector size\n", drive->name, blocks * length / 1024, blocks, length);
floppy->capacity = *descriptor;
@@ -1279,32 +1279,50 @@
printk (KERN_NOTICE "%s: warning: non 512 bytes block size not fully supported\n", drive->name);
rc = 0;
}
+ break;
+ case CAPACITY_NO_CARTRIDGE:
+ /* This is a KERN_ERR so it appears on screen for the user to see */
+ printk (KERN_ERR "%s: No disk in drive\n", drive->name);
+ break;
+ case CAPACITY_INVALID:
+ printk (KERN_ERR "%s: Invalid capacity for disk in drive\n", drive->name);
+ break;
}
-#if IDEFLOPPY_DEBUG_INFO
- if (!i) printk (KERN_INFO "Descriptor 0 Code: %d\n", descriptor->dc);
- printk (KERN_INFO "Descriptor %d: %dkB, %d blocks, %d sector size\n", i, blocks * length / 1024, blocks, length);
-#endif /* IDEFLOPPY_DEBUG_INFO */
}
+ if (!i) {
+ IDEFLOPPY_DEBUG( "Descriptor 0 Code: %d\n", descriptor->dc);
+ }
+ IDEFLOPPY_DEBUG( "Descriptor %d: %dkB, %d blocks, %d sector size\n", i, blocks * length / 1024, blocks, length);
+ }
+
+ /* Clik! disk does not support get_flexible_disk_page */
+ if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags))
(void) idefloppy_get_flexible_disk_page (drive);
+
drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;
return rc;
}
+
/*
* Our special ide-floppy ioctl's.
*
- * Currently there aren't any ioctl's.
+ * Supports eject command
*/
static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
idefloppy_pc_t pc;
+ idefloppy_floppy_t *floppy = drive->driver_data;
if (cmd == CDROMEJECT) {
if (drive->usage > 1)
return -EBUSY;
+ /* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
+ if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
idefloppy_create_prevent_cmd (&pc, 0);
(void) idefloppy_queue_pc_tail (drive, &pc);
+ }
idefloppy_create_start_stop_cmd (&pc, 2);
(void) idefloppy_queue_pc_tail (drive, &pc);
return 0;
@@ -1320,20 +1338,24 @@
idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t pc;
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "Reached idefloppy_open\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "Reached idefloppy_open\n");
MOD_INC_USE_COUNT;
if (drive->usage == 1) {
+ IDEFLOPPY_DEBUG( "Testing if unit is ready...\n");
idefloppy_create_test_unit_ready_cmd(&pc);
if (idefloppy_queue_pc_tail(drive, &pc)) {
+ IDEFLOPPY_DEBUG( "Not ready, issuing start command\n");
idefloppy_create_start_stop_cmd (&pc, 1);
(void) idefloppy_queue_pc_tail (drive, &pc);
+ } else
+ {
+ IDEFLOPPY_DEBUG( "Yes unit is ready\n");
}
if (idefloppy_get_capacity (drive)) {
drive->usage--;
MOD_DEC_USE_COUNT;
+ IDEFLOPPY_DEBUG( "I/O Error Getting Capacity\n");
return -EIO;
}
if (floppy->wp && (filp->f_mode & 2)) {
@@ -1342,8 +1364,11 @@
return -EROFS;
}
set_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
+ /* IOMEGA Clik! drives do not support lock/unlock commands - no room for mechanism */
+ if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
idefloppy_create_prevent_cmd (&pc, 1);
(void) idefloppy_queue_pc_tail (drive, &pc);
+ }
check_disk_change(inode->i_rdev);
}
return 0;
@@ -1352,16 +1377,18 @@
static void idefloppy_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
{
idefloppy_pc_t pc;
+ idefloppy_floppy_t *floppy = drive->driver_data;
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "Reached idefloppy_release\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ IDEFLOPPY_DEBUG( "Reached idefloppy_release\n");
if (!drive->usage) {
invalidate_buffers (inode->i_rdev);
+ /* IOMEGA Clik! drives do not support lock/unlock commands */
+ if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
idefloppy_create_prevent_cmd (&pc, 0);
(void) idefloppy_queue_pc_tail (drive, &pc);
}
+ }
MOD_DEC_USE_COUNT;
}
@@ -1549,6 +1576,17 @@
for (i = 0; i < 1 << PARTN_BITS; i++)
max_sectors[major][minor + i] = 64;
}
+ /*
+ * Guess what? The IOMEGA Clik! drive also needs the
+ * above fix. It makes nasty clicking noises without
+ * it, so please don't remove this.
+ */
+ if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0)
+ {
+ for (i = 0; i < 1 << PARTN_BITS; i++)
+ max_sectors[major][minor + i] = 64;
+ set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags);
+ }
(void) idefloppy_get_capacity (drive);
idefloppy_add_settings(drive);
@@ -1578,6 +1616,7 @@
#endif /* CONFIG_PROC_FS */
+
/*
* IDE subdriver functions, registered with ide.c
*/
@@ -1609,6 +1648,7 @@
NULL
};
+
/*
* idefloppy_init will register the driver for each floppy.
*/
@@ -1641,12 +1681,16 @@
return 0;
}
+
#ifdef MODULE
+/* Initialisation code for loading the driver as a modules */
int init_module (void)
{
return idefloppy_init ();
}
+
+/* Cleanup code for removing the driver module */
void cleanup_module (void)
{
ide_drive_t *drive;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)