diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-29 01:41:54 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-29 01:41:54 +0000 |
commit | f969d69ba9f952e5bdd38278e25e26a3e4a61a70 (patch) | |
tree | b3530d803df59d726afaabebc6626987dee1ca05 /drivers/block | |
parent | a10ce7ef2066b455d69187643ddf2073bfc4db24 (diff) |
Merge with 2.3.27.
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/Config.in | 4 | ||||
-rw-r--r-- | drivers/block/DAC960.c | 29 | ||||
-rw-r--r-- | drivers/block/amiflop.c | 4 | ||||
-rw-r--r-- | drivers/block/cpqarray.c | 37 | ||||
-rw-r--r-- | drivers/block/hpt34x.c | 3 | ||||
-rw-r--r-- | drivers/block/icside.c | 3 | ||||
-rw-r--r-- | drivers/block/ide-cd.c | 106 | ||||
-rw-r--r-- | drivers/block/ide-disk.c | 13 | ||||
-rw-r--r-- | drivers/block/ide-dma.c | 3 | ||||
-rw-r--r-- | drivers/block/ide-floppy.c | 9 | ||||
-rw-r--r-- | drivers/block/ide-geometry.c | 6 | ||||
-rw-r--r-- | drivers/block/ide-pmac.c | 3 | ||||
-rw-r--r-- | drivers/block/ide-proc.c | 26 | ||||
-rw-r--r-- | drivers/block/ide-tape.c | 9 | ||||
-rw-r--r-- | drivers/block/ide.c | 64 | ||||
-rw-r--r-- | drivers/block/ll_rw_blk.c | 39 | ||||
-rw-r--r-- | drivers/block/loop.c | 26 | ||||
-rw-r--r-- | drivers/block/md.c | 130 | ||||
-rw-r--r-- | drivers/block/nbd.c | 2 | ||||
-rw-r--r-- | drivers/block/pdc4030.c | 20 | ||||
-rw-r--r-- | drivers/block/trm290.c | 3 |
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: |