]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/scsi/hpsa.c
[SCSI] hpsa: fixup DMA address before freeing.
[karo-tx-linux.git] / drivers / scsi / hpsa.c
index a6dea08664fc638c611260cbdd067978fb8b8092..e2089a3b50616fc0a072e3ef1566dfe999f2c9af 100644 (file)
@@ -641,11 +641,6 @@ static void fixup_botched_add(struct ctlr_info *h,
 static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1,
        struct hpsa_scsi_dev_t *dev2)
 {
-       if ((is_logical_dev_addr_mode(dev1->scsi3addr) ||
-               (dev1->lun != -1 && dev2->lun != -1)) &&
-               dev1->devtype != 0x0C)
-               return (memcmp(dev1, dev2, sizeof(*dev1)) == 0);
-
        /* we compare everything except lun and target as these
         * are not yet assigned.  Compare parts likely
         * to differ first
@@ -660,12 +655,8 @@ static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1,
                return 0;
        if (memcmp(dev1->vendor, dev2->vendor, sizeof(dev1->vendor)) != 0)
                return 0;
-       if (memcmp(dev1->revision, dev2->revision, sizeof(dev1->revision)) != 0)
-               return 0;
        if (dev1->devtype != dev2->devtype)
                return 0;
-       if (dev1->raid_level != dev2->raid_level)
-               return 0;
        if (dev1->bus != dev2->bus)
                return 0;
        return 1;
@@ -1477,8 +1468,6 @@ static int hpsa_update_device_info(struct ctlr_info *h,
                sizeof(this_device->vendor));
        memcpy(this_device->model, &inq_buff[16],
                sizeof(this_device->model));
-       memcpy(this_device->revision, &inq_buff[32],
-               sizeof(this_device->revision));
        memset(this_device->device_id, 0,
                sizeof(this_device->device_id));
        hpsa_get_device_id(h, scsi3addr, this_device->device_id,
@@ -2278,7 +2267,7 @@ static void cmd_special_free(struct ctlr_info *h, struct CommandList *c)
        pci_free_consistent(h->pdev, sizeof(*c->err_info),
                            c->err_info, (dma_addr_t) temp64.val);
        pci_free_consistent(h->pdev, sizeof(*c),
-                           c, (dma_addr_t) c->busaddr);
+                           c, (dma_addr_t) (c->busaddr & DIRECT_LOOKUP_MASK));
 }
 
 #ifdef CONFIG_COMPAT
@@ -2444,15 +2433,17 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
                buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
                if (buff == NULL)
                        return -EFAULT;
-       }
-       if (iocommand.Request.Type.Direction == XFER_WRITE) {
-               /* Copy the data into the buffer we created */
-               if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) {
-                       kfree(buff);
-                       return -EFAULT;
+               if (iocommand.Request.Type.Direction == XFER_WRITE) {
+                       /* Copy the data into the buffer we created */
+                       if (copy_from_user(buff, iocommand.buf,
+                               iocommand.buf_size)) {
+                               kfree(buff);
+                               return -EFAULT;
+                       }
+               } else {
+                       memset(buff, 0, iocommand.buf_size);
                }
-       } else
-               memset(buff, 0, iocommand.buf_size);
+       }
        c = cmd_special_alloc(h);
        if (c == NULL) {
                kfree(buff);
@@ -2498,8 +2489,8 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
                cmd_special_free(h, c);
                return -EFAULT;
        }
-
-       if (iocommand.Request.Type.Direction == XFER_READ) {
+       if (iocommand.Request.Type.Direction == XFER_READ &&
+               iocommand.buf_size > 0) {
                /* Copy the data out of the buffer we created */
                if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
                        kfree(buff);
@@ -2592,14 +2583,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
        }
        c->cmd_type = CMD_IOCTL_PEND;
        c->Header.ReplyQueue = 0;
-
-       if (ioc->buf_size > 0) {
-               c->Header.SGList = sg_used;
-               c->Header.SGTotal = sg_used;
-       } else {
-               c->Header.SGList = 0;
-               c->Header.SGTotal = 0;
-       }
+       c->Header.SGList = c->Header.SGTotal = sg_used;
        memcpy(&c->Header.LUN, &ioc->LUN_info, sizeof(c->Header.LUN));
        c->Header.Tag.lower = c->busaddr;
        memcpy(&c->Request, &ioc->Request, sizeof(c->Request));
@@ -2616,7 +2600,8 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
                }
        }
        hpsa_scsi_do_simple_cmd_core(h, c);
-       hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
+       if (sg_used)
+               hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
        check_ioctl_unit_attention(h, c);
        /* Copy the error information out */
        memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info));
@@ -2625,7 +2610,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
                status = -EFAULT;
                goto cleanup1;
        }
-       if (ioc->Request.Type.Direction == XFER_READ) {
+       if (ioc->Request.Type.Direction == XFER_READ && ioc->buf_size > 0) {
                /* Copy the data out of the buffer we created */
                BYTE __user *ptr = ioc->buf;
                for (i = 0; i < sg_used; i++) {