e1000: add missing length check to e1000 receive routine
[safe/jmp/linux-2.6] / drivers / scsi / initio.c
index 65ca142..89a5948 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1994-1998 Initio Corporation
  * Copyright (c) 1998 Bas Vermeulen <bvermeul@blackstar.xs4all.nl>
  * Copyright (c) 2004 Christoph Hellwig <hch@lst.de>
- * Copyright (c) 2007 Red Hat <alan@redhat.com>
+ * Copyright (c) 2007 Red Hat
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -665,7 +665,7 @@ static void initio_init(struct initio_host * host, u8 *bios_addr)
                host->max_tags[i] = 0xFF;
        }                       /* for                          */
        printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n",
-              host->addr, host->irq,
+              host->addr, host->pci_dev->irq,
               host->bios_addr, host->scsi_id);
        /* Reset SCSI Bus */
        if (host->config & HCC_SCSI_RESET) {
@@ -823,7 +823,7 @@ static void initio_append_busy_scb(struct initio_host * host, struct scsi_ctrl_b
 {
 
 #if DEBUG_QUEUE
-       printk("append busy SCB %o; ", scbp);
+       printk("append busy SCB %p; ", scbp);
 #endif
        if (scbp->tagmsg)
                host->act_tags[scbp->target]++;
@@ -2563,7 +2563,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
 {                              /* Create corresponding SCB     */
        struct scatterlist *sglist;
        struct sg_entry *sg;            /* Pointer to SG list           */
-       int i;
+       int i, nseg;
        long total_len;
        dma_addr_t dma_addr;
 
@@ -2581,8 +2581,8 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
        /* Map the sense buffer into bus memory */
        dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer,
                                  SENSE_SIZE, DMA_FROM_DEVICE);
-       cblk->senseptr = cpu_to_le32((u32)dma_addr);
-       cblk->senselen = cpu_to_le32(SENSE_SIZE);
+       cblk->senseptr = (u32)dma_addr;
+       cblk->senselen = SENSE_SIZE;
        cmnd->SCp.ptr = (char *)(unsigned long)dma_addr;
        cblk->cdblen = cmnd->cmd_len;
 
@@ -2590,7 +2590,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
        cblk->hastat = 0;
        cblk->tastat = 0;
        /* Command the command */
-       memcpy(&cblk->cdb[0], &cmnd->cmnd, cmnd->cmd_len);
+       memcpy(cblk->cdb, cmnd->cmnd, cmnd->cmd_len);
 
        /* Set up tags */
        if (cmnd->device->tagged_supported) {   /* Tag Support                  */
@@ -2600,34 +2600,29 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
        }
 
        /* todo handle map_sg error */
-       if (cmnd->use_sg) {
+       nseg = scsi_dma_map(cmnd);
+       BUG_ON(nseg < 0);
+       if (nseg) {
                dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0],
                                          sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
                                          DMA_BIDIRECTIONAL);
-               cblk->bufptr = cpu_to_le32((u32)dma_addr);
+               cblk->bufptr = (u32)dma_addr;
                cmnd->SCp.dma_handle = dma_addr;
 
-               sglist = (struct scatterlist *) cmnd->request_buffer;
-               cblk->sglen = dma_map_sg(&host->pci_dev->dev, sglist,
-                                            cmnd->use_sg, cmnd->sc_data_direction);
+               cblk->sglen = nseg;
 
                cblk->flags |= SCF_SG;  /* Turn on SG list flag       */
-               for (i = 0, total_len = 0, sg = &cblk->sglist[0];       /* 1.01g */
-                    i < cblk->sglen; i++, sg++, sglist++) {
+               total_len = 0;
+               sg = &cblk->sglist[0];
+               scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) {
                        sg->data = cpu_to_le32((u32)sg_dma_address(sglist));
-                       total_len += sg->len = cpu_to_le32((u32)sg_dma_len(sglist));
+                       sg->len = cpu_to_le32((u32)sg_dma_len(sglist));
+                       total_len += sg_dma_len(sglist);
+                       ++sg;
                }
 
-               cblk->buflen = (cmnd->request_bufflen > total_len) ?
-                   total_len : cmnd->request_bufflen;
-       } else if (cmnd->request_bufflen) {             /* Non SG */
-               dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->request_buffer,
-                                         cmnd->request_bufflen,
-                                         cmnd->sc_data_direction);
-               cmnd->SCp.dma_handle = dma_addr;
-               cblk->bufptr = cpu_to_le32((u32)dma_addr);
-               cblk->buflen = cpu_to_le32((u32)cmnd->request_bufflen);
-               cblk->sglen = 0;
+               cblk->buflen = (scsi_bufflen(cmnd) > total_len) ?
+                       total_len : scsi_bufflen(cmnd);
        } else {        /* No data transfer required */
                cblk->buflen = 0;
                cblk->sglen = 0;
@@ -2750,18 +2745,12 @@ static void i91u_unmap_scb(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd)
        }
 
        /* request buffer */
-       if (cmnd->use_sg) {
+       if (scsi_sg_count(cmnd)) {
                dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
                                 sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
                                 DMA_BIDIRECTIONAL);
 
-               dma_unmap_sg(&pci_dev->dev, cmnd->request_buffer,
-                            cmnd->use_sg,
-                            cmnd->sc_data_direction);
-       } else if (cmnd->request_bufflen) {
-               dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
-                                cmnd->request_bufflen,
-                                cmnd->sc_data_direction);
+               scsi_dma_unmap(cmnd);
        }
 }
 
@@ -2867,7 +2856,7 @@ static int initio_probe_one(struct pci_dev *pdev,
                reg = 0;
        bios_seg = (bios_seg << 8) + ((u16) ((reg & 0xFF00) >> 8));
 
-       if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+       if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
                printk(KERN_WARNING  "i91u: Could not set 32 bit DMA mask\n");
                error = -ENODEV;
                goto out_disable_device;
@@ -2880,6 +2869,8 @@ static int initio_probe_one(struct pci_dev *pdev,
        }
        host = (struct initio_host *)shost->hostdata;
        memset(host, 0, sizeof(struct initio_host));
+       host->addr = pci_resource_start(pdev, 0);
+       host->bios_addr = bios_seg;
 
        if (!request_region(host->addr, 256, "i91u")) {
                printk(KERN_WARNING "initio: I/O port range 0x%x is busy.\n", host->addr);
@@ -2904,6 +2895,10 @@ static int initio_probe_one(struct pci_dev *pdev,
                goto out_release_region;
        }
 
+       host->pci_dev = pdev;
+
+       host->semaph = 1;
+       spin_lock_init(&host->semaph_lock);
        host->num_scbs = num_scb;
        host->scb = scb;
        host->next_pending = scb;
@@ -2918,8 +2913,9 @@ static int initio_probe_one(struct pci_dev *pdev,
        host->scb_end = tmp;
        host->first_avail = scb;
        host->last_avail = prev;
+       spin_lock_init(&host->avail_lock);
 
-       initio_init(host, phys_to_virt(bios_seg << 4));
+       initio_init(host, phys_to_virt(((u32)bios_seg << 4)));
 
        host->jsstatus0 = 0;
 
@@ -2941,7 +2937,6 @@ static int initio_probe_one(struct pci_dev *pdev,
        }
 
        pci_set_drvdata(pdev, shost);
-       host->pci_dev = pdev;
 
        error = scsi_add_host(shost, &pdev->dev);
        if (error)