]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.32pre4 2.3.32pre4
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:29:14 +0000 (15:29 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:29:14 +0000 (15:29 -0500)
48 files changed:
CREDITS
Makefile
arch/i386/defconfig
arch/i386/kernel/smpboot.c
arch/i386/mm/init.c
drivers/block/ide-cd.c
drivers/block/ide-cd.h
drivers/cdrom/aztcd.c
drivers/cdrom/cdrom.c
drivers/cdrom/cdu31a.c
drivers/cdrom/cm206.c
drivers/cdrom/gscd.c
drivers/cdrom/isp16.c
drivers/cdrom/isp16.h
drivers/cdrom/mcd.c
drivers/cdrom/mcdx.c
drivers/cdrom/optcd.c
drivers/cdrom/sbpcd.c
drivers/cdrom/sjcd.c
drivers/cdrom/sonycd535.c
drivers/char/Config.in
drivers/char/agp/agp.h
drivers/char/agp/agpgart_be.c
drivers/scsi/scsi.c
drivers/scsi/scsi.h
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_merge.c
drivers/scsi/sd.c
drivers/scsi/sr.c
drivers/scsi/sr_ioctl.c
drivers/video/Makefile
fs/affs/symlink.c
fs/efs/symlink.c
fs/hpfs/ea.c
fs/hpfs/file.c
fs/hpfs/hpfs_fn.h
fs/hpfs/inode.c
fs/hpfs/namei.c
fs/isofs/rock.c
fs/isofs/symlink.c
fs/namei.c
fs/ncpfs/symlink.c
fs/umsdos/symlink.c
include/asm-i386/spinlock.h
include/linux/cdrom.h
include/linux/fs.h
include/linux/iso_fs.h
kernel/fork.c

diff --git a/CREDITS b/CREDITS
index aa16a443ce00759ee4f54b275acc2f94362b0cff..c4969b9e913ac960156efd38a2b383c06c0be9e0 100644 (file)
--- 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
index 5c26884b20bbcf647583d6c72299f3806f6ba6e3..eade2313a8ac2843bbb2a47daf1428077f1a3ad9 100644 (file)
--- 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)
index 206cad096e1ceb5c82aa6944c22414fdb1b889c0..9157103958df8030272437e674eebb811f4610b4 100644 (file)
@@ -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
index 811f00f387e9768111ea46b8f6509050be6618a4..fcc851043cf30bd73a63cc4cf105624eb16da236 100644 (file)
@@ -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);
        /*
index 7ff12d210739051e0a7199cae2a1d8e2d4bcf1a8..55d3553e11a47e5888488e538d6f290e51d99f6b 100644 (file)
@@ -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)
index 4a058db7f42bffc9c45fa2f04bfd7093a9f84969..6b71cd7bfdf49ba353792b2eedae912e58edd41e 100644 (file)
@@ -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 {
index b65baa5fe513955c76abc586feac55db1931ae58..8891205edd3a77d2330cb9d5e76a7c80aca2b81f 100644 (file)
@@ -7,6 +7,7 @@
  *  Copyright (C) 1998, 1999 Jens Axboe
  */
 
+#include <linux/cdrom.h>
 #include <asm/byteorder.h>
 
 /* 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 <asm/byteorder.h>"
-#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 <asm/byteorder.h>"
-#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;
index e548170a0da2b82eb31bd14eb4aa35ba74eeb09a..d560fa6a41f9f04fc6da497125da3bed0825d05e 100644 (file)
        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 <tmm@image.dk>
 */
 
 #include <linux/version.h>
@@ -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);
 }
-
-
index c0383af8d9d3098790451d41ee48af5c0007fc2e..d952ecf4bb008d182cbdf59455ca7a9e10e8ff7b 100644 (file)
   -- 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 <axboe@image.dk>
+  -- 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;
                }
index 8e4a8536bc3e83403b089162d82934d17919c220..24e7a5c26197c09324ef4c8704afaea00f327154 100644 (file)
  *                   <kodis@jagunet.com>.  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 <tmm@image.dk>
 */
 
 #include <linux/major.h>
@@ -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);
+
index edb0ab34ae198864ce5ec53c981383c850602f11..e600d81d0d1a5c49063f7e913af5af5412cf166a 100644 (file)
@@ -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 <tmm@image.dk>
  * 
  * 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"
index 7913f7f0db900a1485d54fc227352367bd728e8f..a305c14434fbca357a8d7828a41da71c0cbf0302 100644 (file)
        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 <tmm@image.dk>
 
 */
 
@@ -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. */
index 7b070170749ac8eeadbd5a4bf2fd16786e403000..c2859f450f9879313cc7f970fd8720a81a795b6a 100644 (file)
  *        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 <tmm@image.dk>
+ *
  *    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 __ini
-isp16_setup(char *str, int *ints)
+static in
+__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);
+
+
index 9945bb34c451f14b196034c7bb5d56d6775c50be..7fc74b8e49f1112c9341b7a586896bea919add29 100644 (file)
@@ -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);
index c8adc0200b91d743ab3d3afc063dab069a2a00db..cbb2a27cd9abe858cc82fd637202b9c070706e70 100644 (file)
 
        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 <tmm@image.dk>
+               
+                        
 */
 
 #include <linux/module.h>
@@ -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);
+
+
index 38f838797b8b67573f228fe7df0ed40fdb6ea3d2..32ae52497a1e89d09d29d7e6f3121a2664a570cf 100644 (file)
  *  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 <tmm@image.dk>
  */
 
 
@@ -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 ************************************************/
 
index 94ad9f091494c8b7901a44083a4e3ee84ac1cfbf..4fd96706d6194429d9fea454dd39e135f23c9b5b 100644 (file)
                                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 <tmm@image.dk>
 */
 \f
 /* 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);
+
+
index 7b0fcc10ceea02564f40447b976f5e8b1b31648b..42fa4d62b8744c1deafd3e87f0ee80f3733807dd 100644 (file)
  *  4.62 Fix a bug where playing audio left the drive in an unusable state.
  *         Heiko Eissfeldt <heiko@colossus.escape.de>
  *
+ *  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 <tmm@image.dk>
+ *
  *
  *  TODO
  *     implement "read all subchannel data" (96 bytes per frame)
 
 #include <linux/module.h>
 
+#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -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
 /*==========================================================================*/
 /*
index b5edc20574c394f5eab63ea446ffc87a286b7b69..92bb0b736361fde7fd36f033a19714f45e4ca20a 100644 (file)
  *      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 <tmm@image.dk>
  */
 
 #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);
+
+
index 947277f3d219080f1be15656bfcc56e141c56765..10e693c47f9640bf682ea807ed6cc09cce2b6a37 100644 (file)
  *  More changes to support CDU-510/515 series
  *      (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
  *
+ * 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 <tmm@image.dk>
+ *
  * 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);
+
+
index b32ea52fe907427094ee60334899b074e8c4f3a8..6417d954c705ad4f941dd074e376ec8a394231a3 100644 (file)
@@ -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
index 55d00d8233b7db20fa5658ddf1d444018054a776..70c013b7defb48b93f82d0baecfae3225e12cc3b 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef _AGP_BACKEND_PRIV_H
 #define _AGP_BACKEND_PRIV_H 1
 
+#include <linux/config.h>
+
 enum aper_size_type {
        U8_APER_SIZE,
        U16_APER_SIZE,
index 72f87791a19c70f3f8e564526f09c68f0a913f4a..eeb21921cbecad445da751ca1d7e1804e944ee5c 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/miscdevice.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/system.h>
 #include <asm/io.h>
 #include <asm/page.h>
 
index e70b2d75e5e6e7710e3f477743b1bde70e097de1..f4ccd6e52c7cc02ed5a85b743babb77696012b59 100644 (file)
@@ -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...
index eba0c14b72559084e3ff668e407fe60582c0fd3b..7f7683f623f65a6b3064b5f4dc9b23f0cc791ec5 100644 (file)
@@ -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;
 
index 1e5eb00c1d9afa10f3704a57af9e2f5e25ddec8a..d00b0f539911cec9a95b3dc44e279901cd0028e1 100644 (file)
@@ -7,6 +7,7 @@
  *  anything out of the ordinary is seen.
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
index e31d1a7a436f477c1555343059109c396c73d6c9..8182d0766e34e59d3ab2f4949672b8feac2fb4bc 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #define __NO_VERSION__
+#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/sched.h>
index ce9e28a41f1b3e84f5f8885e6c3d84ecb03aafa6..8e72fd092e5557ac19c16759fcb0b3859fc7e14e 100644 (file)
@@ -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));
index d482a729478a456300c48b3ae00453cd1ffb4fb9..f196732bbae803785d4a0ab5763f19680e3a1c8a 100644 (file)
@@ -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;
index df963da1f97d6010ddda065deea042f0d42448c5..d3a649f4df36bd67d58d46fbc253c070f5f8e64a 100644 (file)
@@ -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;
index 5191847f971b9f7dc8ae81e4f1b21fbbb5a48b91..a9a66455d25bcb39aa20f59fdf74a0a2b837fe5e 100644 (file)
@@ -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/' \
index c979134b4a84a54a7476b82f629856de6c29080c..68515326b8e081103a0e42d963b1e3da0e21eb7e 100644 (file)
  */
 
 #include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/malloc.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/affs_fs.h>
 #include <linux/amigaffs.h>
-#include <asm/uaccess.h>
+#include <linux/pagemap.h>
 
-#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,
+};
index 2b3556995bb5481060067f18a3932e49f074dbf1..ad861b42b9fea5aea0a87e6519f1fa901409b40a 100644 (file)
@@ -7,97 +7,48 @@
  */
 
 #include <linux/string.h>
-#include <linux/malloc.h>
 #include <linux/efs_fs.h>
+#include <linux/pagemap.h>
 
-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
+};
index d7abdc991f7fee6037c362812f8266069457c9b0..9632c054c57f62af8a3721717376b60d7252a077 100644 (file)
@@ -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;
index 79bfb106cd99eddeca768d76401e1051f6472f23..8abaf2fd39e2376800a4c734639f78420b000a1e 100644 (file)
@@ -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);
index 9ae4a67da67389f6eafc812a9965461cdbdb9b5a..377b296e8c62d0eaf98ab6cf74ddea2ac9d646c5 100644 (file)
@@ -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 */
index 4acf7b0e209dd7a181cfb1bf13779e31cc7d6fd2..e4167bfdc6c8e8831bcee8fd9d8145d302960fd1 100644 (file)
@@ -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;
index fe9b66e3da8874447d156ebf896b2704032c163d..85ce143dbd8327936487f6d5c0f5592d31087622 100644 (file)
@@ -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)
 {
index 03235f22f7cdf52d96aaae8059345e4711229b4c..814d90b3c63e857513523014f21518d628543f04 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/pagemap.h>
 
 #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;
 }
index e4e0fb837e4935264f108b5b3dc95b83cdb2bcd5..219a4b9ac998591c78783d6410be6ebca3e7e8b3 100644 (file)
 #include <linux/stat.h>
 #include <linux/malloc.h>
 
-#include <asm/uaccess.h>
-
-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;
-}
index 1aac7fb0cebd56512b4ef7fccda6b33a1184170e..95ee1c127ae7115e9aef60cf65924d3bdbf74aec 100644 (file)
@@ -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);
index 58786a8da97efdc7104d6815f28a089305e23a07..6db4bafcc435fda0d3a0728d28ce9dea37e5dbf1 100644 (file)
 #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 || length<NCP_MIN_SYMLINK_SIZE || 
-          ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 || ((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) {
-               dput(base);
+       if (error) {
                kfree(link);
-               return ERR_PTR(-EIO);
+               goto fail;
        }
-
-       len = NCP_MAX_SYMLINK_SIZE;
-       buf = (char *) kmalloc(len, GFP_NFS);
-       if (!buf) {
-               dput(base);
+       if (length<NCP_MIN_SYMLINK_SIZE || 
+           ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 ||
+           ((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) {
+               error = -EIO;
                kfree(link);
-               return ERR_PTR(-EAGAIN);
-       }
-       error = ncp_vol2io(NCP_SERVER(inode), buf, &len, link+8, length-8, 0);
-       kfree(link);
-       if (error) {
-               dput(base);
-               kfree(buf);
-               return ERR_PTR(error);
-       }
-       
-       /* UPDATE_ATIME(inode); */
-       base = lookup_dentry(buf, base, follow);
-       kfree(buf);
-
-       return base;
-}
-
-/* ----- read symbolic link ---------------------------------------------- */
-
-static int ncp_readlink(struct dentry * dentry, char * buffer, int buflen)
-{
-       struct inode *inode=dentry->d_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) {
index f6614595ab182f4bb9dc62b1850472cb5c985dc7..7bcd09e4421f9f15be26b022f8c77d13bf10c1db 100644 (file)
  *      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 <linux/sched.h>
 #include <linux/fs.h>
 #include <linux/msdos_fs.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/umsdos_fs.h>
-#include <linux/malloc.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-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
 };
-
index 48cb099b71f56aa50757741d427847fdd86d1658..5cf17b846b9ab7af1558f4342637d27a0f2c3001 100644 (file)
@@ -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
index 7b48a5be823773d9d987f8f2c1bb49e48ca725d9..b125ee4d69dcc6e43fd785705b2d3a5d153bfd24 100644 (file)
@@ -12,6 +12,7 @@
 #define        _LINUX_CDROM_H
 
 #include <linux/types.h>
+#include <asm/byteorder.h>
 
 /*******************************************************
  * 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 {
index f94cd91a356b8bc7a2186c48db9dc2a113993da6..63f1e9aa5b0f4aa87d968993b2e5f74eaa730855 100644 (file)
@@ -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 */
 
index e5b3a3d7b3b384b101e03bf68f782316171d63e0..80a8b27f42aae3d28bb5ee48200c3e880824e964 100644 (file)
@@ -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 *);
index 462373b21e5e70984cd75983e8fc6e52616e1a76..e1cfb235722db08033d74a8367d34a08ca6202e9 100644 (file)
@@ -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;