aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2007-10-02 21:55:29 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:53:18 -0400
commitd361db483241489fc4b37cd168c2ce7940a7845b (patch)
tree76550405f5de4a52c1a91c70e751a8ab59e9fd2c
parent9a256fa50e9a9d6bd03e0d6e8eddce9dca4f15f2 (diff)
[SCSI] advansys: Sort out irq number mess
The interrupt number was being stored in 4-5 different places, each with its own type, rules and usage. Fix this by keeping an unsigned int in the struct asc_board, and filling it in from the bus probe functions (since it's different for each of the four bus types). In order to do this, we have to allocate the Scsi_Host in the bus probe functions too. Then we can return an error from advansys_board_found, which requires a little rearranging of code (and removing of the err_code variable). Move the Wide Board flag setting into the PCI bus probe function. Split the AscGetChipIRQ function into three functions (one for each bus type that needs it) and add some commentary to explain what's going on. Also get rid of the AscSetChipIRQ function as we only ever set the interrupt number to the same value it already had. Signed-off-by: Matthew Wilcox <willy@linux.intel.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-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);