⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac53c94.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
			cmd_done(state, DID_ERROR << 16);			return;		}		if (cmd->SCp.this_residual != 0		    && (stat & (STAT_MSG|STAT_CD)) == 0) {			/* Set up the count regs to transfer more */			nb = cmd->SCp.this_residual;			if (nb > 0xfff0)				nb = 0xfff0;			cmd->SCp.this_residual -= nb;			writeb(nb, &regs->count_lo);			writeb(nb >> 8, &regs->count_mid);			writeb(CMD_DMA_MODE + CMD_NOP, &regs->command);			writeb(CMD_DMA_MODE + CMD_XFER_DATA, &regs->command);			break;		}		if ((stat & STAT_PHASE) != STAT_CD + STAT_IO) {			printk(KERN_DEBUG "intr %x before data xfer complete\n", intr);		}		writel(RUN << 16, &dma->control);	/* stop dma */		if (cmd->use_sg != 0) {			pci_unmap_sg(state->pdev,				(struct scatterlist *)cmd->request_buffer,				cmd->use_sg, cmd->sc_data_direction);		} else {			pci_unmap_single(state->pdev, state->dma_addr,				cmd->request_bufflen, cmd->sc_data_direction);		}		/* should check dma status */		writeb(CMD_I_COMPLETE, &regs->command);		state->phase = completing;		break;	case completing:		if (intr != INTR_DONE) {			printk(KERN_DEBUG "got intr %x on completion\n", intr);			cmd_done(state, DID_ERROR << 16);			return;		}		cmd->SCp.Status = readb(&regs->fifo);		cmd->SCp.Message = readb(&regs->fifo);		cmd->result = CMD_ACCEPT_MSG;		writeb(CMD_ACCEPT_MSG, &regs->command);		state->phase = busfreeing;		break;	case busfreeing:		if (intr != INTR_DISCONNECT) {			printk(KERN_DEBUG "got intr %x when expected disconnect\n", intr);		}		cmd_done(state, (DID_OK << 16) + (cmd->SCp.Message << 8)			 + cmd->SCp.Status);		break;	default:		printk(KERN_DEBUG "don't know about phase %d\n", state->phase);	}}static void cmd_done(struct fsc_state *state, int result){	struct scsi_cmnd *cmd;	cmd = state->current_req;	if (cmd != 0) {		cmd->result = result;		(*cmd->scsi_done)(cmd);		state->current_req = NULL;	}	state->phase = idle;	mac53c94_start(state);}/* * Set up DMA commands for transferring data. */static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd){	int i, dma_cmd, total;	struct scatterlist *scl;	struct dbdma_cmd *dcmds;	dma_addr_t dma_addr;	u32 dma_len;	dma_cmd = cmd->sc_data_direction == DMA_TO_DEVICE ?			OUTPUT_MORE : INPUT_MORE;	dcmds = state->dma_cmds;	if (cmd->use_sg > 0) {		int nseg;		total = 0;		scl = (struct scatterlist *) cmd->buffer;		nseg = pci_map_sg(state->pdev, scl, cmd->use_sg,				cmd->sc_data_direction);		for (i = 0; i < nseg; ++i) {			dma_addr = sg_dma_address(scl);			dma_len = sg_dma_len(scl);			if (dma_len > 0xffff)				panic("mac53c94: scatterlist element >= 64k");			total += dma_len;			st_le16(&dcmds->req_count, dma_len);			st_le16(&dcmds->command, dma_cmd);			st_le32(&dcmds->phy_addr, dma_addr);			dcmds->xfer_status = 0;			++scl;			++dcmds;		}	} else {		total = cmd->request_bufflen;		if (total > 0xffff)			panic("mac53c94: transfer size >= 64k");		dma_addr = pci_map_single(state->pdev, cmd->request_buffer,					  total, cmd->sc_data_direction);		state->dma_addr = dma_addr;		st_le16(&dcmds->req_count, total);		st_le32(&dcmds->phy_addr, dma_addr);		dcmds->xfer_status = 0;		++dcmds;	}	dma_cmd += OUTPUT_LAST - OUTPUT_MORE;	st_le16(&dcmds[-1].command, dma_cmd);	st_le16(&dcmds->command, DBDMA_STOP);	cmd->SCp.this_residual = total;}static struct scsi_host_template mac53c94_template = {	.proc_name	= "53c94",	.name		= "53C94",	.queuecommand	= mac53c94_queue,	.eh_abort_handler = mac53c94_abort,	.eh_host_reset_handler = mac53c94_host_reset,	.can_queue	= 1,	.this_id	= 7,	.sg_tablesize	= SG_ALL,	.cmd_per_lun	= 1,	.use_clustering	= DISABLE_CLUSTERING,};static int mac53c94_probe(struct macio_dev *mdev, const struct of_match *match){	struct device_node *node = macio_get_of_node(mdev);	struct pci_dev *pdev = macio_get_pci_dev(mdev);	struct fsc_state *state;	struct Scsi_Host *host;	void *dma_cmd_space;	unsigned char *clkprop;	int proplen;	if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) {		printk(KERN_ERR "mac53c94: expected 2 addrs and intrs (got %d/%d)\n",		       node->n_addrs, node->n_intrs);		return -ENODEV;	}	if (macio_request_resources(mdev, "mac53c94") != 0) {       		printk(KERN_ERR "mac53c94: unable to request memory resources");		return -EBUSY;	}       	host = scsi_host_alloc(&mac53c94_template, sizeof(struct fsc_state));	if (host == NULL) {		printk(KERN_ERR "mac53c94: couldn't register host");		goto out_release;	}	state = (struct fsc_state *) host->hostdata;	macio_set_drvdata(mdev, state);	state->host = host;	state->pdev = pdev;	state->mdev = mdev;	state->regs = (struct mac53c94_regs *)		ioremap(macio_resource_start(mdev, 0), 0x1000);	state->intr = macio_irq(mdev, 0);	state->dma = (struct dbdma_regs *)		ioremap(macio_resource_start(mdev, 1), 0x1000);	state->dmaintr = macio_irq(mdev, 1);	if (state->regs == NULL || state->dma == NULL) {		printk(KERN_ERR "mac53c94: ioremap failed for %s\n",		       node->full_name);		goto out_free;	}       	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.	 * XXX FIXME: Use DMA consistent routines	 */       	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 out_free;       	}	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;	mac53c94_init(state);	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);		goto out_free_dma;	}	/* XXX FIXME: handle failure */	scsi_add_host(host, &mdev->ofdev.dev);	scsi_scan_host(host);	return 0; out_free_dma:	kfree(state->dma_cmd_space); out_free:	if (state->dma != NULL)		iounmap(state->dma);	if (state->regs != NULL)		iounmap(state->regs);	scsi_host_put(host); out_release:	macio_release_resources(mdev);	return  -ENODEV;}static int mac53c94_remove(struct macio_dev *mdev){	struct fsc_state *fp = (struct fsc_state *)macio_get_drvdata(mdev);	struct Scsi_Host *host = fp->host;	scsi_remove_host(host);	free_irq(fp->intr, fp);	if (fp->regs)		iounmap((void *) fp->regs);	if (fp->dma)		iounmap((void *) fp->dma);	kfree(fp->dma_cmd_space);	scsi_host_put(host);	macio_release_resources(mdev);	return 0;}static struct of_match mac53c94_match[] = {	{	.name 		= "53c94",	.type		= OF_ANY_MATCH,	.compatible	= OF_ANY_MATCH	},	{},};static struct macio_driver mac53c94_driver = {	.name 		= "mac53c94",	.match_table	= mac53c94_match,	.probe		= mac53c94_probe,	.remove		= mac53c94_remove,};static int __init init_mac53c94(void){	return macio_register_driver(&mac53c94_driver);}static void __exit exit_mac53c94(void){	return macio_unregister_driver(&mac53c94_driver);}module_init(init_mac53c94);module_exit(exit_mac53c94);MODULE_DESCRIPTION("PowerMac 53c94 SCSI driver");MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -