From: Andrew Morton - kfree(NULL) is legal - Don't "succeed" if register_chrdev() failed - otherwise we'll later unregister a not-registered chrdev. - Don't return from hptiop_do_ioctl() with the spinlock held. - uninline __hpt_do_ioctl() (marginal) Cc: HighPoint Linux Team Signed-off-by: Andrew Morton --- drivers/scsi/hptiop.c | 27 +++++++++++++-------------- 1 files changed, 13 insertions(+), 14 deletions(-) diff -puN drivers/scsi/hptiop.c~hptiop-highpoint-rocketraid-3xxx-controller-driver-list-locking-updates-updates-2 drivers/scsi/hptiop.c --- 25/drivers/scsi/hptiop.c~hptiop-highpoint-rocketraid-3xxx-controller-driver-list-locking-updates-updates-2 Fri May 12 09:59:41 2006 +++ 25-akpm/drivers/scsi/hptiop.c Fri May 12 09:59:41 2006 @@ -708,9 +708,9 @@ static void hptiop_ioctl_done(struct hpt static void hptiop_do_ioctl(struct hpt_ioctl_k *arg) { - struct hptiop_hba * hba = arg->hba; + struct hptiop_hba *hba = arg->hba; u32 val; - struct hpt_iop_request_ioctl_command __iomem * req; + struct hpt_iop_request_ioctl_command __iomem *req; int ioctl_retry = 0; dprintk("scsi%d: hptiop_do_ioctl\n", hba->host->host_no); @@ -735,9 +735,10 @@ retry: val = readl(&hba->iop->inbound_queue); if (val == IOPMU_QUEUE_EMPTY) { + spin_unlock_irq(hba->host->host_lock); dprintk("scsi%d: no free req for ioctl\n", hba->host->host_no); arg->result = -1; - return ; + return; } req = (struct hpt_iop_request_ioctl_command __iomem *) @@ -790,9 +791,8 @@ retry: arg->ioctl_code, arg->result); } -static inline int __hpt_do_ioctl(struct hptiop_hba *hba, - u32 code, void *inbuf, u32 insize, - void *outbuf, u32 outsize) +static int __hpt_do_ioctl(struct hptiop_hba *hba, u32 code, void *inbuf, + u32 insize, void *outbuf, u32 outsize) { struct hpt_ioctl_k arg; arg.hba = hba; @@ -944,8 +944,7 @@ static void hptiop_dump_devinfo(struct h else hptiop_copy_info(pinfo, "CH%d %s\n", devinfo.u.device.path_id + 1, - driveid->model - ); + driveid->model); else { capacity = devinfo.capacity*512; do_div(capacity, 1000000); @@ -1022,7 +1021,7 @@ static ssize_t hptiop_cdev_read(struct f info.buffer = buf; info.buflength = count; - info.bufoffset = ppos? *ppos : 0; + info.bufoffset = ppos ? *ppos : 0; info.filpos = 0; info.buffillen = 0; @@ -1136,10 +1135,8 @@ static int hptiop_cdev_ioctl(struct inod } err_exit: - if (ioctl_k.inbuf) - kfree(ioctl_k.inbuf); - if (ioctl_k.outbuf) - kfree(ioctl_k.outbuf); + kfree(ioctl_k.inbuf); + kfree(ioctl_k.outbuf); return err; } @@ -1497,8 +1494,10 @@ static int __init hptiop_module_init(voi return error; hptiop_cdev_major = register_chrdev(0, "hptiop", &hptiop_cdev_fops); - if (hptiop_cdev_major < 0) + if (hptiop_cdev_major < 0) { printk(KERN_WARNING "unable to register hptiop device.\n"); + return hptiop_cdev_major; + } return 0; } _