static int dmx3191d_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { struct Scsi_Host *shost; struct NCR5380_hostdata *hostdata; unsigned long io; int error = -ENODEV; if (pci_enable_device(pdev)) goto out; io = pci_resource_start(pdev, 0); if (!request_region(io, DMX3191D_REGION_LEN, DMX3191D_DRIVER_NAME)) { printk(KERN_ERR "dmx3191: region 0x%lx-0x%lx already reserved\n", io, io + DMX3191D_REGION_LEN); goto out_disable_device; } shost = scsi_host_alloc(&dmx3191d_driver_template, sizeof(struct NCR5380_hostdata)); if (!shost) goto out_release_region; hostdata = shost_priv(shost); hostdata->base = io; /* This card does not seem to raise an interrupt on pdev->irq. * Steam-powered SCSI controllers run without an IRQ anyway. */ shost->irq = NO_IRQ; error = NCR5380_init(shost, 0); if (error) goto out_host_put; NCR5380_maybe_reset_bus(shost); pci_set_drvdata(pdev, shost); error = scsi_add_host(shost, &pdev->dev); if (error) goto out_exit; scsi_scan_host(shost); return 0; out_exit: NCR5380_exit(shost); out_host_put: scsi_host_put(shost); out_release_region: release_region(io, DMX3191D_REGION_LEN); out_disable_device: pci_disable_device(pdev); out: return error; }
int ecoscsi_detect(Scsi_Host_Template * tpnt) { struct Scsi_Host *instance; tpnt->proc_name = "ecoscsi"; instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); instance->io_port = 0x80ce8000; instance->n_io_port = 144; instance->irq = IRQ_NONE; if (check_region (instance->io_port, instance->n_io_port)) { scsi_unregister (instance); return 0; } ecoscsi_write (instance, MODE_REG, 0x20); /* Is it really SCSI? */ if (ecoscsi_read (instance, MODE_REG) != 0x20) { /* Write to a reg. */ scsi_unregister(instance); return 0; /* and try to read */ } ecoscsi_write( instance, MODE_REG, 0x00 ); /* it back. */ if (ecoscsi_read (instance, MODE_REG) != 0x00) { scsi_unregister(instance); return 0; } NCR5380_init(instance, 0); if (request_region (instance->io_port, instance->n_io_port, "ecoscsi") == NULL) { scsi_unregister(instance); return 0; } if (instance->irq != IRQ_NONE) if (request_irq(instance->irq, do_ecoscsi_intr, SA_INTERRUPT, "ecoscsi", NULL)) { printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = IRQ_NONE; } if (instance->irq != IRQ_NONE) { printk("scsi%d: eek! Interrupts enabled, but I don't think\n", instance->host_no); printk("scsi%d: that the board had an interrupt!\n", instance->host_no); } printk("scsi%d: at port %X irq", instance->host_no, instance->io_port); if (instance->irq == IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, ECOSCSI_PUBLIC_RELEASE); printk("\nscsi%d:", instance->host_no); NCR5380_print_options(instance); printk("\n"); return 1; }
static int __devinit cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; int ret = -ENOMEM; host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata)); if (!host) goto out; host->io_port = ecard_address(ec, ECARD_IOC, ECARD_SLOW) + 0x800; host->irq = ec->irq; NCR5380_init(host, 0); host->n_io_port = 255; if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) { ret = -EBUSY; goto out_free; } ((struct NCR5380_hostdata *)host->hostdata)->ctrl = 0; outb(0x00, host->io_port - 577); ret = request_irq(host->irq, cumanascsi_intr, SA_INTERRUPT, "CumanaSCSI-1", host); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, host->irq, ret); goto out_release; } printk("scsi%d: at port 0x%08lx irq %d", host->host_no, host->io_port, host->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", host->can_queue, host->cmd_per_lun, CUMANASCSI_PUBLIC_RELEASE); printk("\nscsi%d:", host->host_no); NCR5380_print_options(host); printk("\n"); ret = scsi_add_host(host, &ec->dev); if (ret) goto out_free_irq; scsi_scan_host(host); goto out; out_free_irq: free_irq(host->irq, host); out_release: release_region(host->io_port, host->n_io_port); out_free: scsi_host_put(host); out: return ret; }
int oakscsi_detect(Scsi_Host_Template * tpnt) { int count = 0; struct Scsi_Host *instance; tpnt->proc_name = "oakscsi"; memset (ecs, 0, sizeof (ecs)); ecard_startfind (); while(1) { if ((ecs[count] = ecard_find(0, oakscsi_cids)) == NULL) break; instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); instance->io_port = OAK_ADDRESS(ecs[count]); instance->irq = OAK_IRQ(ecs[count]); NCR5380_init(instance, 0); ecard_claim(ecs[count]); instance->n_io_port = 255; request_region (instance->io_port, instance->n_io_port, "Oak SCSI"); if (instance->irq != IRQ_NONE) if (request_irq(instance->irq, do_oakscsi_intr, SA_INTERRUPT, "Oak SCSI", NULL)) { printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = IRQ_NONE; } if (instance->irq != IRQ_NONE) { printk("scsi%d: eek! Interrupts enabled, but I don't think\n", instance->host_no); printk("scsi%d: that the board had an interrupt!\n", instance->host_no); } printk("scsi%d: at port %lX irq", instance->host_no, instance->io_port); if (instance->irq == IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", tpnt->can_queue, tpnt->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE); printk("\nscsi%d:", instance->host_no); NCR5380_print_options(instance); printk("\n"); ++count; } #ifdef MODULE if(count == 0) printk("No oak scsi devices found\n"); #endif return count; }
static int __devinit dmx3191d_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { struct Scsi_Host *shost; unsigned long io; int error = -ENODEV; if (pci_enable_device(pdev)) goto out; io = pci_resource_start(pdev, 0); if (!request_region(io, DMX3191D_REGION_LEN, DMX3191D_DRIVER_NAME)) { printk(KERN_ERR "dmx3191: region 0x%lx-0x%lx already reserved\n", io, io + DMX3191D_REGION_LEN); goto out_disable_device; } shost = scsi_host_alloc(&dmx3191d_driver_template, sizeof(struct NCR5380_hostdata)); if (!shost) goto out_release_region; shost->io_port = io; shost->irq = pdev->irq; NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E); if (request_irq(pdev->irq, NCR5380_intr, IRQF_SHARED, DMX3191D_DRIVER_NAME, shost)) { /* * Steam powered scsi controllers run without an IRQ anyway */ printk(KERN_WARNING "dmx3191: IRQ %d not available - " "switching to polled mode.\n", pdev->irq); shost->irq = SCSI_IRQ_NONE; } pci_set_drvdata(pdev, shost); error = scsi_add_host(shost, &pdev->dev); if (error) goto out_free_irq; scsi_scan_host(shost); return 0; out_free_irq: free_irq(shost->irq, shost); out_release_region: release_region(io, DMX3191D_REGION_LEN); out_disable_device: pci_disable_device(pdev); out: return error; }
int cumanascsi_detect(Scsi_Host_Template * tpnt) { int count = 0; struct Scsi_Host *instance; tpnt->proc_name = "CumanaSCSI-1"; memset (ecs, 0, sizeof (ecs)); while(1) { if((ecs[count] = ecard_find(0, cumanascsi_cids)) == NULL) break; instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); instance->io_port = CUMANA_ADDRESS(ecs[count]); instance->irq = CUMANA_IRQ(ecs[count]); NCR5380_init(instance, 0); ecard_claim(ecs[count]); instance->n_io_port = 255; request_region (instance->io_port, instance->n_io_port, "CumanaSCSI-1"); ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; outb(0x00, instance->io_port - 577); if (instance->irq != IRQ_NONE) if (request_irq(instance->irq, do_cumanascsi_intr, SA_INTERRUPT, "CumanaSCSI-1", NULL)) { printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = IRQ_NONE; } if (instance->irq == IRQ_NONE) { printk("scsi%d: interrupts not enabled. for better interactive performance,\n", instance->host_no); printk("scsi%d: please jumper the board for a free IRQ.\n", instance->host_no); } printk("scsi%d: at port %lX irq", instance->host_no, instance->io_port); if (instance->irq == IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", tpnt->can_queue, tpnt->cmd_per_lun, CUMANASCSI_PUBLIC_RELEASE); printk("\nscsi%d:", instance->host_no); NCR5380_print_options(instance); printk("\n"); ++count; } return count; }
static int __devinit oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; int ret = -ENOMEM; ret = ecard_request_resources(ec); if (ret) goto out; host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); if (!host) { ret = -ENOMEM; goto release; } priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), ecard_resource_len(ec, ECARD_RES_MEMC)); if (!priv(host)->base) { ret = -ENOMEM; goto unreg; } host->irq = IRQ_NONE; host->n_io_port = 255; NCR5380_init(host, 0); printk("scsi%d: at port 0x%08lx irqs disabled", host->host_no, host->io_port); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", host->can_queue, host->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE); printk("\nscsi%d:", host->host_no); NCR5380_print_options(host); printk("\n"); ret = scsi_add_host(host, &ec->dev); if (ret) goto out_unmap; scsi_scan_host(host); goto out; out_unmap: iounmap(priv(host)->base); unreg: scsi_host_put(host); release: ecard_release_resources(ec); out: return ret; }
static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; int ret = -ENOMEM; ret = ecard_request_resources(ec); if (ret) goto out; host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); if (!host) { ret = -ENOMEM; goto release; } priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), ecard_resource_len(ec, ECARD_RES_MEMC)); if (!priv(host)->base) { ret = -ENOMEM; goto unreg; } host->irq = NO_IRQ; host->n_io_port = 255; ret = NCR5380_init(host, 0); if (ret) goto out_unmap; NCR5380_maybe_reset_bus(host); ret = scsi_add_host(host, &ec->dev); if (ret) goto out_exit; scsi_scan_host(host); goto out; out_exit: NCR5380_exit(host); out_unmap: iounmap(priv(host)->base); unreg: scsi_host_put(host); release: ecard_release_resources(ec); out: return ret; }
static int __init dmx3191d_detect(Scsi_Host_Template *tmpl) { int boards = 0; struct Scsi_Host *instance = NULL; struct pci_dev *pdev = NULL; tmpl->proc_name = DMX3191D_DRIVER_NAME; while ((pdev = pci_find_device(PCI_VENDOR_ID_DOMEX, PCI_DEVICE_ID_DOMEX_DMX3191D, pdev))) { unsigned long port; if (pci_enable_device(pdev)) continue; port = pci_resource_start (pdev, 0); if (!request_region(port, DMX3191D_REGION, DMX3191D_DRIVER_NAME)) { printk(KERN_ERR "dmx3191: region 0x%lx-0x%lx already reserved\n", port, port + DMX3191D_REGION); continue; } instance = scsi_register(tmpl, sizeof(struct NCR5380_hostdata)); if(instance == NULL) { release_region(port, DMX3191D_REGION); continue; } scsi_set_device(instance, &pdev->dev); instance->io_port = port; instance->irq = pdev->irq; NCR5380_init(instance, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E); if (request_irq(pdev->irq, dmx3191d_intr, SA_SHIRQ, DMX3191D_DRIVER_NAME, instance)) { printk(KERN_WARNING "dmx3191: IRQ %d not available - switching to polled mode.\n", pdev->irq); /* Steam powered scsi controllers run without an IRQ anyway */ instance->irq = SCSI_IRQ_NONE; } boards++; } return boards; }
static int __devinit oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; int ret = -ENOMEM; host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); if (!host) goto out; host->io_port = ecard_address(ec, ECARD_MEMC, 0); host->irq = IRQ_NONE; host->n_io_port = 255; ret = -EBUSY; if (!request_region (host->io_port, host->n_io_port, "Oak SCSI")) goto unreg; NCR5380_init(host, 0); printk("scsi%d: at port 0x%08lx irqs disabled", host->host_no, host->io_port); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", host->can_queue, host->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE); printk("\nscsi%d:", host->host_no); NCR5380_print_options(host); printk("\n"); ret = scsi_add_host(host, &ec->dev); if (ret) goto out_release; scsi_scan_host(host); goto out; out_release: release_region(host->io_port, host->n_io_port); unreg: scsi_host_put(host); out: return ret; }
int sun3scsi_detect(Scsi_Host_Template * tpnt) { unsigned long ioaddr, iopte; int count = 0; static int called = 0; struct Scsi_Host *instance; if(called) return 0; tpnt->proc_name = "Sun3 5380 SCSI"; /* setup variables */ tpnt->can_queue = (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE; tpnt->cmd_per_lun = (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN; tpnt->sg_tablesize = (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE; if (setup_hostid >= 0) tpnt->this_id = setup_hostid; else { /* use 7 as default */ tpnt->this_id = 7; } /* Taken from Sammy's lance driver: */ /* IOBASE_SUN3_SCSI can be found within the IO pmeg with some effort */ for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 + SUN3_PMEG_SIZE); ioaddr += SUN3_PTE_SIZE) { iopte = sun3_get_pte(ioaddr); if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */ continue; if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) == IOBASE_SUN3_SCSI) { count = 1; break; } } if(!count) { printk("No Sun3 NCR5380 found!\n"); return 0; } sun3_scsi_regp = (unsigned char *)ioaddr; dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8); if((dmabuf = sun3_dvma_malloc(SUN3_DVMA_BUFSIZE)) == NULL) { printk("SUN3 Scsi couldn't allocate DVMA memory!\n"); return 0; } if((udc_regs = sun3_dvma_malloc(sizeof(struct sun3_udc_regs))) == NULL) { printk("SUN3 Scsi couldn't allocate DVMA memory!\n"); return 0; } #ifdef SUPPORT_TAGS if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING; #endif instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); if(instance == NULL) return 0; default_instance = instance; instance->io_port = (unsigned long) ioaddr; instance->irq = IRQ_SUN3_SCSI; NCR5380_init(instance, 0); instance->n_io_port = 32; ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; if (request_irq(instance->irq, scsi_sun3_intr, 0, "Sun3SCSI-5380", NULL)) { #ifndef REAL_DMA printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = IRQ_NONE; #else printk("scsi%d: IRQ%d not free, bailing out\n", instance->host_no, instance->irq); return 0; #endif } printk("scsi%d: Sun3 5380 at port %lX irq", instance->host_no, instance->io_port); if (instance->irq == IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", instance->can_queue, instance->cmd_per_lun, SUN3SCSI_PUBLIC_RELEASE); printk("\nscsi%d:", instance->host_no); NCR5380_print_options(instance); printk("\n"); dregs->csr = 0; udelay(SUN3_DMA_DELAY); dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR; udelay(SUN3_DMA_DELAY); dregs->fifo_count = 0; called = 1; return 1; }
static int sun3scsi_detect(struct scsi_host_template * tpnt) { unsigned long ioaddr, irq = 0; static int called = 0; struct Scsi_Host *instance; int i; unsigned long addrs[3] = { IOBASE_SUN3_VMESCSI, IOBASE_SUN3_VMESCSI + 0x4000, 0 }; unsigned long vecs[3] = { SUN3_VEC_VMESCSI0, SUN3_VEC_VMESCSI1, 0 }; /* check that this machine has an onboard 5380 */ switch(idprom->id_machtype) { case SM_SUN3|SM_3_160: case SM_SUN3|SM_3_260: break; default: return 0; } if(called) return 0; tpnt->proc_name = "Sun3 5380 VME SCSI"; /* setup variables */ tpnt->can_queue = (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE; tpnt->cmd_per_lun = (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN; tpnt->sg_tablesize = (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE; if (setup_hostid >= 0) tpnt->this_id = setup_hostid; else { /* use 7 as default */ tpnt->this_id = 7; } ioaddr = 0; for(i = 0; addrs[i] != 0; i++) { unsigned char x; ioaddr = (unsigned long)sun3_ioremap(addrs[i], PAGE_SIZE, SUN3_PAGE_TYPE_VME16); irq = vecs[i]; sun3_scsi_regp = (unsigned char *)ioaddr; dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8); if(sun3_map_test((unsigned long)dregs, &x)) { unsigned short oldcsr; oldcsr = dregs->csr; dregs->csr = 0; udelay(SUN3_DMA_DELAY); if(dregs->csr == 0x1400) break; dregs->csr = oldcsr; } iounmap((void *)ioaddr); ioaddr = 0; } if(!ioaddr) return 0; #ifdef SUPPORT_TAGS if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = USE_TAGGED_QUEUING; #endif instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); if(instance == NULL) return 0; default_instance = instance; instance->io_port = (unsigned long) ioaddr; instance->irq = irq; NCR5380_init(instance, 0); instance->n_io_port = 32; ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; if (request_irq(instance->irq, scsi_sun3_intr, 0, "Sun3SCSI-5380VME", instance)) { #ifndef REAL_DMA printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = SCSI_IRQ_NONE; #else printk("scsi%d: IRQ%d not free, bailing out\n", instance->host_no, instance->irq); return 0; #endif } printk("scsi%d: Sun3 5380 VME at port %lX irq", instance->host_no, instance->io_port); if (instance->irq == SCSI_IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", instance->can_queue, instance->cmd_per_lun, SUN3SCSI_PUBLIC_RELEASE); printk("\nscsi%d:", instance->host_no); NCR5380_print_options(instance); printk("\n"); dregs->csr = 0; udelay(SUN3_DMA_DELAY); dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR; udelay(SUN3_DMA_DELAY); dregs->fifo_count = 0; dregs->fifo_count_hi = 0; dregs->dma_addr_hi = 0; dregs->dma_addr_lo = 0; dregs->dma_count_hi = 0; dregs->dma_count_lo = 0; dregs->ivect = VME_DATA24 | (instance->irq & 0xff); called = 1; #ifdef RESET_BOOT sun3_scsi_reset_boot(instance); #endif return 1; }
static int __init mac_scsi_probe(struct platform_device *pdev) { struct Scsi_Host *instance; int error; int host_flags = 0; struct resource *irq, *pio_mem, *pdma_mem = NULL; pio_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!pio_mem) return -ENODEV; #ifdef PSEUDO_DMA pdma_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); #endif irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!hwreg_present((unsigned char *)pio_mem->start + (STATUS_REG << 4))) { pr_info(PFX "no device detected at %pap\n", &pio_mem->start); return -ENODEV; } if (setup_can_queue > 0) mac_scsi_template.can_queue = setup_can_queue; if (setup_cmd_per_lun > 0) mac_scsi_template.cmd_per_lun = setup_cmd_per_lun; if (setup_sg_tablesize >= 0) mac_scsi_template.sg_tablesize = setup_sg_tablesize; if (setup_hostid >= 0) mac_scsi_template.this_id = setup_hostid & 7; if (setup_use_pdma < 0) setup_use_pdma = 0; instance = scsi_host_alloc(&mac_scsi_template, sizeof(struct NCR5380_hostdata)); if (!instance) return -ENOMEM; instance->base = pio_mem->start; if (irq) instance->irq = irq->start; else instance->irq = NO_IRQ; if (pdma_mem && setup_use_pdma) { struct NCR5380_hostdata *hostdata = shost_priv(instance); hostdata->pdma_base = (unsigned char *)pdma_mem->start; } else host_flags |= FLAG_NO_PSEUDO_DMA; #ifdef RESET_BOOT mac_scsi_reset_boot(instance); #endif #ifdef SUPPORT_TAGS host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; #endif NCR5380_init(instance, host_flags); if (instance->irq != NO_IRQ) { error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED, "NCR5380", instance); if (error) goto fail_irq; } error = scsi_add_host(instance, NULL); if (error) goto fail_host; platform_set_drvdata(pdev, instance); scsi_scan_host(instance); return 0; fail_host: if (instance->irq != NO_IRQ) free_irq(instance->irq, instance); fail_irq: NCR5380_exit(instance); scsi_host_put(instance); return error; }
int sun3scsi_detect(struct scsi_host_template * tpnt) { unsigned long ioaddr; static int called = 0; struct Scsi_Host *instance; /* check that this machine has an onboard 5380 */ switch(idprom->id_machtype) { case SM_SUN3|SM_3_50: case SM_SUN3|SM_3_60: break; default: return 0; } if(called) return 0; tpnt->proc_name = "Sun3 5380 SCSI"; /* setup variables */ tpnt->can_queue = (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE; tpnt->cmd_per_lun = (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN; tpnt->sg_tablesize = (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE; if (setup_hostid >= 0) tpnt->this_id = setup_hostid; else { /* use 7 as default */ tpnt->this_id = 7; } ioaddr = (unsigned long)ioremap(IOBASE_SUN3_SCSI, PAGE_SIZE); sun3_scsi_regp = (unsigned char *)ioaddr; dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8); if((udc_regs = dvma_malloc(sizeof(struct sun3_udc_regs))) == NULL) { printk("SUN3 Scsi couldn't allocate DVMA memory!\n"); return 0; } #ifdef OLDDMA if((dmabuf = dvma_malloc_align(SUN3_DVMA_BUFSIZE, 0x10000)) == NULL) { printk("SUN3 Scsi couldn't allocate DVMA memory!\n"); return 0; } #endif #ifdef SUPPORT_TAGS if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = USE_TAGGED_QUEUING; #endif instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); if(instance == NULL) return 0; default_instance = instance; instance->io_port = (unsigned long) ioaddr; instance->irq = IRQ_SUN3_SCSI; NCR5380_init(instance, 0); instance->n_io_port = 32; ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; if (request_irq(instance->irq, scsi_sun3_intr, 0, "Sun3SCSI-5380", instance)) { #ifndef REAL_DMA printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = SCSI_IRQ_NONE; #else printk("scsi%d: IRQ%d not free, bailing out\n", instance->host_no, instance->irq); return 0; #endif } printk("scsi%d: Sun3 5380 at port %lX irq", instance->host_no, instance->io_port); if (instance->irq == SCSI_IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", instance->can_queue, instance->cmd_per_lun, SUN3SCSI_PUBLIC_RELEASE); printk("\nscsi%d:", instance->host_no); NCR5380_print_options(instance); printk("\n"); dregs->csr = 0; udelay(SUN3_DMA_DELAY); dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR; udelay(SUN3_DMA_DELAY); dregs->fifo_count = 0; called = 1; #ifdef RESET_BOOT sun3_scsi_reset_boot(instance); #endif return 1; }
int nbpmacscsi_detect(struct scsi_host_template * tpnt) { int flags = 0; struct Scsi_Host *instance; struct device_node *dp; const u32 *reg; if (called) return( 0 ); // dp = find_devices("5380"); dp = of_find_node_by_name(NULL, "5380"); if (!dp) return 0; reg = of_get_property(dp, "reg", NULL); if (reg == NULL) { printk(KERN_ERR "nbpmac5380: No \"reg\" property !\n"); of_node_put(dp); return 0; } tpnt->proc_name = "nbpmac5380"; /* setup variables */ tpnt->can_queue = (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE; tpnt->cmd_per_lun = (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN; tpnt->sg_tablesize = (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE; if (setup_hostid >= 0) tpnt->this_id = setup_hostid; else /* use 7 as default */ tpnt->this_id = 7; #ifdef SUPPORT_TAGS if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = USE_TAGGED_QUEUING; #endif /* Once we support multiple 5380s (e.g. DuoDock) we'll do something different here */ instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); #if NDEBUG default_instance = instance; #endif /* mac68k source says multiple device support is broken */ mac_scsi_regp = (volatile unsigned char *) of_iomap(dp, 0); mac_scsi_drq = (volatile unsigned char *) of_iomap(dp, 1); mac_scsi_nodrq = (volatile unsigned char *) of_iomap(dp, 2); if (! setup_use_pdma) flags = FLAG_NO_PSEUDO_DMA; instance->io_port = (unsigned long) mac_scsi_regp; instance->irq = irq_of_parse_and_map(dp, 0); instance->n_io_port = 255; ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, NCR5380_intr, 0, "ncr5380", instance)) { printk("scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = SCSI_IRQ_NONE; } #ifdef DRQ_INTERRUPT drq = irq_of_parse_and_map(vias, 1); request_irq(drq, macscsi_dma_intr, 0, "ncr5380 DRQ", instance); #endif of_node_put(dp); #ifdef RESET_BOOT mac_scsi_reset_boot(instance); #endif flags |= FLAG_HAS_LAST_BYTE_SENT; NCR5380_init(instance, flags); printk(KERN_INFO "scsi%d : generic 5380 at port %lX irq", instance->host_no, instance->io_port); if (instance->irq == SCSI_IRQ_NONE) printk (KERN_INFO "s disabled"); else printk (KERN_INFO " %d", instance->irq); printk(KERN_INFO " options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", instance->can_queue, instance->cmd_per_lun, MACSCSI_PUBLIC_RELEASE); printk(KERN_INFO "\nscsi%d :", instance->host_no); NCR5380_print_options(instance); printk("\n"); called = 1; return 1; }
int macscsi_detect(struct scsi_host_template * tpnt) { static int called = 0; int flags = 0; struct Scsi_Host *instance; if (!MACH_IS_MAC || called) return( 0 ); if (macintosh_config->scsi_type != MAC_SCSI_OLD) return( 0 ); /* setup variables */ tpnt->can_queue = (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE; tpnt->cmd_per_lun = (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN; tpnt->sg_tablesize = (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE; if (setup_hostid >= 0) tpnt->this_id = setup_hostid; else { /* use 7 as default */ tpnt->this_id = 7; } #ifdef SUPPORT_TAGS if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = USE_TAGGED_QUEUING; #endif /* Once we support multiple 5380s (e.g. DuoDock) we'll do something different here */ instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); #if NDEBUG default_instance = instance; #endif if (macintosh_config->ident == MAC_MODEL_IIFX) { mac_scsi_regp = via1+0x8000; mac_scsi_drq = via1+0xE000; mac_scsi_nodrq = via1+0xC000; /* The IIFX should be able to do true DMA, but pseudo-dma doesn't work */ flags = FLAG_NO_PSEUDO_DMA; } else { mac_scsi_regp = via1+0x10000; mac_scsi_drq = via1+0x6000; mac_scsi_nodrq = via1+0x12000; } if (! setup_use_pdma) flags = FLAG_NO_PSEUDO_DMA; instance->io_port = (unsigned long) mac_scsi_regp; instance->irq = IRQ_MAC_SCSI; #ifdef RESET_BOOT mac_scsi_reset_boot(instance); #endif NCR5380_init(instance, flags); instance->n_io_port = 255; ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, NCR5380_intr, IRQ_FLG_SLOW, "ncr5380", instance)) { printk(KERN_WARNING "scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = SCSI_IRQ_NONE; } printk(KERN_INFO "scsi%d: generic 5380 at port %lX irq", instance->host_no, instance->io_port); if (instance->irq == SCSI_IRQ_NONE) printk (KERN_INFO "s disabled"); else printk (KERN_INFO " %d", instance->irq); printk(KERN_INFO " options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", instance->can_queue, instance->cmd_per_lun, MACSCSI_PUBLIC_RELEASE); printk(KERN_INFO "\nscsi%d:", instance->host_no); NCR5380_print_options(instance); printk("\n"); called = 1; return 1; }
int atari_scsi_detect (Scsi_Host_Template *host) { static int called = 0; struct Scsi_Host *instance; if (!MACH_IS_ATARI || (!ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(TT_SCSI)) || called) return( 0 ); host->proc_name = "Atari"; atari_scsi_reg_read = IS_A_TT() ? atari_scsi_tt_reg_read : atari_scsi_falcon_reg_read; atari_scsi_reg_write = IS_A_TT() ? atari_scsi_tt_reg_write : atari_scsi_falcon_reg_write; /* setup variables */ host->can_queue = (setup_can_queue > 0) ? setup_can_queue : IS_A_TT() ? ATARI_TT_CAN_QUEUE : ATARI_FALCON_CAN_QUEUE; host->cmd_per_lun = (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : IS_A_TT() ? ATARI_TT_CMD_PER_LUN : ATARI_FALCON_CMD_PER_LUN; /* Force sg_tablesize to 0 on a Falcon! */ host->sg_tablesize = !IS_A_TT() ? ATARI_FALCON_SG_TABLESIZE : (setup_sg_tablesize >= 0) ? setup_sg_tablesize : ATARI_TT_SG_TABLESIZE; if (setup_hostid >= 0) host->this_id = setup_hostid; else { /* use 7 as default */ host->this_id = 7; /* Test if a host id is set in the NVRam */ if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) { unsigned char b = nvram_read_byte( 14 ); /* Arbitration enabled? (for TOS) If yes, use configured host ID */ if (b & 0x80) host->this_id = b & 7; } } #ifdef SUPPORT_TAGS if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING; #endif #ifdef REAL_DMA /* If running on a Falcon and if there's TT-Ram (i.e., more than one * memory block, since there's always ST-Ram in a Falcon), then allocate a * STRAM_BUFFER_SIZE byte dribble buffer for transfers from/to alternative * Ram. */ if (MACH_IS_ATARI && ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(EXTD_DMA) && m68k_num_memory > 1) { atari_dma_buffer = atari_stram_alloc(STRAM_BUFFER_SIZE, "SCSI"); if (!atari_dma_buffer) { printk( KERN_ERR "atari_scsi_detect: can't allocate ST-RAM " "double buffer\n" ); return( 0 ); } atari_dma_phys_buffer = virt_to_phys( atari_dma_buffer ); atari_dma_orig_addr = 0; } #endif instance = scsi_register (host, sizeof (struct NCR5380_hostdata)); if(instance == NULL) { atari_stram_free(atari_dma_buffer); atari_dma_buffer = 0; return 0; } atari_scsi_host = instance; /* Set irq to 0, to avoid that the mid-level code disables our interrupt * during queue_command calls. This is completely unnecessary, and even * worse causes bad problems on the Falcon, where the int is shared with * IDE and floppy! */ instance->irq = 0; #ifdef CONFIG_ATARI_SCSI_RESET_BOOT atari_scsi_reset_boot(); #endif NCR5380_init (instance, 0); if (IS_A_TT()) { /* This int is actually "pseudo-slow", i.e. it acts like a slow * interrupt after having cleared the pending flag for the DMA * interrupt. */ if (request_irq(IRQ_TT_MFP_SCSI, scsi_tt_intr, IRQ_TYPE_SLOW, "SCSI NCR5380", scsi_tt_intr)) { printk(KERN_ERR "atari_scsi_detect: cannot allocate irq %d, aborting",IRQ_TT_MFP_SCSI); scsi_unregister(atari_scsi_host); atari_stram_free(atari_dma_buffer); atari_dma_buffer = 0; return 0; } tt_mfp.active_edge |= 0x80; /* SCSI int on L->H */ #ifdef REAL_DMA tt_scsi_dma.dma_ctrl = 0; atari_dma_residual = 0; #ifdef CONFIG_TT_DMA_EMUL if (MACH_IS_HADES) { if (request_irq(IRQ_AUTO_2, hades_dma_emulator, IRQ_TYPE_PRIO, "Hades DMA emulator", hades_dma_emulator)) { printk(KERN_ERR "atari_scsi_detect: cannot allocate irq %d, aborting (MACH_IS_HADES)",IRQ_AUTO_2); free_irq(IRQ_TT_MFP_SCSI, scsi_tt_intr); scsi_unregister(atari_scsi_host); atari_stram_free(atari_dma_buffer); atari_dma_buffer = 0; return 0; } } #endif if (MACH_IS_MEDUSA || MACH_IS_HADES) { /* While the read overruns (described by Drew Eckhardt in * NCR5380.c) never happened on TTs, they do in fact on the Medusa * (This was the cause why SCSI didn't work right for so long * there.) Since handling the overruns slows down a bit, I turned * the #ifdef's into a runtime condition. * * In principle it should be sufficient to do max. 1 byte with * PIO, but there is another problem on the Medusa with the DMA * rest data register. So 'atari_read_overruns' is currently set * to 4 to avoid having transfers that aren't a multiple of 4. If * the rest data bug is fixed, this can be lowered to 1. */ atari_read_overruns = 4; } #endif /*REAL_DMA*/ } else { /* ! IS_A_TT */ /* Nothing to do for the interrupt: the ST-DMA is initialized * already by atari_init_INTS() */ #ifdef REAL_DMA atari_dma_residual = 0; atari_dma_active = 0; atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000 : 0xff000000); #endif } printk(KERN_INFO "scsi%d: options CAN_QUEUE=%d CMD_PER_LUN=%d SCAT-GAT=%d " #ifdef SUPPORT_TAGS "TAGGED-QUEUING=%s " #endif "HOSTID=%d", instance->host_no, instance->hostt->can_queue, instance->hostt->cmd_per_lun, instance->hostt->sg_tablesize, #ifdef SUPPORT_TAGS setup_use_tagged_queuing ? "yes" : "no", #endif instance->hostt->this_id ); NCR5380_print_options (instance); printk ("\n"); called = 1; return( 1 ); }
int atari_scsi_detect (Scsi_Host_Template *host) { static int called = 0; struct Scsi_Host *instance; if (!MACH_IS_ATARI || (!ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(TT_SCSI)) || called) return( 0 ); host->proc_dir = &proc_scsi_atari; atari_scsi_reg_read = IS_A_TT() ? atari_scsi_tt_reg_read : atari_scsi_falcon_reg_read; atari_scsi_reg_write = IS_A_TT() ? atari_scsi_tt_reg_write : atari_scsi_falcon_reg_write; /* setup variables */ host->can_queue = (setup_can_queue > 0) ? setup_can_queue : IS_A_TT() ? ATARI_TT_CAN_QUEUE : ATARI_FALCON_CAN_QUEUE; host->cmd_per_lun = (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : IS_A_TT() ? ATARI_TT_CMD_PER_LUN : ATARI_FALCON_CMD_PER_LUN; /* Force sg_tablesize to 0 on a Falcon! */ host->sg_tablesize = !IS_A_TT() ? ATARI_FALCON_SG_TABLESIZE : (setup_sg_tablesize >= 0) ? setup_sg_tablesize : ATARI_TT_SG_TABLESIZE; if (setup_hostid >= 0) host->this_id = setup_hostid; else { /* use 7 as default */ host->this_id = 7; /* Test if a host id is set in the NVRam */ if (ATARIHW_PRESENT(TT_CLK)) { unsigned char sum = 0, b; int i; /* Make checksum */ for( i = 14; i < 62; ++i ) sum += RTC_READ(i); if (/* NV-Ram checksum valid? */ RTC_READ(62) == sum && RTC_READ(63) == ~sum && /* Arbitration enabled? (for TOS) */ (b = RTC_READ( 30 )) & 0x80) { host->this_id = b & 7; } } } #ifdef SUPPORT_TAGS if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING; #endif /* If running on a Falcon and if there's TT-Ram (i.e., more than one * memory block, since there's always ST-Ram in a Falcon), then allocate a * STRAM_BUFFER_SIZE byte dribble buffer for transfers from/to alternative * Ram. */ if (MACH_IS_ATARI && ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(EXTD_DMA) && boot_info.num_memory > 1) { atari_dma_buffer = scsi_init_malloc(STRAM_BUFFER_SIZE, GFP_ATOMIC | GFP_DMA); atari_dma_phys_buffer = VTOP( atari_dma_buffer ); atari_dma_orig_addr = 0; } instance = scsi_register (host, sizeof (struct NCR5380_hostdata)); atari_scsi_host = instance; instance->irq = IS_A_TT() ? IRQ_TT_MFP_SCSI : IRQ_MFP_FSCSI; atari_scsi_reset_boot(); NCR5380_init (instance, 0); if (IS_A_TT()) { /* This int is actually "pseudo-slow", i.e. it acts like a slow * interrupt after having cleared the pending flag for the DMA * interrupt. */ add_isr(IRQ_TT_MFP_SCSI, scsi_tt_intr, IRQ_TYPE_SLOW, NULL, "SCSI NCR5380"); tt_mfp.active_edge |= 0x80; /* SCSI int on L->H */ #ifdef REAL_DMA tt_scsi_dma.dma_ctrl = 0; atari_dma_residual = 0; #endif /* REAL_DMA */ if (is_medusa) { /* While the read overruns (described by Drew Eckhardt in * NCR5380.c) never happened on TTs, they do in fact on the Medusa * (This was the cause why SCSI didn't work right for so long * there.) Since handling the overruns slows down a bit, I turned * the #ifdef's into a runtime condition. * * In principle it should be sufficient to do max. 1 byte with * PIO, but there is another problem on the Medusa with the DMA * rest data register. So 'atari_read_overruns' is currently set * to 4 to avoid having transfers that aren't a multiple of 4. If * the rest data bug is fixed, this can be lowered to 1. */ atari_read_overruns = 4; } } else { /* ! IS_A_TT */ /* Nothing to do for the interrupt: the ST-DMA is initialized * already by atari_init_INTS() */ #ifdef REAL_DMA atari_dma_residual = 0; atari_dma_active = 0; atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000 : 0xff000000); #endif } printk(KERN_INFO "scsi%d: options CAN_QUEUE=%d CMD_PER_LUN=%d SCAT-GAT=%d " #ifdef SUPPORT_TAGS "TAGGED-QUEUING=%s " #endif "HOSTID=%d", instance->host_no, instance->hostt->can_queue, instance->hostt->cmd_per_lun, instance->hostt->sg_tablesize, #ifdef SUPPORT_TAGS setup_use_tagged_queuing ? "yes" : "no", #endif instance->hostt->this_id ); NCR5380_print_options (instance); printk ("\n"); called = 1; return( 1 ); }
static int __init mac_scsi_probe(struct platform_device *pdev) { struct Scsi_Host *instance; struct NCR5380_hostdata *hostdata; int error; int host_flags = 0; struct resource *irq, *pio_mem, *pdma_mem = NULL; pio_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!pio_mem) return -ENODEV; pdma_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!hwreg_present((unsigned char *)pio_mem->start + (STATUS_REG << 4))) { pr_info(PFX "no device detected at %pap\n", &pio_mem->start); return -ENODEV; } if (setup_can_queue > 0) mac_scsi_template.can_queue = setup_can_queue; if (setup_cmd_per_lun > 0) mac_scsi_template.cmd_per_lun = setup_cmd_per_lun; if (setup_sg_tablesize >= 0) mac_scsi_template.sg_tablesize = setup_sg_tablesize; if (setup_hostid >= 0) mac_scsi_template.this_id = setup_hostid & 7; instance = scsi_host_alloc(&mac_scsi_template, sizeof(struct NCR5380_hostdata)); if (!instance) return -ENOMEM; if (irq) instance->irq = irq->start; else instance->irq = NO_IRQ; hostdata = shost_priv(instance); hostdata->base = pio_mem->start; hostdata->io = (void *)pio_mem->start; if (pdma_mem && setup_use_pdma) hostdata->pdma_io = (void *)pdma_mem->start; else host_flags |= FLAG_NO_PSEUDO_DMA; host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0; error = NCR5380_init(instance, host_flags | FLAG_LATE_DMA_SETUP); if (error) goto fail_init; if (instance->irq != NO_IRQ) { error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED, "NCR5380", instance); if (error) goto fail_irq; } NCR5380_maybe_reset_bus(instance); error = scsi_add_host(instance, NULL); if (error) goto fail_host; platform_set_drvdata(pdev, instance); scsi_scan_host(instance); return 0; fail_host: if (instance->irq != NO_IRQ) free_irq(instance->irq, instance); fail_irq: NCR5380_exit(instance); fail_init: scsi_host_put(instance); return error; }
static int __devinit cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; int ret; ret = ecard_request_resources(ec); if (ret) goto out; host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata)); if (!host) { ret = -ENOMEM; goto out_release; } priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW), ecard_resource_len(ec, ECARD_RES_IOCSLOW)); priv(host)->dma = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), ecard_resource_len(ec, ECARD_RES_MEMC)); if (!priv(host)->base || !priv(host)->dma) { ret = -ENOMEM; goto out_unmap; } host->irq = ec->irq; NCR5380_init(host, 0); priv(host)->ctrl = 0; writeb(0, priv(host)->base + CTRL); host->n_io_port = 255; if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) { ret = -EBUSY; goto out_unmap; } ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED, "CumanaSCSI-1", host); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, host->irq, ret); goto out_unmap; } printk("scsi%d: at port 0x%08lx irq %d", host->host_no, host->io_port, host->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", host->can_queue, host->cmd_per_lun, CUMANASCSI_PUBLIC_RELEASE); printk("\nscsi%d:", host->host_no); NCR5380_print_options(host); printk("\n"); ret = scsi_add_host(host, &ec->dev); if (ret) goto out_free_irq; scsi_scan_host(host); goto out; out_free_irq: free_irq(host->irq, host); out_unmap: iounmap(priv(host)->base); iounmap(priv(host)->dma); scsi_host_put(host); out_release: ecard_release_resources(ec); out: return ret; }
static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, struct device *pdev, int base, int irq, int board) { bool is_pmio = base <= 0xffff; int ret; int flags = 0; unsigned int *ports = NULL; u8 *magic = NULL; int i; int port_idx = -1; unsigned long region_size; struct Scsi_Host *instance; struct NCR5380_hostdata *hostdata; u8 __iomem *iomem; switch (board) { case BOARD_NCR5380: flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP; break; case BOARD_NCR53C400A: ports = ncr_53c400a_ports; magic = ncr_53c400a_magic; break; case BOARD_HP_C2502: ports = ncr_53c400a_ports; magic = hp_c2502_magic; break; case BOARD_DTC3181E: ports = dtc_3181e_ports; magic = ncr_53c400a_magic; break; } if (is_pmio && ports && magic) { /* wakeup sequence for the NCR53C400A and DTC3181E */ /* Disable the adapter and look for a free io port */ magic_configure(-1, 0, magic); region_size = 16; if (base) for (i = 0; ports[i]; i++) { if (base == ports[i]) { /* index found */ if (!request_region(ports[i], region_size, "ncr53c80")) return -EBUSY; break; } } else for (i = 0; ports[i]; i++) { if (!request_region(ports[i], region_size, "ncr53c80")) continue; if (inb(ports[i]) == 0xff) break; release_region(ports[i], region_size); } if (ports[i]) { /* At this point we have our region reserved */ magic_configure(i, 0, magic); /* no IRQ yet */ base = ports[i]; outb(0xc0, base + 9); if (inb(base + 9) != 0x80) { ret = -ENODEV; goto out_release; } port_idx = i; } else return -EINVAL; } else if (is_pmio) { /* NCR5380 - no configuration, just grab */ region_size = 8; if (!base || !request_region(base, region_size, "ncr5380")) return -EBUSY; } else { /* MMIO */ region_size = NCR53C400_region_size; if (!request_mem_region(base, region_size, "ncr5380")) return -EBUSY; } if (is_pmio) iomem = ioport_map(base, region_size); else iomem = ioremap(base, region_size); if (!iomem) { ret = -ENOMEM; goto out_release; } instance = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata)); if (instance == NULL) { ret = -ENOMEM; goto out_unmap; } hostdata = shost_priv(instance); hostdata->io = iomem; hostdata->region_size = region_size; if (is_pmio) { hostdata->io_port = base; hostdata->io_width = 1; /* 8-bit PDMA by default */ hostdata->offset = 0; /* * On NCR53C400 boards, NCR5380 registers are mapped 8 past * the base address. */ switch (board) { case BOARD_NCR53C400: hostdata->io_port += 8; hostdata->c400_ctl_status = 0; hostdata->c400_blk_cnt = 1; hostdata->c400_host_buf = 4; break; case BOARD_DTC3181E: hostdata->io_width = 2; /* 16-bit PDMA */ /* fall through */ case BOARD_NCR53C400A: case BOARD_HP_C2502: hostdata->c400_ctl_status = 9; hostdata->c400_blk_cnt = 10; hostdata->c400_host_buf = 8; break; } } else { hostdata->base = base; hostdata->offset = NCR53C400_mem_base; switch (board) { case BOARD_NCR53C400: hostdata->c400_ctl_status = 0x100; hostdata->c400_blk_cnt = 0x101; hostdata->c400_host_buf = 0x104; break; case BOARD_DTC3181E: case BOARD_NCR53C400A: case BOARD_HP_C2502: pr_err(DRV_MODULE_NAME ": unknown register offsets\n"); ret = -EINVAL; goto out_unregister; } } /* Check for vacant slot */ NCR5380_write(MODE_REG, 0); if (NCR5380_read(MODE_REG) != 0) { ret = -ENODEV; goto out_unregister; } ret = NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP); if (ret) goto out_unregister; switch (board) { case BOARD_NCR53C400: case BOARD_DTC3181E: case BOARD_NCR53C400A: case BOARD_HP_C2502: NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); } NCR5380_maybe_reset_bus(instance); /* Compatibility with documented NCR5380 kernel parameters */ if (irq == 255 || irq == 0) irq = NO_IRQ; else if (irq == -1) irq = IRQ_AUTO; if (board == BOARD_HP_C2502) { int *irq_table = hp_c2502_irqs; int board_irq = -1; switch (irq) { case NO_IRQ: board_irq = 0; break; case IRQ_AUTO: board_irq = legacy_find_free_irq(irq_table); break; default: while (*irq_table != -1) if (*irq_table++ == irq) board_irq = irq; } if (board_irq <= 0) { board_irq = 0; irq = NO_IRQ; } magic_configure(port_idx, board_irq, magic); } if (irq == IRQ_AUTO) { instance->irq = g_NCR5380_probe_irq(instance); if (instance->irq == NO_IRQ) shost_printk(KERN_INFO, instance, "no irq detected\n"); } else { instance->irq = irq; if (instance->irq == NO_IRQ) shost_printk(KERN_INFO, instance, "no irq provided\n"); } if (instance->irq != NO_IRQ) { if (request_irq(instance->irq, generic_NCR5380_intr, 0, "NCR5380", instance)) { instance->irq = NO_IRQ; shost_printk(KERN_INFO, instance, "irq %d denied\n", instance->irq); } else { shost_printk(KERN_INFO, instance, "irq %d acquired\n", instance->irq); } } ret = scsi_add_host(instance, pdev); if (ret) goto out_free_irq; scsi_scan_host(instance); dev_set_drvdata(pdev, instance); return 0; out_free_irq: if (instance->irq != NO_IRQ) free_irq(instance->irq, instance); NCR5380_exit(instance); out_unregister: scsi_host_put(instance); out_unmap: iounmap(iomem); out_release: if (is_pmio) release_region(base, region_size); else release_mem_region(base, region_size); return ret; }