Exemplo n.º 1
0
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);
	}
}
Exemplo n.º 2
0
/*
 * 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;
}