summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
commitf969d69ba9f952e5bdd38278e25e26a3e4a61a70 (patch)
treeb3530d803df59d726afaabebc6626987dee1ca05 /drivers/block
parenta10ce7ef2066b455d69187643ddf2073bfc4db24 (diff)
Merge with 2.3.27.
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/Config.in4
-rw-r--r--drivers/block/DAC960.c29
-rw-r--r--drivers/block/amiflop.c4
-rw-r--r--drivers/block/cpqarray.c37
-rw-r--r--drivers/block/hpt34x.c3
-rw-r--r--drivers/block/icside.c3
-rw-r--r--drivers/block/ide-cd.c106
-rw-r--r--drivers/block/ide-disk.c13
-rw-r--r--drivers/block/ide-dma.c3
-rw-r--r--drivers/block/ide-floppy.c9
-rw-r--r--drivers/block/ide-geometry.c6
-rw-r--r--drivers/block/ide-pmac.c3
-rw-r--r--drivers/block/ide-proc.c26
-rw-r--r--drivers/block/ide-tape.c9
-rw-r--r--drivers/block/ide.c64
-rw-r--r--drivers/block/ll_rw_blk.c39
-rw-r--r--drivers/block/loop.c26
-rw-r--r--drivers/block/md.c130
-rw-r--r--drivers/block/nbd.c2
-rw-r--r--drivers/block/pdc4030.c20
-rw-r--r--drivers/block/trm290.c3
21 files changed, 281 insertions, 258 deletions
diff --git a/drivers/block/Config.in b/drivers/block/Config.in
index 897aaa634..f32c86dc1 100644
--- a/drivers/block/Config.in
+++ b/drivers/block/Config.in
@@ -209,9 +209,9 @@ fi
# controls the choices given to the user ...
if [ "$CONFIG_PARPORT" = "y" -o "$CONFIG_PARPORT" = "n" ]; then
- define_bool CONFIG_PARIDE_PARPORT y
+ define_tristate CONFIG_PARIDE_PARPORT y
else
- define_bool CONFIG_PARIDE_PARPORT m
+ define_tristate CONFIG_PARIDE_PARPORT m
fi
dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARIDE_PARPORT
if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 9f26a4b5e..b2f24a633 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -95,11 +95,11 @@ static FileOperations_T
/*
- DAC960_ProcDirectoryEntry is the DAC960 /proc/rd directory entry.
+ DAC960_ProcDirectoryEntry is the DAC960 /proc/driver/rd directory entry.
*/
-static PROC_DirectoryEntry_T
- DAC960_ProcDirectoryEntry;
+static PROC_DirectoryEntry_T *
+ DAC960_ProcDirectoryEntry = NULL;
/*
@@ -3466,23 +3466,18 @@ static int DAC960_ProcWriteUserCommand(File_T *File, const char *Buffer,
/*
- DAC960_CreateProcEntries creates the /proc/rd/... entries for the DAC960
- Driver.
+ DAC960_CreateProcEntries creates the /proc/driver/rd/... entries
+ for the DAC960 Driver.
*/
static void DAC960_CreateProcEntries(void)
{
- static PROC_DirectoryEntry_T StatusProcEntry;
+ static PROC_DirectoryEntry_T *StatusProcEntry;
int ControllerNumber;
- DAC960_ProcDirectoryEntry.name = "rd";
- DAC960_ProcDirectoryEntry.namelen = strlen(DAC960_ProcDirectoryEntry.name);
- DAC960_ProcDirectoryEntry.mode = S_IFDIR | S_IRUGO | S_IXUGO;
- proc_register(&proc_root, &DAC960_ProcDirectoryEntry);
- StatusProcEntry.name = "status";
- StatusProcEntry.namelen = strlen(StatusProcEntry.name);
- StatusProcEntry.mode = S_IFREG | S_IRUGO;
- StatusProcEntry.read_proc = DAC960_ProcReadStatus;
- proc_register(&DAC960_ProcDirectoryEntry, &StatusProcEntry);
+ DAC960_ProcDirectoryEntry = create_proc_entry("driver/rd", S_IFDIR, NULL);
+ StatusProcEntry = create_proc_read_entry("status", 0,
+ DAC960_ProcDirectoryEntry,
+ DAC960_ProcReadStatus, NULL);
for (ControllerNumber = 0;
ControllerNumber < DAC960_ControllerCount;
ControllerNumber++)
@@ -3495,7 +3490,7 @@ static void DAC960_CreateProcEntries(void)
ControllerProcEntry->name = Controller->ControllerName;
ControllerProcEntry->namelen = strlen(ControllerProcEntry->name);
ControllerProcEntry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
- proc_register(&DAC960_ProcDirectoryEntry, ControllerProcEntry);
+ proc_register(DAC960_ProcDirectoryEntry, ControllerProcEntry);
InitialStatusProcEntry = &Controller->InitialStatusProcEntry;
InitialStatusProcEntry->name = "initial_status";
InitialStatusProcEntry->namelen = strlen(InitialStatusProcEntry->name);
@@ -3529,7 +3524,7 @@ static void DAC960_CreateProcEntries(void)
static void DAC960_DestroyProcEntries(void)
{
- proc_unregister(&proc_root, DAC960_ProcDirectoryEntry.low_ino);
+ remove_proc_entry("driver/rd", NULL);
}
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index b27d12095..a3ee727bd 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1821,13 +1821,13 @@ int __init amiga_floppy_init(void)
return -ENOMEM;
}
- if (!request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) {
+ if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) {
printk("fd: cannot get irq for dma\n");
amiga_chip_free(raw_buf);
unregister_blkdev(MAJOR_NR,"fd");
return -EBUSY;
}
- if (!request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) {
+ if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) {
printk("fd: cannot get irq for timer\n");
free_irq(IRQ_AMIGA_DSKBLK, NULL);
amiga_chip_free(raw_buf);
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 92b1c7d4d..451463111 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -161,8 +161,14 @@ static int frevalidate_logvol(kdev_t dev);
static int revalidate_logvol(kdev_t dev, int maxusage);
static int revalidate_allvol(kdev_t dev);
+#ifdef CONFIG_PROC_FS
static void ida_procinit(int i);
static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
+#else
+static void ida_procinit(int i) {}
+static int ida_proc_get_info(char *buffer, char **start, off_t offset,
+ int length, int *eof, void *data) {}
+#endif
static void ida_geninit(struct gendisk *g)
{
@@ -207,26 +213,21 @@ struct file_operations ida_fops = {
};
+#ifdef CONFIG_PROC_FS
+
/*
* Get us a file in /proc/array that says something about each controller.
* Create /proc/array if it doesn't exist yet.
*/
-static void ida_procinit(int i)
+static void __init ida_procinit(int i)
{
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *pd;
-
if (proc_array == NULL) {
- proc_array = create_proc_entry("array", S_IFDIR|S_IRUGO|S_IXUGO,
- &proc_root);
+ proc_array = create_proc_entry("driver/array", S_IFDIR, NULL);
if (!proc_array) return;
}
- pd = create_proc_entry(hba[i]->devname, S_IFREG|S_IRUGO, proc_array);
- if (!pd) return;
- pd->read_proc = ida_proc_get_info;
- pd->data = hba[i];
-#endif
+ create_proc_read_entry(hba[i]->devname, 0, proc_array,
+ ida_proc_get_info, hba[i]);
}
/*
@@ -311,6 +312,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt
len = length;
return len;
}
+#endif /* CONFIG_PROC_FS */
#ifdef MODULE
@@ -318,7 +320,7 @@ MODULE_PARM(eisa, "1-8i");
EXPORT_NO_SYMBOLS;
/* This is a bit of a hack... */
-int init_module(void)
+int __init init_module(void)
{
int i, j;
cpqarray_init();
@@ -333,11 +335,14 @@ int init_module(void)
}
return 0;
}
+
void cleanup_module(void)
{
int i;
struct gendisk *g;
+ remove_proc_entry("driver/array", NULL);
+
for(i=0; i<nr_ctlr; i++) {
hba[i]->access.set_intr_mask(hba[i], 0);
free_irq(hba[i]->intr, hba[i]);
@@ -359,15 +364,11 @@ void cleanup_module(void)
}
}
}
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("array", &proc_root);
-#endif
+
kfree(ida);
kfree(ida_sizes);
kfree(ida_hardsizes);
kfree(ida_blocksizes);
-
-
}
#endif /* MODULE */
@@ -375,7 +376,7 @@ void cleanup_module(void)
* This is it. Find all the controllers and register them. I really hate
* stealing all these major device numbers.
*/
-void cpqarray_init(void)
+void __init cpqarray_init(void)
{
void (*request_fns[MAX_CTLR])(void) = {
do_ida_request0, do_ida_request1,
diff --git a/drivers/block/hpt34x.c b/drivers/block/hpt34x.c
index 816b4b805..adc3d4156 100644
--- a/drivers/block/hpt34x.c
+++ b/drivers/block/hpt34x.c
@@ -299,8 +299,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
return 0;
- drive->timeout = WAIT_CMD;
- ide_set_handler(drive, &ide_dma_intr); /* issue cmd to drive */
+ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0;
case ide_dma_end: /* returns 1 on error, 0 otherwise */
diff --git a/drivers/block/icside.c b/drivers/block/icside.c
index 5d007fce3..b83781457 100644
--- a/drivers/block/icside.c
+++ b/drivers/block/icside.c
@@ -381,8 +381,7 @@ icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
if (drive->media != ide_disk)
return 0;
- drive->timeout = WAIT_CMD;
- ide_set_handler(drive, &ide_dma_intr);
+ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
IDE_COMMAND_REG);
diff --git a/drivers/block/ide-cd.c b/drivers/block/ide-cd.c
index 19fe18fe0..e3cce8eb4 100644
--- a/drivers/block/ide-cd.c
+++ b/drivers/block/ide-cd.c
@@ -24,11 +24,6 @@
*
* ----------------------------------
* TO DO LIST:
- * -Implement Microsoft Media Status Notification per the spec at
- * http://www.microsoft.com/hwdev/respec/storspec.htm
- * This will allow us to get automagically notified when the media changes
- * on ATAPI drives (something the stock ATAPI spec is lacking). Looks
- * very cool. I discovered its existance the other day at work...
* -Make it so that Pioneer CD DR-A24X and friends don't get screwed up on
* boot
*
@@ -537,6 +532,7 @@ static void cdrom_end_request (int uptodate, ide_drive_t *drive)
}
if (rq->cmd == READ && !rq->current_nr_sectors)
uptodate = 1;
+
ide_end_request (uptodate, HWGROUP(drive));
}
@@ -663,6 +659,21 @@ static int cdrom_decode_status (ide_drive_t *drive, int good_stat,
return 1;
}
+static int cdrom_timer_expiry(ide_drive_t *drive)
+{
+ struct request *rq = HWGROUP(drive)->rq;
+ struct packet_command *pc = (struct packet_command *) rq->buffer;
+ unsigned long wait = 0;
+
+ printk("in expiry\n");
+ /* blank and format can take an extremly long time to
+ * complete, if the IMMED bit was not set.
+ */
+ if (pc->c[0] == GPCMD_BLANK || pc->c[0] == GPCMD_FORMAT_UNIT)
+ wait = 60*60*HZ;
+
+ return wait;
+}
/* Set up the device registers for transferring a packet command on DEV,
expecting to later transfer XFERLEN bytes. HANDLER is the routine
@@ -696,7 +707,7 @@ static int cdrom_start_packet_command (ide_drive_t *drive, int xferlen,
(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
- ide_set_handler (drive, handler);
+ ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
} else {
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
@@ -706,7 +717,6 @@ static int cdrom_start_packet_command (ide_drive_t *drive, int xferlen,
return 0;
}
-
/* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
The device registers must have already been prepared
by cdrom_start_packet_command.
@@ -716,11 +726,6 @@ static int cdrom_transfer_packet_command (ide_drive_t *drive,
unsigned char *cmd_buf, int cmd_len,
ide_handler_t *handler)
{
- /* don't timeout for blank and format commands. they may take
- * a _very_ long time. */
- if (cmd_buf[0] == GPCMD_BLANK || cmd_buf[0] == GPCMD_FORMAT_UNIT)
- drive->timeout = 0;
-
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
/* Here we should have been called after receiving an interrupt
from the device. DRQ should how be set. */
@@ -736,7 +741,7 @@ static int cdrom_transfer_packet_command (ide_drive_t *drive,
}
/* Arm the interrupt handler. */
- ide_set_handler (drive, handler);
+ ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
/* Send the command to the device. */
atapi_output_bytes (drive, cmd_buf, cmd_len);
@@ -769,17 +774,9 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
char *dest;
- /* If we don't yet have a sector buffer, try to allocate one.
- If we can't get one atomically, it's not fatal -- we'll just throw
- the data away rather than caching it. */
- if (info->buffer == NULL) {
- info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_ATOMIC);
-
- /* If we couldn't get a buffer,
- don't try to buffer anything... */
- if (info->buffer == NULL)
+ /* If we couldn't get a buffer, don't try to buffer anything... */
+ if (info->buffer == NULL)
sectors_to_buffer = 0;
- }
/* If this is the first sector in the buffer, remember its number. */
if (info->nsectors_buffered == 0)
@@ -866,13 +863,14 @@ static void cdrom_read_intr (ide_drive_t *drive)
return;
if (dma) {
- if (!dma_error) {
- for (i = rq->nr_sectors; i > 0;) {
- i -= rq->current_nr_sectors;
- ide_end_request(1, HWGROUP(drive));
- }
- } else
+ if (dma_error) {
ide_error (drive, "dma error", stat);
+ return;
+ }
+ for (i = rq->nr_sectors; i > 0;) {
+ i -= rq->current_nr_sectors;
+ ide_end_request(1, HWGROUP(drive));
+ }
return;
}
@@ -968,7 +966,7 @@ static void cdrom_read_intr (ide_drive_t *drive)
/* Done moving data!
Wait for another interrupt. */
- ide_set_handler(drive, &cdrom_read_intr);
+ ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL);
}
/*
@@ -1206,9 +1204,6 @@ static void cdrom_pc_intr (ide_drive_t *drive)
struct request *rq = HWGROUP(drive)->rq;
struct packet_command *pc = (struct packet_command *)rq->buffer;
- /* restore timeout after blank or format command */
- drive->timeout = WAIT_CMD;
-
/* Check for errors. */
if (cdrom_decode_status (drive, 0, &stat))
return;
@@ -1294,7 +1289,7 @@ static void cdrom_pc_intr (ide_drive_t *drive)
}
/* Now we wait for another interrupt. */
- ide_set_handler (drive, &cdrom_pc_intr);
+ ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
}
@@ -1789,7 +1784,7 @@ cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf)
/* Now try to get the total cdrom capacity. */
#if 0
- stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor,
+ stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor),
(long *)&toc->capacity);
if (stat)
#endif
@@ -1797,6 +1792,7 @@ cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf)
if (stat) toc->capacity = 0x1fffff;
/* for general /dev/cdrom like mounting, one big disc */
+ drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
HWIF(drive)->gd->sizes[minor] = (toc->capacity * SECTORS_PER_FRAME) >>
(BLOCK_SIZE_BITS - 9);
@@ -1812,11 +1808,11 @@ cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf)
i = toc->hdr.first_track;
while ((i <= ntracks) && ((minor & CD_PART_MASK) < CD_PART_MAX)) {
drive->part[minor & PARTN_MASK].start_sect = 0;
- drive->part[minor & PARTN_MASK].nr_sects = (toc->ent[i].addr.lba *
+ drive->part[minor & PARTN_MASK].nr_sects =
+ (toc->ent[i].addr.lba *
SECTORS_PER_FRAME) << (BLOCK_SIZE_BITS - 9);
HWIF(drive)->gd->sizes[minor] = (toc->ent[i].addr.lba *
SECTORS_PER_FRAME) >> (BLOCK_SIZE_BITS - 9);
- blksize_size[HWIF(drive)->major][minor] = CD_FRAMESIZE;
i++;
minor++;
}
@@ -2273,8 +2269,11 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
struct atapi_capabilities_page cap;
} buf;
- if (CDROM_CONFIG_FLAGS (drive)->nec260)
+ if (CDROM_CONFIG_FLAGS (drive)->nec260) {
+ CDROM_CONFIG_FLAGS (drive)->no_eject = 0;
+ CDROM_CONFIG_FLAGS (drive)->audio_play = 1;
return nslots;
+ }
init_cdrom_command(&cgc, &buf, sizeof(buf));
/* we have to cheat a little here. the packet will eventually
@@ -2342,9 +2341,12 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
(ntohs(buf.cap.maxspeed) + (176/2)) / 176;
}
- printk ("%s: ATAPI %dX %s",
- drive->name, CDROM_CONFIG_FLAGS (drive)->max_speed,
- (CDROM_CONFIG_FLAGS (drive)->dvd) ? "DVD-ROM" : "CD-ROM");
+ /* don't print speed if the drive reported 0.
+ */
+ printk("%s: ATAPI", drive->name);
+ if (CDROM_CONFIG_FLAGS(drive)->max_speed)
+ printk(" %dX", CDROM_CONFIG_FLAGS(drive)->max_speed);
+ printk(" %s", CDROM_CONFIG_FLAGS(drive)->dvd ? "DVD-ROM" : "CD-ROM");
if (CDROM_CONFIG_FLAGS (drive)->dvd_r|CDROM_CONFIG_FLAGS (drive)->dvd_ram)
printk (" DVD%s%s",
@@ -2398,11 +2400,10 @@ int ide_cdrom_setup (ide_drive_t *drive)
int nslots;
set_device_ro(MKDEV(HWIF(drive)->major, minor), 1);
- blksize_size[HWIF(drive)->major][minor] = CD_FRAMESIZE;
+ set_blocksize(MKDEV(HWIF(drive)->major, minor), CD_FRAMESIZE);
drive->special.all = 0;
drive->ready_stat = 0;
- drive->timeout = WAIT_CMD;
CDROM_STATE_FLAGS (drive)->media_changed = 1;
CDROM_STATE_FLAGS (drive)->toc_valid = 0;
@@ -2435,10 +2436,14 @@ int ide_cdrom_setup (ide_drive_t *drive)
/* limit transfer size per interrupt. */
CDROM_CONFIG_FLAGS (drive)->limit_nframes = 0;
if (drive->id != NULL) {
+ /* a testament to the nice quality of Samsung drives... */
if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430"))
CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
+ /* the 3231 model does not support the SET_CD_SPEED command */
+ else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
+ cdi->mask |= CDC_SELECT_SPEED;
}
#if ! STANDARD_ATAPI
@@ -2534,9 +2539,12 @@ int ide_cdrom_ioctl (ide_drive_t *drive,
static
int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
{
+ struct cdrom_info *info = drive->driver_data;
int rc;
MOD_INC_USE_COUNT;
+ if (info->buffer == NULL)
+ info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL);
rc = cdrom_fops.open (ip, fp);
if (rc) {
drive->usage--;
@@ -2617,12 +2625,7 @@ char *ignore = NULL;
MODULE_PARM(ignore, "s");
MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
-int init_module (void)
-{
- return ide_cdrom_init();
-}
-
-void cleanup_module(void)
+void __exit ide_cdrom_exit(void)
{
ide_drive_t *drive;
int failed = 0;
@@ -2636,7 +2639,7 @@ void cleanup_module(void)
}
#endif /* MODULE */
-int ide_cdrom_init (void)
+int __init ide_cdrom_init (void)
{
ide_drive_t *drive;
struct cdrom_info *info;
@@ -2677,3 +2680,6 @@ int ide_cdrom_init (void)
MOD_DEC_USE_COUNT;
return 0;
}
+
+module_init(ide_cdrom_init);
+module_exit(ide_cdrom_exit);
diff --git a/drivers/block/ide-disk.c b/drivers/block/ide-disk.c
index 8fa7745b4..924451f5a 100644
--- a/drivers/block/ide-disk.c
+++ b/drivers/block/ide-disk.c
@@ -175,7 +175,7 @@ read_next:
if (i > 0) {
if (msect)
goto read_next;
- ide_set_handler (drive, &read_intr);
+ ide_set_handler (drive, &read_intr, WAIT_CMD, NULL);
}
}
@@ -206,7 +206,7 @@ static void write_intr (ide_drive_t *drive)
ide_end_request(1, hwgroup);
if (i > 0) {
idedisk_output_data (drive, rq->buffer, SECTOR_WORDS);
- ide_set_handler (drive, &write_intr);
+ ide_set_handler (drive, &write_intr, WAIT_CMD, NULL);
}
goto out;
}
@@ -271,7 +271,7 @@ static void multwrite_intr (ide_drive_t *drive)
if (stat & DRQ_STAT) {
if (rq->nr_sectors) {
ide_multwrite(drive, drive->mult_count);
- ide_set_handler (drive, &multwrite_intr);
+ ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL);
goto out;
}
} else {
@@ -385,7 +385,7 @@ static void do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long bl
if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_read, drive)))
return;
#endif /* CONFIG_BLK_DEV_IDEDMA */
- ide_set_handler(drive, &read_intr);
+ ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG);
return;
}
@@ -404,10 +404,10 @@ static void do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long bl
__cli(); /* local CPU only */
if (drive->mult_count) {
HWGROUP(drive)->wrq = *rq; /* scratchpad */
- ide_set_handler (drive, &multwrite_intr);
+ ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL);
ide_multwrite(drive, drive->mult_count);
} else {
- ide_set_handler (drive, &write_intr);
+ ide_set_handler (drive, &write_intr, WAIT_CMD, NULL);
idedisk_output_data(drive, rq->buffer, SECTOR_WORDS);
}
return;
@@ -506,7 +506,6 @@ static void idedisk_pre_reset (ide_drive_t *drive)
drive->special.all = 0;
drive->special.b.set_geometry = 1;
drive->special.b.recalibrate = 1;
- drive->timeout = WAIT_CMD;
if (OK_TO_RESET_CONTROLLER)
drive->mult_count = 0;
if (!drive->keep_settings)
diff --git a/drivers/block/ide-dma.c b/drivers/block/ide-dma.c
index 338d51c9a..7712b6cd6 100644
--- a/drivers/block/ide-dma.c
+++ b/drivers/block/ide-dma.c
@@ -420,8 +420,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
return 0;
- drive->timeout = WAIT_CMD;
- ide_set_handler(drive, &ide_dma_intr);/* issue cmd to drive */
+ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);/* issue cmd to drive */
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
case ide_dma_begin:
/* Note that this is done *after* the cmd has
diff --git a/drivers/block/ide-floppy.c b/drivers/block/ide-floppy.c
index 3db1c1515..4609e77d9 100644
--- a/drivers/block/ide-floppy.c
+++ b/drivers/block/ide-floppy.c
@@ -916,7 +916,7 @@ static void idefloppy_pc_intr (ide_drive_t *drive)
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);
+ ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
return;
}
#if IDEFLOPPY_DEBUG_LOG
@@ -938,7 +938,7 @@ static void idefloppy_pc_intr (ide_drive_t *drive)
pc->actually_transferred+=bcount.all; /* Update the current position */
pc->current_position+=bcount.all;
- ide_set_handler (drive,&idefloppy_pc_intr); /* And set the interrupt handler again */
+ ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */
}
static void idefloppy_transfer_pc (ide_drive_t *drive)
@@ -956,7 +956,7 @@ static void idefloppy_transfer_pc (ide_drive_t *drive)
ide_do_reset (drive);
return;
}
- ide_set_handler (drive, &idefloppy_pc_intr); /* Set the interrupt routine */
+ ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */
atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */
}
@@ -1025,7 +1025,7 @@ static void idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *pc)
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
- ide_set_handler (drive, &idefloppy_transfer_pc);
+ ide_set_handler (drive, &idefloppy_transfer_pc, IDEFLOPPY_WAIT_CMD, NULL);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
} else {
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
@@ -1519,7 +1519,6 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
*((unsigned short *) &gcw) = drive->id->config;
drive->driver_data = floppy;
drive->ready_stat = 0;
- drive->timeout = IDEFLOPPY_WAIT_CMD;
memset (floppy, 0, sizeof (idefloppy_floppy_t));
floppy->drive = drive;
floppy->pc = floppy->pc_stack;
diff --git a/drivers/block/ide-geometry.c b/drivers/block/ide-geometry.c
index 44aa1844d..8370d35a6 100644
--- a/drivers/block/ide-geometry.c
+++ b/drivers/block/ide-geometry.c
@@ -81,7 +81,6 @@ void probe_cmos_for_drives (ide_hwif_t *hwif)
*/
static void
ontrack(ide_drive_t *drive, int heads, int *c, int *h, int *s) {
- struct hd_driveid *id = drive->id;
static const byte dm_head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0};
const byte *headp = dm_head_vals;
unsigned long total, tracks;
@@ -92,10 +91,7 @@ ontrack(ide_drive_t *drive, int heads, int *c, int *h, int *s) {
* 1024*255*63. Now take S=63, H the first in the sequence
* 4, 8, 16, 32, 64, 128, 255 such that 63*H*1024 >= total.
*/
- if (id)
- total = id->cyls * id->heads * id->sectors;
- else
- total = drive->cyl * drive->head * drive->sect;
+ total = DRIVER(drive)->capacity(drive);
*s = 63;
diff --git a/drivers/block/ide-pmac.c b/drivers/block/ide-pmac.c
index c3e800249..e1eadcaa2 100644
--- a/drivers/block/ide-pmac.c
+++ b/drivers/block/ide-pmac.c
@@ -363,8 +363,7 @@ int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
return 0;
- drive->timeout = WAIT_CMD;
- ide_set_handler(drive, &ide_dma_intr);
+ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
IDE_COMMAND_REG);
case ide_dma_begin:
diff --git a/drivers/block/ide-proc.c b/drivers/block/ide-proc.c
index 48d77c160..b68072428 100644
--- a/drivers/block/ide-proc.c
+++ b/drivers/block/ide-proc.c
@@ -769,31 +769,25 @@ static void destroy_proc_ide_interfaces(void)
void proc_ide_create(void)
{
- struct proc_dir_entry *ent;
proc_ide_root = create_proc_entry("ide", S_IFDIR, 0);
if (!proc_ide_root) return;
+
create_proc_ide_interfaces();
- ent = create_proc_entry("drivers", 0, proc_ide_root);
- if (!ent) return;
- ent->read_proc = proc_ide_read_drivers;
+ create_proc_read_entry("drivers",0,proc_ide_root,
+ proc_ide_read_drivers, NULL);
+
#ifdef CONFIG_BLK_DEV_ALI15X3
- if ((ali_display_info) && (ali_proc)) {
- ent = create_proc_entry("ali", 0, proc_ide_root);
- ent->get_info = ali_display_info;
- }
+ if ((ali_display_info) && (ali_proc))
+ create_proc_info_entry("ali", 0, proc_ide_root, ali_display_info);
#endif /* CONFIG_BLK_DEV_ALI15X3 */
#ifdef CONFIG_BLK_DEV_SIS5513
- if ((sis_display_info) && (sis_proc)) {
- ent = create_proc_entry("sis", 0, proc_ide_root);
- ent->get_info = sis_display_info;
- }
+ if ((sis_display_info) && (sis_proc))
+ create_proc_info_entry("sis", 0, proc_ide_root, sis_display_info);
#endif /* CONFIG_BLK_DEV_SIS5513 */
#ifdef CONFIG_BLK_DEV_VIA82CXXX
- if ((via_display_info) && (via_proc)) {
- ent = create_proc_entry("via", 0, proc_ide_root);
- ent->get_info = via_display_info;
- }
+ if ((via_display_info) && (via_proc))
+ create_proc_info_entry("via", 0, proc_ide_root, via_display_info);
#endif /* CONFIG_BLK_DEV_VIA82CXXX */
}
diff --git a/drivers/block/ide-tape.c b/drivers/block/ide-tape.c
index bbf222338..5ea3230dc 100644
--- a/drivers/block/ide-tape.c
+++ b/drivers/block/ide-tape.c
@@ -1833,7 +1833,7 @@ static void idetape_pc_intr (ide_drive_t *drive)
if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
idetape_discard_data (drive,bcount.all);
- ide_set_handler (drive,&idetape_pc_intr);
+ ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL);
return;
}
#if IDETAPE_DEBUG_LOG
@@ -1855,7 +1855,7 @@ static void idetape_pc_intr (ide_drive_t *drive)
pc->actually_transferred+=bcount.all; /* Update the current position */
pc->current_position+=bcount.all;
- ide_set_handler (drive,&idetape_pc_intr); /* And set the interrupt handler again */
+ ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL); /* And set the interrupt handler again */
}
/*
@@ -1928,7 +1928,7 @@ static void idetape_transfer_pc(ide_drive_t *drive)
ide_do_reset (drive);
return;
}
- ide_set_handler(drive, &idetape_pc_intr); /* Set the interrupt routine */
+ ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */
atapi_output_bytes (drive,pc->c,12); /* Send the actual packet */
}
@@ -1995,7 +1995,7 @@ static void idetape_issue_packet_command (ide_drive_t *drive, idetape_pc_t *pc)
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
- ide_set_handler(drive, &idetape_transfer_pc);
+ ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
} else {
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
@@ -3579,7 +3579,6 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
spin_lock_init(&tape->spinlock);
drive->driver_data = tape;
drive->ready_stat = 0; /* An ATAPI device ignores DRDY */
- drive->timeout = IDETAPE_WAIT_CMD;
#ifdef CONFIG_BLK_DEV_IDEPCI
/*
* These two ide-pci host adapters appear to need this disabled.
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index f0c9d58da..0f3e41fed 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -307,6 +307,7 @@ int drive_is_flashcard (ide_drive_t *drive)
struct hd_driveid *id = drive->id;
if (drive->removable && id != NULL) {
+ if (id->config == 0x848a) return 1; /* CompactFlash */
if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */
|| !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */
|| !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */
@@ -498,25 +499,14 @@ void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup)
}
/*
- * The below two are helpers used when modifying the drive timeout.
- */
-static inline unsigned long set_timeout(ide_drive_t *drive, unsigned long timeout)
-{
- unsigned long foo = drive->timeout;
- drive->timeout = timeout;
- return foo;
-}
-
-#define restore_timeout(drive, old) (drive->timeout = old)
-
-/*
* This should get invoked any time we exit the driver to
* wait for an interrupt response from a drive. handler() points
* at the appropriate code to handle the next interrupt, and a
* timer is started to prevent us from waiting forever in case
* something goes wrong (see the ide_timer_expiry() handler later on).
*/
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler)
+void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
+ unsigned int timeout, ide_expiry_t *expiry)
{
unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
@@ -528,12 +518,10 @@ void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler)
drive->name, hwgroup->handler, handler);
}
#endif
- hwgroup->handler = handler;
- /* 0 means don't timeout */
- if (drive->timeout && !timer_pending(&hwgroup->timer)) {
- hwgroup->timer.expires = jiffies + drive->timeout;
- add_timer(&(hwgroup->timer));
- }
+ hwgroup->handler = handler;
+ hwgroup->expiry = expiry;
+ hwgroup->timer.expires = jiffies + timeout;
+ add_timer(&(hwgroup->timer));
spin_unlock_irqrestore(&hwgroup->spinlock, flags);
}
@@ -580,7 +568,6 @@ static void do_reset1 (ide_drive_t *, int); /* needed below */
static void atapi_reset_pollfunc (ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
- unsigned long old_timeout;
byte stat;
SELECT_DRIVE(HWIF(drive),drive);
@@ -590,9 +577,7 @@ static void atapi_reset_pollfunc (ide_drive_t *drive)
printk("%s: ATAPI reset complete\n", drive->name);
} else {
if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
- old_timeout = set_timeout(drive, HZ / 20);
- ide_set_handler (drive, &atapi_reset_pollfunc);
- restore_timeout(drive, old_timeout);
+ ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
return; /* continue polling */
}
hwgroup->poll_timeout = 0; /* end of polling */
@@ -613,14 +598,11 @@ static void reset_pollfunc (ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
ide_hwif_t *hwif = HWIF(drive);
- unsigned long old_timeout;
byte tmp;
if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) {
if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
- old_timeout = set_timeout(drive, HZ / 20);
- ide_set_handler (drive, &reset_pollfunc);
- restore_timeout(drive, old_timeout);
+ ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
return; /* continue polling */
}
printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
@@ -688,7 +670,6 @@ static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
unsigned long flags;
ide_hwif_t *hwif = HWIF(drive);
ide_hwgroup_t *hwgroup = HWGROUP(drive);
- unsigned long old_timeout;
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
@@ -700,9 +681,7 @@ static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
udelay (20);
OUT_BYTE (WIN_SRST, IDE_COMMAND_REG);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- old_timeout = set_timeout(drive, HZ / 20);
- ide_set_handler (drive, &atapi_reset_pollfunc);
- restore_timeout(drive, old_timeout);
+ ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
__restore_flags (flags); /* local CPU only */
return;
}
@@ -732,9 +711,7 @@ static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */
udelay(10); /* more than enough time */
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- old_timeout = set_timeout(drive, HZ / 20);
- ide_set_handler (drive, &reset_pollfunc);
- restore_timeout(drive, old_timeout);
+ ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
/*
* Some weird controller like resetting themselves to a strange
@@ -934,7 +911,7 @@ void ide_error (ide_drive_t *drive, const char *msg, byte stat)
*/
void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
{
- ide_set_handler (drive, handler);
+ ide_set_handler (drive, handler, WAIT_CMD, NULL);
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */
OUT_BYTE(nsect,IDE_NSECTOR_REG);
@@ -1425,7 +1402,9 @@ void ide_timer_expiry (unsigned long data)
ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
ide_drive_t *drive;
ide_handler_t *handler;
+ ide_expiry_t *expiry;
unsigned long flags;
+ unsigned long wait;
spin_lock_irqsave(&hwgroup->spinlock, flags);
drive = hwgroup->drive;
@@ -1434,9 +1413,22 @@ void ide_timer_expiry (unsigned long data)
do_hwgroup_request(hwgroup);
return;
}
+
hwgroup->busy = 1; /* should already be "1" */
+
+ if ((expiry = hwgroup->expiry) != NULL) {
+ /* continue */
+ if ((wait = expiry(drive)) != 0) {
+ /* reset timer */
+ hwgroup->timer.expires = jiffies + wait;
+ add_timer(&(hwgroup->timer));
+ spin_unlock_irqrestore(&hwgroup->spinlock, flags);
+ return;
+ }
+ }
+
hwgroup->handler = NULL;
- /* polling in progress or just don't timeout */
+
if (hwgroup->poll_timeout != 0) {
spin_unlock_irqrestore(&hwgroup->spinlock, flags);
handler(drive);
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 59116c19d..5363e04e2 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -22,6 +22,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <linux/blk.h>
+#include <linux/highmem.h>
#include <linux/module.h>
@@ -388,9 +389,12 @@ out:
/*
* Has to be called with the request spinlock aquired
*/
-static inline void attempt_merge (struct request *req, int max_sectors)
+static inline void attempt_merge (struct request *req,
+ int max_sectors,
+ int max_segments)
{
struct request *next = req->next;
+ int total_segments;
if (!next)
return;
@@ -398,9 +402,15 @@ static inline void attempt_merge (struct request *req, int max_sectors)
return;
if (next->sem || req->cmd != next->cmd || req->rq_dev != next->rq_dev || req->nr_sectors + next->nr_sectors > max_sectors)
return;
+ total_segments = req->nr_segments + next->nr_segments;
+ if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
+ total_segments--;
+ if (total_segments > max_segments)
+ return;
req->bhtail->b_reqnext = next->bh;
req->bhtail = next->bhtail;
req->nr_sectors += next->nr_sectors;
+ req->nr_segments = total_segments;
next->rq_status = RQ_INACTIVE;
req->next = next->next;
wake_up (&wait_for_request);
@@ -410,7 +420,7 @@ void make_request(int major,int rw, struct buffer_head * bh)
{
unsigned int sector, count;
struct request * req;
- int rw_ahead, max_req, max_sectors;
+ int rw_ahead, max_req, max_sectors, max_segments;
unsigned long flags;
count = bh->b_size >> 9;
@@ -483,6 +493,15 @@ void make_request(int major,int rw, struct buffer_head * bh)
if (!buffer_mapped(bh))
BUG();
+ /*
+ * Temporary solution - in 2.5 this will be done by the lowlevel
+ * driver. Create a bounce buffer if the buffer data points into
+ * high memory - keep the original buffer otherwise.
+ */
+#if CONFIG_HIGHMEM
+ bh = create_bounce(rw, bh);
+#endif
+
/* look for a free request. */
/* Loop uses two requests, 1 for loop and 1 for the real device.
* Cut max_req in half to avoid running out and deadlocking. */
@@ -493,6 +512,7 @@ void make_request(int major,int rw, struct buffer_head * bh)
* Try to coalesce the new request with old requests
*/
max_sectors = get_max_sectors(bh->b_rdev);
+ max_segments = get_max_segments(bh->b_rdev);
/*
* Now we acquire the request spinlock, we have to be mega careful
@@ -572,14 +592,26 @@ void make_request(int major,int rw, struct buffer_head * bh)
continue;
/* Can we add it to the end of this request? */
if (req->sector + req->nr_sectors == sector) {
+ if (req->bhtail->b_data + req->bhtail->b_size
+ != bh->b_data) {
+ if (req->nr_segments < max_segments)
+ req->nr_segments++;
+ else continue;
+ }
req->bhtail->b_reqnext = bh;
req->bhtail = bh;
req->nr_sectors += count;
drive_stat_acct(req, count, 0);
/* Can we now merge this req with the next? */
- attempt_merge(req, max_sectors);
+ attempt_merge(req, max_sectors, max_segments);
/* or to the beginning? */
} else if (req->sector - count == sector) {
+ if (bh->b_data + bh->b_size
+ != req->bh->b_data) {
+ if (req->nr_segments < max_segments)
+ req->nr_segments++;
+ else continue;
+ }
bh->b_reqnext = req->bh;
req->bh = bh;
req->buffer = bh->b_data;
@@ -613,6 +645,7 @@ void make_request(int major,int rw, struct buffer_head * bh)
req->errors = 0;
req->sector = sector;
req->nr_sectors = count;
+ req->nr_segments = 1;
req->current_nr_sectors = count;
req->buffer = bh->b_data;
req->sem = NULL;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 45f91b2da..cace2226c 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -23,9 +23,12 @@
* Reed H. Petty, rhp@draper.net
*
* Maximum number of loop devices now dynamic via max_loop module parameter.
- * Still fixed at 8 devices when compiled into the kernel normally.
* Russell Kroll <rkroll@exploits.org> 19990701
*
+ * Maximum number of loop devices when compiled-in now selectable by passing
+ * max_loop=<1-255> to the kernel on boot.
+ * Erik I. Bolsų, <eriki@himolde.no>, Oct 31, 1999
+ *
* Still To Fix:
* - Advisory locking is ignored here.
* - Should use an own CAP_* category instead of CAP_SYS_ADMIN
@@ -148,12 +151,12 @@ static void figure_loop_size(struct loop_device *lo)
int size;
if (S_ISREG(lo->lo_dentry->d_inode->i_mode))
- size = (lo->lo_dentry->d_inode->i_size - lo->lo_offset) / BLOCK_SIZE;
+ size = (lo->lo_dentry->d_inode->i_size - lo->lo_offset) >> BLOCK_SIZE_BITS;
else {
kdev_t lodev = lo->lo_device;
if (blk_size[MAJOR(lodev)])
size = blk_size[MAJOR(lodev)][MINOR(lodev)] -
- lo->lo_offset / BLOCK_SIZE;
+ (lo->lo_offset >> BLOCK_SIZE_BITS);
else
size = MAX_DISK_SIZE;
}
@@ -723,15 +726,12 @@ int __init loop_init(void)
}
if ((max_loop < 1) || (max_loop > 255)) {
- printk (KERN_WARNING "loop: max_loop must be between 1 and 255\n");
- return -EINVAL;
+ printk (KERN_WARNING "loop: invalid max_loop (must be between 1 and 255), using default (8)\n");
+ max_loop = 8;
}
-#ifndef MODULE
printk(KERN_INFO "loop: registered device at major %d\n", MAJOR_NR);
-#else
printk(KERN_INFO "loop: enabling %d loop devices\n", max_loop);
-#endif
loop_dev = kmalloc (max_loop * sizeof(struct loop_device), GFP_KERNEL);
if (!loop_dev) {
@@ -778,3 +778,13 @@ void cleanup_module(void)
kfree (loop_blksizes);
}
#endif
+
+#ifndef MODULE
+static int __init max_loop_setup(char *str)
+{
+ max_loop = simple_strtol(str,NULL,0);
+ return 1;
+}
+
+__setup("max_loop=", max_loop_setup);
+#endif
diff --git a/drivers/block/md.c b/drivers/block/md.c
index 684b47c1b..4dedb8671 100644
--- a/drivers/block/md.c
+++ b/drivers/block/md.c
@@ -872,11 +872,74 @@ EXPORT_SYMBOL(md_wakeup_thread);
EXPORT_SYMBOL(md_do_sync);
#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry proc_md = {
- PROC_MD, 6, "mdstat",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, &proc_array_inode_operations,
-};
+static int md_status_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int sz = 0, i, j, size;
+ int begin = 0;
+
+ sz=sprintf( page, "Personalities : ");
+ for (i=0; i<MAX_PERSONALITY; i++)
+ if (pers[i])
+ sz+=sprintf (page+sz, "[%d %s] ", i, pers[i]->name);
+ page[sz-1]='\n';
+
+ sz+=sprintf (page+sz, "read_ahead ");
+ if (read_ahead[MD_MAJOR]==INT_MAX)
+ sz+=sprintf (page+sz, "not set\n");
+ else
+ sz+=sprintf (page+sz, "%d sectors\n", read_ahead[MD_MAJOR]);
+
+ for (i=0; i<MAX_MD_DEV; i++) {
+ if (sz < off) {
+ begin += sz;
+ off -= sz;
+ sz = 0;
+ }
+ if (sz >= off+count) {
+ *eof = 1;
+ break;
+ }
+ sz+=sprintf (page+sz, "md%d : %sactive",
+ i, md_dev[i].pers ? "" : "in");
+
+ if (md_dev[i].pers)
+ sz+=sprintf (page+sz, " %s", md_dev[i].pers->name);
+
+ for (j=0, size=0; j<md_dev[i].nb_dev; j++) {
+ sz+=sprintf (page+sz, " %s",
+ partition_name(md_dev[i].devices[j].dev));
+ size+=md_dev[i].devices[j].size;
+ }
+
+ if (md_dev[i].nb_dev) {
+ if (md_dev[i].pers)
+ sz+=sprintf (page+sz, " %d blocks", md_size[i]);
+ else
+ sz+=sprintf (page+sz, " %d blocks", size);
+ }
+
+ if (!md_dev[i].pers) {
+ sz+=sprintf (page+sz, "\n");
+ continue;
+ }
+
+ if (md_dev[i].pers->max_invalid_dev)
+ sz+=sprintf (page+sz, " maxfault=%ld",
+ MAX_FAULT(md_dev+i));
+
+ sz+=md_dev[i].pers->status (page+sz, i, md_dev+i);
+ sz+=sprintf (page+sz, "\n");
+ }
+
+ sz -= off;
+ *start = page + off;
+ if (sz>count)
+ sz = count;
+ if (sz<0)
+ sz = 0;
+ return sz;
+}
#endif
static void md_geninit (struct gendisk *gdisk)
@@ -896,7 +959,7 @@ static void md_geninit (struct gendisk *gdisk)
max_readahead[MD_MAJOR] = md_maxreadahead;
#ifdef CONFIG_PROC_FS
- proc_register(&proc_root, &proc_md);
+ create_proc_read_entry("mdstat", 0, NULL, md_status_read_proc, NULL);
#endif
}
@@ -919,61 +982,6 @@ int md_error (kdev_t mddev, kdev_t rdev)
return 0;
}
-int get_md_status (char *page)
-{
- int sz=0, i, j, size;
-
- sz+=sprintf( page+sz, "Personalities : ");
- for (i=0; i<MAX_PERSONALITY; i++)
- if (pers[i])
- sz+=sprintf (page+sz, "[%d %s] ", i, pers[i]->name);
-
- page[sz-1]='\n';
-
- sz+=sprintf (page+sz, "read_ahead ");
- if (read_ahead[MD_MAJOR]==INT_MAX)
- sz+=sprintf (page+sz, "not set\n");
- else
- sz+=sprintf (page+sz, "%d sectors\n", read_ahead[MD_MAJOR]);
-
- for (i=0; i<MAX_MD_DEV; i++)
- {
- sz+=sprintf (page+sz, "md%d : %sactive", i, md_dev[i].pers ? "" : "in");
-
- if (md_dev[i].pers)
- sz+=sprintf (page+sz, " %s", md_dev[i].pers->name);
-
- size=0;
- for (j=0; j<md_dev[i].nb_dev; j++)
- {
- sz+=sprintf (page+sz, " %s",
- partition_name(md_dev[i].devices[j].dev));
- size+=md_dev[i].devices[j].size;
- }
-
- if (md_dev[i].nb_dev) {
- if (md_dev[i].pers)
- sz+=sprintf (page+sz, " %d blocks", md_size[i]);
- else
- sz+=sprintf (page+sz, " %d blocks", size);
- }
-
- if (!md_dev[i].pers)
- {
- sz+=sprintf (page+sz, "\n");
- continue;
- }
-
- if (md_dev[i].pers->max_invalid_dev)
- sz+=sprintf (page+sz, " maxfault=%ld", MAX_FAULT(md_dev+i));
-
- sz+=md_dev[i].pers->status (page+sz, i, md_dev+i);
- sz+=sprintf (page+sz, "\n");
- }
-
- return (sz);
-}
-
int register_md_personality (int p_num, struct md_personality *p)
{
int i=(p_num >> PERSONALITY_SHIFT);
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index ab18b55b0..7c24449ac 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -35,6 +35,7 @@
#include <linux/errno.h>
#include <linux/file.h>
#include <linux/ioctl.h>
+#include <net/sock.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
@@ -105,6 +106,7 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size)
do {
+ sock->sk->allocation = GFP_ATOMIC;
iov.iov_base = buf;
iov.iov_len = size;
msg.msg_name = NULL;
diff --git a/drivers/block/pdc4030.c b/drivers/block/pdc4030.c
index 080d353a5..bf5465695 100644
--- a/drivers/block/pdc4030.c
+++ b/drivers/block/pdc4030.c
@@ -162,7 +162,6 @@ int __init setup_pdc4030 (ide_hwif_t *hwif)
if (!hwif) return 0;
drive = &hwif->drives[0];
- drive->timeout = HZ/100;
hwif2 = &ide_hwifs[hwif->index+1];
if (hwif->chipset == ide_pdc4030) /* we've already been found ! */
return 1;
@@ -309,9 +308,6 @@ static void promise_read_intr (ide_drive_t *drive)
unsigned int sectors_left, sectors_avail, nsect;
struct request *rq;
- /* reset timeout */
- drive->timeout = HZ/100;
-
if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
ide_error(drive, "promise_read_intr", stat);
return;
@@ -366,8 +362,7 @@ read_next:
if (stat & DRQ_STAT)
goto read_again;
if (stat & BUSY_STAT) {
- drive->timeout = WAIT_CMD;
- ide_set_handler (drive, &promise_read_intr);
+ ide_set_handler (drive, &promise_read_intr, WAIT_CMD, NULL);
#ifdef DEBUG_READ
printk(KERN_DEBUG "%s: promise_read: waiting for"
"interrupt\n", drive->name);
@@ -396,7 +391,7 @@ static void promise_complete_pollfunc(ide_drive_t *drive)
if (GET_STAT() & BUSY_STAT) {
if (time_before(jiffies, hwgroup->poll_timeout)) {
- ide_set_handler(drive, &promise_complete_pollfunc);
+ ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
return; /* continue polling... */
}
hwgroup->poll_timeout = 0;
@@ -425,7 +420,7 @@ static void promise_write_pollfunc (ide_drive_t *drive)
if (IN_BYTE(IDE_NSECTOR_REG) != 0) {
if (time_before(jiffies, hwgroup->poll_timeout)) {
- ide_set_handler (drive, &promise_write_pollfunc);
+ ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
return; /* continue polling... */
}
hwgroup->poll_timeout = 0;
@@ -439,7 +434,7 @@ static void promise_write_pollfunc (ide_drive_t *drive)
*/
ide_multwrite(drive, 4);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler(drive, &promise_complete_pollfunc);
+ ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
#ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
drive->name, GET_STAT());
@@ -472,7 +467,7 @@ static void promise_write (ide_drive_t *drive)
if (rq->nr_sectors > 4) {
ide_multwrite(drive, rq->nr_sectors - 4);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler (drive, &promise_write_pollfunc);
+ ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
} else {
/*
* There are 4 or fewer sectors to transfer, do them all in one go
@@ -480,7 +475,7 @@ static void promise_write (ide_drive_t *drive)
*/
ide_multwrite(drive, rq->nr_sectors);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler(drive, &promise_complete_pollfunc);
+ ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
#ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
"status = %02x\n", drive->name, GET_STAT());
@@ -523,8 +518,7 @@ void do_pdc4030_io (ide_drive_t *drive, struct request *rq)
printk(KERN_DEBUG "%s: read: waiting for "
"interrupt\n", drive->name);
#endif
- drive->timeout = WAIT_CMD;
- ide_set_handler(drive, &promise_read_intr);
+ ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
return;
}
udelay(1);
diff --git a/drivers/block/trm290.c b/drivers/block/trm290.c
index 5c7c8fd3c..1308c7bd7 100644
--- a/drivers/block/trm290.c
+++ b/drivers/block/trm290.c
@@ -192,8 +192,7 @@ static int trm290_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
if (drive->media != ide_disk)
return 0;
- drive->timeout = WAIT_CMD;
- ide_set_handler(drive, &ide_dma_intr);
+ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0;
case ide_dma_begin: