diff options
Diffstat (limited to 'drivers/scsi/advansys.c')
-rw-r--r-- | drivers/scsi/advansys.c | 387 |
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 | ||
11482 | static void __devinit AscToggleIRQAct(PortAddr iop_base) | ||
11483 | { | ||
11484 | AscSetChipStatus(iop_base, CIW_IRQ_ACT); | ||
11485 | AscSetChipStatus(iop_base, 0); | ||
11486 | return; | ||
11487 | } | ||
11488 | |||
11489 | static 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 | |||
11517 | static uchar __devinit | ||
11518 | AscSetChipIRQ(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 |
11554 | static void __devinit AscEnableIsaDma(uchar dma_channel) | 11469 | static 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 | ||
13882 | static struct Scsi_Host *__devinit | 13788 | static int __devinit advansys_board_found(struct Scsi_Host *shost, |
13883 | advansys_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 | */ | ||
14327 | static 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 | |||
14451 | static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) | 14336 | static 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 | ||
14479 | static int __devexit advansys_isa_remove(struct device *dev, unsigned int id) | 14377 | static 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 | */ | ||
14405 | static 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 | |||
14496 | static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) | 14414 | static 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 | */ | ||
14496 | static 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 | |||
14554 | static int __devinit advansys_eisa_probe(struct device *dev) | 14505 | static 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); |