aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/advansys.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/advansys.c')
-rw-r--r--drivers/scsi/advansys.c387
1 files changed, 189 insertions, 198 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index a5bb4e416bea..e2bd4c9e7c22 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -461,23 +461,13 @@ typedef struct asc_risc_sg_list_q {
461/* 461/*
462 * Error code values are set in ASC_DVC_VAR 'err_code'. 462 * Error code values are set in ASC_DVC_VAR 'err_code'.
463 */ 463 */
464#define ASC_IERR_WRITE_EEPROM 0x0001
465#define ASC_IERR_MCODE_CHKSUM 0x0002 464#define ASC_IERR_MCODE_CHKSUM 0x0002
466#define ASC_IERR_SET_PC_ADDR 0x0004 465#define ASC_IERR_SET_PC_ADDR 0x0004
467#define ASC_IERR_START_STOP_CHIP 0x0008 466#define ASC_IERR_START_STOP_CHIP 0x0008
468#define ASC_IERR_IRQ_NO 0x0010
469#define ASC_IERR_SET_IRQ_NO 0x0020
470#define ASC_IERR_CHIP_VERSION 0x0040
471#define ASC_IERR_SET_SCSI_ID 0x0080 467#define ASC_IERR_SET_SCSI_ID 0x0080
472#define ASC_IERR_GET_PHY_ADDR 0x0100
473#define ASC_IERR_BAD_SIGNATURE 0x0200 468#define ASC_IERR_BAD_SIGNATURE 0x0200
474#define ASC_IERR_NO_BUS_TYPE 0x0400 469#define ASC_IERR_NO_BUS_TYPE 0x0400
475#define ASC_IERR_SCAM 0x0800
476#define ASC_IERR_SET_SDTR 0x1000
477#define ASC_IERR_RW_LRAM 0x8000
478 470
479#define ASC_MAX_IRQ_NO 15
480#define ASC_MIN_IRQ_NO 10
481#define ASC_DEF_MAX_TOTAL_QNG (0xF0) 471#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
482#define ASC_MIN_TAG_Q_PER_DVC (0x04) 472#define ASC_MIN_TAG_Q_PER_DVC (0x04)
483#define ASC_MIN_FREE_Q (0x02) 473#define ASC_MIN_FREE_Q (0x02)
@@ -605,7 +595,6 @@ typedef struct asc_dvc_var {
605 uchar max_total_qng; 595 uchar max_total_qng;
606 uchar cur_total_qng; 596 uchar cur_total_qng;
607 uchar in_critical_cnt; 597 uchar in_critical_cnt;
608 uchar irq_no;
609 uchar last_q_shortage; 598 uchar last_q_shortage;
610 ushort init_state; 599 ushort init_state;
611 uchar cur_dvc_qng[ASC_MAX_TID + 1]; 600 uchar cur_dvc_qng[ASC_MAX_TID + 1];
@@ -1711,11 +1700,9 @@ typedef struct adveep_38C1600_config {
1711/* 1700/*
1712 * Error code values are set in ADV_DVC_VAR 'err_code'. 1701 * Error code values are set in ADV_DVC_VAR 'err_code'.
1713 */ 1702 */
1714#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
1715#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */ 1703#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
1716#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */ 1704#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
1717#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */ 1705#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
1718#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
1719#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */ 1706#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
1720#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */ 1707#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
1721#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */ 1708#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
@@ -1919,7 +1906,6 @@ typedef struct adv_dvc_var {
1919 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */ 1906 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
1920 uchar chip_no; /* should be assigned by caller */ 1907 uchar chip_no; /* should be assigned by caller */
1921 uchar max_host_qng; /* maximum number of Q'ed command allowed */ 1908 uchar max_host_qng; /* maximum number of Q'ed command allowed */
1922 uchar irq_no; /* IRQ number */
1923 ushort no_scam; /* scam_tolerant of EEPROM */ 1909 ushort no_scam; /* scam_tolerant of EEPROM */
1924 struct asc_board *drv_ptr; /* driver pointer to private structure */ 1910 struct asc_board *drv_ptr; /* driver pointer to private structure */
1925 uchar chip_scsi_id; /* chip SCSI target ID */ 1911 uchar chip_scsi_id; /* chip SCSI target ID */
@@ -2501,6 +2487,7 @@ typedef struct asc_board {
2501 struct device *dev; 2487 struct device *dev;
2502 int id; /* Board Id */ 2488 int id; /* Board Id */
2503 uint flags; /* Board flags */ 2489 uint flags; /* Board flags */
2490 unsigned int irq;
2504 union { 2491 union {
2505 ASC_DVC_VAR asc_dvc_var; /* Narrow board */ 2492 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2506 ADV_DVC_VAR adv_dvc_var; /* Wide board */ 2493 ADV_DVC_VAR adv_dvc_var; /* Wide board */
@@ -2573,7 +2560,7 @@ static void asc_prt_scsi_host(struct Scsi_Host *s)
2573 s->host_busy, s->host_no, (unsigned)s->last_reset); 2560 s->host_busy, s->host_no, (unsigned)s->last_reset);
2574 2561
2575 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n", 2562 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
2576 (ulong)s->base, (ulong)s->io_port, s->irq); 2563 (ulong)s->base, (ulong)s->io_port, boardp->irq);
2577 2564
2578 printk(" dma_channel %d, this_id %d, can_queue %d,\n", 2565 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2579 s->dma_channel, s->this_id, s->can_queue); 2566 s->dma_channel, s->this_id, s->can_queue);
@@ -2651,7 +2638,7 @@ static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
2651 (unsigned)h->init_state, (unsigned)h->no_scam, 2638 (unsigned)h->init_state, (unsigned)h->no_scam,
2652 (unsigned)h->pci_fix_asyn_xfer); 2639 (unsigned)h->pci_fix_asyn_xfer);
2653 2640
2654 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no); 2641 printk(" cfg 0x%lx\n", (ulong)h->cfg);
2655} 2642}
2656 2643
2657/* 2644/*
@@ -2749,9 +2736,8 @@ static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
2749 (ulong)h->isr_callback, (unsigned)h->sdtr_able, 2736 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
2750 (unsigned)h->wdtr_able); 2737 (unsigned)h->wdtr_able);
2751 2738
2752 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n", 2739 printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n",
2753 (unsigned)h->start_motor, 2740 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2754 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
2755 2741
2756 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n", 2742 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
2757 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng, 2743 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
@@ -2958,7 +2944,7 @@ static const char *advansys_info(struct Scsi_Host *shost)
2958 ASC_VERSION, busname, 2944 ASC_VERSION, busname,
2959 (ulong)shost->io_port, 2945 (ulong)shost->io_port,
2960 (ulong)shost->io_port + ASC_IOADR_GAP - 1, 2946 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2961 shost->irq, shost->dma_channel); 2947 boardp->irq, shost->dma_channel);
2962 } else { 2948 } else {
2963 if (asc_dvc_varp->bus_type & ASC_IS_VL) { 2949 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2964 busname = "VL"; 2950 busname = "VL";
@@ -2981,7 +2967,7 @@ static const char *advansys_info(struct Scsi_Host *shost)
2981 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", 2967 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
2982 ASC_VERSION, busname, (ulong)shost->io_port, 2968 ASC_VERSION, busname, (ulong)shost->io_port,
2983 (ulong)shost->io_port + ASC_IOADR_GAP - 1, 2969 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2984 shost->irq); 2970 boardp->irq);
2985 } 2971 }
2986 } else { 2972 } else {
2987 /* 2973 /*
@@ -3002,7 +2988,7 @@ static const char *advansys_info(struct Scsi_Host *shost)
3002 sprintf(info, 2988 sprintf(info,
3003 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X", 2989 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
3004 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base, 2990 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
3005 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq); 2991 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
3006 } 2992 }
3007 BUG_ON(strlen(info) >= ASC_INFO_SIZE); 2993 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
3008 ASC_DBG(1, "advansys_info: end\n"); 2994 ASC_DBG(1, "advansys_info: end\n");
@@ -11479,77 +11465,6 @@ AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
11479 return AscGetChipVerNo(iop_base); 11465 return AscGetChipVerNo(iop_base);
11480} 11466}
11481 11467
11482static void __devinit AscToggleIRQAct(PortAddr iop_base)
11483{
11484 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
11485 AscSetChipStatus(iop_base, 0);
11486 return;
11487}
11488
11489static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
11490{
11491 ushort cfg_lsw;
11492 uchar chip_irq;
11493
11494 if ((bus_type & ASC_IS_EISA) != 0) {
11495 cfg_lsw = AscGetEisaChipCfg(iop_base);
11496 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
11497 if ((chip_irq == 13) || (chip_irq > 15)) {
11498 return (0);
11499 }
11500 return (chip_irq);
11501 }
11502 if ((bus_type & ASC_IS_VL) != 0) {
11503 cfg_lsw = AscGetChipCfgLsw(iop_base);
11504 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
11505 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
11506 return (0);
11507 }
11508 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
11509 }
11510 cfg_lsw = AscGetChipCfgLsw(iop_base);
11511 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
11512 if (chip_irq == 3)
11513 chip_irq += (uchar)2;
11514 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
11515}
11516
11517static uchar __devinit
11518AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
11519{
11520 ushort cfg_lsw;
11521
11522 if ((bus_type & ASC_IS_VL) != 0) {
11523 if (irq_no != 0) {
11524 if ((irq_no < ASC_MIN_IRQ_NO)
11525 || (irq_no > ASC_MAX_IRQ_NO)) {
11526 irq_no = 0;
11527 } else {
11528 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
11529 }
11530 }
11531 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
11532 cfg_lsw |= (ushort)0x0010;
11533 AscSetChipCfgLsw(iop_base, cfg_lsw);
11534 AscToggleIRQAct(iop_base);
11535 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
11536 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
11537 AscSetChipCfgLsw(iop_base, cfg_lsw);
11538 AscToggleIRQAct(iop_base);
11539 return (AscGetChipIRQ(iop_base, bus_type));
11540 }
11541 if ((bus_type & (ASC_IS_ISA)) != 0) {
11542 if (irq_no == 15)
11543 irq_no -= (uchar)2;
11544 irq_no -= (uchar)ASC_MIN_IRQ_NO;
11545 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
11546 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
11547 AscSetChipCfgLsw(iop_base, cfg_lsw);
11548 return (AscGetChipIRQ(iop_base, bus_type));
11549 }
11550 return (0);
11551}
11552
11553#ifdef CONFIG_ISA 11468#ifdef CONFIG_ISA
11554static void __devinit AscEnableIsaDma(uchar dma_channel) 11469static void __devinit AscEnableIsaDma(uchar dma_channel)
11555{ 11470{
@@ -12157,9 +12072,6 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
12157 eep_config->disc_enable = eep_config->use_cmd_qng; 12072 eep_config->disc_enable = eep_config->use_cmd_qng;
12158 warn_code |= ASC_WARN_CMD_QNG_CONFLICT; 12073 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12159 } 12074 }
12160 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12161 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12162 }
12163 ASC_EEP_SET_CHIP_ID(eep_config, 12075 ASC_EEP_SET_CHIP_ID(eep_config,
12164 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID); 12076 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12165 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config); 12077 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
@@ -12276,12 +12188,6 @@ static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp)
12276 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { 12188 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12277 warn_code |= ASC_WARN_AUTO_CONFIG; 12189 warn_code |= ASC_WARN_AUTO_CONFIG;
12278 } 12190 }
12279 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12280 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12281 != asc_dvc->irq_no) {
12282 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
12283 }
12284 }
12285#ifdef CONFIG_PCI 12191#ifdef CONFIG_PCI
12286 if (asc_dvc->bus_type & ASC_IS_PCI) { 12192 if (asc_dvc->bus_type & ASC_IS_PCI) {
12287 cfg_msw &= 0xFFC0; 12193 cfg_msw &= 0xFFC0;
@@ -13879,49 +13785,19 @@ static void advansys_wide_free_mem(asc_board_t *boardp)
13879 } 13785 }
13880} 13786}
13881 13787
13882static struct Scsi_Host *__devinit 13788static int __devinit advansys_board_found(struct Scsi_Host *shost,
13883advansys_board_found(int iop, struct device *dev, int bus_type) 13789 unsigned int iop, int bus_type)
13884{ 13790{
13885 struct Scsi_Host *shost; 13791 struct pci_dev *pdev;
13886 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
13887 asc_board_t *boardp; 13792 asc_board_t *boardp;
13888 ASC_DVC_VAR *asc_dvc_varp = NULL; 13793 ASC_DVC_VAR *asc_dvc_varp = NULL;
13889 ADV_DVC_VAR *adv_dvc_varp = NULL; 13794 ADV_DVC_VAR *adv_dvc_varp = NULL;
13890 int share_irq; 13795 int share_irq, warn_code, ret;
13891 int warn_code, err_code;
13892 int ret;
13893
13894 /*
13895 * Register the adapter, get its configuration, and
13896 * initialize it.
13897 */
13898 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
13899 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
13900 if (!shost)
13901 return NULL;
13902 13796
13903 /* Initialize private per board data */
13904 boardp = ASC_BOARDP(shost); 13797 boardp = ASC_BOARDP(shost);
13905 memset(boardp, 0, sizeof(asc_board_t));
13906 boardp->id = asc_board_count++; 13798 boardp->id = asc_board_count++;
13907 spin_lock_init(&boardp->lock); 13799 spin_lock_init(&boardp->lock);
13908 boardp->dev = dev; 13800 pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
13909
13910 /*
13911 * Handle both narrow and wide boards.
13912 *
13913 * If a Wide board was detected, set the board structure
13914 * wide board flag. Set-up the board structure based on
13915 * the board type.
13916 */
13917#ifdef CONFIG_PCI
13918 if (bus_type == ASC_IS_PCI &&
13919 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
13920 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
13921 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
13922 boardp->flags |= ASC_IS_WIDE_BOARD;
13923 }
13924#endif /* CONFIG_PCI */
13925 13801
13926 if (ASC_NARROW_BOARD(boardp)) { 13802 if (ASC_NARROW_BOARD(boardp)) {
13927 ASC_DBG(1, "advansys_board_found: narrow board\n"); 13803 ASC_DBG(1, "advansys_board_found: narrow board\n");
@@ -13956,6 +13832,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
13956 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n", 13832 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
13957 boardp->id, pci_resource_start(pdev, 1), 13833 boardp->id, pci_resource_start(pdev, 1),
13958 boardp->asc_n_io_port); 13834 boardp->asc_n_io_port);
13835 ret = -ENODEV;
13959 goto err_shost; 13836 goto err_shost;
13960 } 13837 }
13961 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr 13838 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
@@ -13984,6 +13861,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
13984 if (!boardp->prtbuf) { 13861 if (!boardp->prtbuf) {
13985 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) " 13862 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
13986 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE); 13863 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
13864 ret = -ENOMEM;
13987 goto err_unmap; 13865 goto err_unmap;
13988 } 13866 }
13989#endif /* CONFIG_PROC_FS */ 13867#endif /* CONFIG_PROC_FS */
@@ -14010,7 +13888,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
14010#endif /* CONFIG_ISA */ 13888#endif /* CONFIG_ISA */
14011#ifdef CONFIG_PCI 13889#ifdef CONFIG_PCI
14012 case ASC_IS_PCI: 13890 case ASC_IS_PCI:
14013 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
14014 shost->unchecked_isa_dma = FALSE; 13891 shost->unchecked_isa_dma = FALSE;
14015 share_irq = IRQF_SHARED; 13892 share_irq = IRQF_SHARED;
14016 break; 13893 break;
@@ -14031,23 +13908,22 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
14031 * referenced only use the bit-wise AND operator "&". 13908 * referenced only use the bit-wise AND operator "&".
14032 */ 13909 */
14033 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n"); 13910 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
14034 err_code = AscInitGetConfig(boardp); 13911 ret = AscInitGetConfig(boardp) ? -ENODEV : 0;
14035 } else { 13912 } else {
14036#ifdef CONFIG_PCI 13913#ifdef CONFIG_PCI
14037 /* 13914 /*
14038 * For Wide boards set PCI information before calling 13915 * For Wide boards set PCI information before calling
14039 * AdvInitGetConfig(). 13916 * AdvInitGetConfig().
14040 */ 13917 */
14041 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
14042 shost->unchecked_isa_dma = FALSE; 13918 shost->unchecked_isa_dma = FALSE;
14043 share_irq = IRQF_SHARED; 13919 share_irq = IRQF_SHARED;
14044 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n"); 13920 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
14045 13921
14046 err_code = AdvInitGetConfig(pdev, boardp); 13922 ret = AdvInitGetConfig(pdev, boardp) ? -ENODEV : 0;
14047#endif /* CONFIG_PCI */ 13923#endif /* CONFIG_PCI */
14048 } 13924 }
14049 13925
14050 if (err_code != 0) 13926 if (ret)
14051 goto err_free_proc; 13927 goto err_free_proc;
14052 13928
14053 /* 13929 /*
@@ -14091,17 +13967,9 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
14091 * Modify board configuration. 13967 * Modify board configuration.
14092 */ 13968 */
14093 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n"); 13969 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
14094 err_code = AscInitSetConfig(pdev, boardp); 13970 ret = AscInitSetConfig(pdev, boardp) ? -ENODEV : 0;
14095 if (err_code) 13971 if (ret)
14096 goto err_free_proc; 13972 goto err_free_proc;
14097
14098 /*
14099 * Finish initializing the 'Scsi_Host' structure.
14100 */
14101 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
14102 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
14103 shost->irq = asc_dvc_varp->irq_no;
14104 }
14105 } else { 13973 } else {
14106 ADVEEP_3550_CONFIG *ep_3550; 13974 ADVEEP_3550_CONFIG *ep_3550;
14107 ADVEEP_38C0800_CONFIG *ep_38C0800; 13975 ADVEEP_38C0800_CONFIG *ep_38C0800;
@@ -14346,24 +14214,24 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
14346#endif /* CONFIG_ISA */ 14214#endif /* CONFIG_ISA */
14347 14215
14348 /* Register IRQ Number. */ 14216 /* Register IRQ Number. */
14349 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq); 14217 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", boardp->irq);
14350 14218
14351 ret = request_irq(shost->irq, advansys_interrupt, share_irq, 14219 ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
14352 DRV_NAME, shost); 14220 DRV_NAME, shost);
14353 14221
14354 if (ret) { 14222 if (ret) {
14355 if (ret == -EBUSY) { 14223 if (ret == -EBUSY) {
14356 ASC_PRINT2 14224 ASC_PRINT2
14357 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n", 14225 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
14358 boardp->id, shost->irq); 14226 boardp->id, boardp->irq);
14359 } else if (ret == -EINVAL) { 14227 } else if (ret == -EINVAL) {
14360 ASC_PRINT2 14228 ASC_PRINT2
14361 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n", 14229 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
14362 boardp->id, shost->irq); 14230 boardp->id, boardp->irq);
14363 } else { 14231 } else {
14364 ASC_PRINT3 14232 ASC_PRINT3
14365 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n", 14233 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
14366 boardp->id, shost->irq, ret); 14234 boardp->id, boardp->irq, ret);
14367 } 14235 }
14368 goto err_free_dma; 14236 goto err_free_dma;
14369 } 14237 }
@@ -14374,33 +14242,35 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
14374 if (ASC_NARROW_BOARD(boardp)) { 14242 if (ASC_NARROW_BOARD(boardp)) {
14375 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n"); 14243 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
14376 warn_code = AscInitAsc1000Driver(asc_dvc_varp); 14244 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
14377 err_code = asc_dvc_varp->err_code;
14378 14245
14379 if (warn_code || err_code) { 14246 if (warn_code || asc_dvc_varp->err_code) {
14380 ASC_PRINT4 14247 ASC_PRINT4("advansys_board_found: board %d error: "
14381 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n", 14248 "init_state 0x%x, warn 0x%x, error 0x%x\n",
14382 boardp->id, 14249 boardp->id, asc_dvc_varp->init_state,
14383 asc_dvc_varp->init_state, warn_code, err_code); 14250 warn_code, asc_dvc_varp->err_code);
14251 if (asc_dvc_varp->err_code)
14252 ret = -ENODEV;
14384 } 14253 }
14385 } else { 14254 } else {
14386 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp); 14255 if (advansys_wide_init_chip(boardp, adv_dvc_varp))
14256 ret = -ENODEV;
14387 } 14257 }
14388 14258
14389 if (err_code != 0) 14259 if (ret)
14390 goto err_free_wide_mem; 14260 goto err_free_wide_mem;
14391 14261
14392 ASC_DBG_PRT_SCSI_HOST(2, shost); 14262 ASC_DBG_PRT_SCSI_HOST(2, shost);
14393 14263
14394 ret = scsi_add_host(shost, dev); 14264 ret = scsi_add_host(shost, boardp->dev);
14395 if (ret) 14265 if (ret)
14396 goto err_free_wide_mem; 14266 goto err_free_wide_mem;
14397 14267
14398 scsi_scan_host(shost); 14268 scsi_scan_host(shost);
14399 return shost; 14269 return 0;
14400 14270
14401 err_free_wide_mem: 14271 err_free_wide_mem:
14402 advansys_wide_free_mem(boardp); 14272 advansys_wide_free_mem(boardp);
14403 free_irq(shost->irq, shost); 14273 free_irq(boardp->irq, shost);
14404 err_free_dma: 14274 err_free_dma:
14405 if (shost->dma_channel != NO_ISA_DMA) 14275 if (shost->dma_channel != NO_ISA_DMA)
14406 free_dma(shost->dma_channel); 14276 free_dma(shost->dma_channel);
@@ -14410,8 +14280,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
14410 if (boardp->ioremap_addr) 14280 if (boardp->ioremap_addr)
14411 iounmap(boardp->ioremap_addr); 14281 iounmap(boardp->ioremap_addr);
14412 err_shost: 14282 err_shost:
14413 scsi_host_put(shost); 14283 return ret;
14414 return NULL;
14415} 14284}
14416 14285
14417/* 14286/*
@@ -14426,7 +14295,7 @@ static int advansys_release(struct Scsi_Host *shost)
14426 ASC_DBG(1, "advansys_release: begin\n"); 14295 ASC_DBG(1, "advansys_release: begin\n");
14427 scsi_remove_host(shost); 14296 scsi_remove_host(shost);
14428 boardp = ASC_BOARDP(shost); 14297 boardp = ASC_BOARDP(shost);
14429 free_irq(shost->irq, shost); 14298 free_irq(boardp->irq, shost);
14430 if (shost->dma_channel != NO_ISA_DMA) { 14299 if (shost->dma_channel != NO_ISA_DMA) {
14431 ASC_DBG(1, "advansys_release: free_dma()\n"); 14300 ASC_DBG(1, "advansys_release: free_dma()\n");
14432 free_dma(shost->dma_channel); 14301 free_dma(shost->dma_channel);
@@ -14448,10 +14317,28 @@ static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
14448 0x0210, 0x0230, 0x0250, 0x0330 14317 0x0210, 0x0230, 0x0250, 0x0330
14449}; 14318};
14450 14319
14320/*
14321 * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw. It decodes as:
14322 * 00: 10
14323 * 01: 11
14324 * 10: 12
14325 * 11: 15
14326 */
14327static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base)
14328{
14329 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14330 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
14331 if (chip_irq == 13)
14332 chip_irq = 15;
14333 return chip_irq;
14334}
14335
14451static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) 14336static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14452{ 14337{
14338 int err = -ENODEV;
14453 PortAddr iop_base = _asc_def_iop_base[id]; 14339 PortAddr iop_base = _asc_def_iop_base[id];
14454 struct Scsi_Host *shost; 14340 struct Scsi_Host *shost;
14341 struct asc_board *board;
14455 14342
14456 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { 14343 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14457 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n", 14344 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
@@ -14460,20 +14347,31 @@ static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14460 } 14347 }
14461 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base); 14348 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
14462 if (!AscFindSignature(iop_base)) 14349 if (!AscFindSignature(iop_base))
14463 goto nodev; 14350 goto release_region;
14464 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT)) 14351 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
14465 goto nodev; 14352 goto release_region;
14466 14353
14467 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA); 14354 err = -ENOMEM;
14355 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14468 if (!shost) 14356 if (!shost)
14469 goto nodev; 14357 goto release_region;
14358
14359 board = ASC_BOARDP(shost);
14360 board->irq = advansys_isa_irq_no(iop_base);
14361 board->dev = dev;
14362
14363 err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
14364 if (err)
14365 goto free_host;
14470 14366
14471 dev_set_drvdata(dev, shost); 14367 dev_set_drvdata(dev, shost);
14472 return 0; 14368 return 0;
14473 14369
14474 nodev: 14370 free_host:
14371 scsi_host_put(shost);
14372 release_region:
14475 release_region(iop_base, ASC_IOADR_GAP); 14373 release_region(iop_base, ASC_IOADR_GAP);
14476 return -ENODEV; 14374 return err;
14477} 14375}
14478 14376
14479static int __devexit advansys_isa_remove(struct device *dev, unsigned int id) 14377static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
@@ -14493,10 +14391,32 @@ static struct isa_driver advansys_isa_driver = {
14493 }, 14391 },
14494}; 14392};
14495 14393
14394/*
14395 * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw. It decodes as:
14396 * 000: invalid
14397 * 001: 10
14398 * 010: 11
14399 * 011: 12
14400 * 100: invalid
14401 * 101: 14
14402 * 110: 15
14403 * 111: invalid
14404 */
14405static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base)
14406{
14407 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14408 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
14409 if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
14410 return 0;
14411 return chip_irq;
14412}
14413
14496static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) 14414static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14497{ 14415{
14416 int err = -ENODEV;
14498 PortAddr iop_base = _asc_def_iop_base[id]; 14417 PortAddr iop_base = _asc_def_iop_base[id];
14499 struct Scsi_Host *shost; 14418 struct Scsi_Host *shost;
14419 struct asc_board *board;
14500 14420
14501 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { 14421 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14502 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n", 14422 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
@@ -14505,23 +14425,34 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14505 } 14425 }
14506 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base); 14426 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
14507 if (!AscFindSignature(iop_base)) 14427 if (!AscFindSignature(iop_base))
14508 goto nodev; 14428 goto release_region;
14509 /* 14429 /*
14510 * I don't think this condition can actually happen, but the old 14430 * I don't think this condition can actually happen, but the old
14511 * driver did it, and the chances of finding a VLB setup in 2007 14431 * driver did it, and the chances of finding a VLB setup in 2007
14512 * to do testing with is slight to none. 14432 * to do testing with is slight to none.
14513 */ 14433 */
14514 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL) 14434 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14515 goto nodev; 14435 goto release_region;
14516 14436
14517 shost = advansys_board_found(iop_base, dev, ASC_IS_VL); 14437 err = -ENOMEM;
14438 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14518 if (!shost) 14439 if (!shost)
14519 goto nodev; 14440 goto release_region;
14441
14442 board = ASC_BOARDP(shost);
14443 board->irq = advansys_vlb_irq_no(iop_base);
14444 board->dev = dev;
14445
14446 err = advansys_board_found(shost, iop_base, ASC_IS_VL);
14447 if (err)
14448 goto free_host;
14520 14449
14521 dev_set_drvdata(dev, shost); 14450 dev_set_drvdata(dev, shost);
14522 return 0; 14451 return 0;
14523 14452
14524 nodev: 14453 free_host:
14454 scsi_host_put(shost);
14455 release_region:
14525 release_region(iop_base, ASC_IOADR_GAP); 14456 release_region(iop_base, ASC_IOADR_GAP);
14526 return -ENODEV; 14457 return -ENODEV;
14527} 14458}
@@ -14551,9 +14482,29 @@ struct eisa_scsi_data {
14551 struct Scsi_Host *host[2]; 14482 struct Scsi_Host *host[2];
14552}; 14483};
14553 14484
14485/*
14486 * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw. It decodes as:
14487 * 000: 10
14488 * 001: 11
14489 * 010: 12
14490 * 011: invalid
14491 * 100: 14
14492 * 101: 15
14493 * 110: invalid
14494 * 111: invalid
14495 */
14496static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev)
14497{
14498 unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
14499 unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
14500 if ((chip_irq == 13) || (chip_irq > 15))
14501 return 0;
14502 return chip_irq;
14503}
14504
14554static int __devinit advansys_eisa_probe(struct device *dev) 14505static int __devinit advansys_eisa_probe(struct device *dev)
14555{ 14506{
14556 int i, ioport; 14507 int i, ioport, irq = 0;
14557 int err; 14508 int err;
14558 struct eisa_device *edev = to_eisa_device(dev); 14509 struct eisa_device *edev = to_eisa_device(dev);
14559 struct eisa_scsi_data *data; 14510 struct eisa_scsi_data *data;
@@ -14566,6 +14517,8 @@ static int __devinit advansys_eisa_probe(struct device *dev)
14566 14517
14567 err = -ENODEV; 14518 err = -ENODEV;
14568 for (i = 0; i < 2; i++, ioport += 0x20) { 14519 for (i = 0; i < 2; i++, ioport += 0x20) {
14520 struct asc_board *board;
14521 struct Scsi_Host *shost;
14569 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) { 14522 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
14570 printk(KERN_WARNING "Region %x-%x busy\n", ioport, 14523 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14571 ioport + ASC_IOADR_GAP - 1); 14524 ioport + ASC_IOADR_GAP - 1);
@@ -14584,20 +14537,40 @@ static int __devinit advansys_eisa_probe(struct device *dev)
14584 * test with. 14537 * test with.
14585 */ 14538 */
14586 inw(ioport + 4); 14539 inw(ioport + 4);
14587 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA); 14540
14588 if (data->host[i]) { 14541 if (!irq)
14589 err = 0; 14542 irq = advansys_eisa_irq_no(edev);
14590 } else { 14543
14591 release_region(ioport, ASC_IOADR_GAP); 14544 err = -ENOMEM;
14545 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14546 if (!shost)
14547 goto release_region;
14548
14549 board = ASC_BOARDP(shost);
14550 board->irq = irq;
14551 board->dev = dev;
14552
14553 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
14554 if (!err) {
14555 data->host[i] = shost;
14556 continue;
14592 } 14557 }
14593 }
14594 14558
14595 if (err) { 14559 scsi_host_put(shost);
14596 kfree(data); 14560 release_region:
14597 } else { 14561 release_region(ioport, ASC_IOADR_GAP);
14598 dev_set_drvdata(dev, data); 14562 break;
14599 } 14563 }
14600 14564
14565 if (err)
14566 goto free_data;
14567 dev_set_drvdata(dev, data);
14568 return 0;
14569
14570 free_data:
14571 kfree(data->host[0]);
14572 kfree(data->host[1]);
14573 kfree(data);
14601 fail: 14574 fail:
14602 return err; 14575 return err;
14603} 14576}
@@ -14667,6 +14640,7 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14667{ 14640{
14668 int err, ioport; 14641 int err, ioport;
14669 struct Scsi_Host *shost; 14642 struct Scsi_Host *shost;
14643 struct asc_board *board;
14670 14644
14671 err = pci_enable_device(pdev); 14645 err = pci_enable_device(pdev);
14672 if (err) 14646 if (err)
@@ -14677,20 +14651,37 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14677 pci_set_master(pdev); 14651 pci_set_master(pdev);
14678 advansys_set_latency(pdev); 14652 advansys_set_latency(pdev);
14679 14653
14654 err = -ENODEV;
14680 if (pci_resource_len(pdev, 0) == 0) 14655 if (pci_resource_len(pdev, 0) == 0)
14681 goto nodev; 14656 goto release_region;
14682 14657
14683 ioport = pci_resource_start(pdev, 0); 14658 ioport = pci_resource_start(pdev, 0);
14684 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
14685 14659
14660 err = -ENOMEM;
14661 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14686 if (!shost) 14662 if (!shost)
14687 goto nodev; 14663 goto release_region;
14664
14665 board = ASC_BOARDP(shost);
14666 board->irq = pdev->irq;
14667 board->dev = &pdev->dev;
14668
14669 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14670 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14671 pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
14672 board->flags |= ASC_IS_WIDE_BOARD;
14673 }
14674
14675 err = advansys_board_found(shost, ioport, ASC_IS_PCI);
14676 if (err)
14677 goto free_host;
14688 14678
14689 pci_set_drvdata(pdev, shost); 14679 pci_set_drvdata(pdev, shost);
14690 return 0; 14680 return 0;
14691 14681
14692 nodev: 14682 free_host:
14693 err = -ENODEV; 14683 scsi_host_put(shost);
14684 release_region:
14694 pci_release_regions(pdev); 14685 pci_release_regions(pdev);
14695 disable_device: 14686 disable_device:
14696 pci_disable_device(pdev); 14687 pci_disable_device(pdev);