Example #1
0
int
mac53c94_host_reset(Scsi_Cmnd *cmd)
{
	struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata;
	volatile struct mac53c94_regs *regs = state->regs;
	volatile struct dbdma_regs *dma = state->dma;

	st_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
	regs->command = CMD_SCSI_RESET;	/* assert RST */
	eieio();
	udelay(100);			/* leave it on for a while (>= 25us) */
	regs->command = CMD_RESET;
	eieio();
	udelay(20);
	mac53c94_init(state);
	regs->command = CMD_NOP;
	eieio();
	return SUCCESS;
}
Example #2
0
static int mac53c94_host_reset(struct scsi_cmnd *cmd)
{
	struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata;
	struct mac53c94_regs __iomem *regs = state->regs;
	struct dbdma_regs __iomem *dma = state->dma;
	unsigned long flags;

	spin_lock_irqsave(cmd->device->host->host_lock, flags);

	writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control);
	writeb(CMD_SCSI_RESET, &regs->command);	/* assert RST */
	udelay(100);			/* leave it on for a while (>= 25us) */
	writeb(CMD_RESET, &regs->command);
	udelay(20);
	mac53c94_init(state);
	writeb(CMD_NOP, &regs->command);

	spin_unlock_irqrestore(cmd->device->host->host_lock, flags);
	return SUCCESS;
}
Example #3
0
int
mac53c94_detect(Scsi_Host_Template *tp)
{
	struct device_node *node;
	int nfscs;
	struct fsc_state *state, **prev_statep;
	struct Scsi_Host *host;
	void *dma_cmd_space;
	unsigned char *clkprop;
	int proplen;
	struct pci_dev *pdev;
	u8 pbus, devfn;

	nfscs = 0;
	prev_statep = &all_53c94s;
	for (node = find_devices("53c94"); node != 0; node = node->next) {
		if (node->n_addrs != 2 || node->n_intrs != 2) {
			printk(KERN_ERR "mac53c94: expected 2 addrs and intrs"
			       " (got %d/%d) for node %s\n",
			       node->n_addrs, node->n_intrs, node->full_name);
			continue;
		}

		pdev = NULL;
		if (node->parent != NULL
		    && !pci_device_from_OF_node(node->parent, &pbus, &devfn))
			pdev = pci_find_slot(pbus, devfn);
		if (pdev == NULL) {
			printk(KERN_ERR "mac53c94: can't find PCI device "
			       "for %s\n", node->full_name);
			continue;
		}

		host = scsi_register(tp, sizeof(struct fsc_state));
		if (host == NULL)
			break;
		host->unique_id = nfscs;

		state = (struct fsc_state *) host->hostdata;
		if (state == 0) {
			/* "can't happen" */
			printk(KERN_ERR "mac53c94: no state for %s?!\n",
			       node->full_name);
			scsi_unregister(host);
			break;
		}
		state->host = host;
		state->pdev = pdev;

		state->regs = (volatile struct mac53c94_regs *)
			ioremap(node->addrs[0].address, 0x1000);
		state->intr = node->intrs[0].line;
		state->dma = (volatile struct dbdma_regs *)
			ioremap(node->addrs[1].address, 0x1000);
		state->dmaintr = node->intrs[1].line;
		if (state->regs == NULL || state->dma == NULL) {
			printk(KERN_ERR "mac53c94: ioremap failed for %s\n",
			       node->full_name);
			if (state->dma != NULL)
				iounmap(state->dma);
			if (state->regs != NULL)
				iounmap(state->regs);
			scsi_unregister(host);
			break;
		}

		clkprop = get_property(node, "clock-frequency", &proplen);
		if (clkprop == NULL || proplen != sizeof(int)) {
			printk(KERN_ERR "%s: can't get clock frequency, "
			       "assuming 25MHz\n", node->full_name);
			state->clk_freq = 25000000;
		} else
			state->clk_freq = *(int *)clkprop;

		/* Space for dma command list: +1 for stop command,
		   +1 to allow for aligning. */
		dma_cmd_space = kmalloc((host->sg_tablesize + 2) *
					sizeof(struct dbdma_cmd), GFP_KERNEL);
		if (dma_cmd_space == 0) {
			printk(KERN_ERR "mac53c94: couldn't allocate dma "
			       "command space for %s\n", node->full_name);
			goto err_cleanup;
		}
		state->dma_cmds = (struct dbdma_cmd *)
			DBDMA_ALIGN(dma_cmd_space);
		memset(state->dma_cmds, 0, (host->sg_tablesize + 1)
		       * sizeof(struct dbdma_cmd));
		state->dma_cmd_space = dma_cmd_space;

		*prev_statep = state;
		prev_statep = &state->next;

		if (request_irq(state->intr, do_mac53c94_interrupt, 0,
				"53C94", state)) {
			printk(KERN_ERR "mac53C94: can't get irq %d for %s\n",
			       state->intr, node->full_name);
		err_cleanup:
			iounmap(state->dma);
			iounmap(state->regs);
			scsi_unregister(host);
			break;
		}

		mac53c94_init(state);

		++nfscs;
	}
	return nfscs;
}