diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/ll_rw_blk.c | 9 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 34 | ||||
-rw-r--r-- | drivers/scsi/53c700.c | 3 | ||||
-rw-r--r-- | drivers/scsi/53c700.h | 192 | ||||
-rw-r--r-- | drivers/scsi/Kconfig | 10 | ||||
-rw-r--r-- | drivers/scsi/NCR_D700.c | 5 | ||||
-rw-r--r-- | drivers/scsi/lasi700.c | 1 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 6 | ||||
-rw-r--r-- | drivers/scsi/scsi_scan.c | 1 | ||||
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 3 | ||||
-rw-r--r-- | drivers/scsi/sg.c | 203 | ||||
-rw-r--r-- | drivers/scsi/sim710.c | 5 |
12 files changed, 186 insertions, 286 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 46e54b441663..11ef9d9ea139 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1715,6 +1715,15 @@ request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) if (blk_init_free_list(q)) goto out_init; + /* + * if caller didn't supply a lock, they get per-queue locking with + * our embedded lock + */ + if (!lock) { + spin_lock_init(&q->__queue_lock); + lock = &q->__queue_lock; + } + q->request_fn = rfn; q->back_merge_fn = ll_back_merge_fn; q->front_merge_fn = ll_front_merge_fn; diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index a393cf4d0313..1f9aeb4accc6 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -52,19 +52,18 @@ static inline int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *, static inline int zfcp_sg_list_copy_to_user(void __user *, struct zfcp_sg_list *, size_t); -static int zfcp_cfdc_dev_ioctl(struct inode *, struct file *, - unsigned int, unsigned long); +static int zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long); #define ZFCP_CFDC_IOC_MAGIC 0xDD #define ZFCP_CFDC_IOC \ _IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_sense_data) -#ifdef CONFIG_COMPAT -static struct ioctl_trans zfcp_ioctl_trans = {ZFCP_CFDC_IOC, (void*) sys_ioctl}; -#endif static struct file_operations zfcp_cfdc_fops = { - .ioctl = zfcp_cfdc_dev_ioctl + .unlocked_ioctl = zfcp_cfdc_dev_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = zfcp_cfdc_dev_ioctl +#endif }; static struct miscdevice zfcp_cfdc_misc = { @@ -308,23 +307,16 @@ zfcp_module_init(void) if (!zfcp_transport_template) return -ENODEV; - retval = register_ioctl32_conversion(zfcp_ioctl_trans.cmd, - zfcp_ioctl_trans.handler); - if (retval != 0) { - ZFCP_LOG_INFO("registration of ioctl32 conversion failed\n"); - goto out; - } - retval = misc_register(&zfcp_cfdc_misc); if (retval != 0) { ZFCP_LOG_INFO("registration of misc device " "zfcp_cfdc failed\n"); - goto out_misc_register; - } else { - ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n", - ZFCP_CFDC_DEV_MAJOR, zfcp_cfdc_misc.minor); + goto out; } + ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n", + ZFCP_CFDC_DEV_MAJOR, zfcp_cfdc_misc.minor); + /* Initialise proc semaphores */ sema_init(&zfcp_data.config_sema, 1); @@ -348,8 +340,6 @@ zfcp_module_init(void) out_ccw_register: misc_deregister(&zfcp_cfdc_misc); - out_misc_register: - unregister_ioctl32_conversion(zfcp_ioctl_trans.cmd); out: return retval; } @@ -370,9 +360,9 @@ zfcp_module_init(void) * -EPERM - Cannot create or queue FSF request or create SBALs * -ERESTARTSYS- Received signal (is mapped to EAGAIN by VFS) */ -static int -zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, - unsigned int command, unsigned long buffer) +static long +zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, + unsigned long buffer) { struct zfcp_cfdc_sense_data *sense_data, __user *sense_data_user; struct zfcp_adapter *adapter = NULL; diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index a591fcb8aab1..4b1bb529f676 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -389,8 +389,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, host->max_lun = NCR_700_MAX_LUNS; BUG_ON(NCR_700_transport_template == NULL); host->transportt = NCR_700_transport_template; - host->unique_id = hostdata->base; - host->base = hostdata->base; + host->unique_id = (unsigned long)hostdata->base; hostdata->eh_complete = NULL; host->hostdata[0] = (unsigned long)hostdata; /* kick the chip */ diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h index df4aa30ae0aa..e86012cf6ab7 100644 --- a/drivers/scsi/53c700.h +++ b/drivers/scsi/53c700.h @@ -14,10 +14,6 @@ #include <scsi/scsi_device.h> -#if defined(CONFIG_53C700_MEM_MAPPED) && defined(CONFIG_53C700_IO_MAPPED) -#define CONFIG_53C700_BOTH_MAPPED -#endif - /* Turn on for general debugging---too verbose for normal use */ #undef NCR_700_DEBUG /* Debug the tag queues, checking hash queue allocation and deallocation @@ -49,13 +45,6 @@ /* magic byte identifying an internally generated REQUEST_SENSE command */ #define NCR_700_INTERNAL_SENSE_MAGIC 0x42 -/* WARNING: Leave this in for now: the dependency preprocessor doesn't - * pick up file specific flags, so must define here if they are not - * set */ -#if !defined(CONFIG_53C700_IO_MAPPED) && !defined(CONFIG_53C700_MEM_MAPPED) -#error "Config.in must define either CONFIG_53C700_IO_MAPPED or CONFIG_53C700_MEM_MAPPED to use this scsi core." -#endif - struct NCR_700_Host_Parameters; /* These are the externally used routines */ @@ -184,7 +173,7 @@ struct NCR_700_command_slot { struct NCR_700_Host_Parameters { /* These must be filled in by the calling driver */ int clock; /* board clock speed in MHz */ - unsigned long base; /* the base for the port (copied to host) */ + void __iomem *base; /* the base for the port (copied to host) */ struct device *dev; __u32 dmode_extra; /* adjustable bus settings */ __u32 differential:1; /* if we are differential */ @@ -199,9 +188,6 @@ struct NCR_700_Host_Parameters { /* NOTHING BELOW HERE NEEDS ALTERING */ __u32 fast:1; /* if we can alter the SCSI bus clock speed (so can negiotiate sync) */ -#ifdef CONFIG_53C700_BOTH_MAPPED - __u32 mem_mapped; /* set if memory mapped */ -#endif int sync_clock; /* The speed of the SYNC core */ __u32 *script; /* pointer to script location */ @@ -246,12 +232,18 @@ struct NCR_700_Host_Parameters { #ifdef CONFIG_53C700_LE_ON_BE #define bE (hostdata->force_le_on_be ? 0 : 3) #define bSWAP (hostdata->force_le_on_be) +/* This is terrible, but there's no raw version of ioread32. That means + * that on a be board we swap twice (once in ioread32 and once again to + * get the value correct) */ +#define bS_to_io(x) ((hostdata->force_le_on_be) ? (x) : cpu_to_le32(x)) #elif defined(__BIG_ENDIAN) #define bE 3 #define bSWAP 0 +#define bS_to_io(x) (x) #elif defined(__LITTLE_ENDIAN) #define bE 0 #define bSWAP 0 +#define bS_to_io(x) (x) #else #error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined, did you include byteorder.h?" #endif @@ -455,91 +447,42 @@ struct NCR_700_Host_Parameters { static inline __u8 -NCR_700_mem_readb(struct Scsi_Host *host, __u32 reg) -{ - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) - = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - - return readb(host->base + (reg^bE)); -} - -static inline __u32 -NCR_700_mem_readl(struct Scsi_Host *host, __u32 reg) -{ - __u32 value = __raw_readl(host->base + reg); - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) - = (struct NCR_700_Host_Parameters *)host->hostdata[0]; -#if 1 - /* sanity check the register */ - if((reg & 0x3) != 0) - BUG(); -#endif - - return bS_to_cpu(value); -} - -static inline void -NCR_700_mem_writeb(__u8 value, struct Scsi_Host *host, __u32 reg) -{ - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) - = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - - writeb(value, host->base + (reg^bE)); -} - -static inline void -NCR_700_mem_writel(__u32 value, struct Scsi_Host *host, __u32 reg) -{ - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) - = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - -#if 1 - /* sanity check the register */ - if((reg & 0x3) != 0) - BUG(); -#endif - - __raw_writel(bS_to_host(value), host->base + reg); -} - -static inline __u8 -NCR_700_io_readb(struct Scsi_Host *host, __u32 reg) +NCR_700_readb(struct Scsi_Host *host, __u32 reg) { - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) + const struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - return inb(host->base + (reg^bE)); + return ioread8(hostdata->base + (reg^bE)); } static inline __u32 -NCR_700_io_readl(struct Scsi_Host *host, __u32 reg) +NCR_700_readl(struct Scsi_Host *host, __u32 reg) { - __u32 value = inl(host->base + reg); - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) + const struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - + __u32 value = ioread32(hostdata->base + reg); #if 1 /* sanity check the register */ if((reg & 0x3) != 0) BUG(); #endif - return bS_to_cpu(value); + return bS_to_io(value); } static inline void -NCR_700_io_writeb(__u8 value, struct Scsi_Host *host, __u32 reg) +NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg) { - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) + const struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - outb(value, host->base + (reg^bE)); + iowrite8(value, hostdata->base + (reg^bE)); } static inline void -NCR_700_io_writel(__u32 value, struct Scsi_Host *host, __u32 reg) +NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg) { - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) + const struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0]; #if 1 @@ -548,102 +491,7 @@ NCR_700_io_writel(__u32 value, struct Scsi_Host *host, __u32 reg) BUG(); #endif - outl(bS_to_host(value), host->base + reg); -} - -#ifdef CONFIG_53C700_BOTH_MAPPED - -static inline __u8 -NCR_700_readb(struct Scsi_Host *host, __u32 reg) -{ - __u8 val; - - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) - = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - - if(hostdata->mem_mapped) - val = NCR_700_mem_readb(host, reg); - else - val = NCR_700_io_readb(host, reg); - - return val; -} - -static inline __u32 -NCR_700_readl(struct Scsi_Host *host, __u32 reg) -{ - __u32 val; - - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) - = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - - if(hostdata->mem_mapped) - val = NCR_700_mem_readl(host, reg); - else - val = NCR_700_io_readl(host, reg); - - return val; -} - -static inline void -NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg) -{ - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) - = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - - if(hostdata->mem_mapped) - NCR_700_mem_writeb(value, host, reg); - else - NCR_700_io_writeb(value, host, reg); -} - -static inline void -NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg) -{ - const struct NCR_700_Host_Parameters *hostdata __attribute__((unused)) - = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - - if(hostdata->mem_mapped) - NCR_700_mem_writel(value, host, reg); - else - NCR_700_io_writel(value, host, reg); -} - -static inline void -NCR_700_set_mem_mapped(struct NCR_700_Host_Parameters *hostdata) -{ - hostdata->mem_mapped = 1; -} - -static inline void -NCR_700_set_io_mapped(struct NCR_700_Host_Parameters *hostdata) -{ - hostdata->mem_mapped = 0; + iowrite32(bS_to_io(value), hostdata->base + reg); } - -#elif defined(CONFIG_53C700_IO_MAPPED) - -#define NCR_700_readb NCR_700_io_readb -#define NCR_700_readl NCR_700_io_readl -#define NCR_700_writeb NCR_700_io_writeb -#define NCR_700_writel NCR_700_io_writel - -#define NCR_700_set_io_mapped(x) -#define NCR_700_set_mem_mapped(x) error I/O mapped only - -#elif defined(CONFIG_53C700_MEM_MAPPED) - -#define NCR_700_readb NCR_700_mem_readb -#define NCR_700_readl NCR_700_mem_readl -#define NCR_700_writeb NCR_700_mem_writeb -#define NCR_700_writel NCR_700_mem_writel - -#define NCR_700_set_io_mapped(x) error MEM mapped only -#define NCR_700_set_mem_mapped(x) - -#else -#error neither CONFIG_53C700_MEM_MAPPED nor CONFIG_53C700_IO_MAPPED is set -#endif - #endif diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index d22b32f4662d..718df4c6c3b2 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -942,11 +942,6 @@ config SCSI_NCR_D700 Unless you have an NCR manufactured machine, the chances are that you do not have this SCSI card, so say N. -config 53C700_IO_MAPPED - bool - depends on SCSI_NCR_D700 - default y - config SCSI_LASI700 tristate "HP Lasi SCSI support for 53c700/710" depends on GSC && SCSI @@ -956,11 +951,6 @@ config SCSI_LASI700 many PA-RISC workstations & servers. If you do not know whether you have a Lasi chip, it is safe to say "Y" here. -config 53C700_MEM_MAPPED - bool - depends on SCSI_LASI700 - default y - config 53C700_LE_ON_BE bool depends on SCSI_LASI700 diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index 507751941f1e..e993a7ba276f 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -197,12 +197,10 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, } /* Fill in the three required pieces of hostdata */ - hostdata->base = region; + hostdata->base = ioport_map(region, 64); hostdata->differential = (((1<<siop) & differential) != 0); hostdata->clock = NCR_D700_CLOCK_MHZ; - NCR_700_set_io_mapped(hostdata); - /* and register the siop */ host = NCR_700_detect(&NCR_D700_driver_template, hostdata, p->dev); if (!host) { @@ -214,6 +212,7 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, /* FIXME: read this from SUS */ host->this_id = id_array[slot * 2 + siop]; host->irq = irq; + host->base = region; scsi_scan_host(host); return 0; diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index 29f250c80b98..4cbb6187cc44 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -131,6 +131,7 @@ lasi700_probe(struct parisc_device *dev) if (!host) goto out_kfree; host->this_id = 7; + host->base = base; host->irq = dev->irq; if(request_irq(dev->irq, NCR_700_intr, SA_SHIRQ, "lasi700", host)) { printk(KERN_ERR "lasi700: request_irq failed!\n"); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 619d3fb7a2f0..d18da21c9c57 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -358,9 +358,9 @@ void scsi_device_unbusy(struct scsi_device *sdev) shost->host_failed)) scsi_eh_wakeup(shost); spin_unlock(shost->host_lock); - spin_lock(&sdev->sdev_lock); + spin_lock(sdev->request_queue->queue_lock); sdev->device_busy--; - spin_unlock_irqrestore(&sdev->sdev_lock, flags); + spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); } /* @@ -1423,7 +1423,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) struct Scsi_Host *shost = sdev->host; struct request_queue *q; - q = blk_init_queue(scsi_request_fn, &sdev->sdev_lock); + q = blk_init_queue(scsi_request_fn, NULL); if (!q) return NULL; diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index a8a37a338c02..287d197a7c17 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -249,7 +249,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, */ sdev->borken = 1; - spin_lock_init(&sdev->sdev_lock); sdev->request_queue = scsi_alloc_queue(sdev); if (!sdev->request_queue) { /* release fn is set up in scsi_sysfs_device_initialise, so diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 134d3a3e4222..e75ee4671ee3 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -171,6 +171,9 @@ void scsi_device_dev_release(struct device *dev) if (sdev->request_queue) { sdev->request_queue->queuedata = NULL; scsi_free_queue(sdev->request_queue); + /* temporary expedient, try to catch use of queue lock + * after free of sdev */ + sdev->request_queue = NULL; } scsi_target_reap(scsi_target(sdev)); diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index cf6b1f0fb124..ce8332297dfa 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -18,8 +18,8 @@ * */ -static int sg_version_num = 30532; /* 2 digits for each component */ -#define SG_VERSION_STR "3.5.32" +static int sg_version_num = 30533; /* 2 digits for each component */ +#define SG_VERSION_STR "3.5.33" /* * D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes: @@ -61,7 +61,7 @@ static int sg_version_num = 30532; /* 2 digits for each component */ #ifdef CONFIG_SCSI_PROC_FS #include <linux/proc_fs.h> -static char *sg_version_date = "20050117"; +static char *sg_version_date = "20050328"; static int sg_proc_init(void); static void sg_proc_cleanup(void); @@ -331,14 +331,13 @@ sg_release(struct inode *inode, struct file *filp) static ssize_t sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) { - int res; Sg_device *sdp; Sg_fd *sfp; Sg_request *srp; int req_pack_id = -1; - struct sg_header old_hdr; - sg_io_hdr_t new_hdr; sg_io_hdr_t *hp; + struct sg_header *old_hdr = NULL; + int retval = 0; if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) return -ENXIO; @@ -347,98 +346,138 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) if (!access_ok(VERIFY_WRITE, buf, count)) return -EFAULT; if (sfp->force_packid && (count >= SZ_SG_HEADER)) { - if (__copy_from_user(&old_hdr, buf, SZ_SG_HEADER)) - return -EFAULT; - if (old_hdr.reply_len < 0) { + old_hdr = kmalloc(SZ_SG_HEADER, GFP_KERNEL); + if (!old_hdr) + return -ENOMEM; + if (__copy_from_user(old_hdr, buf, SZ_SG_HEADER)) { + retval = -EFAULT; + goto free_old_hdr; + } + if (old_hdr->reply_len < 0) { if (count >= SZ_SG_IO_HDR) { - if (__copy_from_user - (&new_hdr, buf, SZ_SG_IO_HDR)) - return -EFAULT; - req_pack_id = new_hdr.pack_id; + sg_io_hdr_t *new_hdr; + new_hdr = kmalloc(SZ_SG_IO_HDR, GFP_KERNEL); + if (!new_hdr) { + retval = -ENOMEM; + goto free_old_hdr; + } + retval =__copy_from_user + (new_hdr, buf, SZ_SG_IO_HDR); + req_pack_id = new_hdr->pack_id; + kfree(new_hdr); + if (retval) { + retval = -EFAULT; + goto free_old_hdr; + } } } else - req_pack_id = old_hdr.pack_id; + req_pack_id = old_hdr->pack_id; } srp = sg_get_rq_mark(sfp, req_pack_id); if (!srp) { /* now wait on packet to arrive */ - if (sdp->detached) - return -ENODEV; - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; + if (sdp->detached) { + retval = -ENODEV; + goto free_old_hdr; + } + if (filp->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto free_old_hdr; + } while (1) { - res = 0; /* following is a macro that beats race condition */ + retval = 0; /* following macro beats race condition */ __wait_event_interruptible(sfp->read_wait, - (sdp->detached || (srp = sg_get_rq_mark(sfp, req_pack_id))), - res); - if (sdp->detached) - return -ENODEV; - if (0 == res) + (sdp->detached || + (srp = sg_get_rq_mark(sfp, req_pack_id))), + retval); + if (sdp->detached) { + retval = -ENODEV; + goto free_old_hdr; + } + if (0 == retval) break; - return res; /* -ERESTARTSYS because signal hit process */ + + /* -ERESTARTSYS as signal hit process */ + goto free_old_hdr; } } - if (srp->header.interface_id != '\0') - return sg_new_read(sfp, buf, count, srp); + if (srp->header.interface_id != '\0') { + retval = sg_new_read(sfp, buf, count, srp); + goto free_old_hdr; + } hp = &srp->header; - memset(&old_hdr, 0, SZ_SG_HEADER); - old_hdr.reply_len = (int) hp->timeout; - old_hdr.pack_len = old_hdr.reply_len; /* very old, strange behaviour */ - old_hdr.pack_id = hp->pack_id; - old_hdr.twelve_byte = + if (old_hdr == NULL) { + old_hdr = kmalloc(SZ_SG_HEADER, GFP_KERNEL); + if (! old_hdr) { + retval = -ENOMEM; + goto free_old_hdr; + } + } + memset(old_hdr, 0, SZ_SG_HEADER); + old_hdr->reply_len = (int) hp->timeout; + old_hdr->pack_len = old_hdr->reply_len; /* old, strange behaviour */ + old_hdr->pack_id = hp->pack_id; + old_hdr->twelve_byte = ((srp->data.cmd_opcode >= 0xc0) && (12 == hp->cmd_len)) ? 1 : 0; - old_hdr.target_status = hp->masked_status; - old_hdr.host_status = hp->host_status; - old_hdr.driver_status = hp->driver_status; + old_hdr->target_status = hp->masked_status; + old_hdr->host_status = hp->host_status; + old_hdr->driver_status = hp->driver_status; if ((CHECK_CONDITION & hp->masked_status) || (DRIVER_SENSE & hp->driver_status)) - memcpy(old_hdr.sense_buffer, srp->sense_b, - sizeof (old_hdr.sense_buffer)); + memcpy(old_hdr->sense_buffer, srp->sense_b, + sizeof (old_hdr->sense_buffer)); switch (hp->host_status) { /* This setup of 'result' is for backward compatibility and is best ignored by the user who should use target, host + driver status */ case DID_OK: case DID_PASSTHROUGH: case DID_SOFT_ERROR: - old_hdr.result = 0; + old_hdr->result = 0; break; case DID_NO_CONNECT: case DID_BUS_BUSY: case DID_TIME_OUT: - old_hdr.result = EBUSY; + old_hdr->result = EBUSY; break; case DID_BAD_TARGET: case DID_ABORT: case DID_PARITY: case DID_RESET: case DID_BAD_INTR: - old_hdr.result = EIO; + old_hdr->result = EIO; break; case DID_ERROR: - old_hdr.result = (srp->sense_b[0] == 0 && + old_hdr->result = (srp->sense_b[0] == 0 && hp->masked_status == GOOD) ? 0 : EIO; break; default: - old_hdr.result = EIO; + old_hdr->result = EIO; break; } /* Now copy the result back to the user buffer. */ if (count >= SZ_SG_HEADER) { - if (__copy_to_user(buf, &old_hdr, SZ_SG_HEADER)) - return -EFAULT; + if (__copy_to_user(buf, old_hdr, SZ_SG_HEADER)) { + retval = -EFAULT; + goto free_old_hdr; + } buf += SZ_SG_HEADER; - if (count > old_hdr.reply_len) - count = old_hdr.reply_len; + if (count > old_hdr->reply_len) + count = old_hdr->reply_len; if (count > SZ_SG_HEADER) { - if ((res = - sg_read_oxfer(srp, buf, count - SZ_SG_HEADER))) - return -EFAULT; + if (sg_read_oxfer(srp, buf, count - SZ_SG_HEADER)) { + retval = -EFAULT; + goto free_old_hdr; + } } } else - count = (old_hdr.result == 0) ? 0 : -EIO; + count = (old_hdr->result == 0) ? 0 : -EIO; sg_finish_rem_req(srp); - return count; + retval = count; +free_old_hdr: + if (old_hdr) + kfree(old_hdr); + return retval; } static ssize_t @@ -725,7 +764,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, srp->data.sglist_len = 0; srp->data.bufflen = 0; srp->data.buffer = NULL; - hp->duration = jiffies; /* unit jiffies now, millisecs after done */ + hp->duration = jiffies_to_msecs(jiffies); /* Now send everything of to mid-level. The next time we hear about this packet is when sg_cmd_done() is called (i.e. a callback). */ scsi_do_req(SRpnt, (void *) cmnd, @@ -938,8 +977,13 @@ sg_ioctl(struct inode *inode, struct file *filp, if (!access_ok(VERIFY_WRITE, p, SZ_SG_REQ_INFO * SG_MAX_QUEUE)) return -EFAULT; else { - sg_req_info_t rinfo[SG_MAX_QUEUE]; - Sg_request *srp; + sg_req_info_t *rinfo; + unsigned int ms; + + rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, + GFP_KERNEL); + if (!rinfo) + return -ENOMEM; read_lock_irqsave(&sfp->rq_list_lock, iflags); for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE; ++val, srp = srp ? srp->nextrp : srp) { @@ -950,19 +994,30 @@ sg_ioctl(struct inode *inode, struct file *filp, srp->header.masked_status & srp->header.host_status & srp->header.driver_status; - rinfo[val].duration = - srp->done ? srp->header.duration : - jiffies_to_msecs( - jiffies - srp->header.duration); + if (srp->done) + rinfo[val].duration = + srp->header.duration; + else { + ms = jiffies_to_msecs(jiffies); + rinfo[val].duration = + (ms > srp->header.duration) ? + (ms - srp->header.duration) : 0; + } rinfo[val].orphan = srp->orphan; - rinfo[val].sg_io_owned = srp->sg_io_owned; - rinfo[val].pack_id = srp->header.pack_id; - rinfo[val].usr_ptr = srp->header.usr_ptr; + rinfo[val].sg_io_owned = + srp->sg_io_owned; + rinfo[val].pack_id = + srp->header.pack_id; + rinfo[val].usr_ptr = + srp->header.usr_ptr; } } read_unlock_irqrestore(&sfp->rq_list_lock, iflags); - return (__copy_to_user(p, rinfo, - SZ_SG_REQ_INFO * SG_MAX_QUEUE) ? -EFAULT : 0); + result = __copy_to_user(p, rinfo, + SZ_SG_REQ_INFO * SG_MAX_QUEUE); + result = result ? -EFAULT : 0; + kfree(rinfo); + return result; } case SG_EMULATED_HOST: if (sdp->detached) @@ -1209,11 +1264,12 @@ static int sg_mmap(struct file *filp, struct vm_area_struct *vma) { Sg_fd *sfp; - unsigned long req_sz = vma->vm_end - vma->vm_start; + unsigned long req_sz; Sg_scatter_hold *rsv_schp; if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data))) return -ENXIO; + req_sz = vma->vm_end - vma->vm_start; SCSI_LOG_TIMEOUT(3, printk("sg_mmap starting, vm_start=%p, len=%d\n", (void *) vma->vm_start, (int) req_sz)); if (vma->vm_pgoff) @@ -1260,6 +1316,7 @@ sg_cmd_done(Scsi_Cmnd * SCpnt) Sg_fd *sfp; Sg_request *srp = NULL; unsigned long iflags; + unsigned int ms; if (SCpnt && (SRpnt = SCpnt->sc_request)) srp = (Sg_request *) SRpnt->upper_private_data; @@ -1296,9 +1353,9 @@ sg_cmd_done(Scsi_Cmnd * SCpnt) SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n", sdp->disk->disk_name, srp->header.pack_id, (int) SRpnt->sr_result)); srp->header.resid = SCpnt->resid; - /* N.B. unit of duration changes here from jiffies to millisecs */ - srp->header.duration = - jiffies_to_msecs(jiffies - srp->header.duration); + ms = jiffies_to_msecs(jiffies); + srp->header.duration = (ms > srp->header.duration) ? + (ms - srp->header.duration) : 0; if (0 != SRpnt->sr_result) { struct scsi_sense_hdr sshdr; @@ -2396,7 +2453,7 @@ sg_add_request(Sg_fd * sfp) } if (resp) { resp->nextrp = NULL; - resp->header.duration = jiffies; + resp->header.duration = jiffies_to_msecs(jiffies); resp->my_cmdp = NULL; } write_unlock_irqrestore(&sfp->rq_list_lock, iflags); @@ -2991,6 +3048,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) Sg_fd *fp; const sg_io_hdr_t *hp; const char * cp; + unsigned int ms; for (k = 0; (fp = sg_get_nth_sfp(sdp, k)); ++k) { seq_printf(s, " FD(%d): timeout=%dms bufflen=%d " @@ -3029,10 +3087,13 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) srp->header.pack_id, blen); if (srp->done) seq_printf(s, " dur=%d", hp->duration); - else + else { + ms = jiffies_to_msecs(jiffies); seq_printf(s, " t_o/elap=%d/%d", - new_interface ? hp->timeout : jiffies_to_msecs(fp->timeout), - jiffies_to_msecs(hp->duration ? (jiffies - hp->duration) : 0)); + (new_interface ? hp->timeout : + jiffies_to_msecs(fp->timeout)), + (ms > hp->duration ? ms - hp->duration : 0)); + } seq_printf(s, "ms sgat=%d op=0x%02x\n", usg, (int) srp->data.cmd_opcode); } diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 63bf2aecbc57..9171788348c4 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -120,11 +120,10 @@ sim710_probe_common(struct device *dev, unsigned long base_addr, } /* Fill in the three required pieces of hostdata */ - hostdata->base = base_addr; + hostdata->base = ioport_map(base_addr, 64); hostdata->differential = differential; hostdata->clock = clock; hostdata->chip710 = 1; - NCR_700_set_io_mapped(hostdata); /* and register the chip */ if((host = NCR_700_detect(&sim710_driver_template, hostdata, dev)) @@ -133,6 +132,7 @@ sim710_probe_common(struct device *dev, unsigned long base_addr, goto out_release; } host->this_id = scsi_id; + host->base = base_addr; host->irq = irq; if (request_irq(irq, NCR_700_intr, SA_SHIRQ, "sim710", host)) { printk(KERN_ERR "sim710: request_irq failed\n"); @@ -164,6 +164,7 @@ sim710_device_remove(struct device *dev) NCR_700_release(host); kfree(hostdata); free_irq(host->irq, host); + release_region(host->base, 64); return 0; } |