patch-2.1.30 linux/drivers/block/ide-floppy.c
Next file: linux/drivers/block/ide-tape.c
Previous file: linux/drivers/block/ide-cd.c
Back to the patch index
Back to the overall index
- Lines: 234
- Date:
Tue Mar 11 14:19:11 1997
- Orig file:
v2.1.29/linux/drivers/block/ide-floppy.c
- Orig date:
Sat Jan 25 10:51:17 1997
diff -u --recursive --new-file v2.1.29/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/block/ide-floppy.c Version 0.4 - ALPHA Jan 26, 1997
+ * linux/drivers/block/ide-floppy.c Version 0.5 - ALPHA Feb 21, 1997
*
* Copyright (C) 1996, 1997 Gadi Oxman <gadio@netvision.net.il>
*/
@@ -17,6 +17,10 @@
* Ver 0.2 Oct 31 96 Minor changes.
* Ver 0.3 Dec 2 96 Fixed error recovery bug.
* Ver 0.4 Jan 26 97 Add support for the HDIO_GETGEO ioctl.
+ * Ver 0.5 Feb 21 97 Add partitions support.
+ * Use the minimum of the LBA and CHS capacities.
+ * Avoid hwgroup->rq == NULL on the last irq.
+ * Fix potential null dereferencing with DEBUG_LOG.
*/
#include <linux/config.h>
@@ -481,25 +485,23 @@
struct request *rq = pc->rq;
struct buffer_head *bh = rq->bh;
int count;
-
+
while (bcount) {
-#if IDEFLOPPY_DEBUG_BUGS
+ if (pc->b_count == bh->b_size) {
+ rq->sector += rq->current_nr_sectors;
+ rq->nr_sectors -= rq->current_nr_sectors;
+ idefloppy_end_request (1, HWGROUP(drive));
+ if ((bh = rq->bh) != NULL)
+ pc->b_count = 0;
+ }
if (bh == NULL) {
printk (KERN_ERR "%s: bh == NULL in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount);
idefloppy_discard_data (drive, bcount);
return;
}
-#endif /* IDEFLOPPY_DEBUG_BUGS */
count = IDEFLOPPY_MIN (bh->b_size - pc->b_count, bcount);
atapi_input_bytes (drive, bh->b_data + pc->b_count, count);
bcount -= count; pc->b_count += count;
- if (pc->b_count == bh->b_size) {
- rq->sector += rq->current_nr_sectors;
- rq->nr_sectors -= rq->current_nr_sectors;
- idefloppy_end_request (1, HWGROUP(drive));
- if ((bh = rq->bh) != NULL)
- pc->b_count = 0;
- }
}
}
@@ -510,16 +512,6 @@
int count;
while (bcount) {
-#if IDEFLOPPY_DEBUG_BUGS
- if (bh == NULL) {
- printk (KERN_ERR "%s: bh == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
- idefloppy_write_zeros (drive, bcount);
- return;
- }
-#endif /* IDEFLOPPY_DEBUG_BUGS */
- count = IDEFLOPPY_MIN (pc->b_count, bcount);
- atapi_output_bytes (drive, pc->b_data, count);
- bcount -= count; pc->b_data += count; pc->b_count -= count;
if (!pc->b_count) {
rq->sector += rq->current_nr_sectors;
rq->nr_sectors -= rq->current_nr_sectors;
@@ -529,6 +521,14 @@
pc->b_count = bh->b_size;
}
}
+ if (bh == NULL) {
+ printk (KERN_ERR "%s: bh == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
+ idefloppy_write_zeros (drive, bcount);
+ return;
+ }
+ count = IDEFLOPPY_MIN (pc->b_count, bcount);
+ atapi_output_bytes (drive, pc->b_data, count);
+ bcount -= count; pc->b_data += count; pc->b_count -= count;
}
}
@@ -584,7 +584,10 @@
floppy->sense_key = result->sense_key; floppy->asc = result->asc; floppy->ascq = result->ascq;
#if IDEFLOPPY_DEBUG_LOG
- 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);
+ 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 */
}
@@ -726,7 +729,7 @@
if (clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
printk (KERN_ERR "ide-floppy: The floppy wants to issue more interrupts in DMA mode\n");
printk (KERN_ERR "ide-floppy: DMA disabled, reverting to PIO\n");
- drive->using_dma=0;
+ HWIF(drive)->dmaproc(ide_dma_off, drive);
ide_do_reset (drive);
return;
}
@@ -841,7 +844,7 @@
#ifdef CONFIG_BLK_DEV_TRITON
if (clear_bit (PC_DMA_ERROR, &pc->flags)) {
printk (KERN_WARNING "ide-floppy: DMA disabled, reverting to PIO\n");
- drive->using_dma=0;
+ HWIF(drive)->dmaproc(ide_dma_off, drive);
}
if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
@@ -875,6 +878,7 @@
printk (KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n");
#endif /* IDEFLOPPY_DEBUG_LOG */
+ idefloppy_end_request(1, HWGROUP(drive));
return;
}
@@ -930,9 +934,9 @@
pc->c[4] = start;
}
-static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq)
+static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector)
{
- int block = rq->sector / floppy->bs_factor;
+ int block = sector / floppy->bs_factor;
int blocks = rq->nr_sectors / floppy->bs_factor;
#if IDEFLOPPY_DEBUG_LOG
@@ -991,7 +995,7 @@
return;
}
pc = idefloppy_next_pc_storage (drive);
- idefloppy_create_rw_cmd (floppy, pc, rq);
+ idefloppy_create_rw_cmd (floppy, pc, rq, block);
break;
case IDEFLOPPY_PC_RQ:
pc = (idefloppy_pc_t *) rq->buffer;
@@ -1029,7 +1033,7 @@
idefloppy_pc_t pc;
idefloppy_mode_parameter_header_t *header;
idefloppy_flexible_disk_page_t *page;
- int capacity;
+ int capacity, lba_capacity;
idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE, MODE_SENSE_CURRENT);
if (idefloppy_queue_pc_tail (drive,&pc)) {
@@ -1044,17 +1048,21 @@
page->cyls = ntohs (page->cyls);
page->rpm = ntohs (page->rpm);
capacity = page->cyls * page->heads * page->sectors * page->sector_size;
- if (memcmp (page, &floppy->flexible_disk_page, sizeof (idefloppy_flexible_disk_page_t))) {
+ if (memcmp (page, &floppy->flexible_disk_page, sizeof (idefloppy_flexible_disk_page_t)))
printk (KERN_INFO "%s: %dkB, %d/%d/%d CHS, %d kBps, %d sector size, %d rpm\n",
drive->name, capacity / 1024, page->cyls, page->heads, page->sectors,
page->transfer_rate / 8, page->sector_size, page->rpm);
- floppy->flexible_disk_page = *page;
- drive->bios_cyl = page->cyls;
- drive->bios_head = page->heads;
- drive->bios_sect = page->sectors;
- if (capacity != floppy->blocks * floppy->block_size)
- printk (KERN_NOTICE "%s: The drive reports both %d and %d bytes as its capacity\n",
- drive->name, capacity, floppy->blocks * floppy->block_size);
+
+ floppy->flexible_disk_page = *page;
+ drive->bios_cyl = page->cyls;
+ drive->bios_head = page->heads;
+ drive->bios_sect = page->sectors;
+ 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",
+ drive->name, capacity, lba_capacity);
+ capacity = IDEFLOPPY_MIN(capacity, lba_capacity);
+ floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0;
}
return 0;
}
@@ -1071,6 +1079,11 @@
idefloppy_capacity_descriptor_t *descriptor;
int i, descriptors, rc = 1, blocks, length;
+ drive->bios_cyl = 0;
+ drive->bios_head = drive->bios_sect = 0;
+ floppy->blocks = floppy->bs_factor = 0;
+ drive->part[0].nr_sects = 0;
+
idefloppy_create_read_capacity_cmd (&pc);
if (idefloppy_queue_pc_tail (drive, &pc)) {
printk (KERN_ERR "ide-floppy: Can't get floppy parameters\n");
@@ -1083,10 +1096,9 @@
blocks = descriptor->blocks = ntohl (descriptor->blocks);
length = descriptor->length = ntohs (descriptor->length);
if (!i && descriptor->dc == CAPACITY_CURRENT) {
- if (memcmp (descriptor, &floppy->capacity, sizeof (idefloppy_capacity_descriptor_t))) {
+ 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;
- }
+ floppy->capacity = *descriptor;
if (!length || length % 512)
printk (KERN_ERR "%s: %d bytes block size not supported\n", drive->name, length);
else {
@@ -1094,9 +1106,6 @@
floppy->block_size = length;
if ((floppy->bs_factor = length / 512) != 1)
printk (KERN_NOTICE "%s: warning: non 512 bytes block size not fully supported\n", drive->name);
- drive->part[0].nr_sects = blocks * floppy->bs_factor;
- if (length > BLOCK_SIZE)
- blksize_size[HWIF(drive)->major][drive->select.b.unit << PARTN_BITS] = length;
rc = 0;
}
}
@@ -1106,6 +1115,7 @@
#endif /* IDEFLOPPY_DEBUG_INFO */
}
(void) idefloppy_get_flexible_disk_page (drive);
+ drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;
return rc;
}
@@ -1183,7 +1193,7 @@
idefloppy_floppy_t *floppy = drive->driver_data;
unsigned long capacity = floppy->blocks * floppy->bs_factor;
- return capacity ? capacity : 0x7fffffff;
+ return capacity;
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov