genirq: add support for threaded interrupts to devres
[safe/jmp/linux-2.6] / drivers / scsi / advansys.c
index 88e7fef..7507d8b 100644 (file)
@@ -120,7 +120,7 @@ typedef unsigned char uchar;
 #define CC_VERY_LONG_SG_LIST 0
 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
 
-#define PortAddr                 unsigned short        /* port address size  */
+#define PortAddr                 unsigned int  /* port address size  */
 #define inp(port)                inb(port)
 #define outp(port, byte)         outb((byte), (port))
 
@@ -529,7 +529,6 @@ typedef struct asc_dvc_cfg {
        ushort mcode_date;
        ushort mcode_version;
        uchar max_tag_qng[ASC_MAX_TID + 1];
-       uchar *overrun_buf;
        uchar sdtr_period_offset[ASC_MAX_TID + 1];
        uchar adapter_info[6];
 } ASC_DVC_CFG;
@@ -551,6 +550,7 @@ typedef struct asc_dvc_cfg {
 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
 #define ASC_MIN_TAGGED_CMD  7
 #define ASC_MAX_SCSI_RESET_WAIT      30
+#define ASC_OVERRUN_BSIZE              64
 
 struct asc_dvc_var;            /* Forward Declaration. */
 
@@ -566,6 +566,8 @@ typedef struct asc_dvc_var {
        ASC_SCSI_BIT_ID_TYPE unit_not_ready;
        ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
        ASC_SCSI_BIT_ID_TYPE start_motor;
+       uchar *overrun_buf;
+       dma_addr_t overrun_dma;
        uchar scsi_reset_wait;
        uchar chip_no;
        char is_in_int;
@@ -668,7 +670,6 @@ typedef struct asceep_config {
 #define ASC_EEP_CMD_WRITE         0x40
 #define ASC_EEP_CMD_WRITE_ABLE    0x30
 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
-#define ASC_OVERRUN_BSIZE  0x00000048UL
 #define ASCV_MSGOUT_BEG         0x0000
 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
@@ -2277,7 +2278,7 @@ do { \
 #define ASC_DBG(lvl, format, arg...) {                                 \
        if (asc_dbglvl >= (lvl))                                        \
                printk(KERN_DEBUG "%s: %s: " format, DRV_NAME,          \
-                       __FUNCTION__ , ## arg);                         \
+                       __func__ , ## arg);                             \
 }
 
 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
@@ -2404,13 +2405,12 @@ struct asc_board {
        ushort bios_codelen;    /* BIOS Code Segment Length. */
 };
 
+#define asc_dvc_to_board(asc_dvc) container_of(asc_dvc, struct asc_board, \
+                                                       dvc_var.asc_dvc_var)
 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
                                                        dvc_var.adv_dvc_var)
 #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
 
-/* Overrun buffer used by all narrow boards. */
-static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
-
 #ifdef ADVANSYS_DEBUG
 static int asc_dbglvl = 3;
 
@@ -2465,8 +2465,8 @@ static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
                "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed,
                h->isa_dma_channel, h->chip_version);
 
-       printk(" mcode_date 0x%x, mcode_version %d, overrun_buf 0x%p\n",
-               h->mcode_date, h->mcode_version, h->overrun_buf);
+       printk(" mcode_date 0x%x, mcode_version %d\n",
+               h->mcode_date, h->mcode_version);
 }
 
 /*
@@ -2527,7 +2527,7 @@ static void asc_prt_scsi_host(struct Scsi_Host *s)
 {
        struct asc_board *boardp = shost_priv(s);
 
-       printk("Scsi_Host at addr 0x%p, device %s\n", s, boardp->dev->bus_id);
+       printk("Scsi_Host at addr 0x%p, device %s\n", s, dev_name(boardp->dev));
        printk(" host_busy %u, host_no %d, last_reset %d,\n",
               s->host_busy, s->host_no, (unsigned)s->last_reset);
 
@@ -6316,6 +6316,7 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
        PortAddr iop_base;
        ASC_PADDR phy_addr;
        ASC_DCNT phy_size;
+       struct asc_board *board = asc_dvc_to_board(asc_dvc);
 
        iop_base = asc_dvc->iop_base;
        warn_code = 0;
@@ -6330,12 +6331,14 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
        AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
                         ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
 
-       /* Align overrun buffer on an 8 byte boundary. */
-       phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
-       phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
+       /* Ensure overrun buffer is aligned on an 8 byte boundary. */
+       BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
+       asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
+                                       ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+       phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
        AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
                                 (uchar *)&phy_addr, 1);
-       phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
+       phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE);
        AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
                                 (uchar *)&phy_size, 1);
 
@@ -6436,7 +6439,7 @@ static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
                        i += 2;
                        len += 2;
                } else {
-                       unsigned char off = buf[i] * 2;
+                       unsigned int off = buf[i] * 2;
                        unsigned short word = (buf[off + 1] << 8) | buf[off];
                        AdvWriteWordAutoIncLram(iop_base, word);
                        len += 2;
@@ -8230,7 +8233,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
                        if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
                                ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
                                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
-                                                 sizeof(scp->sense_buffer));
+                                                 SCSI_SENSE_BUFFERSIZE);
                                /*
                                 * Note: The 'status_byte()' macro used by
                                 * target drivers defined in scsi.h shifts the
@@ -9133,7 +9136,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
        BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
 
        dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
-                       sizeof(scp->sense_buffer), DMA_FROM_DEVICE);
+                        SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
        /*
         * 'qdonep' contains the command's ending status.
         */
@@ -9163,7 +9166,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
                        if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
                                ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
                                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
-                                                 sizeof(scp->sense_buffer));
+                                                 SCSI_SENSE_BUFFERSIZE);
                                /*
                                 * Note: The 'status_byte()' macro used by
                                 * target drivers defined in scsi.h shifts the
@@ -9878,9 +9881,9 @@ static __le32 advansys_get_sense_buffer_dma(struct scsi_cmnd *scp)
 {
        struct asc_board *board = shost_priv(scp->device->host);
        scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer,
-                               sizeof(scp->sense_buffer), DMA_FROM_DEVICE);
+                                            SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
        dma_cache_sync(board->dev, scp->sense_buffer,
-                               sizeof(scp->sense_buffer), DMA_FROM_DEVICE);
+                      SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
        return cpu_to_le32(scp->SCp.dma_handle);
 }
 
@@ -9911,7 +9914,7 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
        asc_scsi_q->q2.target_ix =
            ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
        asc_scsi_q->q1.sense_addr = advansys_get_sense_buffer_dma(scp);
-       asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
+       asc_scsi_q->q1.sense_len = SCSI_SENSE_BUFFERSIZE;
 
        /*
         * If there are any outstanding requests for the current target,
@@ -10170,7 +10173,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
        scsiqp->target_lun = scp->device->lun;
 
        scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
-       scsiqp->sense_len = sizeof(scp->sense_buffer);
+       scsiqp->sense_len = SCSI_SENSE_BUFFERSIZE;
 
        /* Build ADV_SCSI_REQ_Q */
 
@@ -12258,7 +12261,7 @@ static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-void __devinit
+static void __devinit
 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
 {
        ushort *wbuf;
@@ -12325,7 +12328,7 @@ AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-void __devinit
+static void __devinit
 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
 {
        ushort *wbuf;
@@ -12392,7 +12395,7 @@ AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-void __devinit
+static void __devinit
 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
 {
        ushort *wbuf;
@@ -13330,8 +13333,8 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
 
        }
 
-       ASC_DBG(1, "sg_cnt %d * %u = %u bytes\n", sg_cnt, sizeof(adv_sgblk_t),
-                (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
+       ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", sg_cnt, sizeof(adv_sgblk_t),
+                sizeof(adv_sgblk_t) * sg_cnt);
 
        if (!board->adv_sgblkp)
                goto kmalloc_failed;
@@ -13404,7 +13407,6 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                asc_dvc_varp->bus_type = bus_type;
                asc_dvc_varp->drv_ptr = boardp;
                asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
-               asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
                asc_dvc_varp->iop_base = iop;
        } else {
 #ifdef CONFIG_PCI
@@ -13423,12 +13425,11 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                }
 
                boardp->asc_n_io_port = pci_resource_len(pdev, 1);
-               boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
-                                              boardp->asc_n_io_port);
+               boardp->ioremap_addr = pci_ioremap_bar(pdev, 1);
                if (!boardp->ioremap_addr) {
-                       shost_printk(KERN_ERR, shost, "ioremap(%x, %d) "
+                       shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) "
                                        "returned NULL\n",
-                                       pci_resource_start(pdev, 1),
+                                       (long)pci_resource_start(pdev, 1),
                                        boardp->asc_n_io_port);
                        ret = -ENODEV;
                        goto err_shost;
@@ -13831,6 +13832,12 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
         */
        if (ASC_NARROW_BOARD(boardp)) {
                ASC_DBG(2, "AscInitAsc1000Driver()\n");
+
+               asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
+               if (!asc_dvc_varp->overrun_buf) {
+                       ret = -ENOMEM;
+                       goto err_free_wide_mem;
+               }
                warn_code = AscInitAsc1000Driver(asc_dvc_varp);
 
                if (warn_code || asc_dvc_varp->err_code) {
@@ -13838,8 +13845,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                                        "warn 0x%x, error 0x%x\n",
                                        asc_dvc_varp->init_state, warn_code,
                                        asc_dvc_varp->err_code);
-                       if (asc_dvc_varp->err_code)
+                       if (asc_dvc_varp->err_code) {
                                ret = -ENODEV;
+                               kfree(asc_dvc_varp->overrun_buf);
+                       }
                }
        } else {
                if (advansys_wide_init_chip(shost))
@@ -13862,8 +13871,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
        advansys_wide_free_mem(boardp);
        free_irq(boardp->irq, shost);
  err_free_dma:
+#ifdef CONFIG_ISA
        if (shost->dma_channel != NO_ISA_DMA)
                free_dma(shost->dma_channel);
+#endif
  err_free_proc:
        kfree(boardp->prtbuf);
  err_unmap:
@@ -13880,19 +13891,26 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
  */
 static int advansys_release(struct Scsi_Host *shost)
 {
-       struct asc_board *boardp = shost_priv(shost);
+       struct asc_board *board = shost_priv(shost);
        ASC_DBG(1, "begin\n");
        scsi_remove_host(shost);
-       free_irq(boardp->irq, shost);
+       free_irq(board->irq, shost);
+#ifdef CONFIG_ISA
        if (shost->dma_channel != NO_ISA_DMA) {
                ASC_DBG(1, "free_dma()\n");
                free_dma(shost->dma_channel);
        }
-       if (!ASC_NARROW_BOARD(boardp)) {
-               iounmap(boardp->ioremap_addr);
-               advansys_wide_free_mem(boardp);
+#endif
+       if (ASC_NARROW_BOARD(board)) {
+               dma_unmap_single(board->dev,
+                                       board->dvc_var.asc_dvc_var.overrun_dma,
+                                       ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+               kfree(board->dvc_var.asc_dvc_var.overrun_buf);
+       } else {
+               iounmap(board->ioremap_addr);
+               advansys_wide_free_mem(board);
        }
-       kfree(boardp->prtbuf);
+       kfree(board->prtbuf);
        scsi_host_put(shost);
        ASC_DBG(1, "end\n");
        return 0;
@@ -13900,7 +13918,7 @@ static int advansys_release(struct Scsi_Host *shost)
 
 #define ASC_IOADR_TABLE_MAX_IX  11
 
-static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
+static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = {
        0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
        0x0210, 0x0230, 0x0250, 0x0330
 };