int scsibus_bioctl(struct device *dev, u_long cmd, caddr_t addr) { struct scsibus_softc *sc = (struct scsibus_softc *)dev; struct sbioc_device *sdev; switch (cmd) { case SBIOCPROBE: sdev = (struct sbioc_device *)addr; return (scsi_probe(sc, sdev->sd_target, sdev->sd_lun)); case SBIOCDETACH: sdev = (struct sbioc_device *)addr; return (scsi_detach(sc, sdev->sd_target, sdev->sd_lun, 0)); default: return (ENOTTY); } }
/* * Initialize the device. */ int siop_init(int bus, int dev, int func) { struct siop_adapter tmp; struct siop_xfer *xfer; struct scsipi_generic *cmd; struct scsi_request_sense *sense; uint32_t reg; u_long addr; uint32_t *script; int slot, id, i; void *scriptaddr; u_char *data; const int clock_div = 3; /* 53c810 */ slot = PCISlotnum(bus, dev, func); if (slot == -1) return ENOENT; addr = PCIAddress(slot, 1, PCI_MAPREG_TYPE_MEM); if (addr == 0xffffffff) return EINVAL; enablePCI(slot, 0, 1, 1); script = ALLOC(uint32_t, SIOP_SCRIPT_SIZE); if (script == NULL) return ENOMEM; scriptaddr = (void *)local_to_PCI((u_long)script); cmd = ALLOC(struct scsipi_generic, SIOP_SCSI_COMMAND_SIZE); if (cmd == NULL) return ENOMEM; sense = ALLOC(struct scsi_request_sense, SIOP_SCSI_COMMAND_SIZE); if (sense == NULL) return ENOMEM; data = ALLOC(u_char, SIOP_SCSI_DATA_SIZE); if (data == NULL) return ENOMEM; xfer = ALLOC(struct siop_xfer, sizeof(struct siop_xfer)); if (xfer == NULL) return ENOMEM; siop_xfer_setup(xfer, scriptaddr); id = readb(addr + SIOP_SCID) & SCID_ENCID_MASK; /* reset bus */ reg = readb(addr + SIOP_SCNTL1); writeb(addr + SIOP_SCNTL1, reg | SCNTL1_RST); delay(100); writeb(addr + SIOP_SCNTL1, reg); /* reset the chip */ writeb(addr + SIOP_ISTAT, ISTAT_SRST); delay(1000); writeb(addr + SIOP_ISTAT, 0); /* init registers */ writeb(addr + SIOP_SCNTL0, SCNTL0_ARB_MASK | SCNTL0_EPC | SCNTL0_AAP); writeb(addr + SIOP_SCNTL1, 0); writeb(addr + SIOP_SCNTL3, clock_div); writeb(addr + SIOP_SXFER, 0); writeb(addr + SIOP_DIEN, 0xff); writeb(addr + SIOP_SIEN0, 0xff & ~(SIEN0_CMP | SIEN0_SEL | SIEN0_RSL)); writeb(addr + SIOP_SIEN1, 0xff & ~(SIEN1_HTH | SIEN1_GEN)); writeb(addr + SIOP_STEST2, 0); writeb(addr + SIOP_STEST3, STEST3_TE); writeb(addr + SIOP_STIME0, (0xb << STIME0_SEL_SHIFT)); writeb(addr + SIOP_SCID, id | SCID_RRE); writeb(addr + SIOP_RESPID0, 1 << id); writeb(addr + SIOP_DCNTL, DCNTL_COM); /* BeBox uses PCIC */ writeb(addr + SIOP_STEST1, STEST1_SCLK); siop_pci_reset(addr); /* copy and patch the script */ for (i = 0; i < __arraycount(siop_script); i++) script[i] = htoc32(siop_script[i]); for (i = 0; i < __arraycount(E_abs_msgin_Used); i++) script[E_abs_msgin_Used[i]] = htoc32(scriptaddr + Ent_msgin_space); /* start script */ _wbinv((u_long)script, SIOP_SCRIPT_SIZE); writel(addr + SIOP_DSP, (int)scriptaddr + Ent_reselect); memset(&tmp, 0, sizeof(tmp)); tmp.id = id; tmp.clock_div = clock_div; tmp.addr = addr; tmp.script = script; tmp.xfer = xfer; tmp.cmd = cmd; tmp.sense = sense; tmp.data = data; tmp.currschedslot = 0; tmp.sel_t = -1; if (scsi_probe(&tmp) == 0) return ENXIO; adapt = tmp; return 0; }