Exemplo n.º 1
0
static int __devinit esp_mac_probe(struct platform_device *dev)
{
    struct scsi_host_template *tpnt = &scsi_esp_template;
    struct Scsi_Host *host;
    struct esp *esp;
    int err;
    struct mac_esp_priv *mep;

    if (!MACH_IS_MAC)
        return -ENODEV;

    if (dev->id > 1)
        return -ENODEV;

    host = scsi_host_alloc(tpnt, sizeof(struct esp));

    err = -ENOMEM;
    if (!host)
        goto fail;

    host->max_id = 8;
    host->use_clustering = DISABLE_CLUSTERING;
    esp = shost_priv(host);

    esp->host = host;
    esp->dev = dev;

    esp->command_block = kzalloc(16, GFP_KERNEL);
    if (!esp->command_block)
        goto fail_unlink;
    esp->command_block_dma = (dma_addr_t)esp->command_block;

    esp->scsi_id = 7;
    host->this_id = esp->scsi_id;
    esp->scsi_id_mask = 1 << esp->scsi_id;

    mep = kzalloc(sizeof(struct mac_esp_priv), GFP_KERNEL);
    if (!mep)
        goto fail_free_command_block;
    mep->esp = esp;
    platform_set_drvdata(dev, mep);

    switch (macintosh_config->scsi_type) {
    case MAC_SCSI_QUADRA:
        esp->cfreq     = 16500000;
        esp->regs      = (void __iomem *)MAC_ESP_REGS_QUADRA;
        mep->pdma_io   = esp->regs + MAC_ESP_PDMA_IO_OFFSET;
        mep->pdma_regs = NULL;
        break;
    case MAC_SCSI_QUADRA2:
        esp->cfreq     = 25000000;
        esp->regs      = (void __iomem *)(MAC_ESP_REGS_QUADRA2 +
                                          dev->id * MAC_ESP_REGS_SPACING);
        mep->pdma_io   = esp->regs + MAC_ESP_PDMA_IO_OFFSET;
        mep->pdma_regs = (void __iomem *)(MAC_ESP_PDMA_REG +
                                          dev->id * MAC_ESP_PDMA_REG_SPACING);
        nubus_writel(0x1d1, mep->pdma_regs);
        break;
    case MAC_SCSI_QUADRA3:
        /* These quadras have a real DMA controller (the PSC) but we
         * don't know how to drive it so we must use PIO instead.
         */
        esp->cfreq     = 25000000;
        esp->regs      = (void __iomem *)MAC_ESP_REGS_QUADRA3;
        mep->pdma_io   = NULL;
        mep->pdma_regs = NULL;
        break;
    }

    esp->ops = &mac_esp_ops;
    if (mep->pdma_io == NULL) {
        printk(KERN_INFO PFX "using PIO for controller %d\n", dev->id);
        esp_write8(0, ESP_TCLOW);
        esp_write8(0, ESP_TCMED);
        esp->flags = ESP_FLAG_DISABLE_SYNC;
        mac_esp_ops.send_dma_cmd = mac_esp_send_pio_cmd;
    } else {
        printk(KERN_INFO PFX "using PDMA for controller %d\n", dev->id);
    }

    host->irq = IRQ_MAC_SCSI;
    esp_chips[dev->id] = esp;
    mb();
    if (esp_chips[!dev->id] == NULL) {
        err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
        if (err < 0) {
            esp_chips[dev->id] = NULL;
            goto fail_free_priv;
        }
    }

    err = scsi_esp_register(esp, &dev->dev);
    if (err)
        goto fail_free_irq;

    return 0;

fail_free_irq:
    if (esp_chips[!dev->id] == NULL)
        free_irq(host->irq, esp);
fail_free_priv:
    kfree(mep);
fail_free_command_block:
    kfree(esp->command_block);
fail_unlink:
    scsi_host_put(host);
fail:
    return err;
}
Exemplo n.º 2
0
static int __devinit esp_sun3x_probe(struct platform_device *dev)
{
	struct scsi_host_template *tpnt = &scsi_esp_template;
	struct Scsi_Host *host;
	struct esp *esp;
	struct resource *res;
	int err = -ENOMEM;

	host = scsi_host_alloc(tpnt, sizeof(struct esp));
	if (!host)
		goto fail;

	host->max_id = 8;
	esp = shost_priv(host);

	esp->host = host;
	esp->dev = dev;
	esp->ops = &sun3x_esp_ops;

	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!res && !res->start)
		goto fail_unlink;

	esp->regs = ioremap_nocache(res->start, 0x20);
	if (!esp->regs)
		goto fail_unmap_regs;

	res = platform_get_resource(dev, IORESOURCE_MEM, 1);
	if (!res && !res->start)
		goto fail_unmap_regs;

	esp->dma_regs = ioremap_nocache(res->start, 0x10);

	esp->command_block = dma_alloc_coherent(esp->dev, 16,
						&esp->command_block_dma,
						GFP_KERNEL);
	if (!esp->command_block)
		goto fail_unmap_regs_dma;

	host->irq = platform_get_irq(dev, 0);
	err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED,
			  "SUN3X ESP", esp);
	if (err < 0)
		goto fail_unmap_command_block;

	esp->scsi_id = 7;
	esp->host->this_id = esp->scsi_id;
	esp->scsi_id_mask = (1 << esp->scsi_id);
	esp->cfreq = 20000000;

	dev_set_drvdata(&dev->dev, esp);

	err = scsi_esp_register(esp, &dev->dev);
	if (err)
		goto fail_free_irq;

	return 0;

fail_free_irq:
	free_irq(host->irq, esp);
fail_unmap_command_block:
	dma_free_coherent(esp->dev, 16,
			  esp->command_block,
			  esp->command_block_dma);
fail_unmap_regs_dma:
	iounmap(esp->dma_regs);
fail_unmap_regs:
	iounmap(esp->regs);
fail_unlink:
	scsi_host_put(host);
fail:
	return err;
}