From 1a15c9bc642c4e1f7b5cab501177e6499b132695 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:29:14 -0500 Subject: [PATCH] Import 2.3.32pre4 --- CREDITS | 9 +- Makefile | 4 +- arch/i386/defconfig | 1 - arch/i386/kernel/smpboot.c | 1 - arch/i386/mm/init.c | 9 +- drivers/block/ide-cd.c | 280 ++++++++++++++-------------------- drivers/block/ide-cd.h | 40 +---- drivers/cdrom/aztcd.c | 59 ++++--- drivers/cdrom/cdrom.c | 16 +- drivers/cdrom/cdu31a.c | 38 +++-- drivers/cdrom/cm206.c | 26 +++- drivers/cdrom/gscd.c | 30 +++- drivers/cdrom/isp16.c | 38 +++-- drivers/cdrom/isp16.h | 1 - drivers/cdrom/mcd.c | 37 +++-- drivers/cdrom/mcdx.c | 29 +++- drivers/cdrom/optcd.c | 35 +++-- drivers/cdrom/sbpcd.c | 33 +++- drivers/cdrom/sjcd.c | 29 +++- drivers/cdrom/sonycd535.c | 33 ++-- drivers/char/Config.in | 2 +- drivers/char/agp/agp.h | 2 + drivers/char/agp/agpgart_be.c | 1 - drivers/scsi/scsi.c | 2 + drivers/scsi/scsi.h | 7 +- drivers/scsi/scsi_debug.c | 1 + drivers/scsi/scsi_merge.c | 1 + drivers/scsi/sd.c | 105 +++++++------ drivers/scsi/sr.c | 55 +++---- drivers/scsi/sr_ioctl.c | 1 - drivers/video/Makefile | 30 +++- fs/affs/symlink.c | 140 ++++------------- fs/efs/symlink.c | 115 ++++---------- fs/hpfs/ea.c | 58 ++++++- fs/hpfs/file.c | 2 +- fs/hpfs/hpfs_fn.h | 8 +- fs/hpfs/inode.c | 24 +-- fs/hpfs/namei.c | 61 +++----- fs/isofs/rock.c | 270 ++++++++++++++++---------------- fs/isofs/symlink.c | 65 +------- fs/namei.c | 17 ++- fs/ncpfs/symlink.c | 155 +++++-------------- fs/umsdos/symlink.c | 137 +---------------- include/asm-i386/spinlock.h | 2 + include/linux/cdrom.h | 43 +++++- include/linux/fs.h | 1 + include/linux/iso_fs.h | 2 +- kernel/fork.c | 1 - 48 files changed, 920 insertions(+), 1136 deletions(-) diff --git a/CREDITS b/CREDITS index aa16a443ce00..c4969b9e913a 100644 --- a/CREDITS +++ b/CREDITS @@ -1821,11 +1821,14 @@ S: Rueting 4 S: 23743 Groemitz S: Germany -N: Paul Russell -E: Paul.Russell@rustcorp.com.au +N: Paul `Rusty' Russell +E: rusty@linuxcare.com W: http://www.rustcorp.com D: Ruggedly handsome. -D: Developed Generic IP Firewalling Chains with Michael Neuling. +D: netfilter, ipchains with Michael Neuling. +S: 301/222 City Walk +S: Canberra ACT 2601 +S: Australia N: Thomas Sailer E: sailer@ife.ee.ethz.ch diff --git a/Makefile b/Makefile index 5c26884b20bb..eade2313a8ac 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,7 @@ ifdef CONFIG_DRM DRIVERS += drivers/char/drm/drm.o endif -ifdef CONFIG_AGP +ifeq ($(CONFIG_AGP),y) DRIVERS += drivers/char/agp/agp.o endif @@ -206,7 +206,7 @@ DRIVERS := $(DRIVERS) drivers/sgi/sgi.a endif ifdef CONFIG_VT -DRIVERS := $(DRIVERS) drivers/video/video.a +DRIVERS := $(DRIVERS) drivers/video/video.o endif ifeq ($(CONFIG_PARIDE),y) diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 206cad096e1c..9157103958df 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -430,7 +430,6 @@ CONFIG_EXT2_FS=y # CONFIG_CODA_FS is not set CONFIG_NFS_FS=y CONFIG_NFSD=y -# CONFIG_NFSD_SUN is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 811f00f387e9..fcc851043cf3 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -655,7 +655,6 @@ void __init smp_store_cpu_info(int id) *c = boot_cpu_data; c->pte_quick = 0; c->pmd_quick = 0; - c->pgd_quick = 0; c->pgtable_cache_sz = 0; identify_cpu(c); /* diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 7ff12d210739..55d3553e11a4 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -162,11 +162,12 @@ int do_check_pgt_cache(int low, int high) int freed = 0; if(pgtable_cache_size > high) { do { - if(pgd_quicklist) - mmlist_modify_lock(), \ - free_pgd_slow(get_pgd_fast()), \ - mmlist_modify_unlock(), \ + if(pgd_quicklist) { + mmlist_modify_lock(); + free_pgd_slow(get_pgd_fast()); + mmlist_modify_unlock(); freed++; + } if(pmd_quicklist) free_pmd_slow(get_pmd_fast()), freed++; if(pte_quicklist) diff --git a/drivers/block/ide-cd.c b/drivers/block/ide-cd.c index 4a058db7f42b..6b71cd7bfdf4 100644 --- a/drivers/block/ide-cd.c +++ b/drivers/block/ide-cd.c @@ -313,8 +313,7 @@ static void cdrom_saw_media_change (ide_drive_t *drive) static -void cdrom_analyze_sense_data (ide_drive_t *drive, - struct atapi_request_sense *reqbuf, +void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf, struct packet_command *failed_command) { if (reqbuf->sense_key == NOT_READY || @@ -431,27 +430,21 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, * In the case of NOT_READY, if SKSV is set the drive can * give us nice ETA readings. */ - if (reqbuf->sense_key == NOT_READY && - (reqbuf->sense_key_specific[0] & 0x80)) { - int progress = (reqbuf->sense_key_specific[1] << 8 | - reqbuf->sense_key_specific[2]) * 100; + if (reqbuf->sense_key == NOT_READY && (reqbuf->sks[0] & 0x80)) { + int progress = (reqbuf->sks[1] << 8 | reqbuf->sks[2]) * 100; printk(" Command is %02d%% complete\n", progress / 0xffff); } if (reqbuf->sense_key == ILLEGAL_REQUEST && - (reqbuf->sense_key_specific[0] & 0x80) != 0) { + (reqbuf->sks[0] & 0x80) != 0) { printk (" Error in %s byte %d", - (reqbuf->sense_key_specific[0] & 0x40) != 0 - ? "command packet" - : "command data", - (reqbuf->sense_key_specific[1] << 8) + - reqbuf->sense_key_specific[2]); - - if ((reqbuf->sense_key_specific[0] & 0x40) != 0) { - printk (" bit %d", - reqbuf->sense_key_specific[0] & 0x07); - } + (reqbuf->sks[0] & 0x40) != 0 ? + "command packet" : "command data", + (reqbuf->sks[1] << 8) + reqbuf->sks[2]); + + if ((reqbuf->sks[0] & 0x40) != 0) + printk (" bit %d", reqbuf->sks[0] & 0x07); printk ("\n"); } @@ -476,39 +469,25 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, static void cdrom_queue_request_sense (ide_drive_t *drive, struct semaphore *sem, - struct atapi_request_sense *reqbuf, struct packet_command *failed_command) { struct cdrom_info *info = drive->driver_data; struct request *rq; struct packet_command *pc; - int len; - - /* If the request didn't explicitly specify where - to put the sense data, use the statically allocated structure. */ - if (reqbuf == NULL) - reqbuf = &info->sense_data; /* Make up a new request to retrieve sense information. */ - pc = &info->request_sense_pc; - memset (pc, 0, sizeof (*pc)); - - /* The request_sense structure has an odd number of (16-bit) words, - which won't work well with 32-bit transfers. However, we don't care - about the last two bytes, so just truncate the structure down - to an even length. */ - len = sizeof (*reqbuf) / 4; - len *= 4; + memset(pc, 0, sizeof (*pc)); pc->c[0] = GPCMD_REQUEST_SENSE; - pc->c[4] = (unsigned char) len; - pc->buffer = (char *)reqbuf; - pc->buflen = len; - pc->sense_data = (struct atapi_request_sense *)failed_command; - /* stuff the sense request in front of our current request */ + /* just get the first 18 bytes of the sense info, there might not + * be more available */ + pc->c[4] = pc->buflen = 18; + pc->buffer = (char *)&info->sense_data; + pc->sense_data = (struct request_sense *)failed_command; + /* stuff the sense request in front of our current request */ rq = &info->request_sense_request; ide_init_drive_cmd (rq); rq->cmd = REQUEST_SENSE_COMMAND; @@ -526,7 +505,7 @@ static void cdrom_end_request (int uptodate, ide_drive_t *drive) struct packet_command *pc = (struct packet_command *) rq->buffer; cdrom_analyze_sense_data (drive, - (struct atapi_request_sense *) (pc->buffer - pc->c[4]), + (struct request_sense *) (pc->buffer - pc->c[4]), (struct packet_command *) pc->sense_data); } if (rq->cmd == READ && !rq->current_nr_sectors) @@ -609,8 +588,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, cdrom_end_request (1, drive); if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense (drive, sem, - pc->sense_data, pc); + cdrom_queue_request_sense(drive, sem, pc); } else { /* Handle errors from READ requests. */ @@ -649,8 +627,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, /* If we got a CHECK_CONDITION status, queue a request sense command. */ if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense (drive, - NULL, NULL, NULL); + cdrom_queue_request_sense(drive, NULL, NULL); } } @@ -1200,9 +1177,7 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block) */ /* Forward declarations. */ -static int -cdrom_lockdoor (ide_drive_t *drive, int lockflag, - struct atapi_request_sense *reqbuf); +static int cdrom_lockdoor(ide_drive_t *drive, int lockflag); /* Interrupt routine for packet command completion. */ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) @@ -1210,8 +1185,11 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) int ireason, len, stat, thislen; struct request *rq = HWGROUP(drive)->rq; struct packet_command *pc = (struct packet_command *)rq->buffer; + struct cdrom_info *info = drive->driver_data; ide_startstop_t startstop; + pc->sense_data = &info->sense_data; + /* Check for errors. */ if (cdrom_decode_status (&startstop, drive, 0, &stat)) return startstop; @@ -1339,18 +1317,11 @@ void cdrom_sleep (int time) } static -int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc) +int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc) { - struct atapi_request_sense my_reqbuf; int retries = 10; struct request req; - /* If our caller has not provided a place to stick any sense data, - use our own area. */ - if (pc->sense_data == NULL) - pc->sense_data = &my_reqbuf; - pc->sense_data->sense_key = 0; - /* Start of retry loop. */ do { ide_init_drive_cmd (&req); @@ -1365,7 +1336,7 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc) /* The request failed. Retry if it was due to a unit attention status (usually means media was changed). */ - struct atapi_request_sense *reqbuf = pc->sense_data; + struct request_sense *reqbuf = pc->sense_data; if (reqbuf->sense_key == UNIT_ATTENTION) cdrom_saw_media_change (drive); @@ -1386,25 +1357,24 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc) } while (pc->stat != 0 && retries >= 0); /* Return an error if the command failed. */ - if (pc->stat != 0) + if (pc->stat) return -EIO; - else { - /* The command succeeded. If it was anything other than - a request sense, eject, or door lock command, - and we think that the door is presently unlocked, lock it - again. (The door was probably unlocked via an explicit - CDROMEJECT ioctl.) */ - if (CDROM_STATE_FLAGS (drive)->door_locked == 0 && - (pc->c[0] != GPCMD_TEST_UNIT_READY && - pc->c[0] != GPCMD_REQUEST_SENSE && - pc->c[0] != GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL && - pc->c[0] != GPCMD_START_STOP_UNIT && - pc->c[0] != GPCMD_MODE_SENSE_10 && - pc->c[0] != GPCMD_MODE_SELECT_10)) { - (void) cdrom_lockdoor (drive, 1, NULL); - } - return 0; + + /* The command succeeded. If it was anything other than + a request sense, eject, or door lock command, + and we think that the door is presently unlocked, lock it + again. (The door was probably unlocked via an explicit + CDROMEJECT ioctl.) */ + if (CDROM_STATE_FLAGS (drive)->door_locked == 0 && + (pc->c[0] != GPCMD_TEST_UNIT_READY && + pc->c[0] != GPCMD_REQUEST_SENSE && + pc->c[0] != GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL && + pc->c[0] != GPCMD_START_STOP_UNIT && + pc->c[0] != GPCMD_MODE_SENSE_10 && + pc->c[0] != GPCMD_MODE_SELECT_10)) { + (void) cdrom_lockdoor (drive, 1); } + return 0; } /**************************************************************************** @@ -1463,7 +1433,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, unsigned long block) * Ioctl handling. * * Routines which queue packet commands take as a final argument a pointer - * to an atapi_request_sense struct. If execution of the command results + * to a request_sense struct. If execution of the command results * in an error with a CHECK CONDITION status, this structure will be filled * with the results of the subsequent request sense command. The pointer * can also be NULL, in which case no sense information is returned. @@ -1512,18 +1482,14 @@ int msf_to_lba (byte m, byte s, byte f) return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET; } - -static int -cdrom_check_status (ide_drive_t *drive, - struct atapi_request_sense *reqbuf) +static int cdrom_check_status (ide_drive_t *drive) { struct packet_command pc; struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *cdi = &info->devinfo; - memset (&pc, 0, sizeof (pc)); + memset(&pc, 0, sizeof(pc)); - pc.sense_data = reqbuf; pc.c[0] = GPCMD_TEST_UNIT_READY; #if ! STANDARD_ATAPI @@ -1533,39 +1499,35 @@ cdrom_check_status (ide_drive_t *drive, pc.c[7] = cdi->sanyo_slot % 3; #endif /* not STANDARD_ATAPI */ - return cdrom_queue_packet_command (drive, &pc); + return cdrom_queue_packet_command(drive, &pc); } /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ static int -cdrom_lockdoor (ide_drive_t *drive, int lockflag, - struct atapi_request_sense *reqbuf) +cdrom_lockdoor(ide_drive_t *drive, int lockflag) { - struct atapi_request_sense my_reqbuf; - int stat; + struct request_sense *sense; struct packet_command pc; - - if (reqbuf == NULL) - reqbuf = &my_reqbuf; + int stat; /* If the drive cannot lock the door, just pretend. */ if (CDROM_CONFIG_FLAGS (drive)->no_doorlock) stat = 0; else { - memset (&pc, 0, sizeof (pc)); - pc.sense_data = reqbuf; - + memset(&pc, 0, sizeof(pc)); pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; pc.c[4] = (lockflag != 0); stat = cdrom_queue_packet_command (drive, &pc); } + sense = pc.sense_data; + /* If we got an illegal field error, the drive probably cannot lock the door. */ if (stat != 0 && - reqbuf->sense_key == ILLEGAL_REQUEST && - (reqbuf->asc == 0x24 || reqbuf->asc == 0x20)) { + sense->sense_key == ILLEGAL_REQUEST && + (sense->asc == 0x24 || sense->asc == 0x20)) { printk ("%s: door locking not supported\n", drive->name); CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1; @@ -1573,7 +1535,7 @@ cdrom_lockdoor (ide_drive_t *drive, int lockflag, } /* no medium, that's alright. */ - if (stat != 0 && reqbuf->sense_key == NOT_READY && reqbuf->asc == 0x3a) + if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a) stat = 0; if (stat == 0) @@ -1585,30 +1547,25 @@ cdrom_lockdoor (ide_drive_t *drive, int lockflag, /* Eject the disk if EJECTFLAG is 0. If EJECTFLAG is 1, try to reload the disk. */ -static int -cdrom_eject (ide_drive_t *drive, int ejectflag, - struct atapi_request_sense *reqbuf) +static int cdrom_eject(ide_drive_t *drive, int ejectflag) { struct packet_command pc; - if (CDROM_CONFIG_FLAGS (drive)->no_eject && !ejectflag) + if (CDROM_CONFIG_FLAGS(drive)->no_eject && !ejectflag) return -EDRIVE_CANT_DO_THIS; /* reload fails on some drives, if the tray is locked */ - if (CDROM_STATE_FLAGS (drive)->door_locked && ejectflag) + if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag) return 0; - memset (&pc, 0, sizeof (pc)); - pc.sense_data = reqbuf; + memset(&pc, 0, sizeof (pc)); pc.c[0] = GPCMD_START_STOP_UNIT; pc.c[4] = 0x02 + (ejectflag != 0); return cdrom_queue_packet_command (drive, &pc); } -static int -cdrom_read_capacity (ide_drive_t *drive, unsigned *capacity, - struct atapi_request_sense *reqbuf) +static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity) { struct { __u32 lba; @@ -1618,30 +1575,25 @@ cdrom_read_capacity (ide_drive_t *drive, unsigned *capacity, int stat; struct packet_command pc; - memset (&pc, 0, sizeof (pc)); - pc.sense_data = reqbuf; + memset(&pc, 0, sizeof (pc)); pc.c[0] = GPCMD_READ_CDVD_CAPACITY; pc.buffer = (char *)&capbuf; - pc.buflen = sizeof (capbuf); + pc.buflen = sizeof(capbuf); - stat = cdrom_queue_packet_command (drive, &pc); + stat = cdrom_queue_packet_command(drive, &pc); if (stat == 0) *capacity = be32_to_cpu(capbuf.lba); return stat; } - -static int -cdrom_read_tocentry (ide_drive_t *drive, int trackno, int msf_flag, - int format, char *buf, int buflen, - struct atapi_request_sense *reqbuf) +static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, + int format, char *buf, int buflen) { struct packet_command pc; - memset (&pc, 0, sizeof (pc)); - pc.sense_data = reqbuf; + memset(&pc, 0, sizeof(pc)); pc.buffer = buf; pc.buflen = buflen; @@ -1650,14 +1602,16 @@ cdrom_read_tocentry (ide_drive_t *drive, int trackno, int msf_flag, pc.c[7] = (buflen >> 8); pc.c[8] = (buflen & 0xff); pc.c[9] = (format << 6); - if (msf_flag) pc.c[1] = 2; + + if (msf_flag) + pc.c[1] = 2; + return cdrom_queue_packet_command (drive, &pc); } /* Try to read the entire TOC for the disk into our internal buffer. */ -static int -cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf) +static int cdrom_read_toc (ide_drive_t *drive) { int stat, ntracks, i; struct cdrom_info *info = drive->driver_data; @@ -1682,13 +1636,13 @@ cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf) /* Check to see if the existing data is still valid. If it is, just return. */ if (CDROM_STATE_FLAGS (drive)->toc_valid) - (void) cdrom_check_status (drive, NULL); + (void) cdrom_check_status(drive); if (CDROM_STATE_FLAGS (drive)->toc_valid) return 0; /* First read just the header, so we know how long the TOC is. */ stat = cdrom_read_tocentry (drive, 0, 1, 0, (char *)&toc->hdr, - sizeof (struct atapi_toc_header), reqbuf); + sizeof (struct atapi_toc_header)); if (stat) return stat; #if ! STANDARD_ATAPI @@ -1706,7 +1660,7 @@ cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf) stat = cdrom_read_tocentry (drive, toc->hdr.first_track, 1, 0, (char *)&toc->hdr, sizeof (struct atapi_toc_header) + (ntracks + 1) * - sizeof (struct atapi_toc_entry), reqbuf); + sizeof (struct atapi_toc_entry)); if (stat && toc->hdr.first_track > 1) { /* Cds with CDI tracks only don't have any TOC entries, @@ -1723,8 +1677,7 @@ cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf) 0, (char *)&toc->hdr, sizeof (struct atapi_toc_header) + (ntracks+1) * - sizeof (struct atapi_toc_entry), - reqbuf); + sizeof (struct atapi_toc_entry)); if (stat) { return stat; } @@ -1769,8 +1722,7 @@ cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf) if (toc->hdr.first_track != CDROM_LEADOUT) { /* Read the multisession information. */ stat = cdrom_read_tocentry (drive, 0, 1, 1, - (char *)&ms_tmp, sizeof (ms_tmp), - reqbuf); + (char *)&ms_tmp, sizeof (ms_tmp)); if (stat) return stat; } else { ms_tmp.ent.addr.msf.minute = 0; @@ -1796,7 +1748,7 @@ cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf) (long *)&toc->capacity); if (stat) #endif - stat = cdrom_read_capacity (drive, &toc->capacity, reqbuf); + stat = cdrom_read_capacity (drive, &toc->capacity); if (stat) toc->capacity = 0x1fffff; /* for general /dev/cdrom like mounting, one big disc */ @@ -1829,17 +1781,14 @@ cdrom_read_toc (ide_drive_t *drive, struct atapi_request_sense *reqbuf) } -static int -cdrom_read_subchannel (ide_drive_t *drive, int format, - char *buf, int buflen, - struct atapi_request_sense *reqbuf) +static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf, + int buflen) { struct packet_command pc; - memset (&pc, 0, sizeof (pc)); - pc.sense_data = reqbuf; + memset(&pc, 0, sizeof(pc)); - pc.buffer = buf; + pc.buffer = buf; pc.buflen = buflen; pc.c[0] = GPCMD_READ_SUBCHANNEL; pc.c[1] = 2; /* MSF addressing */ @@ -1847,23 +1796,20 @@ cdrom_read_subchannel (ide_drive_t *drive, int format, pc.c[3] = format; pc.c[7] = (buflen >> 8); pc.c[8] = (buflen & 0xff); - return cdrom_queue_packet_command (drive, &pc); + return cdrom_queue_packet_command(drive, &pc); } /* ATAPI cdrom drives are free to select the speed you request or any slower rate :-( Requesting too fast a speed will _not_ produce an error. */ -static int -cdrom_select_speed (ide_drive_t *drive, int speed, - struct atapi_request_sense *reqbuf) +static int cdrom_select_speed (ide_drive_t *drive, int speed) { struct packet_command pc; - memset (&pc, 0, sizeof (pc)); - pc.sense_data = reqbuf; + memset(&pc, 0, sizeof(pc)); if (speed == 0) - speed = 0xffff; /* set to max */ + speed = 0xffff; /* set to max */ else - speed *= 177; /* Nx to kbytes/s */ + speed *= 177; /* Nx to kbytes/s */ pc.c[0] = GPCMD_SET_SPEED; /* Read Drive speed in kbytes/second MSB */ @@ -1882,10 +1828,8 @@ cdrom_select_speed (ide_drive_t *drive, int speed, } -static -int cdrom_get_toc_entry (ide_drive_t *drive, int track, - struct atapi_toc_entry **ent, - struct atapi_request_sense *reqbuf) +static int cdrom_get_toc_entry(ide_drive_t *drive, int track, + struct atapi_toc_entry **ent) { struct cdrom_info *info = drive->driver_data; struct atapi_toc *toc = info->toc; @@ -1923,7 +1867,13 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi, memcpy(pc.c, cgc->cmd, CDROM_PACKET_SIZE); pc.buffer = cgc->buffer; pc.buflen = cgc->buflen; - return cgc->stat = cdrom_queue_packet_command(drive, &pc); + cgc->stat = cdrom_queue_packet_command(drive, &pc); + + /* There was an error, assign sense. */ + if (cgc->stat) + cgc->sense = pc.sense_data; + + return cgc->stat; } static @@ -1987,7 +1937,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi, struct atapi_toc *toc; /* Make sure our saved TOC is valid. */ - stat = cdrom_read_toc (drive, NULL); + stat = cdrom_read_toc(drive); if (stat) return stat; toc = info->toc; @@ -2002,8 +1952,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi, struct cdrom_tocentry *tocentry = (struct cdrom_tocentry*) arg; struct atapi_toc_entry *toce; - stat = cdrom_get_toc_entry (drive, tocentry->cdte_track, &toce, - NULL); + stat = cdrom_get_toc_entry (drive, tocentry->cdte_track, &toce); if (stat) return stat; tocentry->cdte_ctrl = toce->control; @@ -2040,21 +1989,20 @@ static int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position) { ide_drive_t *drive = (ide_drive_t*) cdi->handle; - struct atapi_request_sense rq; if (position) { - int stat = cdrom_lockdoor (drive, 0, &rq); + int stat = cdrom_lockdoor (drive, 0); if (stat) return stat; } - return cdrom_eject (drive, !position, NULL); + return cdrom_eject(drive, !position); } static int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock) { ide_drive_t *drive = (ide_drive_t*) cdi->handle; - return cdrom_lockdoor (drive, lock, NULL); + return cdrom_lockdoor (drive, lock); } static @@ -2062,14 +2010,13 @@ int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) { int stat, attempts = 3; ide_drive_t *drive = (ide_drive_t*) cdi->handle; - struct atapi_request_sense reqbuf; struct cdrom_generic_command cgc; struct { char pad[8]; struct atapi_capabilities_page cap; } buf; - stat=cdrom_select_speed (drive, speed, &reqbuf); - if (stat<0) + + if ((stat = cdrom_select_speed (drive, speed)) < 0) return stat; init_cdrom_command(&cgc, &buf, sizeof(buf)); @@ -2100,19 +2047,19 @@ static int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr) { ide_drive_t *drive = (ide_drive_t*) cdi->handle; + struct cdrom_info *info = drive->driver_data; if (slot_nr == CDSL_CURRENT) { - - struct atapi_request_sense sense; - int stat = cdrom_check_status (drive, &sense); - if (stat == 0 || sense.sense_key == UNIT_ATTENTION) + struct request_sense *sense = &info->sense_data; + int stat = cdrom_check_status(drive); + if (stat == 0 || sense->sense_key == UNIT_ATTENTION) return CDS_DISC_OK; - if (sense.sense_key == NOT_READY && sense.asc == 0x04 && - sense.ascq == 0x04) + if (sense->sense_key == NOT_READY && sense->asc == 0x04 && + sense->ascq == 0x04) return CDS_DISC_OK; - if (sense.sense_key == NOT_READY) { + if (sense->sense_key == NOT_READY) { /* ATAPI doesn't have anything that can help us decide whether the drive is really emtpy or the tray is just open. irk. */ @@ -2148,10 +2095,9 @@ int ide_cdrom_get_mcn (struct cdrom_device_info *cdi, char mcnbuf[24]; ide_drive_t *drive = (ide_drive_t*) cdi->handle; - stat = cdrom_read_subchannel (drive, 2, /* get MCN */ - mcnbuf, sizeof (mcnbuf), - NULL); - if (stat) return stat; +/* get MCN */ + if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf)))) + return stat; memcpy (mcn_info->medium_catalog_number, mcnbuf+9, sizeof (mcn_info->medium_catalog_number)-1); @@ -2174,7 +2120,7 @@ int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi, ide_drive_t *drive = (ide_drive_t*) cdi->handle; if (slot_nr == CDSL_CURRENT) { - (void) cdrom_check_status (drive, NULL); + (void) cdrom_check_status(drive); CDROM_STATE_FLAGS (drive)->media_changed = 0; return CDROM_STATE_FLAGS (drive)->media_changed; } else { diff --git a/drivers/block/ide-cd.h b/drivers/block/ide-cd.h index b65baa5fe513..8891205edd3a 100644 --- a/drivers/block/ide-cd.h +++ b/drivers/block/ide-cd.h @@ -7,6 +7,7 @@ * Copyright (C) 1998, 1999 Jens Axboe */ +#include #include /* Turn this on to have the driver print out the meanings of the @@ -95,47 +96,14 @@ struct ide_cd_state_flags { __u8 reserved : 4; byte current_speed; /* Current speed of the drive */ }; -#define CDROM_STATE_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->state_flags)) - -struct atapi_request_sense { -#if defined(__BIG_ENDIAN_BITFIELD) - unsigned char valid : 1; - unsigned char error_code : 7; -#elif defined(__LITTLE_ENDIAN_BITFIELD) - unsigned char error_code : 7; - unsigned char valid : 1; -#else -#error "Please fix " -#endif - byte reserved1; -#if defined(__BIG_ENDIAN_BITFIELD) - unsigned char reserved3 : 2; - unsigned char ili : 1; - unsigned char reserved2 : 1; - unsigned char sense_key : 4; -#elif defined(__LITTLE_ENDIAN_BITFIELD) - unsigned char sense_key : 4; - unsigned char reserved2 : 1; - unsigned char ili : 1; - unsigned char reserved3 : 2; -#else -#error "Please fix " -#endif - byte info[4]; - byte sense_len; - byte command_info[4]; - byte asc; - byte ascq; - byte fru; - byte sense_key_specific[3]; -}; +#define CDROM_STATE_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->state_flags)) struct packet_command { char *buffer; int buflen; int stat; - struct atapi_request_sense *sense_data; + struct request_sense *sense_data; unsigned char c[12]; }; @@ -502,7 +470,7 @@ struct cdrom_info { /* The result of the last successful request sense command on this device. */ - struct atapi_request_sense sense_data; + struct request_sense sense_data; struct request request_sense_request; struct packet_command request_sense_pc; diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c index e548170a0da2..d560fa6a41f9 100644 --- a/drivers/cdrom/aztcd.c +++ b/drivers/cdrom/aztcd.c @@ -158,6 +158,11 @@ V2.60 Implemented Auto-Probing; made changes for kernel's 2.1.xx blocksize Adaption to linux kernel > 2.1.0 Werner Zimmermann, Nov 29, 97 + + November 1999 -- Make kernel-parameter implementation work with 2.3.x + Removed init_module & cleanup_module in favor of + module_init & module_exit. + Torben Mathiasen */ #include @@ -351,7 +356,6 @@ static int aztGetDiskInfo(void); static int aztGetToc(int multi); /* Kernel Interface Functions */ -void aztcd_setup(char *str, int *ints); static int check_aztcd_media_change(kdev_t full_dev); static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); static void azt_transfer(void); @@ -365,11 +369,8 @@ static void aztcd_release(struct inode * inode, struct file * file); static int aztcd_release(struct inode * inode, struct file * file); #endif -int aztcd_init(void); -#ifdef MODULE - int init_module(void); - void cleanup_module(void); -#endif MODULE +int aztcd_init(void); + static struct file_operations azt_fops = { NULL, /* lseek - default */ block_read, /* read - general block-dev read */ @@ -1084,17 +1085,25 @@ static int aztGetToc(int multi) Kernel Interface Functions ########################################################################## */ -#ifdef AZT_KERNEL_PRIOR_2_1 -void aztcd_setup(char *str, int *ints) -#else -void __init aztcd_setup(char *str, int *ints) -#endif -{ if (ints[0] > 0) - azt_port = ints[1]; - if (ints[0] > 1) - azt_cont = ints[2]; + +#ifndef MODULE +static int __init aztcd_setup(char *str) +{ + int ints[4]; + + (void)get_options(str, ARRAY_SIZE(ints), ints); + + if (ints[0] > 0) + azt_port = ints[1]; + if (ints[1] > 1) + azt_cont = ints[2]; + return 1; } +__setup("aztcd=", aztcd_setup); + +#endif /* !MODULE */ + /* * Checking if the media has been changed */ @@ -1614,11 +1623,7 @@ static int aztcd_release(struct inode * inode, struct file * file) * Test for presence of drive and initialize it. Called at boot time. */ -#ifdef AZT_KERNEL_PRIOR_2_1 -int aztcd_init(void) -#else int __init aztcd_init(void) -#endif { long int count, max_count; unsigned char result[50]; int st; @@ -1815,14 +1820,7 @@ int __init aztcd_init(void) return (0); } -#ifdef MODULE - -int init_module(void) -{ - return aztcd_init(); -} - -void cleanup_module(void) +void __exit aztcd_exit(void) { if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) { printk("What's that: can't unregister aztcd\n"); @@ -1836,8 +1834,11 @@ void cleanup_module(void) release_region(azt_port,4); /*proprietary interface*/ printk(KERN_INFO "aztcd module released.\n"); } -#endif MODULE +#ifdef MODULE +module_init(aztcd_init); +#endif +module_exit(aztcd_exit); /*########################################################################## Aztcd State Machine: Controls Drive Operating State @@ -2283,5 +2284,3 @@ static void azt_bin2bcd(unsigned char *p) static int azt_bcd2bin(unsigned char bcd) { return (bcd >> 4) * 10 + (bcd & 0xF); } - - diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index c0383af8d9d3..d952ecf4bb00 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -186,11 +186,15 @@ -- Added setup of write mode for packet writing. -- Fixed CDDA ripping with cdda2wav - accept much larger requests of number of frames and split the reads in blocks of 8. + + 3.05 Dec 13, 1999 - Jens Axboe + -- Added support for changing the region of DVD drives. + -- Added sense data to generic command. -------------------------------------------------------------------------*/ -#define REVISION "Revision: 3.05" -#define VERSION "Id: cdrom.c 3.05 1999/10/24" +#define REVISION "Revision: 3.06" +#define VERSION "Id: cdrom.c 3.06 1999/12/13" /* I use an error-log mask to give fine grain control over the type of messages dumped to the system logs. The available masks include: */ @@ -1909,7 +1913,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, cgc.cmd[5] = entry.cdte_addr.msf.frame; entry.cdte_track = ti.cdti_trk1; - if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry)) + if (cdo->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry)) return -EINVAL; cgc.cmd[6] = entry.cdte_addr.msf.minute; @@ -2053,6 +2057,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, case CDROM_SEND_PACKET: { __u8 *userbuf, copy = 0; + struct request_sense *sense; if (!CDROM_CAN(CDC_GENERIC_PACKET)) return -ENOSYS; cdinfo(CD_DO_IOCTL, "entering CDROM_SEND_PACKET\n"); @@ -2060,6 +2065,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, copy = !!cgc.buflen; userbuf = cgc.buffer; cgc.buffer = NULL; + sense = cgc.sense; if (userbuf != NULL && copy) { /* usually commands just copy data one way, i.e. * we send a buffer to the drive and the command @@ -2090,6 +2096,10 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, ret = cdo->generic_packet(cdi, &cgc); if (copy && !ret) __copy_to_user(userbuf, cgc.buffer, cgc.buflen); + /* copy back sense data */ + if (ret && sense != NULL) + if (copy_to_user(sense, cgc.sense, sizeof(struct request_sense))) + ret = -EFAULT; kfree(cgc.buffer); return ret; } diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c index 8e4a8536bc3e..24e7a5c26197 100644 --- a/drivers/cdrom/cdu31a.c +++ b/drivers/cdrom/cdu31a.c @@ -142,6 +142,11 @@ * . Work begun on fixing driver to * work under 2.1.X. Added temporary extra printks * which seem to slow it down enough to work. + * + * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x + * Removed init_module & cleanup_module in favor of + * module_init & module_exit. + * Torben Mathiasen */ #include @@ -3317,11 +3322,15 @@ get_drive_configuration(unsigned short base_io, #ifndef MODULE /* * Set up base I/O and interrupts, called from main.c. + */ -void __init -cdu31a_setup(char *strings, - int *ints) + +static int __init cdu31a_setup(char *strings) { + int ints[4]; + + (void)get_options(strings, ARRAY_SIZE(ints), ints); + if (ints[0] > 0) { cdu31a_port = ints[1]; @@ -3341,7 +3350,12 @@ cdu31a_setup(char *strings, printk("CDU31A: Unknown interface type: %s\n", strings); } } + + return 1; } + +__setup("cdu31a=", cdu31a_setup); + #endif static int cdu31a_block_size; @@ -3539,16 +3553,9 @@ errout3: return -EIO; } -#ifdef MODULE -int -init_module(void) -{ - return cdu31a_init(); -} - -void -cleanup_module(void) +void __exit +cdu31a_exit(void) { if (unregister_cdrom(&scd_info)) { @@ -3567,4 +3574,9 @@ cleanup_module(void) release_region(cdu31a_port,4); printk(KERN_INFO "cdu31a module released.\n"); } -#endif MODULE + +#ifdef MODULE +module_init(cdu31a_init); +#endif +module_exit(cdu31a_exit); + diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c index edb0ab34ae19..e600d81d0d1a 100644 --- a/drivers/cdrom/cm206.c +++ b/drivers/cdrom/cm206.c @@ -151,6 +151,11 @@ History: 24 jan 1998 Removed the cm206_disc_status() function, as it was now dead code. The Uniform CDROM driver now provides this functionality. + +9 Nov. 1999 Make kernel-parameter implementation work with 2.3.x + Removed init_module & cleanup_module in favor of + module_init & module_exit. + Torben Mathiasen * * Parts of the code are based upon lmscd.c written by Kai Petzke, * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin @@ -1429,7 +1434,7 @@ void __init parse_options(void) } } -int init_module(void) +int __cm206_init(void) { parse_options(); #if !defined(AUTO_PROBE_MODULE) @@ -1438,19 +1443,26 @@ int init_module(void) return cm206_init(); } -void cleanup_module(void) +void __exit cm206_exit(void) { cleanup(4); printk(KERN_INFO "cm206 removed\n"); } + +module_init(__cm206_init); +module_exit(cm206_exit); #else /* !MODULE */ /* This setup function accepts either `auto' or numbers in the range * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */ -void __init cm206_setup(char *s, int *p) + +static int __init cm206_setup(char *s) { - int i; + int i, p[4]; + + (void)get_options(s, ARRAY_SIZE(p), p); + if (!strcmp(s, "auto")) auto_probe=1; for(i=1; i<=p[0]; i++) { if (0x300 <= p[i] && i<= 0x370 && p[i] % 0x10 == 0) { @@ -1462,8 +1474,12 @@ void __init cm206_setup(char *s, int *p) auto_probe = 0; } } + return 1; } -#endif /* MODULE */ + +__setup("cm206=", cm206_setup); + +#endif /* !MODULE */ /* * Local variables: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -D__SMP__ -pipe -fno-strength-reduce -m486 -DCPU=486 -D__SMP__ -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h -c -o cm206.o cm206.c" diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c index 7913f7f0db90..a305c14434fb 100644 --- a/drivers/cdrom/gscd.c +++ b/drivers/cdrom/gscd.c @@ -31,6 +31,13 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + -------------------------------------------------------------------- + + 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x + Removed init_module & cleanup_module in favor of + module_init & module_exit. + Torben Mathiasen */ @@ -195,14 +202,24 @@ static int check_gscd_med_chg (kdev_t full_dev) } -void __init gscd_setup (char *str, int *ints) +#ifndef MODULE +/* Using new interface for kernel-parameters */ + +static int __init gscd_setup (char *str) { + int ints[2]; + (void)get_options(str, ARRAY_SIZE(ints), ints); + if (ints[0] > 0) { gscd_port = ints[1]; } + return 1; } +__setup("gscd=", gscd_setup); + +#endif static int gscd_ioctl (struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) { @@ -963,9 +980,8 @@ unsigned int AX; } #endif -#ifdef MODULE /* Init for the Module-Version */ -int init_module (void) +int init_gscd(void) { long err; @@ -984,7 +1000,7 @@ long err; } } -void cleanup_module (void) +void __exit exit_gscd(void) { if ((unregister_blkdev(MAJOR_NR, "gscd" ) == -EINVAL)) @@ -996,7 +1012,11 @@ void cleanup_module (void) release_region (gscd_port,4); printk(KERN_INFO "GoldStar-module released.\n" ); } -#endif + +#ifdef MODULE +module_init(init_gscd); +#endif +module_exit(exit_gscd); /* Test for presence of drive and initialize it. Called only at boot time. */ diff --git a/drivers/cdrom/isp16.c b/drivers/cdrom/isp16.c index 7b070170749a..c2859f450f98 100644 --- a/drivers/cdrom/isp16.c +++ b/drivers/cdrom/isp16.c @@ -11,6 +11,11 @@ * Removed sound configuration. * Added "module" support. * + * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x + * Removed init_module & cleanup_module in favor of + * module_init & module_exit. + * Torben Mathiasen + * * Detect cdrom interface on ISP16 sound card. * Configure cdrom interface. * @@ -69,17 +74,20 @@ MODULE_PARM(isp16_cdrom_base, "i"); MODULE_PARM(isp16_cdrom_irq, "i"); MODULE_PARM(isp16_cdrom_dma, "i"); MODULE_PARM(isp16_cdrom_type, "s"); -int init_module(void); -void cleanup_module(void); +void isp16_exit(void); #endif #define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p)) #define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p)) +#ifndef MODULE -void __init -isp16_setup(char *str, int *ints) +static int +__init isp16_setup(char *str) { + int ints[4]; + + (void)get_options(str, ARRAY_SIZE(ints), ints); if ( ints[0] > 0 ) isp16_cdrom_base = ints[1]; if ( ints[0] > 1 ) @@ -88,8 +96,14 @@ isp16_setup(char *str, int *ints) isp16_cdrom_dma = ints[3]; if ( str ) isp16_cdrom_type = str; + + return 1; } +__setup("isp16=", isp16_setup); + +#endif /* MODULE */ + /* * ISP16 initialisation. * @@ -307,15 +321,15 @@ isp16_cdi_config(int base, u_char drive_type, int irq, int dma) return(0); } -#ifdef MODULE -int init_module(void) -{ - return isp16_init(); -} - -void cleanup_module(void) +void __exit isp16_exit(void) { release_region(ISP16_IO_BASE, ISP16_IO_SIZE); printk(KERN_INFO "ISP16: module released.\n"); } -#endif /* MODULE */ + +#ifdef MODULE +module_init(isp16_init); +#endif +module_exit(isp16_exit); + + diff --git a/drivers/cdrom/isp16.h b/drivers/cdrom/isp16.h index 9945bb34c451..7fc74b8e49f1 100644 --- a/drivers/cdrom/isp16.h +++ b/drivers/cdrom/isp16.h @@ -71,5 +71,4 @@ #define ISP16_IO_BASE 0xF8D #define ISP16_IO_SIZE 5 /* ports used from 0xF8D up to 0xF91 */ -void isp16_setup(char *str, int *ints); int isp16_init(void); diff --git a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c index c8adc0200b91..cbb2a27cd9ab 100644 --- a/drivers/cdrom/mcd.c +++ b/drivers/cdrom/mcd.c @@ -68,6 +68,13 @@ November 1997 -- ported to the Uniform CD-ROM driver by Erik Andersen. March 1999 -- made io base and irq CONFIG_ options (Tigran Aivazian). + + November 1999 -- Make kernel-parameter implementation work with 2.3.x + Removed init_module & cleanup_module in favor of + module_init & module_exit. + Torben Mathiasen + + */ #include @@ -229,9 +236,13 @@ static struct cdrom_device_info mcd_info = { "mcd", /* name of the device type */ }; - -void __init mcd_setup(char *str, int *ints) +#ifndef MODULE +static int __init mcd_setup(char *str) { + int ints[9]; + + (void)get_options(str, ARRAY_SIZE(ints), ints); + if (ints[0] > 0) mcd_port = ints[1]; if (ints[0] > 1) @@ -240,8 +251,13 @@ void __init mcd_setup(char *str, int *ints) if (ints[0] > 2) mitsumi_bug_93_wait = ints[3]; #endif /* WORK_AROUND_MITSUMI_BUG_93 */ + + return 1; } +__setup("mcd=", mcd_setup); + +#endif /* MODULE */ static int mcd_media_changed(struct cdrom_device_info * cdi, int disc_nr) { @@ -1127,7 +1143,7 @@ static void mcd_release(struct cdrom_device_info * cdi) /* This routine gets called during initialization if things go wrong, - * and is used in cleanup_module as well. */ + * and is used in mcd_exit as well. */ static void cleanup(int level) { switch (level) { @@ -1635,14 +1651,15 @@ Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame); return limit > 0 ? 0 : -1; } -#ifdef MODULE -int init_module(void) -{ - return mcd_init(); -} -void cleanup_module(void) +void __exit mcd_exit(void) { cleanup(3); } -#endif MODULE + +#ifdef MODULE +module_init(mcd_init); +#endif +module_exit(mcd_exit); + + diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c index 38f838797b8b..32ae52497a1e 100644 --- a/drivers/cdrom/mcdx.c +++ b/drivers/cdrom/mcdx.c @@ -44,6 +44,10 @@ * Marcin Dalecki (improved performance, shortened code) * ... somebody forgotten? * + * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x + * Removed init_module & cleanup_module in favor of + * module_init & module_exit. + * Torben Mathiasen */ @@ -210,8 +214,6 @@ struct s_drive_stuff { int mcdx_init(void); void do_mcdx_request(request_queue_t * q); -/* already declared in init/main */ -void mcdx_setup(char *, int *); /* Indirect exported functions. These functions are exported by their addresses, such as mcdx_open and mcdx_close in the @@ -770,12 +772,21 @@ static int mcdx_media_changed(struct cdrom_device_info * cdi, int disc_nr) return 1; } -void __init mcdx_setup(char *str, int *pi) +#ifndef MODULE +static int __init mcdx_setup(char *str) { + int pi[4]; + (void)get_options(str, ARRAY_SIZE(pi), pi); + if (pi[0] > 0) mcdx_drive_map[0][0] = pi[1]; if (pi[0] > 1) mcdx_drive_map[0][1] = pi[2]; + return 1; } +__setup("mcdx=", mcdx_setup); + +#endif + /* DIRTY PART ******************************************************/ static void mcdx_delay(struct s_drive_stuff *stuff, long jifs) @@ -953,10 +964,10 @@ mcdx_talk ( } /* MODULE STUFF ***********************************************************/ -#ifdef MODULE + EXPORT_NO_SYMBOLS; -int init_module(void) +int __mcdx_init(void) { int i; int drives = 0; @@ -976,7 +987,7 @@ int init_module(void) return 0; } -void cleanup_module(void) +void __exit mcdx_exit(void) { int i; @@ -1009,7 +1020,11 @@ void cleanup_module(void) #endif } -#endif MODULE +#ifdef MODULE +module_init(__mcdx_init); +#endif +module_exit(mcdx_exit); + /* Support functions ************************************************/ diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c index 94ad9f091494..4fd96706d619 100644 --- a/drivers/cdrom/optcd.c +++ b/drivers/cdrom/optcd.c @@ -57,6 +57,11 @@ thanks to Luke McFarlane. Also tidied up some printk behaviour. ISP16 initialization is now handled by a separate driver. + + 09-11-99 Make kernel-parameter implementation work with 2.3.x + Removed init_module & cleanup_module in favor of + module_init & module_exit. + Torben Mathiasen */ /* Includes */ @@ -2020,14 +2025,23 @@ static struct file_operations opt_fops = { NULL /* revalidate */ }; - +#ifndef MODULE /* Get kernel parameter when used as a kernel driver */ -void __init optcd_setup(char *str, int *ints) +static int optcd_setup(char *str) { + int ints[4]; + (void)get_options(str, ARRAY_SIZE(ints), ints); + if (ints[0] > 0) optcd_port = ints[1]; + + return 1; } +__setup("optcd=", optcd_setup); + +#endif MODULE + /* Test for presence of drive and initialize it. Called at boot time or during module initialisation. */ int __init optcd_init(void) @@ -2076,14 +2090,7 @@ int __init optcd_init(void) } -#ifdef MODULE -int init_module(void) -{ - return optcd_init(); -} - - -void cleanup_module(void) +void __exit optcd_exit(void) { if (unregister_blkdev(MAJOR_NR, "optcd") == -EINVAL) { printk(KERN_ERR "optcd: what's that: can't unregister\n"); @@ -2092,4 +2099,10 @@ void cleanup_module(void) release_region(optcd_port, 4); printk(KERN_INFO "optcd: module released.\n"); } -#endif MODULE + +#ifdef MODULE +module_init(optcd_init); +#endif +module_exit(optcd_exit); + + diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c index 7b0fcc10ceea..42fa4d62b874 100644 --- a/drivers/cdrom/sbpcd.c +++ b/drivers/cdrom/sbpcd.c @@ -307,6 +307,11 @@ * 4.62 Fix a bug where playing audio left the drive in an unusable state. * Heiko Eissfeldt * + * November 1999 -- Make kernel-parameter implementation work with 2.3.x + * Removed init_module & cleanup_module in favor of + * module_init & module_exit. + * Torben Mathiasen + * * * TODO * implement "read all subchannel data" (96 bytes per frame) @@ -324,6 +329,7 @@ #include +#include #include #include #include @@ -5457,12 +5463,15 @@ static struct cdrom_device_info sbpcd_info = { * bytes above). * */ + #if (SBPCD_ISSUE-1) -static void __init sbpcd_setup(const char *s, int *p) +static int sbpcd_setup(char *s) #else -void __init sbpcd_setup(const char *s, int *p) +int sbpcd_setup(char *s) #endif { + int p[4]; + (void)get_options(s, ARRAY_SIZE(p), p); setup_done++; msg(DBG_INI,"sbpcd_setup called with %04X,%s\n",p[1], s); sbpro_type=0; /* default: "LaserMate" */ @@ -5494,7 +5503,13 @@ void __init sbpcd_setup(const char *s, int *p) } } else CDi_data=sbpcd_ioaddr+2; + + return 1; } + +__setup("sbpcd=", sbpcd_setup); + + /*==========================================================================*/ /* * Sequoia S-1000 CD-ROM Interface Configuration @@ -5569,7 +5584,7 @@ static int __init config_spea(void) * Called once at boot or load time. */ #ifdef MODULE -int init_module(void) +int __init __SBPCD_INIT(void) #else int __init SBPCD_INIT(void) #endif MODULE @@ -5616,7 +5631,7 @@ int __init SBPCD_INIT(void) else if (sbpcd[port_index+1]==1) type=str_sb; else if (sbpcd[port_index+1]==3) type=str_t16; else type=str_lm; - sbpcd_setup(type, addr); + sbpcd_setup((char *)type); #if DISTRIBUTION msg(DBG_INF,"Scanning 0x%X (%s)...\n", CDo_command, type); #endif DISTRIBUTION @@ -5808,7 +5823,7 @@ int __init SBPCD_INIT(void) } /*==========================================================================*/ #ifdef MODULE -void cleanup_module(void) +void sbpcd_exit(void) { int j; @@ -5833,6 +5848,14 @@ void cleanup_module(void) } msg(DBG_INF, "%s module released.\n", major_name); } + + +#ifdef MODULE +module_init(__SBPCD_INIT) /*HACK!*/; +#endif +module_exit(sbpcd_exit); + + #endif MODULE /*==========================================================================*/ /* diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c index b5edc20574c3..92bb0b736361 100644 --- a/drivers/cdrom/sjcd.c +++ b/drivers/cdrom/sjcd.c @@ -49,6 +49,10 @@ * the previous version of this driver. Coded added by Anthony Barbachan * from bugfix tip originally suggested by Alan Cox. * + * November 1999 -- Make kernel-parameter implementation work with 2.3.x + * Removed init_module & cleanup_module in favor of + * module_init & module_exit. + * Torben Mathiasen */ #define SJCD_VERSION_MAJOR 1 @@ -163,12 +167,21 @@ static int sjcd_cleanup(void); * Set up device, i.e., use command line data to set * base address. */ -void __init sjcd_setup( char *str, int *ints ) +#ifndef MODULE +static int __init sjcd_setup( char *str) { + int ints[2]; + (void)get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] > 0) sjcd_base = ints[1]; + + return 1; } +__setup("sjcd=", sjcd_setup); + +#endif + /* * Special converters. */ @@ -1577,18 +1590,18 @@ sjcd_cleanup(void) return(0); } -#ifdef MODULE - -int init_module(void) -{ - return sjcd_init(); -} -void cleanup_module(void) +void __exit sjcd_exit(void) { if ( sjcd_cleanup() ) printk( "SJCD: module: cannot be removed.\n" ); else printk(KERN_INFO "SJCD: module: removed.\n"); } + +#ifdef MODULE +module_init(sjcd_init); #endif +module_exit(sjcd_exit); + + diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c index 947277f3d219..10e693c47f96 100644 --- a/drivers/cdrom/sonycd535.c +++ b/drivers/cdrom/sonycd535.c @@ -31,6 +31,11 @@ * More changes to support CDU-510/515 series * (Claudio Porfiri) * + * November 1999 -- Make kernel-parameter implementation work with 2.3.x + * Removed init_module & cleanup_module in favor of + * module_init & module_exit. + * Torben Mathiasen + * * Things to do: * - handle errors and status better, put everything into a single word * - use interrupts (code mostly there, but a big hole still missing) @@ -1648,6 +1653,7 @@ sony535_init(void) } #ifndef MODULE + /* * accept "kernel command line" parameters * (added by emoenke@gwdg.de) @@ -1657,9 +1663,11 @@ sony535_init(void) * * the address value has to be the existing CDROM port address. */ -void __init -sonycd535_setup(char *strings, int *ints) +static int __init +sonycd535_setup(char *strings) { + int ints[3]; + (void)get_options(strings, ARRAY_SIZE(ints), ints); /* if IRQ change and default io base desired, * then call with io base of 0 */ @@ -1671,17 +1679,16 @@ sonycd535_setup(char *strings, int *ints) if ((strings != NULL) && (*strings != '\0')) printk(CDU535_MESSAGE_NAME ": Warning: Unknown interface type: %s\n", strings); + + return 1; } -#else /* MODULE */ +__setup("sonycd535=", sonycd535_setup); -int init_module(void) -{ - return sony535_init(); -} +#endif /* MODULE */ -void -cleanup_module(void) +void __exit +sony535_exit(void) { int i; @@ -1696,4 +1703,10 @@ cleanup_module(void) else printk(KERN_INFO CDU535_HANDLE " module released\n"); } -#endif /* MODULE */ + +#ifdef MODULE +module_init(sony535_init); +#endif +module_exit(sony535_exit); + + diff --git a/drivers/char/Config.in b/drivers/char/Config.in index b32ea52fe907..6417d954c705 100644 --- a/drivers/char/Config.in +++ b/drivers/char/Config.in @@ -214,7 +214,7 @@ if [ "$CONFIG_FTAPE" != "n" ]; then fi endmenu -bool 'Direct Rendering Manager (XFree86 DRI support) (EXPERIMENTAL)' CONFIG_DRM +bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM dep_tristate ' 3dfx Banshee/Voodoo3' CONFIG_DRM_TDFX $CONFIG_DRM if [ "$CONFIG_DRM" = "y" ]; then dep_tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA m diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 55d00d8233b7..70c013b7defb 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -27,6 +27,8 @@ #ifndef _AGP_BACKEND_PRIV_H #define _AGP_BACKEND_PRIV_H 1 +#include + enum aper_size_type { U8_APER_SIZE, U16_APER_SIZE, diff --git a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c index 72f87791a19c..eeb21921cbec 100644 --- a/drivers/char/agp/agpgart_be.c +++ b/drivers/char/agp/agpgart_be.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index e70b2d75e5e6..f4ccd6e52c7c 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -292,6 +292,8 @@ static struct dev_info device_list[] = {"MATSHITA","PD-2 LF-D100","*", BLIST_GHOST}, {"HITACHI", "GF-1050","*", BLIST_GHOST}, /* Hitachi SCSI DVD-RAM */ {"TOSHIBA","CDROM","*", BLIST_ISROM}, + {"Toshiba","DVD-RAM SD-W1101","*", BLIST_GHOST}, + {"Toshiba","DVD-RAM SD-W1111","*", BLIST_GHOST}, /* * Must be at end of list... diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h index eba0c14b7255..7f7683f623f6 100644 --- a/drivers/scsi/scsi.h +++ b/drivers/scsi/scsi.h @@ -619,9 +619,10 @@ struct scsi_cmnd { struct request request; /* A copy of the command we are working on */ - unsigned char sense_buffer[64]; /* obtained by REQUEST SENSE when - CHECK CONDITION is received on - original command (auto-sense) */ + unsigned char sense_buffer[64]; /* obtained by REQUEST SENSE + * when CHECK CONDITION is + * received on original command + * (auto-sense) */ unsigned flags; diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 1e5eb00c1d9a..d00b0f539911 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7,6 +7,7 @@ * anything out of the ordinary is seen. */ +#include #include #include diff --git a/drivers/scsi/scsi_merge.c b/drivers/scsi/scsi_merge.c index e31d1a7a436f..8182d0766e34 100644 --- a/drivers/scsi/scsi_merge.c +++ b/drivers/scsi/scsi_merge.c @@ -32,6 +32,7 @@ */ #define __NO_VERSION__ +#include #include #include diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ce9e28a41f1b..8e72fd092e55 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -314,7 +314,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) SCpnt->cmnd[1] = (SCpnt->lun << 5) & 0xe0; - if (((this_count > 0xff) || (block > 0x1fffff)) && SCpnt->device->ten) { + if (((this_count > 0xff) || (block > 0x1fffff)) || SCpnt->device->ten) { if (this_count > 0xffff) this_count = 0xffff; @@ -405,8 +405,9 @@ static int sd_open(struct inode *inode, struct file *filp) return -EROFS; } /* - * It is possible that the disk changing stuff resulted in the device being taken - * offline. If this is the case, report this to the user, and don't pretend that + * It is possible that the disk changing stuff resulted in the device + * being taken offline. If this is the case, report this to the user, + * and don't pretend that * the open actually succeeded. */ if (!rscsi_disks[target].device->online) { @@ -529,41 +530,50 @@ static void rw_intr(Scsi_Cmnd * SCpnt) /* Handle MEDIUM ERRORs that indicate partial success. Since this is a - relatively rare error condition, no care is taken to avoid unnecessary - additional work such as memcpy's that could be avoided. + relatively rare error condition, no care is taken to avoid + unnecessary additional work such as memcpy's that could be avoided. */ - if (driver_byte(result) != 0 && /* An error occurred */ - SCpnt->sense_buffer[0] == 0xF0 && /* Sense data is valid */ - SCpnt->sense_buffer[2] == MEDIUM_ERROR) { - long error_sector = (SCpnt->sense_buffer[3] << 24) | - (SCpnt->sense_buffer[4] << 16) | - (SCpnt->sense_buffer[5] << 8) | - SCpnt->sense_buffer[6]; - if (SCpnt->request.bh != NULL) - block_sectors = SCpnt->request.bh->b_size >> 9; - switch (SCpnt->device->sector_size) { - case 1024: - error_sector <<= 1; - if (block_sectors < 2) - block_sectors = 2; - break; - case 2048: - error_sector <<= 2; - if (block_sectors < 4) - block_sectors = 4; - break; - case 256: - error_sector >>= 1; - break; - default: - break; + /* An error occurred */ + if (driver_byte(result) != 0) { + /* Sense data is valid */ + if (SCpnt->sense_buffer[0] == 0xF0 && SCpnt->sense_buffer[2] == MEDIUM_ERROR) { + long error_sector = (SCpnt->sense_buffer[3] << 24) | + (SCpnt->sense_buffer[4] << 16) | + (SCpnt->sense_buffer[5] << 8) | + SCpnt->sense_buffer[6]; + if (SCpnt->request.bh != NULL) + block_sectors = SCpnt->request.bh->b_size >> 9; + switch (SCpnt->device->sector_size) { + case 1024: + error_sector <<= 1; + if (block_sectors < 2) + block_sectors = 2; + break; + case 2048: + error_sector <<= 2; + if (block_sectors < 4) + block_sectors = 4; + break; + case 256: + error_sector >>= 1; + break; + default: + break; + } + error_sector -= sd[MINOR(SCpnt->request.rq_dev)].start_sect; + error_sector &= ~(block_sectors - 1); + good_sectors = error_sector - SCpnt->request.sector; + if (good_sectors < 0 || good_sectors >= this_count) + good_sectors = 0; + } + if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) { + if (SCpnt->device->ten == 1) { + if (SCpnt->cmnd[0] == READ_10 || + SCpnt->cmnd[0] == WRITE_10) + SCpnt->device->ten = 0; + } } - error_sector -= sd[MINOR(SCpnt->request.rq_dev)].start_sect; - error_sector &= ~(block_sectors - 1); - good_sectors = error_sector - SCpnt->request.sector; - if (good_sectors < 0 || good_sectors >= this_count) - good_sectors = 0; } /* * This calls the generic completion function, now that we know @@ -597,10 +607,10 @@ static int check_scsidisk_media_change(kdev_t full_dev) return 0; /* - * If the device is offline, don't send any commands - just pretend as if - * the command failed. If the device ever comes back online, we can deal with - * it then. It is only because of unrecoverable errors that we would ever - * take a device offline in the first place. + * If the device is offline, don't send any commands - just pretend as + * if the command failed. If the device ever comes back online, we + * can deal with it then. It is only because of unrecoverable errors + * that we would ever take a device offline in the first place. */ if (rscsi_disks[target].device->online == FALSE) { rscsi_disks[target].ready = 0; @@ -618,10 +628,11 @@ static int check_scsidisk_media_change(kdev_t full_dev) */ retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_START_UNIT, 0); - if (retval) { /* Unable to test, unit probably not ready. This usually - * means there is no disc in the drive. Mark as changed, - * and we will figure it out later once the drive is - * available again. */ + if (retval) { /* Unable to test, unit probably not ready. + * This usually means there is no disc in the + * drive. Mark as changed, and we will figure + * it out later once the drive is available + * again. */ rscsi_disks[target].ready = 0; rscsi_disks[target].device->changed = 1; @@ -744,8 +755,12 @@ static int sd_init_onedisk(int i) } spintime = 1; spintime_value = jiffies; - time1 = jiffies + HZ; - while (time_before(jiffies, time1)); /* Wait 1 second for next try */ + time1 = HZ; + /* Wait 1 second for next try */ + do { + current->state = TASK_UNINTERRUPTIBLE; + time1 = schedule_timeout(time1); + } while(time1); printk("."); } } while (the_result && spintime && time_after(spintime_value + 100 * HZ, jiffies)); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d482a729478a..f196732bbae8 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -244,9 +244,12 @@ static void rw_intr(Scsi_Cmnd * SCpnt) static request_queue_t *sr_find_queue(kdev_t dev) { - if (MINOR(dev) >= sr_template.dev_max - || !scsi_CDs[MINOR(dev)].device) - return NULL; /* No such device */ + /* + * No such device + */ + if (MINOR(dev) >= sr_template.dev_max || !scsi_CDs[MINOR(dev)].device) + return NULL; + return &scsi_CDs[MINOR(dev)].device->request_queue; } @@ -328,13 +331,13 @@ static int sr_init_command(Scsi_Cmnd * SCpnt) SCpnt = scsi_end_request(SCpnt, 0, SCpnt->request.nr_sectors); return 0; } - SCpnt->cmnd[0] = WRITE_6; + SCpnt->cmnd[0] = WRITE_10; break; case READ: - SCpnt->cmnd[0] = READ_6; + SCpnt->cmnd[0] = READ_10; break; default: - panic("Unknown sd command %d\n", SCpnt->request.cmd); + panic("Unknown sr command %d\n", SCpnt->request.cmd); } SCSI_LOG_HLQUEUE(2, printk("sr%d : %s %d/%ld 512 byte blocks.\n", @@ -344,28 +347,16 @@ static int sr_init_command(Scsi_Cmnd * SCpnt) SCpnt->cmnd[1] = (SCpnt->lun << 5) & 0xe0; - if (((this_count > 0xff) || (block > 0x1fffff)) && SCpnt->device->ten) { - if (this_count > 0xffff) - this_count = 0xffff; - - SCpnt->cmnd[0] += READ_10 - READ_6; - SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; - SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; - SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; - SCpnt->cmnd[5] = (unsigned char) block & 0xff; - SCpnt->cmnd[6] = SCpnt->cmnd[9] = 0; - SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; - SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; - } else { - if (this_count > 0xff) - this_count = 0xff; - - SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); - SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff); - SCpnt->cmnd[3] = (unsigned char) block & 0xff; - SCpnt->cmnd[4] = (unsigned char) this_count; - SCpnt->cmnd[5] = 0; - } + if (this_count > 0xffff) + this_count = 0xffff; + + SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; + SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; + SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; + SCpnt->cmnd[5] = (unsigned char) block & 0xff; + SCpnt->cmnd[6] = SCpnt->cmnd[9] = 0; + SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; + SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; /* * We shouldn't disconnect in the middle of a sector, so with a dumb @@ -666,7 +657,6 @@ static int sr_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command Scsi_Device *device = scsi_CDs[MINOR(cdi->dev)].device; unsigned char *buffer = cgc->buffer; int buflen; - int stat; /* get the device */ SCpnt = scsi_allocate_device(device, 1); @@ -695,7 +685,8 @@ static int sr_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command scsi_wait_cmd(SCpnt, (void *) cgc->cmd, (void *) buffer, cgc->buflen, sr_init_done, SR_TIMEOUT, MAX_RETRIES); - stat = SCpnt->result; + if ((cgc->stat = SCpnt->result)) + cgc->sense = (struct request_sense *) SCpnt->sense_buffer; /* release */ SCpnt->request.rq_dev = MKDEV(0, 0); @@ -707,7 +698,9 @@ static int sr_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command memcpy(cgc->buffer, buffer, cgc->buflen); scsi_free(buffer, buflen); } - return stat; + + + return cgc->stat; } static int sr_registered = 0; diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index df963da1f97d..d3a649f4df36 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -56,7 +56,6 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen Scsi_Cmnd *SCpnt; Scsi_Device *SDev; int result, err = 0, retries = 0; - unsigned long flags; char *bounce_buffer; SDev = scsi_CDs[target].device; diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 5191847f971b..a9a66455d25b 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -7,6 +7,12 @@ MOD_SUB_DIRS := MOD_IN_SUB_DIRS := ALL_SUB_DIRS := +O_TARGET := video.o +O_OBJS := +M_OBJS := +# This is a nice idea but needs depmod altering +# MOD_LIST_NAME := VIDEO_MODULES + # All of the (potential) objects that export symbols. # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. @@ -96,27 +102,35 @@ obj-$(CONFIG_FBCON_MAC) += fbcon-mac.o obj-$(CONFIG_FBCON_MFB) += fbcon-mfb.o obj-$(CONFIG_FBCON_VGA) += fbcon-vga.o +# Extract lists of the multi-part drivers. +# The 'int-*' lists are the intermediate files used to build the multi's. + +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) + # Files that are both resident and modular: remove from modular. obj-m := $(filter-out $(obj-y), $(obj-m)) +int-m := $(filter-out $(int-y), $(int-m)) # Take multi-part drivers out of obj-y and put components in. -obj-y := $(filter-out $(list-multi), $(obj-y)) +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) # Translate to Rules.make lists. -L_TARGET := video.a -# This is a nice idea but needs depmod altering -#MOD_LIST_NAME := VIDEO_MODULES - -L_OBJS := $(sort $(filter-out $(export-objs), $(obj-y))) -LX_OBJS := $(sort $(filter $(export-objs), $(obj-y))) +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make +clean: + rm -f core *.o *.a *.s + promcon_tbl.c: prom.uni ../char/conmakehash ../char/conmakehash prom.uni | \ sed -e '/#include <[^>]*>/p' -e 's/types/init/' \ diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c index c979134b4a84..68515326b8e0 100644 --- a/fs/affs/symlink.c +++ b/fs/affs/symlink.c @@ -9,101 +9,19 @@ */ #include -#include -#include #include #include #include #include -#include +#include -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) - -static int affs_readlink(struct dentry *, char *, int); -static struct dentry *affs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int); - -struct inode_operations affs_symlink_inode_operations = { - NULL, /* no file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - affs_readlink, /* readlink */ - affs_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL /* revalidate */ -}; - -static int -affs_readlink(struct dentry *dentry, char *buffer, int buflen) +static int affs_symlink_readpage(struct dentry *dentry, struct page *page) { + struct buffer_head *bh; struct inode *inode = dentry->d_inode; - struct buffer_head *bh; - struct slink_front *lf; - int i, j; - char c; - char lc; - char *pf; - - pr_debug("AFFS: readlink(ino=%lu,buflen=%d)\n",inode->i_ino,buflen); - - bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode)); - if (!bh) { - affs_warning(inode->i_sb,"follow_link","Unable to read i-node block %lu\n", - inode->i_ino); - return -EIO; - } - lf = (struct slink_front *)bh->b_data; - lc = 0; - i = 0; - j = 0; - pf = inode->i_sb->u.affs_sb.s_prefix ? inode->i_sb->u.affs_sb.s_prefix : "/"; - - if (strchr(lf->symname,':')) { /* Handle assign or volume name */ - while (i < buflen && (c = pf[i])) { - put_user(c,buffer++); - i++; - } - while (i < buflen && (c = lf->symname[j]) != ':') { - put_user(c,buffer++); - i++, j++; - } - if (i < buflen) { - put_user('/',buffer++); - i++, j++; - } - lc = '/'; - } - while (i < buflen && (c = lf->symname[j])) { - if (c == '/' && lc == '/' && (i + 3 < buflen)) { /* parent dir */ - put_user('.',buffer++); - put_user('.',buffer++); - i += 2; - } - put_user(c,buffer++); - lc = c; - i++, j++; - } - affs_brelse(bh); - return i; -} - -static struct dentry * -affs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow) -{ - struct inode *inode = dentry->d_inode; - struct buffer_head *bh; - struct slink_front *lf; - char *buffer; + char *link = (char*)kmap(page); + struct slink_front *lf; + int err; int i, j; char c; char lc; @@ -111,47 +29,49 @@ affs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino); - if (!(buffer = kmalloc(1024,GFP_KERNEL))) { - dput(base); - return ERR_PTR(-ENOSPC); - } + err = -EIO; bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode)); - if (!bh) { - affs_warning(inode->i_sb,"follow_link","Unable to read i-node block %lu\n", - inode->i_ino); - kfree(buffer); - dput(base); - return ERR_PTR(-EIO); - } + if (!bh) + goto fail; i = 0; j = 0; lf = (struct slink_front *)bh->b_data; lc = 0; pf = inode->i_sb->u.affs_sb.s_prefix ? inode->i_sb->u.affs_sb.s_prefix : "/"; - if (strchr(lf->symname,':')) { /* Handle assign or volume name */ + if (strchr(lf->symname,':')) { /* Handle assign or volume name */ while (i < 1023 && (c = pf[i])) - buffer[i++] = c; + link[i++] = c; while (i < 1023 && lf->symname[j] != ':') - buffer[i++] = lf->symname[j++]; + link[i++] = lf->symname[j++]; if (i < 1023) - buffer[i++] = '/'; + link[i++] = '/'; j++; lc = '/'; } while (i < 1023 && (c = lf->symname[j])) { if (c == '/' && lc == '/' && i < 1020) { /* parent dir */ - buffer[i++] = '.'; - buffer[i++] = '.'; + link[i++] = '.'; + link[i++] = '.'; } - buffer[i++] = c; + link[i++] = c; lc = c; j++; } - buffer[i] = '\0'; + link[i] = '\0'; affs_brelse(bh); - base = lookup_dentry(buffer,base,follow); - kfree(buffer); - return base; + kunmap(page); + UnlockPage(page); + return 0; +fail: + SetPageError(page); + kunmap(page); + UnlockPage(page); + return err; } +struct inode_operations affs_symlink_inode_operations = { + readlink: page_readlink, + follow_link: page_follow_link, + readpage: affs_symlink_readpage, +}; diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index 2b3556995bb5..ad861b42b9fe 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c @@ -7,97 +7,48 @@ */ #include -#include #include +#include -static int efs_readlink(struct dentry *, char *, int); -static struct dentry * efs_follow_link(struct dentry *, struct dentry *, unsigned int); - -struct inode_operations efs_symlink_inode_operations = { - NULL, /* no symlink file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - efs_readlink, /* readlink */ - efs_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL /* revalidate */ -}; - -static char *efs_linktarget(struct inode *in, int *len) { - char *name; +static int efs_symlink_readpage(struct dentry *dentry, struct page *page) +{ + char *link = (char*)kmap(page); struct buffer_head * bh; - efs_block_t size = in->i_size; - - if (size > 2 * EFS_BLOCKSIZE) { - printk(KERN_ERR "EFS: linktarget(): name too long: %lu\n", in->i_size); - return NULL; - } + struct inode * inode = dentry->d_inode; + efs_block_t size = inode->i_size; + int err; - if (!(name = kmalloc(size + 1, GFP_KERNEL))) - return NULL; + err = -ENAMETOOLONG; + if (size > 2 * EFS_BLOCKSIZE) + goto fail; /* read first 512 bytes of link target */ - bh = bread(in->i_dev, efs_bmap(in, 0), EFS_BLOCKSIZE); - if (!bh) { - kfree(name); - printk(KERN_ERR "EFS: linktarget(): couldn't read block %d\n", efs_bmap(in, 0)); - return NULL; - } - - memcpy(name, bh->b_data, (size > EFS_BLOCKSIZE) ? EFS_BLOCKSIZE : size); + err = -EIO; + bh = bread(inode->i_dev, efs_bmap(inode, 0), EFS_BLOCKSIZE); + if (!bh) + goto fail; + memcpy(link, bh->b_data, (size > EFS_BLOCKSIZE) ? EFS_BLOCKSIZE : size); brelse(bh); - if (size > EFS_BLOCKSIZE) { - bh = bread(in->i_dev, efs_bmap(in, 1), EFS_BLOCKSIZE); - if (!bh) { - kfree(name); - printk(KERN_ERR "EFS: linktarget(): couldn't read block %d\n", efs_bmap(in, 1)); - return NULL; - } - memcpy(name + EFS_BLOCKSIZE, bh->b_data, size - EFS_BLOCKSIZE); + bh = bread(inode->i_dev, efs_bmap(inode, 1), EFS_BLOCKSIZE); + if (!bh) + goto fail; + memcpy(link + EFS_BLOCKSIZE, bh->b_data, size - EFS_BLOCKSIZE); brelse(bh); } - - name[size] = (char) 0; - if (len) *len = size; - - return name; -} - -static struct dentry *efs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow) { - char *name; - struct inode *inode = dentry->d_inode; - - if (!(name = efs_linktarget(inode, NULL))) { - dput(base); - return ERR_PTR(-ELOOP); - } - base = lookup_dentry(name, base, follow); - kfree(name); - - return base; -} - -static int efs_readlink(struct dentry * dir, char * buf, int bufsiz) { - int rc; - char *name; - struct inode *inode = dir->d_inode; - - if (!(name = efs_linktarget(inode, &bufsiz))) return 0; - rc = copy_to_user(buf, name, bufsiz) ? -EFAULT : bufsiz; - kfree(name); - - return rc; + link[size] = '\0'; + kunmap(page); + UnlockPage(page); + return 0; +fail: + SetPageError(page); + kunmap(page); + UnlockPage(page); + return err; } +struct inode_operations efs_symlink_inode_operations = { + readlink: page_readlink, + follow_link: page_follow_link, + readpage: efs_symlink_readpage +}; diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c index d7abdc991f7f..9632c054c57f 100644 --- a/fs/hpfs/ea.c +++ b/fs/hpfs/ea.c @@ -69,8 +69,64 @@ static void set_indirect_ea(struct super_block *s, int ano, secno a, char *data, hpfs_ea_write(s, a, ano, 0, size, data); } -/* Read an extended attribute named 'key' */ +/* Read an extended attribute named 'key' into the provided buffer */ +int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, + char *buf, int size) +{ + unsigned pos; + int ano, len; + secno a; + struct extended_attribute *ea; + struct extended_attribute *ea_end = fnode_end_ea(fnode); + for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) + if (!strcmp(ea->name, key)) { + if (ea->indirect) + goto indirect; + if (ea->valuelen >= size) + return -EINVAL; + memcpy(buf, ea_data(ea), ea->valuelen); + buf[ea->valuelen] = 0; + return 0; + } + a = fnode->ea_secno; + len = fnode->ea_size_l; + ano = fnode->ea_anode; + pos = 0; + while (pos < len) { + char ex[4 + 255 + 1 + 8]; + ea = (struct extended_attribute *)ex; + if (pos + 4 > len) { + hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x", + ano ? "anode" : "sectors", a, len); + return -EIO; + } + if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO; + if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4)) + return -EIO; + if (!strcmp(ea->name, key)) { + if (ea->indirect) + goto indirect; + if (ea->valuelen >= size) + return -EINVAL; + if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, buf)) + return -EIO; + buf[ea->valuelen] = 0; + return 0; + } + pos += ea->namelen + ea->valuelen + 5; + } + return -ENOENT; +indirect: + if (ea_len(ea) >= size) + return -EINVAL; + if (hpfs_ea_read(s, ea_sec(ea), ea->anode, 0, ea_len(ea), buf)) + return -EIO; + buf[ea_len(ea)] = 0; + return 0; +} + +/* Read an extended attribute named 'key' */ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *size) { char *ret; diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 79bfb106cd99..8abaf2fd39e2 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -96,7 +96,7 @@ static int hpfs_write_partial_page(struct file *file, struct page *page, unsigne pgpos = ((inode->i_blocks - 1) * 512) >> PAGE_CACHE_SHIFT; while (pgpos < page->index) { status = -ENOMEM; - new_page = grab_page_cache(&inode->i_data, pgpos); + new_page = grab_cache_page(&inode->i_data, pgpos); if (!new_page) goto out; status = block_write_cont_page(file, new_page, PAGE_SIZE, 0, NULL); diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 9ae4a67da673..377b296e8c62 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h @@ -249,6 +249,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *, fnode_secno, struct f /* ea.c */ void hpfs_ea_ext_remove(struct super_block *, secno, int, unsigned); +int hpfs_read_ea(struct super_block *, struct fnode *, char *, char *, int); char *hpfs_get_ea(struct super_block *, struct fnode *, char *, int *); void hpfs_set_ea(struct inode *, struct fnode *, char *, char *, int); @@ -283,10 +284,6 @@ struct anode *hpfs_map_anode(struct super_block *s, anode_secno, struct buffer_h struct dnode *hpfs_map_dnode(struct super_block *s, dnode_secno, struct quad_buffer_head *); dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino); -/* mmap.c */ - -int hpfs_mmap(struct file *, struct vm_area_struct *); - /* name.c */ unsigned char hpfs_upcase(unsigned char *, unsigned char); @@ -305,8 +302,7 @@ int hpfs_mknod(struct inode *, struct dentry *, int, int); int hpfs_symlink(struct inode *, struct dentry *, const char *); int hpfs_unlink(struct inode *, struct dentry *); int hpfs_rmdir(struct inode *, struct dentry *); -int hpfs_readlink(struct dentry *, char *, int); -struct dentry *hpfs_follow_link(struct dentry *, struct dentry *, unsigned int); +int hpfs_symlink_readpage(struct dentry *, struct page *); int hpfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); /* super.c */ diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 4acf7b0e209d..e4167bfdc6c8 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c @@ -16,7 +16,7 @@ static const struct file_operations hpfs_file_ops = NULL, /* readdir - bad */ NULL, /* poll - default */ NULL, /* ioctl - default */ - generic_file_mmap/*hpfs_mmap*/, /* mmap */ + generic_file_mmap, /* mmap */ hpfs_open, /* open */ NULL, /* flush */ hpfs_file_release, /* release */ @@ -92,27 +92,11 @@ static const struct inode_operations hpfs_dir_iops = const struct inode_operations hpfs_symlink_iops = { - NULL, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - hpfs_readlink, /* readlink */ - hpfs_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL /* revalidate */ + readlink: page_readlink, + follow_link: page_follow_link, + readpage: hpfs_symlink_readpage }; - void hpfs_read_inode(struct inode *i) { struct buffer_head *bh; diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index fe9b66e3da88..85ce143dbd83 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -396,54 +396,33 @@ int hpfs_rmdir(struct inode *dir, struct dentry *dentry) return r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0; } -int hpfs_readlink(struct dentry *dentry, char *buf, int len) +int hpfs_symlink_readpage(struct dentry *dentry, struct page *page) { + char *link = (char*)kmap(page); struct inode *i = dentry->d_inode; struct fnode *fnode; struct buffer_head *bh; - char *symlink; - int slen; - if (!S_ISLNK(i->i_mode)) { - return -EINVAL; - } - if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { - return -EIO; - } - if (!(symlink = hpfs_get_ea(i->i_sb, fnode, "SYMLINK", &slen))) { - brelse(bh); - return -EFSERROR; - } - brelse(bh); - if (slen > len) slen = len; - memcpy_tofs(buf, symlink, slen); - kfree(symlink); - return slen; -} + int err; -struct dentry *hpfs_follow_link(struct dentry *dinode, struct dentry *ddir, - unsigned int follow) -{ - struct inode *inode = dinode->d_inode; - char *link; - unsigned len; - struct buffer_head *bh; - struct fnode *fnode; - if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) { - dput(dinode); - return ERR_PTR(-EIO); - } - if (!(link = hpfs_get_ea(inode->i_sb, fnode, "SYMLINK", &len))) { - brelse(bh); - dput(dinode); - return ERR_PTR(-EIO); - } + err = -EIO; + if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) + goto fail; + err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE); brelse(bh); - UPDATE_ATIME(inode); - ddir = lookup_dentry(link, ddir, follow); - kfree(link); - return ddir; -} + if (err) + goto fail; + SetPageUptodate(page); + kunmap(page); + UnlockPage(page); + return 0; +fail: + SetPageError(page); + kunmap(page); + UnlockPage(page); + return err; +} + int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 03235f22f7cd..814d90b3c63e 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "rock.h" @@ -387,142 +388,155 @@ int parse_rock_ridge_inode(struct iso_directory_record * de, return 0; } +static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr) +{ + int slen; + int rootflag; + struct SL_component *oldslp; + struct SL_component *slp; + slen = rr->len - 5; + slp = &rr->u.SL.link; + while (slen > 1) { + rootflag = 0; + switch (slp->flags & ~1) { + case 0: + memcpy(rpnt, slp->text, slp->len); + rpnt+=slp->len; + break; + case 4: + *rpnt++='.'; + /* fallthru */ + case 2: + *rpnt++='.'; + break; + case 8: + rootflag = 1; + *rpnt++='/'; + break; + default: + printk("Symlink component flag not implemented (%d)\n", + slp->flags); + } + slen -= slp->len + 2; + oldslp = slp; + slp = (struct SL_component *) ((char *) slp + slp->len + 2); + + if (slen < 2) { + /* + * If there is another SL record, and this component + * record isn't continued, then add a slash. + */ + if ((rr->u.SL.flags & 1) && !(oldslp->flags & 1)) + *rpnt++='/'; + break; + } + + /* + * If this component record isn't continued, then append a '/'. + */ + if (!rootflag && !(oldslp->flags & 1)) + *rpnt++='/'; -/* Returns the name of the file that this inode is symlinked to. This is - in malloc'd memory, so it needs to be freed, once we are through with it */ + } + return rpnt; +} -char * get_rock_ridge_symlink(struct inode * inode) -{ - unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); - unsigned char bufbits = ISOFS_BUFFER_BITS(inode); - struct buffer_head * bh; - char * rpnt = NULL; - unsigned char * pnt; - struct iso_directory_record * raw_inode; - CONTINUE_DECLS; - int block; - int sig; - int rootflag; - int len; - unsigned char * chr; - struct rock_ridge * rr; - - if (!inode->i_sb->u.isofs_sb.s_rock) - panic("Cannot have symlink with high sierra variant of iso filesystem\n"); - block = inode->i_ino >> bufbits; - bh = bread(inode->i_dev, block, bufsize); - if (!bh) - goto out_noread; - - pnt = ((unsigned char *) bh->b_data) + (inode->i_ino & (bufsize - 1)); - - raw_inode = ((struct iso_directory_record *) pnt); - - /* - * If we go past the end of the buffer, there is some sort of error. - */ - if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize) - goto out_bad_span; - - /* Now test for possible Rock Ridge extensions which will override some of - these numbers in the inode structure. */ - - SETUP_ROCK_RIDGE(raw_inode, chr, len); - - repeat: - while (len > 1){ /* There may be one byte for padding somewhere */ - rr = (struct rock_ridge *) chr; - if (rr->len == 0) goto out; /* Something got screwed up here */ - sig = (chr[0] << 8) + chr[1]; - chr += rr->len; - len -= rr->len; - - switch(sig){ - case SIG('R','R'): - if((rr->u.RR.flags[0] & RR_SL) == 0) goto out; - break; - case SIG('S','P'): - CHECK_SP(goto out); - break; - case SIG('S','L'): - {int slen; - struct SL_component * oldslp; - struct SL_component * slp; - slen = rr->len - 5; - slp = &rr->u.SL.link; - while (slen > 1){ - if (!rpnt){ - rpnt = (char *) kmalloc (inode->i_size +1, GFP_KERNEL); - if (!rpnt) goto out; - *rpnt = 0; - }; - rootflag = 0; - switch(slp->flags &~1){ - case 0: - strncat(rpnt,slp->text, slp->len); - break; - case 2: - strcat(rpnt,"."); - break; - case 4: - strcat(rpnt,".."); - break; - case 8: - rootflag = 1; - strcat(rpnt,"/"); - break; - default: - printk("Symlink component flag not implemented (%d)\n",slen); - }; - slen -= slp->len + 2; - oldslp = slp; - slp = (struct SL_component *) (((char *) slp) + slp->len + 2); - - if(slen < 2) { - /* - * If there is another SL record, and this component record - * isn't continued, then add a slash. - */ - if( ((rr->u.SL.flags & 1) != 0) - && ((oldslp->flags & 1) == 0) ) strcat(rpnt,"/"); - break; - } +/* readpage() for symlinks: reads symlink contents into the page and either + makes it uptodate and returns 0 or returns error (-EIO) */ - /* - * If this component record isn't continued, then append a '/'. - */ - if( (!rootflag) - && ((oldslp->flags & 1) == 0) ) strcat(rpnt,"/"); - - }; - break; - case SIG('C','E'): - CHECK_CE; /* This tells is if there is a continuation record */ - break; - default: - break; - } - }; - }; - MAYBE_CONTINUE(repeat,inode); - -out_freebh: +int rock_ridge_symlink_readpage(struct dentry *dentry, struct page *page) +{ + struct inode *inode = dentry->d_inode; + char *link = (char*)kmap(page); + unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); + unsigned char bufbits = ISOFS_BUFFER_BITS(inode); + struct buffer_head *bh; + char *rpnt = link; + unsigned char *pnt; + struct iso_directory_record *raw_inode; + CONTINUE_DECLS; + int block; + int sig; + int len; + unsigned char *chr; + struct rock_ridge *rr; + + if (!inode->i_sb->u.isofs_sb.s_rock) + panic ("Cannot have symlink with high sierra variant of iso filesystem\n"); + + block = inode->i_ino >> bufbits; + bh = bread(inode->i_dev, block, bufsize); + if (!bh) + goto out_noread; + + pnt = (unsigned char *) bh->b_data + (inode->i_ino & (bufsize - 1)); + + raw_inode = (struct iso_directory_record *) pnt; + + /* + * If we go past the end of the buffer, there is some sort of error. + */ + if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize) + goto out_bad_span; + + /* Now test for possible Rock Ridge extensions which will override + some of these numbers in the inode structure. */ + + SETUP_ROCK_RIDGE(raw_inode, chr, len); + + repeat: + while (len > 1) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *) chr; + if (rr->len == 0) + goto out; /* Something got screwed up here */ + sig = (chr[0] << 8) + chr[1]; + chr += rr->len; + len -= rr->len; + + switch (sig) { + case SIG('R', 'R'): + if ((rr->u.RR.flags[0] & RR_SL) == 0) + goto out; + break; + case SIG('S', 'P'): + CHECK_SP(goto out); + break; + case SIG('S', 'L'): + rpnt = get_symlink_chunk(rpnt, rr); + break; + case SIG('C', 'E'): + /* This tells is if there is a continuation record */ + CHECK_CE; + default: + break; + } + } + MAYBE_CONTINUE(repeat, inode); + + if (rpnt == link) + goto fail; brelse(bh); - return rpnt; + *rpnt = '\0'; + SetPageUptodate(page); + kunmap(page); + UnlockPage(page); + return 0; /* error exit from macro */ -out: - if(buffer) + out: + if (buffer) kfree(buffer); - if(rpnt) - kfree(rpnt); - rpnt = NULL; - goto out_freebh; -out_noread: + goto fail; + out_noread: printk("unable to read i-node block"); - goto out_freebh; -out_bad_span: + goto fail; + out_bad_span: printk("symlink spans iso9660 blocks\n"); - goto out_freebh; + fail: + brelse(bh); + SetPageError(page); + kunmap(page); + UnlockPage(page); + return -EIO; } diff --git a/fs/isofs/symlink.c b/fs/isofs/symlink.c index e4e0fb837e49..219a4b9ac998 100644 --- a/fs/isofs/symlink.c +++ b/fs/isofs/symlink.c @@ -17,70 +17,11 @@ #include #include -#include - -static int isofs_readlink(struct dentry *, char *, int); -static struct dentry * isofs_follow_link(struct dentry *, struct dentry *, unsigned int); - /* * symlinks can't do much... */ struct inode_operations isofs_symlink_inode_operations = { - NULL, /* no file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - isofs_readlink, /* readlink */ - isofs_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL /* revalidate */ + readlink: page_readlink, + follow_link: page_follow_link, + readpage: rock_ridge_symlink_readpage }; - -static int isofs_readlink(struct dentry * dentry, char * buffer, int buflen) -{ - char * pnt; - int i; - - if (buflen > 1023) - buflen = 1023; - pnt = get_rock_ridge_symlink(dentry->d_inode); - - if (!pnt) - return 0; - - i = strlen(pnt); - if (i > buflen) - i = buflen; - if (copy_to_user(buffer, pnt, i)) - i = -EFAULT; - kfree(pnt); - return i; -} - -static struct dentry * isofs_follow_link(struct dentry * dentry, - struct dentry *base, - unsigned int follow) -{ - char * pnt; - - pnt = get_rock_ridge_symlink(dentry->d_inode); - if(!pnt) { - dput(base); - return ERR_PTR(-ELOOP); - } - - base = lookup_dentry(pnt, base, follow); - - kfree(pnt); - return base; -} diff --git a/fs/namei.c b/fs/namei.c index 1aac7fb0cebd..95ee1c127ae7 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -284,7 +284,7 @@ static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry if ((follow & LOOKUP_FOLLOW) && inode && inode->i_op && inode->i_op->follow_link) { - if (current->link_count < 5) { + if (current->link_count < 32) { struct dentry * result; current->link_count++; @@ -1437,9 +1437,9 @@ out: return len; } -struct dentry * -vfs_follow_link(struct dentry *dentry, struct dentry *base, -unsigned int follow, char *link) +static inline struct dentry * +__vfs_follow_link(struct dentry *dentry, struct dentry *base, + unsigned follow, char *link) { struct dentry *result; UPDATE_ATIME(dentry->d_inode); @@ -1455,6 +1455,13 @@ fail: return (struct dentry *)link; } +struct dentry * +vfs_follow_link(struct dentry *dentry, struct dentry *base, +unsigned int follow, char *link) +{ + return __vfs_follow_link(dentry,base,follow,link); +} + /* get the link contents into pagecache */ static char *page_getlink(struct dentry * dentry, struct page **ppage) { @@ -1495,7 +1502,7 @@ page_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow { struct page *page = NULL; char *s = page_getlink(dentry, &page); - struct dentry *res = vfs_follow_link(dentry,base,follow,s); + struct dentry *res = __vfs_follow_link(dentry,base,follow,s); if (page) { kunmap(page); page_cache_release(page); diff --git a/fs/ncpfs/symlink.c b/fs/ncpfs/symlink.c index 58786a8da97e..6db4bafcc435 100644 --- a/fs/ncpfs/symlink.c +++ b/fs/ncpfs/symlink.c @@ -38,152 +38,69 @@ #define NCP_SYMLINK_MAGIC0 le32_to_cpu(0x6c6d7973) /* "symlnk->" */ #define NCP_SYMLINK_MAGIC1 le32_to_cpu(0x3e2d6b6e) -static int ncp_readlink(struct dentry *, char *, int); -static struct dentry *ncp_follow_link(struct dentry *, struct dentry *, unsigned int); int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,int attributes); -/* - * symlinks can't do much... - */ -struct inode_operations ncp_symlink_inode_operations={ - NULL, /* no file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - ncp_readlink, /* readlink */ - ncp_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL /* revalidate */ -}; - -/* ----- follow a symbolic link ------------------------------------------ */ +/* ----- read a symbolic link ------------------------------------------ */ -static struct dentry *ncp_follow_link(struct dentry *dentry, - struct dentry *base, - unsigned int follow) +static int ncp_symlink_readpage(struct dentry *dentry, struct page *page) { struct inode *inode=dentry->d_inode; int error, length, len, cnt; - char *link, *buf; - -#ifdef DEBUG - PRINTK("ncp_follow_link(dentry=%p,base=%p,follow=%u)\n",dentry,base,follow); -#endif - - if(!S_ISLNK(inode->i_mode)) { - dput(base); - return ERR_PTR(-EINVAL); - } + char *link; + char *buf = (char*)kmap(page); - if(ncp_make_open(inode,O_RDONLY)) { - dput(base); - return ERR_PTR(-EIO); - } + error = -EIO; + if (ncp_make_open(inode,O_RDONLY)) + goto fail; + error = -ENOMEM; for (cnt = 0; (link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE, GFP_NFS))==NULL; cnt++) { - if (cnt > 10) { - dput(base); - return ERR_PTR(-EAGAIN); /* -ENOMEM? */ - } + if (cnt > 10) + goto fail; schedule(); } error=ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle, 0,NCP_MAX_SYMLINK_SIZE,link,&length); - if (error!=0 || lengthd_inode; - char *link, *buf; - int length, len, error; - -#ifdef DEBUG - PRINTK("ncp_readlink(dentry=%p,buffer=%p,buflen=%d)\n",dentry,buffer,buflen); -#endif - - if(!S_ISLNK(inode->i_mode)) - return -EINVAL; - - if(ncp_make_open(inode,O_RDONLY)) - return -EIO; - - if((link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE,GFP_NFS))==NULL) - return -ENOMEM; - - error = ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle, - 0,NCP_MAX_SYMLINK_SIZE,link,&length); - - if (error!=0 || length < NCP_MIN_SYMLINK_SIZE || buflen < (length-8) || - ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 ||((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) { - error = -EIO; - goto out; + goto fail; } len = NCP_MAX_SYMLINK_SIZE; - buf = (char *) kmalloc(len, GFP_NFS); - if (!buf) { - error = -ENOMEM; - goto out; - } error = ncp_vol2io(NCP_SERVER(inode), buf, &len, link+8, length-8, 0); - if (error || buflen < len) { - error = -EIO; - kfree(buf); - goto out; - } - - error = len; - if(copy_to_user(buffer, buf, error)) - error = -EFAULT; - kfree(buf); - -out: kfree(link); + if (error) + goto fail; + kunmap(page); + UnlockPage(page); + return 0; + +fail: + SetPageError(page); + kunmap(page); + UnlockPage(page); return error; } +/* + * symlinks can't do much... + */ +struct inode_operations ncp_symlink_inode_operations={ + readlink: page_readlink, + follow_link: page_follow_link, + readpage: ncp_symlink_readpage, +}; + /* ----- create a new symbolic link -------------------------------------- */ int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { diff --git a/fs/umsdos/symlink.c b/fs/umsdos/symlink.c index f6614595ab18..7bcd09e4421f 100644 --- a/fs/umsdos/symlink.c +++ b/fs/umsdos/symlink.c @@ -5,141 +5,18 @@ * inspired from linux/fs/msdos/file.c Werner Almesberger * * Extended MS-DOS regular file handling primitives + * + * Wow. It looks like we could support them on FAT with little (if any) + * problems. Oh, well... */ -#include #include #include -#include -#include -#include -#include -#include - -#include -#include - -static struct file_operations umsdos_symlink_operations; - - -/* - * Read the data associate with the symlink. - * Return length read in buffer or a negative error code. - * - */ - -int umsdos_readlink_x ( struct dentry *dentry, - char *buffer, - int bufsiz) -{ - size_t size = dentry->d_inode->i_size; - loff_t loffs = 0; - ssize_t ret; - struct file filp; - -Printk((KERN_DEBUG "UMSDOS_read: %s/%s, size=%u\n", -dentry->d_parent->d_name.name, dentry->d_name.name, size)); - - fill_new_filp (&filp, dentry); - filp.f_reada = 0; - filp.f_flags = O_RDONLY; - filp.f_op = &umsdos_symlink_operations; - - if (size > bufsiz) - size = bufsiz; - - ret = fat_file_read (&filp, buffer, size, &loffs); - if (ret != size) { - ret = -EIO; - } - return ret; -} - - - -static int UMSDOS_readlink (struct dentry *dentry, char *buffer, int buflen) -{ - return umsdos_readlink_x (dentry, buffer, buflen); -} - -/* this one mostly stolen from romfs :) */ -static struct dentry *UMSDOS_followlink (struct dentry *dentry, - struct dentry *base, - unsigned int follow) -{ - struct inode *inode = dentry->d_inode; - char *symname; - int len, cnt; - mm_segment_t old_fs = get_fs (); - -Printk((KERN_DEBUG "UMSDOS_followlink /mn/: (%s/%s)\n", -dentry->d_parent->d_name.name, dentry->d_name.name)); - - len = inode->i_size; - - if (!(symname = kmalloc (len + 1, GFP_KERNEL))) { - dentry = ERR_PTR (-ENOMEM); - goto outnobuf; - } - - set_fs (KERNEL_DS); /* we read into kernel space this time */ - cnt = umsdos_readlink_x (dentry, symname, len); - set_fs (old_fs); - - if (len != cnt) { - dentry = ERR_PTR (-EIO); - goto out; - } - - symname[len] = 0; - dentry = lookup_dentry (symname, base, follow); - kfree (symname); - - if (0) { - out: - kfree (symname); - outnobuf: - dput (base); - } - return dentry; -} - -/* needed to patch the file structure */ -static struct file_operations umsdos_symlink_operations = -{ - NULL, /* lseek - default */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir - bad */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open is needed */ - NULL, /* no flush code */ - NULL, /* release */ - NULL /* fsync */ -}; - struct inode_operations umsdos_symlink_inode_operations = { - NULL, /* default file operations (none) */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - UMSDOS_readlink, /* readlink */ - UMSDOS_followlink, /* followlink */ - fat_get_block, /* get_block */ - block_read_full_page, /* readpage */ - NULL, /* writepage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL /* revalidate */ + readlink: page_readlink, + follow_link: page_follow_link, + get_block: fat_get_block, + readpage: block_read_full_page }; - diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index 48cb099b71f5..5cf17b846b9a 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -88,6 +88,8 @@ extern inline void spin_unlock(spinlock_t *lock) #if SPINLOCK_DEBUG if (lock->magic != SPINLOCK_MAGIC) BUG(); + if (!lock->lock) + BUG(); #endif __asm__ __volatile__( spin_unlock_string diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index 7b48a5be8237..b125ee4d69dc 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -12,6 +12,7 @@ #define _LINUX_CDROM_H #include +#include /******************************************************* * As of Linux 2.1.x, all Linux CD-ROM application programs will use this @@ -269,11 +270,12 @@ struct cdrom_blk /* for CDROM_PACKET_COMMAND ioctl */ struct cdrom_generic_command { - unsigned char cmd[CDROM_PACKET_SIZE]; - unsigned char *buffer; - unsigned int buflen; - int stat; - void *reserved[4]; + unsigned char cmd[CDROM_PACKET_SIZE]; + unsigned char *buffer; + unsigned int buflen; + int stat; + struct request_sense *sense; + void *reserved[3]; }; @@ -646,6 +648,7 @@ struct dvd_lu_send_asf { }; struct dvd_host_send_rpcstate { + __u8 type; __u8 pdrc; }; @@ -671,6 +674,36 @@ typedef union { struct dvd_lu_send_rpcstate lrpcs; } dvd_authinfo; +struct request_sense { +#if defined(__BIG_ENDIAN_BITFIELD) + __u8 valid : 1; + __u8 error_code : 7; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + __u8 error_code : 7; + __u8 valid : 1; +#endif + __u8 segment_number; +#if defined(__BIG_ENDIAN_BITFIELD) + __u8 reserved1 : 2; + __u8 ili : 1; + __u8 reserved2 : 1; + __u8 sense_key : 4; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + __u8 sense_key : 4; + __u8 reserved2 : 1; + __u8 ili : 1; + __u8 reserved1 : 2; +#endif + __u8 information[4]; + __u8 add_sense_len; + __u8 command_info[4]; + __u8 asc; + __u8 ascq; + __u8 fruc; + __u8 sks[3]; + __u8 asb[46]; +}; + #ifdef __KERNEL__ struct cdrom_write_settings { diff --git a/include/linux/fs.h b/include/linux/fs.h index f94cd91a356b..63f1e9aa5b0f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -62,6 +62,7 @@ extern int max_super_blocks, nr_super_blocks; #define READ 0 #define WRITE 1 #define READA 2 /* read-ahead - don't block if no resources */ +#define SPECIAL 4 /* For non-blockdevice requests in request queue */ #define WRITERAW 5 /* raw write - don't play with buffer lists */ diff --git a/include/linux/iso_fs.h b/include/linux/iso_fs.h index e5b3a3d7b3b3..80a8b27f42aa 100644 --- a/include/linux/iso_fs.h +++ b/include/linux/iso_fs.h @@ -178,7 +178,7 @@ extern int iso_date(char *, int); extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *); extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *); -extern char * get_rock_ridge_symlink(struct inode *); +extern int rock_ridge_symlink_readpage(struct dentry *, struct page *); extern int find_rock_ridge_relocation(struct iso_directory_record *, struct inode *); int get_joliet_filename(struct iso_directory_record *, struct inode *, unsigned char *); diff --git a/kernel/fork.c b/kernel/fork.c index 462373b21e5e..e1cfb235722d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -320,7 +320,6 @@ struct mm_struct * mm_alloc(void) mmlist_modify_unlock(); return mm; } - mmlist_modify_unlock(); kmem_cache_free(mm_cachep, mm); } return NULL; -- 2.39.5