Re: LS120 enhancements

Paul Flinders (paul@dawa.demon.co.uk)
31 Dec 1998 21:47:19 +0000


--Multipart_Thu_Dec_31_21:47:19_1998-1
Content-Type: text/plain; charset=US-ASCII

Junichi Saito <j.saito@wanadoo.fr> writes:
>
> I tried the ide-floppy.patch not against linux-2.1.132-ac2 but 2.2.0-pre1
> and got the following:
>
> ide-floppy.c: In function `idefloppy_ioctl':
> ide-floppy.c:1463: void value not ignored as it ought to be
> make[2]: *** [ide-floppy.o] Error 1
>
> Is the patch valid only against 2.1.132-ac2 ? Or is there a way to fix
> this ? The patch itself applied with some offsets but no *.rej.

The offsets should be ok - an alternative fix for the DMA related oops
has been added to the 2.2 version of ide-floppy.c but there shouldn't
be any issue in having both fixes in the code.

>
> kernel compiled using gcc 2.7.2.3

There was a bug(let) in the patch - some junk from testing got left in
the format unit ioctl.

Attached is a corrected patch which should apply OK against 2.2preX
(although there will still be a 3 line offset for some of the hunks)
but if you don't want to have to back out the original patch and apply
this one then change the end of the FDFMTUNIT part of the switch
statement in idefloppy_ioctl from

idefloppy_create_format_track_cmd (floppy, &pc, &f);
idefloppy_queue_pc_tail (drive, &pc);
return idefloppy_create_request_sense_cmd (&pc);

to

idefloppy_create_format_track_cmd (floppy, &pc, &f);
return idefloppy_queue_pc_tail (drive, &pc);

--Multipart_Thu_Dec_31_21:47:19_1998-1
Content-Type: application/octet-stream; type=patch
Content-Disposition: attachment; filename="ide-floppy.patch"
Content-Transfer-Encoding: 8bit

--- linux-2.1.132-ac2/include/linux/fd.h.orig Wed Jun 24 22:30:11 1998
+++ linux-2.1.132-ac2/include/linux/fd.h Tue Dec 29 14:21:15 1998
@@ -71,6 +71,8 @@
/* format the specified track */
#define FDFMTEND _IO(2,0x49)
/* end formatting a disk */
+#define FDFMTUNIT _IO(2,0x4a)
+/* Format whole disk (ide-floppy) */


/*
--- linux-2.1.132-ac2/drivers/block/ide-floppy.c.orig Mon Dec 28 17:17:49 1998
+++ linux-2.1.132-ac2/drivers/block/ide-floppy.c Wed Dec 30 12:32:40 1998
@@ -26,9 +26,17 @@
* Issue START command only if TEST UNIT READY fails.
* Add work-around for IOMEGA ZIP revision 21.D.
* Remove idefloppy_get_capabilities().
+ * Ver 0.9 Dec 30 98 Avoid rq == NULL in idefloppy_end_request when
+ * DMA enabled
+ * Allow read of multicount for hdparm
+ * Copy current geometry to id struct for hdparm
+ * Add FDGETPRM ioctl to get geometry in a manner
+ * compatible with "normal floppies"
+ * Add FDFMT{BEG,TRK,END} ioctls
+ * Allow timeout to be specified per command
*/

-#define IDEFLOPPY_VERSION "0.8"
+#define IDEFLOPPY_VERSION "0.9"

#include <linux/config.h>
#include <linux/module.h>
@@ -44,6 +52,7 @@
#include <linux/genhd.h>
#include <linux/malloc.h>
#include <linux/cdrom.h>
+#include <linux/fd.h>

#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -67,7 +76,8 @@
/*
* Some drives require a longer irq timeout.
*/
-#define IDEFLOPPY_WAIT_CMD (5 * WAIT_CMD)
+#define IDEFLOPPY_WAIT_CMD (5 * WAIT_CMD) /* 50 secs */
+#define IDEFLOPPY_FORMAT_WAIT (10 * WAIT_CMD) /* 100 secs */

/*
* After each failed packet command we issue a request sense command
@@ -92,7 +102,9 @@
* Our view of a packet command.
*/
typedef struct idefloppy_packet_command_s {
- u8 c[12]; /* Actual packet bytes */
+ u8 c[12]; /* Actual packet bytes */
+ u8 p[12]; /* parameter block */
+ int pl; /* parameter block len */
int retries; /* On each retry, we increment retries */
int error; /* Error code */
int request_transfer; /* Bytes to transfer */
@@ -106,6 +118,7 @@
void (*callback) (ide_drive_t *); /* Called when this packet command is completed */
byte pc_buffer[IDEFLOPPY_PC_BUFFER_SIZE]; /* Temporary buffer */
unsigned int flags; /* Status/Action bit flags */
+ unsigned int timeout; /* timeout */
} idefloppy_pc_t;

/*
@@ -173,7 +186,7 @@
u8 page_length; /* Page Length - Should be 0x1e */
u16 transfer_rate; /* In kilobits per second */
u8 heads, sectors; /* Number of heads, Number of sectors per track */
- u16 sector_size; /* Byes per sector */
+ u16 sector_size; /* Bytes per sector */
u16 cyls; /* Number of cylinders */
u8 reserved10[10];
u8 motor_delay; /* Motor off delay */
@@ -183,7 +196,7 @@
} idefloppy_flexible_disk_page_t;

/*
- * Format capacity
+ * Format capacity as read from drive
*/
typedef struct {
u8 reserved[3];
@@ -210,6 +223,46 @@
#define CAPACITY_CURRENT 0x02
#define CAPACITY_NO_CARTRIDGE 0x03

+typedef struct {
+ u8 reserved; /* */
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ unsigned side :1;
+ unsigned immed :1;
+ unsigned reserved2 :2;
+ unsigned dcrt :1;
+ unsigned singletrack :1;
+ unsigned reserved3 :1;
+ unsigned fov :1;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ unsigned fov :1;
+ unsigned reserved3 :1;
+ unsigned singletrack :1;
+ unsigned dcrt :1;
+ unsigned reserved2 :2;
+ unsigned immed :1;
+ unsigned side :1;
+#else
+#error "Bitfield endianness not defined! Check your byteorder.h"
+#endif
+ u8 dll_msb; /* Defect List Length */
+ u8 dll_lsb; /* Defect List Length */
+} idefloppy_format_list_hdr_t;
+
+/*
+ * Format capacity as written to drive for FORMAT UNIT
+ */
+typedef struct {
+ u32 blocks; /* Number of blocks */
+ u8 reserved;
+ u8 length_msb; /* Block Length (MSB)*/
+ u16 length; /* Block Length */
+} idefloppy_format_capacity_descriptor_t;
+
+typedef struct {
+ idefloppy_format_list_hdr_t flist;
+ idefloppy_format_capacity_descriptor_t capacity;
+} idefloppy_fmt_unit_params_t;
+
/*
* Most of our global data which we need to save even as we leave the
* driver due to an interrupt or a timer event is stored in a variable
@@ -696,11 +749,10 @@
#ifdef CONFIG_BLK_DEV_IDEDMA
static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
{
- struct request *rq = pc->rq;
- struct buffer_head *bh = rq->bh;
-
- while ((bh = rq->bh) != NULL)
- idefloppy_end_request (1, HWGROUP(drive));
+ struct request *rq = pc->rq;
+
+ while (rq->bh->b_reqnext != NULL)
+ idefloppy_end_request(1, HWGROUP(drive));
}
#endif /* CONFIG_BLK_DEV_IDEDMA */

@@ -787,7 +839,8 @@
*/
static void idefloppy_init_pc (idefloppy_pc_t *pc)
{
- memset (pc->c, 0, 12);
+ memset (pc->c, 0, sizeof(pc->c));
+ pc->pl = 0;
pc->retries = 0;
pc->flags = 0;
pc->request_transfer = 0;
@@ -795,6 +848,7 @@
pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;
pc->b_data = NULL;
pc->callback = &idefloppy_pc_callback;
+ pc->timeout = IDEFLOPPY_WAIT_CMD;
}

static void idefloppy_create_request_sense_cmd (idefloppy_pc_t *pc)
@@ -806,6 +860,53 @@
pc->callback = &idefloppy_request_sense_callback;
}

+static void idefloppy_create_format_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc)
+{
+ idefloppy_fmt_unit_params_t *params = (idefloppy_fmt_unit_params_t *)pc->p;
+ memset(params, '\0', sizeof(*params));
+
+ idefloppy_init_pc (pc);
+ pc->c[0] = IDEFLOPPY_FORMAT_UNIT_CMD;
+ pc->c[1] = 0x17;
+ params->flist.fov = 1;
+ /* params->flist.immed = 1; */
+ params->flist.dll_lsb = 8;
+
+ put_unaligned (htons (floppy->block_size), (unsigned short *) &params->capacity.length);
+ put_unaligned (htonl (floppy->blocks), (unsigned long *) &params->capacity.blocks);
+ pc->pl = 12;
+ set_bit (PC_WRITING, &pc->flags);
+ /* format takes about 60 secs */
+ pc->timeout = IDEFLOPPY_FORMAT_WAIT;
+}
+
+static void idefloppy_create_format_track_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct format_descr *f)
+{
+ idefloppy_fmt_unit_params_t *params = (idefloppy_fmt_unit_params_t *)pc->p;
+ memset(params, '\0', sizeof(*params));
+
+#if IDEFLOPPY_DEBUG_INFO
+ printk(KERN_INFO "ide-floppy: format track %d head %d\n", f->track, f->head);
+#endif
+ idefloppy_init_pc (pc);
+ pc->c[0] = IDEFLOPPY_FORMAT_UNIT_CMD;
+ pc->c[1] = 0x17;
+ pc->c[2] = f->track;
+ params->flist.fov = 1;
+ /* params->flist.immed = 1; */
+ params->flist.dcrt = 1;
+ params->flist.singletrack = 1;
+ if (f->head)
+ params->flist.side = 1;
+ params->flist.dll_lsb = 8;
+
+ put_unaligned (htons (floppy->block_size), (unsigned short *) &params->capacity.length);
+ put_unaligned (htonl (floppy->blocks), (unsigned long *) &params->capacity.blocks);
+ pc->pl = 12;
+ set_bit (PC_WRITING, &pc->flags);
+ /* default timeout should be OK for single track w/o check */
+}
+
/*
* idefloppy_retry_pc is called when an error was detected during the
* last packet command. We queue a request sense packet command in
@@ -914,7 +1015,7 @@
if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n");
idefloppy_discard_data (drive,bcount.all);
- ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD);
+ ide_set_handler (drive,&idefloppy_pc_intr,pc->timeout);
return;
}
#if IDEFLOPPY_DEBUG_LOG
@@ -923,10 +1024,13 @@
}
}
if (test_bit (PC_WRITING, &pc->flags)) {
- if (pc->buffer != NULL)
+ if (pc->pl != 0) {
+ atapi_output_bytes (drive,pc->p, pc->pl); /* Write the parameter block */
+ } else if (pc->buffer != NULL) {
atapi_output_bytes (drive,pc->current_position,bcount.all); /* Write the current buffer */
- else
+ } else {
idefloppy_output_buffers (drive, pc, bcount.all);
+ }
} else {
if (pc->buffer != NULL)
atapi_input_bytes (drive,pc->current_position,bcount.all); /* Read the current buffer */
@@ -936,7 +1040,7 @@
pc->actually_transferred+=bcount.all; /* Update the current position */
pc->current_position+=bcount.all;

- ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD); /* And set the interrupt handler again */
+ ide_set_handler (drive,&idefloppy_pc_intr,pc->timeout); /* And set the interrupt handler again */
}

static void idefloppy_transfer_pc (ide_drive_t *drive)
@@ -954,7 +1058,7 @@
ide_do_reset (drive);
return;
}
- ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD); /* Set the interrupt routine */
+ ide_set_handler (drive, &idefloppy_pc_intr, floppy->pc->timeout); /* Set the interrupt routine */
atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */
}

@@ -1223,6 +1327,14 @@
drive->bios_cyl = page->cyls;
drive->bios_head = page->heads;
drive->bios_sect = page->sectors;
+ /* Copy to identity struct for HDIO_GET_IDENITY */
+ if (drive->id)
+ {
+ drive->id->cur_sectors = drive->bios_sect;
+ drive->id->cur_heads = drive->bios_head;
+ drive->id->cur_cyls = drive->bios_cyl;
+ drive->id->sector_bytes = page->sector_size;
+ }
lba_capacity = floppy->blocks * floppy->block_size;
if (capacity != lba_capacity) {
printk (KERN_NOTICE "%s: The drive reports both %d and %d bytes as its capacity\n",
@@ -1294,8 +1406,11 @@
unsigned int cmd, unsigned long arg)
{
idefloppy_pc_t pc;
+ idefloppy_floppy_t *floppy = (idefloppy_floppy_t *)drive->driver_data;

- if (cmd == CDROMEJECT) {
+ switch (cmd) {
+ case FDEJECT:
+ case CDROMEJECT:
if (drive->usage > 1)
return -EBUSY;
idefloppy_create_prevent_cmd (&pc, 0);
@@ -1303,6 +1418,45 @@
idefloppy_create_start_stop_cmd (&pc, 2);
(void) idefloppy_queue_pc_tail (drive, &pc);
return 0;
+ case FDGETPRM:
+ {
+ struct floppy_struct params;
+ memset(&params, '\0', sizeof(params));
+ params.size = floppy->blocks;
+ params.sect = drive->id->cur_sectors;
+ params.head = drive->id->cur_heads;
+ params.track = drive->id->cur_cyls;
+ return copy_to_user((void *)arg,&params, sizeof(params)) ? -EFAULT : 0;
+ }
+ case FDFMTBEG:
+ case FDFMTTRK:
+ case FDFMTUNIT:
+ if (drive->usage > 1)
+ return -EBUSY;
+ if (!(file->f_mode & 2))
+ return -EBADF;
+ if (floppy->wp)
+ /* Shouldn't get here as check in write or
+ above should prevent trying to format write
+ protected media */
+ return -EROFS;
+ switch (cmd) {
+ case FDFMTBEG:
+ return 0;
+ case FDFMTTRK:
+ {
+ struct format_descr f;
+ if (copy_from_user(&f, (void *)arg, sizeof(f)))
+ return -EFAULT;
+ idefloppy_create_format_track_cmd (floppy, &pc, &f);
+ return idefloppy_queue_pc_tail (drive, &pc);
+ }
+ case FDFMTUNIT:
+ idefloppy_create_format_cmd (floppy, &pc);
+ return idefloppy_queue_pc_tail (drive, &pc);
+ }
+ case FDFMTEND:
+ return 0;
}
return -EIO;
}
@@ -1501,6 +1656,7 @@
ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL);
ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL);
ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL);
+ ide_add_setting(drive, "multcount", SETTING_READ, HDIO_GET_MULTCOUNT, -1, TYPE_BYTE, 0, 0, 1, 1, &drive->mult_count, NULL);

}

--Multipart_Thu_Dec_31_21:47:19_1998-1--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/