USB: add imx udc gadget driver
[safe/jmp/linux-2.6] / drivers / scsi / qlogicpti.c
index 7a2e798..69d6ad8 100644 (file)
@@ -1,6 +1,6 @@
 /* qlogicpti.c: Performance Technologies QlogicISP sbus card driver.
  *
- * Copyright (C) 1996, 2006 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996, 2006, 2008 David S. Miller (davem@davemloft.net)
  *
  * A lot of this driver was directly stolen from Erik H. Moe's PCI
  * Qlogic ISP driver.  Mucho kudos to him for this code.
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/jiffies.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/byteorder.h>
 
 #include "qlogicpti.h"
 
-#include <asm/sbus.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/ptrace.h>
@@ -157,7 +159,7 @@ static inline void set_sbus_cfg1(struct qlogicpti *qpti)
         * is a nop and the chip ends up using the smallest burst
         * size. -DaveM
         */
-       if (sbus_can_burst64(qpti->sdev) && (bursts & DMA_BURST64)) {
+       if (sbus_can_burst64() && (bursts & DMA_BURST64)) {
                val = (SBUS_CFG1_BENAB | SBUS_CFG1_B64);
        } else
 #endif
@@ -651,7 +653,7 @@ static int qlogicpti_verify_tmon(struct qlogicpti *qpti)
 
 static irqreturn_t qpti_intr(int irq, void *dev_id);
 
-static void __init qpti_chain_add(struct qlogicpti *qpti)
+static void __devinit qpti_chain_add(struct qlogicpti *qpti)
 {
        spin_lock_irq(&qptichain_lock);
        if (qptichain != NULL) {
@@ -667,7 +669,7 @@ static void __init qpti_chain_add(struct qlogicpti *qpti)
        spin_unlock_irq(&qptichain_lock);
 }
 
-static void __init qpti_chain_del(struct qlogicpti *qpti)
+static void __devexit qpti_chain_del(struct qlogicpti *qpti)
 {
        spin_lock_irq(&qptichain_lock);
        if (qptichain == qpti) {
@@ -682,21 +684,21 @@ static void __init qpti_chain_del(struct qlogicpti *qpti)
        spin_unlock_irq(&qptichain_lock);
 }
 
-static int __init qpti_map_regs(struct qlogicpti *qpti)
+static int __devinit qpti_map_regs(struct qlogicpti *qpti)
 {
-       struct sbus_dev *sdev = qpti->sdev;
+       struct of_device *op = qpti->op;
 
-       qpti->qregs = sbus_ioremap(&sdev->resource[0], 0,
-                                  sdev->reg_addrs[0].reg_size,
-                                  "PTI Qlogic/ISP");
+       qpti->qregs = of_ioremap(&op->resource[0], 0,
+                                resource_size(&op->resource[0]),
+                                "PTI Qlogic/ISP");
        if (!qpti->qregs) {
                printk("PTI: Qlogic/ISP registers are unmappable\n");
                return -1;
        }
        if (qpti->is_pti) {
-               qpti->sreg = sbus_ioremap(&sdev->resource[0], (16 * 4096),
-                                         sizeof(unsigned char),
-                                         "PTI Qlogic/ISP statreg");
+               qpti->sreg = of_ioremap(&op->resource[0], (16 * 4096),
+                                       sizeof(unsigned char),
+                                       "PTI Qlogic/ISP statreg");
                if (!qpti->sreg) {
                        printk("PTI: Qlogic/ISP status register is unmappable\n");
                        return -1;
@@ -705,11 +707,11 @@ static int __init qpti_map_regs(struct qlogicpti *qpti)
        return 0;
 }
 
-static int __init qpti_register_irq(struct qlogicpti *qpti)
+static int __devinit qpti_register_irq(struct qlogicpti *qpti)
 {
-       struct sbus_dev *sdev = qpti->sdev;
+       struct of_device *op = qpti->op;
 
-       qpti->qhost->irq = qpti->irq = sdev->irqs[0];
+       qpti->qhost->irq = qpti->irq = op->irqs[0];
 
        /* We used to try various overly-clever things to
         * reduce the interrupt processing overhead on
@@ -730,19 +732,21 @@ fail:
        return -1;
 }
 
-static void __init qpti_get_scsi_id(struct qlogicpti *qpti)
+static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti)
 {
-       qpti->scsi_id = prom_getintdefault(qpti->prom_node,
-                                          "initiator-id",
-                                          -1);
+       struct of_device *op = qpti->op;
+       struct device_node *dp;
+
+       dp = op->node;
+
+       qpti->scsi_id = of_getintprop_default(dp, "initiator-id", -1);
        if (qpti->scsi_id == -1)
-               qpti->scsi_id = prom_getintdefault(qpti->prom_node,
-                                                  "scsi-initiator-id",
-                                                  -1);
+               qpti->scsi_id = of_getintprop_default(dp, "scsi-initiator-id",
+                                                     -1);
        if (qpti->scsi_id == -1)
                qpti->scsi_id =
-                       prom_getintdefault(qpti->sdev->bus->prom_node,
-                                          "scsi-initiator-id", 7);
+                       of_getintprop_default(dp->parent,
+                                             "scsi-initiator-id", 7);
        qpti->qhost->this_id = qpti->scsi_id;
        qpti->qhost->max_sectors = 64;
 
@@ -751,12 +755,11 @@ static void __init qpti_get_scsi_id(struct qlogicpti *qpti)
 
 static void qpti_get_bursts(struct qlogicpti *qpti)
 {
-       struct sbus_dev *sdev = qpti->sdev;
+       struct of_device *op = qpti->op;
        u8 bursts, bmask;
 
-       bursts = prom_getintdefault(qpti->prom_node, "burst-sizes", 0xff);
-       bmask = prom_getintdefault(sdev->bus->prom_node,
-                                  "burst-sizes", 0xff);
+       bursts = of_getintprop_default(op->node, "burst-sizes", 0xff);
+       bmask = of_getintprop_default(op->node->parent, "burst-sizes", 0xff);
        if (bmask != 0xff)
                bursts &= bmask;
        if (bursts == 0xff ||
@@ -783,27 +786,27 @@ static void qpti_get_clock(struct qlogicpti *qpti)
 /* The request and response queues must each be aligned
  * on a page boundary.
  */
-static int __init qpti_map_queues(struct qlogicpti *qpti)
+static int __devinit qpti_map_queues(struct qlogicpti *qpti)
 {
-       struct sbus_dev *sdev = qpti->sdev;
+       struct of_device *op = qpti->op;
 
 #define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
-       qpti->res_cpu = sbus_alloc_consistent(sdev,
-                                             QSIZE(RES_QUEUE_LEN),
-                                             &qpti->res_dvma);
+       qpti->res_cpu = dma_alloc_coherent(&op->dev,
+                                          QSIZE(RES_QUEUE_LEN),
+                                          &qpti->res_dvma, GFP_ATOMIC);
        if (qpti->res_cpu == NULL ||
            qpti->res_dvma == 0) {
                printk("QPTI: Cannot map response queue.\n");
                return -1;
        }
 
-       qpti->req_cpu = sbus_alloc_consistent(sdev,
-                                             QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
-                                             &qpti->req_dvma);
+       qpti->req_cpu = dma_alloc_coherent(&op->dev,
+                                          QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
+                                          &qpti->req_dvma, GFP_ATOMIC);
        if (qpti->req_cpu == NULL ||
            qpti->req_dvma == 0) {
-               sbus_free_consistent(sdev, QSIZE(RES_QUEUE_LEN),
-                                    qpti->res_cpu, qpti->res_dvma);
+               dma_free_coherent(&op->dev, QSIZE(RES_QUEUE_LEN),
+                                 qpti->res_cpu, qpti->res_dvma);
                printk("QPTI: Cannot map request queue.\n");
                return -1;
        }
@@ -871,11 +874,13 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
        struct scatterlist *sg, *s;
        int i, n;
 
-       if (Cmnd->use_sg) {
+       if (scsi_bufflen(Cmnd)) {
                int sg_count;
 
-               sg = (struct scatterlist *) Cmnd->request_buffer;
-               sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction);
+               sg = scsi_sglist(Cmnd);
+               sg_count = dma_map_sg(&qpti->op->dev, sg,
+                                     scsi_sg_count(Cmnd),
+                                     Cmnd->sc_data_direction);
 
                ds = cmd->dataseg;
                cmd->segment_cnt = sg_count;
@@ -913,17 +918,8 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
                                ds[i].d_count = sg_dma_len(s);
                        }
                        sg_count -= n;
+                       sg = s;
                }
-       } else if (Cmnd->request_bufflen) {
-               Cmnd->SCp.ptr = (char *)(unsigned long)
-                       sbus_map_single(qpti->sdev,
-                                       Cmnd->request_buffer,
-                                       Cmnd->request_bufflen,
-                                       Cmnd->sc_data_direction);
-
-               cmd->dataseg[0].d_base = (u32) ((unsigned long)Cmnd->SCp.ptr);
-               cmd->dataseg[0].d_count = Cmnd->request_bufflen;
-               cmd->segment_cnt = 1;
        } else {
                cmd->dataseg[0].d_base = 0;
                cmd->dataseg[0].d_count = 0;
@@ -1151,7 +1147,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti)
 
                if (sts->state_flags & SF_GOT_SENSE)
                        memcpy(Cmnd->sense_buffer, sts->req_sense_data,
-                              sizeof(Cmnd->sense_buffer));
+                              SCSI_SENSE_BUFFERSIZE);
 
                if (sts->hdr.entry_type == ENTRY_STATUS)
                        Cmnd->result =
@@ -1159,17 +1155,11 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti)
                else
                        Cmnd->result = DID_ERROR << 16;
 
-               if (Cmnd->use_sg) {
-                       sbus_unmap_sg(qpti->sdev,
-                                     (struct scatterlist *)Cmnd->request_buffer,
-                                     Cmnd->use_sg,
-                                     Cmnd->sc_data_direction);
-               } else if (Cmnd->request_bufflen) {
-                       sbus_unmap_single(qpti->sdev,
-                                         (__u32)((unsigned long)Cmnd->SCp.ptr),
-                                         Cmnd->request_bufflen,
-                                         Cmnd->sc_data_direction);
-               }
+               if (scsi_bufflen(Cmnd))
+                       dma_unmap_sg(&qpti->op->dev,
+                                    scsi_sglist(Cmnd), scsi_sg_count(Cmnd),
+                                    Cmnd->sc_data_direction);
+
                qpti->cmd_count[Cmnd->device->id]--;
                sbus_writew(out_ptr, qpti->qregs + MBOX5);
                Cmnd->host_scribble = (unsigned char *) done_queue;
@@ -1282,34 +1272,32 @@ static struct scsi_host_template qpti_template = {
        .use_clustering         = ENABLE_CLUSTERING,
 };
 
-static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
-       static int nqptis;
-       struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-       struct device_node *dp = dev->node;
        struct scsi_host_template *tpnt = match->data;
+       struct device_node *dp = op->node;
        struct Scsi_Host *host;
        struct qlogicpti *qpti;
+       static int nqptis;
        const char *fcode;
 
        /* Sometimes Antares cards come up not completely
         * setup, and we get a report of a zero IRQ.
         */
-       if (sdev->irqs[0] == 0)
+       if (op->irqs[0] == 0)
                return -ENODEV;
 
        host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti));
        if (!host)
                return -ENOMEM;
 
-       qpti = (struct qlogicpti *) host->hostdata;
+       qpti = shost_priv(host);
 
        host->max_id = MAX_TARGETS;
        qpti->qhost = host;
-       qpti->sdev = sdev;
+       qpti->op = op;
        qpti->qpti_id = nqptis;
-       qpti->prom_node = sdev->prom_node;
-       strcpy(qpti->prom_name, sdev->ofdev.node->name);
+       strcpy(qpti->prom_name, op->node->name);
        qpti->is_pti = strcmp(qpti->prom_name, "QLGC,isp");
 
        if (qpti_map_regs(qpti) < 0)
@@ -1355,12 +1343,12 @@ static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_devi
                (qpti->ultra ? "Ultra" : "Fast"),
                (qpti->differential ? "differential" : "single ended"));
 
-       if (scsi_add_host(host, &dev->dev)) {
+       if (scsi_add_host(host, &op->dev)) {
                printk("qlogicpti%d: Failed scsi_add_host\n", qpti->qpti_id);
                goto fail_unmap_queues;
        }
 
-       dev_set_drvdata(&sdev->ofdev.dev, qpti);
+       dev_set_drvdata(&op->dev, qpti);
 
        qpti_chain_add(qpti);
 
@@ -1371,19 +1359,20 @@ static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_devi
 
 fail_unmap_queues:
 #define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
-       sbus_free_consistent(qpti->sdev,
-                            QSIZE(RES_QUEUE_LEN),
-                            qpti->res_cpu, qpti->res_dvma);
-       sbus_free_consistent(qpti->sdev,
-                            QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
-                            qpti->req_cpu, qpti->req_dvma);
+       dma_free_coherent(&op->dev,
+                         QSIZE(RES_QUEUE_LEN),
+                         qpti->res_cpu, qpti->res_dvma);
+       dma_free_coherent(&op->dev,
+                         QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
+                         qpti->req_cpu, qpti->req_dvma);
 #undef QSIZE
 
 fail_unmap_regs:
-       sbus_iounmap(qpti->qregs,
-                    qpti->sdev->reg_addrs[0].reg_size);
+       of_iounmap(&op->resource[0], qpti->qregs,
+                  resource_size(&op->resource[0]));
        if (qpti->is_pti)
-               sbus_iounmap(qpti->sreg, sizeof(unsigned char));
+               of_iounmap(&op->resource[0], qpti->sreg,
+                          sizeof(unsigned char));
 
 fail_free_irq:
        free_irq(qpti->irq, qpti);
@@ -1394,9 +1383,9 @@ fail_unlink:
        return -ENODEV;
 }
 
-static int __devexit qpti_sbus_remove(struct of_device *dev)
+static int __devexit qpti_sbus_remove(struct of_device *op)
 {
-       struct qlogicpti *qpti = dev_get_drvdata(&dev->dev);
+       struct qlogicpti *qpti = dev_get_drvdata(&op->dev);
 
        qpti_chain_del(qpti);
 
@@ -1409,24 +1398,25 @@ static int __devexit qpti_sbus_remove(struct of_device *dev)
        free_irq(qpti->irq, qpti);
 
 #define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
-       sbus_free_consistent(qpti->sdev,
-                            QSIZE(RES_QUEUE_LEN),
-                            qpti->res_cpu, qpti->res_dvma);
-       sbus_free_consistent(qpti->sdev,
-                            QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
-                            qpti->req_cpu, qpti->req_dvma);
+       dma_free_coherent(&op->dev,
+                         QSIZE(RES_QUEUE_LEN),
+                         qpti->res_cpu, qpti->res_dvma);
+       dma_free_coherent(&op->dev,
+                         QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
+                         qpti->req_cpu, qpti->req_dvma);
 #undef QSIZE
 
-       sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size);
+       of_iounmap(&op->resource[0], qpti->qregs,
+                  resource_size(&op->resource[0]));
        if (qpti->is_pti)
-               sbus_iounmap(qpti->sreg, sizeof(unsigned char));
+               of_iounmap(&op->resource[0], qpti->sreg, sizeof(unsigned char));
 
        scsi_host_put(qpti->qhost);
 
        return 0;
 }
 
-static struct of_device_id qpti_match[] = {
+static const struct of_device_id qpti_match[] = {
        {
                .name = "ptisp",
                .data = &qpti_template,
@@ -1456,7 +1446,7 @@ static struct of_platform_driver qpti_sbus_driver = {
 
 static int __init qpti_init(void)
 {
-       return of_register_driver(&qpti_sbus_driver, &sbus_bus_type);
+       return of_register_driver(&qpti_sbus_driver, &of_bus_type);
 }
 
 static void __exit qpti_exit(void)
@@ -1467,7 +1457,7 @@ static void __exit qpti_exit(void)
 MODULE_DESCRIPTION("QlogicISP SBUS driver");
 MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("2.0");
+MODULE_VERSION("2.1");
 
 module_init(qpti_init);
 module_exit(qpti_exit);