コード例 #1
0
ファイル: sgiwd93.c プロジェクト: xricson/knoppix
int __init sgiwd93_detect(Scsi_Host_Template *SGIblows)
{
	static unsigned char called = 0;
	struct hpc3_scsiregs *hregs = &hpc3c0->scsi_chan0;
	struct hpc3_scsiregs *hregs1 = &hpc3c0->scsi_chan1;
	struct WD33C93_hostdata *hdata;
	struct WD33C93_hostdata *hdata1;
	wd33c93_regs regs;
	uchar *buf;
	
	if(called)
		return 0; /* Should bitch on the console about this... */

	SGIblows->proc_name = "SGIWD93";

	sgiwd93_host = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata));
	if(sgiwd93_host == NULL)
		return 0;
	sgiwd93_host->base = (unsigned long) hregs;
	sgiwd93_host->irq = SGI_WD93_0_IRQ;

	buf = (uchar *) get_zeroed_page(GFP_KERNEL);
	if (!buf) {
		printk(KERN_WARNING "sgiwd93: Could not allocate memory for host0 buffer.\n");
		scsi_unregister(sgiwd93_host);
		return 0;
	}
	init_hpc_chain(buf);
	
	/* HPC_SCSI_REG0 | 0x03 | KSEG1 */
	regs.SASR = (unsigned char*) KSEG1ADDR (0x1fbc0003);
	regs.SCMD = (unsigned char*) KSEG1ADDR (0x1fbc0007);
	wd33c93_init(sgiwd93_host, regs, dma_setup, dma_stop, WD33C93_FS_16_20);

	hdata = (struct WD33C93_hostdata *)sgiwd93_host->hostdata;
	hdata->no_sync = 0;
	hdata->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf));

	if (request_irq(SGI_WD93_0_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host)) {
		printk(KERN_WARNING "sgiwd93: Could not register IRQ %d (for host 0).\n", SGI_WD93_0_IRQ);
		wd33c93_release();
		free_page((unsigned long)buf);
		scsi_unregister(sgiwd93_host);
		return 0;
	}
        /* set up second controller on the Indigo2 */
	if(!sgi_guiness) {
		sgiwd93_host1 = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata));
		if(sgiwd93_host1 != NULL)
		{
			sgiwd93_host1->base = (unsigned long) hregs1;
			sgiwd93_host1->irq = SGI_WD93_1_IRQ;
	
			buf = (uchar *) get_zeroed_page(GFP_KERNEL);
			if (!buf) {
				printk(KERN_WARNING "sgiwd93: Could not allocate memory for host1 buffer.\n");
				scsi_unregister(sgiwd93_host1);
				called = 1;
				return 1; /* We registered host0 so return success*/
			}
			init_hpc_chain(buf);

			/* HPC_SCSI_REG1 | 0x03 | KSEG1 */
			regs.SASR = (unsigned char*) KSEG1ADDR(0x1fbc8003);
			regs.SCMD = (unsigned char*) KSEG1ADDR(0x1fbc8007);
			wd33c93_init(sgiwd93_host1, regs, dma_setup, dma_stop,
			             WD33C93_FS_16_20);
	
			hdata1 = (struct WD33C93_hostdata *)sgiwd93_host1->hostdata;
			hdata1->no_sync = 0;
			hdata1->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf));
	
			if (request_irq(SGI_WD93_1_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host1)) {
				printk(KERN_WARNING "sgiwd93: Could not allocate irq %d (for host1).\n", SGI_WD93_1_IRQ);
				wd33c93_release();
				free_page((unsigned long)buf);
				scsi_unregister(sgiwd93_host1);
				/* Fall through since host0 registered OK */
			}
		}
	}
	
	called = 1;

	return 1; /* Found one. */
}
コード例 #2
0
static int __devinit sgiwd93_probe(struct platform_device *pdev)
{
	struct sgiwd93_platform_data *pd = pdev->dev.platform_data;
	unsigned char *wdregs = pd->wdregs;
	struct hpc3_scsiregs *hregs = pd->hregs;
	struct ip22_hostdata *hdata;
	struct Scsi_Host *host;
	wd33c93_regs regs;
	unsigned int unit = pd->unit;
	unsigned int irq = pd->irq;
	int err;

	host = scsi_host_alloc(&sgiwd93_template, sizeof(struct ip22_hostdata));
	if (!host) {
		err = -ENOMEM;
		goto out;
	}

	host->base = (unsigned long) hregs;
	host->irq = irq;

	hdata = host_to_hostdata(host);
	hdata->dev = &pdev->dev;
	hdata->cpu = dma_alloc_noncoherent(&pdev->dev, HPC_DMA_SIZE,
					   &hdata->dma, GFP_KERNEL);
	if (!hdata->cpu) {
		printk(KERN_WARNING "sgiwd93: Could not allocate memory for "
		       "host %d buffer.\n", unit);
		err = -ENOMEM;
		goto out_put;
	}

	init_hpc_chain(hdata);

	regs.SASR = wdregs + 3;
	regs.SCMD = wdregs + 7;

	hdata->wh.no_sync = 0;
	hdata->wh.fast = 1;
	hdata->wh.dma_mode = CTRL_BURST;

	wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_MHZ(20));

	err = request_irq(irq, sgiwd93_intr, 0, "SGI WD93", host);
	if (err) {
		printk(KERN_WARNING "sgiwd93: Could not register irq %d "
		       "for host %d.\n", irq, unit);
		goto out_free;
	}

	platform_set_drvdata(pdev, host);

	err = scsi_add_host(host, NULL);
	if (err)
		goto out_irq;

	scsi_scan_host(host);

	return 0;

out_irq:
	free_irq(irq, host);
out_free:
	dma_free_noncoherent(&pdev->dev, HPC_DMA_SIZE, hdata->cpu, hdata->dma);
out_put:
	scsi_host_put(host);
out:

	return err;
}