Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ff228af authored by Finn Thain's avatar Finn Thain Committed by Christoph Hellwig
Browse files

atari_scsi: Convert to platform device



Convert atari_scsi to platform device and eliminate scsi_register().

Validate __setup options later on so that module options are checked as well.

Remove the comment about the scsi mid-layer disabling the host irq as it
is no longer true (AFAICT). Also remove the obsolete slow interrupt stuff
(IRQ_TYPE_SLOW == 0 anyway).

Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Acked-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 16b29e75
Loading
Loading
Loading
Loading
+27 −0
Original line number Original line Diff line number Diff line
@@ -858,6 +858,24 @@ static struct platform_device *atari_netusbee_devices[] __initdata = {
};
};
#endif /* CONFIG_ATARI_ETHERNEC */
#endif /* CONFIG_ATARI_ETHERNEC */


#ifdef CONFIG_ATARI_SCSI
static const struct resource atari_scsi_st_rsrc[] __initconst = {
	{
		.flags = IORESOURCE_IRQ,
		.start = IRQ_MFP_FSCSI,
		.end   = IRQ_MFP_FSCSI,
	},
};

static const struct resource atari_scsi_tt_rsrc[] __initconst = {
	{
		.flags = IORESOURCE_IRQ,
		.start = IRQ_TT_MFP_SCSI,
		.end   = IRQ_TT_MFP_SCSI,
	},
};
#endif

int __init atari_platform_init(void)
int __init atari_platform_init(void)
{
{
	int rv = 0;
	int rv = 0;
@@ -892,6 +910,15 @@ int __init atari_platform_init(void)
	}
	}
#endif
#endif


#ifdef CONFIG_ATARI_SCSI
	if (ATARIHW_PRESENT(ST_SCSI))
		platform_device_register_simple("atari_scsi", -1,
			atari_scsi_st_rsrc, ARRAY_SIZE(atari_scsi_st_rsrc));
	else if (ATARIHW_PRESENT(TT_SCSI))
		platform_device_register_simple("atari_scsi", -1,
			atari_scsi_tt_rsrc, ARRAY_SIZE(atari_scsi_tt_rsrc));
#endif

	return rv;
	return rv;
}
}


+210 −214
Original line number Original line Diff line number Diff line
@@ -74,33 +74,26 @@
#define	MAX_TAGS 32
#define	MAX_TAGS 32


#include <linux/types.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/nvram.h>
#include <linux/nvram.h>
#include <linux/bitops.h>
#include <linux/bitops.h>
#include <linux/wait.h>
#include <linux/wait.h>
#include <linux/platform_device.h>


#include <asm/setup.h>
#include <asm/setup.h>
#include <asm/atarihw.h>
#include <asm/atarihw.h>
#include <asm/atariints.h>
#include <asm/atariints.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/traps.h>

#include <scsi/scsi_host.h>
#include "atari_scsi.h"
#include "NCR5380.h"
#include <asm/atari_stdma.h>
#include <asm/atari_stdma.h>
#include <asm/atari_stram.h>
#include <asm/atari_stram.h>
#include <asm/io.h>
#include <asm/io.h>


#include <linux/stat.h>
#include <scsi/scsi_host.h>

#include "atari_scsi.h"
#include "NCR5380.h"


#define	IS_A_TT()	ATARIHW_PRESENT(TT_SCSI)
#define	IS_A_TT()	ATARIHW_PRESENT(TT_SCSI)


@@ -176,25 +169,9 @@ static inline void DISABLE_IRQ(void)
#define	AFTER_RESET_DELAY	(5*HZ/2)
#define	AFTER_RESET_DELAY	(5*HZ/2)
#endif
#endif


/***************************** Prototypes *****************************/

#ifdef REAL_DMA
#ifdef REAL_DMA
static void atari_scsi_fetch_restbytes(void);
static void atari_scsi_fetch_restbytes(void);
#endif
#endif
static irqreturn_t scsi_tt_intr(int irq, void *dummy);
static irqreturn_t scsi_falcon_intr(int irq, void *dummy);
static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata);
static int falcon_get_lock(void);
#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
static void atari_scsi_reset_boot(void);
#endif
static unsigned char atari_scsi_tt_reg_read(unsigned char reg);
static void atari_scsi_tt_reg_write(unsigned char reg, unsigned char value);
static unsigned char atari_scsi_falcon_reg_read(unsigned char reg);
static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value);

/************************* End of Prototypes **************************/



static struct Scsi_Host *atari_scsi_host;
static struct Scsi_Host *atari_scsi_host;
static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
@@ -517,160 +494,12 @@ static int falcon_get_lock(void)
	return 1;
	return 1;
}
}



static int __init atari_scsi_detect(struct scsi_host_template *host)
{
	static int called = 0;
	struct Scsi_Host *instance;

	if (!MACH_IS_ATARI ||
	    (!ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(TT_SCSI)) ||
	    called)
		return 0;

	host->proc_name = "Atari";

	atari_scsi_reg_read  = IS_A_TT() ? atari_scsi_tt_reg_read :
					   atari_scsi_falcon_reg_read;
	atari_scsi_reg_write = IS_A_TT() ? atari_scsi_tt_reg_write :
					   atari_scsi_falcon_reg_write;

	/* setup variables */
	host->can_queue =
		(setup_can_queue > 0) ? setup_can_queue :
		IS_A_TT() ? ATARI_TT_CAN_QUEUE : ATARI_FALCON_CAN_QUEUE;
	host->cmd_per_lun =
		(setup_cmd_per_lun > 0) ? setup_cmd_per_lun :
		IS_A_TT() ? ATARI_TT_CMD_PER_LUN : ATARI_FALCON_CMD_PER_LUN;
	/* Force sg_tablesize to 0 on a Falcon! */
	host->sg_tablesize =
		!IS_A_TT() ? ATARI_FALCON_SG_TABLESIZE :
		(setup_sg_tablesize >= 0) ? setup_sg_tablesize : ATARI_TT_SG_TABLESIZE;

	if (setup_hostid >= 0)
		host->this_id = setup_hostid;
	else {
		/* use 7 as default */
		host->this_id = 7;
		/* Test if a host id is set in the NVRam */
		if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
			unsigned char b = nvram_read_byte( 14 );
			/* Arbitration enabled? (for TOS) If yes, use configured host ID */
			if (b & 0x80)
				host->this_id = b & 7;
		}
	}

#ifdef SUPPORT_TAGS
	if (setup_use_tagged_queuing < 0)
		setup_use_tagged_queuing = 0;
#endif
#ifdef REAL_DMA
	/* If running on a Falcon and if there's TT-Ram (i.e., more than one
	 * memory block, since there's always ST-Ram in a Falcon), then allocate a
	 * STRAM_BUFFER_SIZE byte dribble buffer for transfers from/to alternative
	 * Ram.
	 */
	if (MACH_IS_ATARI && ATARIHW_PRESENT(ST_SCSI) &&
	    !ATARIHW_PRESENT(EXTD_DMA) && m68k_num_memory > 1) {
		atari_dma_buffer = atari_stram_alloc(STRAM_BUFFER_SIZE, "SCSI");
		if (!atari_dma_buffer) {
			printk(KERN_ERR "atari_scsi_detect: can't allocate ST-RAM "
					"double buffer\n");
			return 0;
		}
		atari_dma_phys_buffer = atari_stram_to_phys(atari_dma_buffer);
		atari_dma_orig_addr = 0;
	}
#endif
	instance = scsi_register(host, sizeof(struct NCR5380_hostdata));
	if (instance == NULL) {
		atari_stram_free(atari_dma_buffer);
		atari_dma_buffer = 0;
		return 0;
	}
	atari_scsi_host = instance;
	/*
	 * Set irq to 0, to avoid that the mid-level code disables our interrupt
	 * during queue_command calls. This is completely unnecessary, and even
	 * worse causes bad problems on the Falcon, where the int is shared with
	 * IDE and floppy!
	 */
       instance->irq = 0;

#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
	atari_scsi_reset_boot();
#endif
	NCR5380_init(instance, 0);

	if (IS_A_TT()) {

		/* This int is actually "pseudo-slow", i.e. it acts like a slow
		 * interrupt after having cleared the pending flag for the DMA
		 * interrupt. */
		if (request_irq(IRQ_TT_MFP_SCSI, scsi_tt_intr, IRQ_TYPE_SLOW,
				 "SCSI NCR5380", instance)) {
			printk(KERN_ERR "atari_scsi_detect: cannot allocate irq %d, aborting",IRQ_TT_MFP_SCSI);
			scsi_unregister(atari_scsi_host);
			atari_stram_free(atari_dma_buffer);
			atari_dma_buffer = 0;
			return 0;
		}
		tt_mfp.active_edge |= 0x80;		/* SCSI int on L->H */
#ifdef REAL_DMA
		tt_scsi_dma.dma_ctrl = 0;
		atari_dma_residual = 0;

		if (MACH_IS_MEDUSA) {
			/* While the read overruns (described by Drew Eckhardt in
			 * NCR5380.c) never happened on TTs, they do in fact on the Medusa
			 * (This was the cause why SCSI didn't work right for so long
			 * there.) Since handling the overruns slows down a bit, I turned
			 * the #ifdef's into a runtime condition.
			 *
			 * In principle it should be sufficient to do max. 1 byte with
			 * PIO, but there is another problem on the Medusa with the DMA
			 * rest data register. So 'atari_read_overruns' is currently set
			 * to 4 to avoid having transfers that aren't a multiple of 4. If
			 * the rest data bug is fixed, this can be lowered to 1.
			 */
			atari_read_overruns = 4;
		}
#endif /*REAL_DMA*/
	} else { /* ! IS_A_TT */

		/* Nothing to do for the interrupt: the ST-DMA is initialized
		 * already by atari_init_INTS()
		 */

#ifdef REAL_DMA
		atari_dma_residual = 0;
		atari_dma_active = 0;
		atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000
					: 0xff000000);
#endif
	}

	called = 1;
	return 1;
}

static int atari_scsi_release(struct Scsi_Host *sh)
{
	if (IS_A_TT())
		free_irq(IRQ_TT_MFP_SCSI, sh);
	if (atari_dma_buffer)
		atari_stram_free(atari_dma_buffer);
	NCR5380_exit(sh);
	return 1;
}

#ifndef MODULE
#ifndef MODULE
static int __init atari_scsi_setup(char *str)
static int __init atari_scsi_setup(char *str)
{
{
	/* Format of atascsi parameter is:
	/* Format of atascsi parameter is:
	 *   atascsi=<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
	 *   atascsi=<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
	 * Defaults depend on TT or Falcon, hostid determined at run time.
	 * Defaults depend on TT or Falcon, determined at run time.
	 * Negative values mean don't change.
	 * Negative values mean don't change.
	 */
	 */
	int ints[6];
	int ints[6];
@@ -681,36 +510,17 @@ static int __init atari_scsi_setup(char *str)
		printk("atari_scsi_setup: no arguments!\n");
		printk("atari_scsi_setup: no arguments!\n");
		return 0;
		return 0;
	}
	}

	if (ints[0] >= 1)
	if (ints[0] >= 1) {
		if (ints[1] > 0)
			/* no limits on this, just > 0 */
		setup_can_queue = ints[1];
		setup_can_queue = ints[1];
	}
	if (ints[0] >= 2)
	if (ints[0] >= 2) {
		if (ints[2] > 0)
		setup_cmd_per_lun = ints[2];
		setup_cmd_per_lun = ints[2];
	}
	if (ints[0] >= 3)
	if (ints[0] >= 3) {
		if (ints[3] >= 0) {
		setup_sg_tablesize = ints[3];
		setup_sg_tablesize = ints[3];
			/* Must be <= SG_ALL (255) */
	if (ints[0] >= 4)
			if (setup_sg_tablesize > SG_ALL)
				setup_sg_tablesize = SG_ALL;
		}
	}
	if (ints[0] >= 4) {
		/* Must be between 0 and 7 */
		if (ints[4] >= 0 && ints[4] <= 7)
		setup_hostid = ints[4];
		setup_hostid = ints[4];
		else if (ints[4] > 7)
			printk("atari_scsi_setup: invalid host ID %d !\n", ints[4]);
	}
#ifdef SUPPORT_TAGS
#ifdef SUPPORT_TAGS
	if (ints[0] >= 5) {
	if (ints[0] >= 5)
		if (ints[5] >= 0)
		setup_use_tagged_queuing = ints[5];
			setup_use_tagged_queuing = !!ints[5];
	}
#endif
#endif


	return 1;
	return 1;
@@ -1019,23 +829,209 @@ static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
	return rv;
	return rv;
}
}


static struct scsi_host_template driver_template = {
#define DRV_MODULE_NAME         "atari_scsi"
#define PFX                     DRV_MODULE_NAME ": "

static struct scsi_host_template atari_scsi_template = {
	.module			= THIS_MODULE,
	.proc_name		= DRV_MODULE_NAME,
	.show_info		= atari_scsi_show_info,
	.show_info		= atari_scsi_show_info,
	.name			= "Atari native SCSI",
	.name			= "Atari native SCSI",
	.detect			= atari_scsi_detect,
	.release		= atari_scsi_release,
	.info			= atari_scsi_info,
	.info			= atari_scsi_info,
	.queuecommand		= atari_scsi_queue_command,
	.queuecommand		= atari_scsi_queue_command,
	.eh_abort_handler	= atari_scsi_abort,
	.eh_abort_handler	= atari_scsi_abort,
	.eh_bus_reset_handler	= atari_scsi_bus_reset,
	.eh_bus_reset_handler	= atari_scsi_bus_reset,
	.can_queue		= 0, /* initialized at run-time */
	.this_id		= 7,
	.this_id		= 0, /* initialized at run-time */
	.sg_tablesize		= 0, /* initialized at run-time */
	.cmd_per_lun		= 0, /* initialized at run-time */
	.use_clustering		= DISABLE_CLUSTERING
	.use_clustering		= DISABLE_CLUSTERING
};
};


static int __init atari_scsi_probe(struct platform_device *pdev)
{
	struct Scsi_Host *instance;
	int error;
	struct resource *irq;

	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!irq)
		return -ENODEV;

	if (ATARIHW_PRESENT(TT_SCSI)) {
		atari_scsi_reg_read  = atari_scsi_tt_reg_read;
		atari_scsi_reg_write = atari_scsi_tt_reg_write;
	} else {
		atari_scsi_reg_read  = atari_scsi_falcon_reg_read;
		atari_scsi_reg_write = atari_scsi_falcon_reg_write;
	}

	/* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary.
	 * Higher values should work, too; try it!
	 * (But cmd_per_lun costs memory!)
	 *
	 * But there seems to be a bug somewhere that requires CAN_QUEUE to be
	 * 2*CMD_PER_LUN. At least on a TT, no spurious timeouts seen since
	 * changed CMD_PER_LUN...
	 *
	 * Note: The Falcon currently uses 8/1 setting due to unsolved problems
	 * with cmd_per_lun != 1
	 */
	if (ATARIHW_PRESENT(TT_SCSI)) {
		atari_scsi_template.can_queue    = 16;
		atari_scsi_template.cmd_per_lun  = 8;
		atari_scsi_template.sg_tablesize = SG_ALL;
	} else {
		atari_scsi_template.can_queue    = 8;
		atari_scsi_template.cmd_per_lun  = 1;
		atari_scsi_template.sg_tablesize = SG_NONE;
	}

	if (setup_can_queue > 0)
		atari_scsi_template.can_queue = setup_can_queue;

	if (setup_cmd_per_lun > 0)
		atari_scsi_template.cmd_per_lun = setup_cmd_per_lun;

	/* Leave sg_tablesize at 0 on a Falcon! */
	if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize >= 0)
		atari_scsi_template.sg_tablesize = setup_sg_tablesize;

	if (setup_hostid >= 0) {
		atari_scsi_template.this_id = setup_hostid & 7;
	} else {
		/* Test if a host id is set in the NVRam */
		if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
			unsigned char b = nvram_read_byte(14);

			/* Arbitration enabled? (for TOS)
			 * If yes, use configured host ID
			 */
			if (b & 0x80)
				atari_scsi_template.this_id = b & 7;
		}
	}

#ifdef SUPPORT_TAGS
	if (setup_use_tagged_queuing < 0)
		setup_use_tagged_queuing = 0;
#endif

#ifdef REAL_DMA
	/* If running on a Falcon and if there's TT-Ram (i.e., more than one
	 * memory block, since there's always ST-Ram in a Falcon), then
	 * allocate a STRAM_BUFFER_SIZE byte dribble buffer for transfers
	 * from/to alternative Ram.
	 */
	if (ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(EXTD_DMA) &&
	    m68k_num_memory > 1) {
		atari_dma_buffer = atari_stram_alloc(STRAM_BUFFER_SIZE, "SCSI");
		if (!atari_dma_buffer) {
			pr_err(PFX "can't allocate ST-RAM double buffer\n");
			return -ENOMEM;
		}
		atari_dma_phys_buffer = atari_stram_to_phys(atari_dma_buffer);
		atari_dma_orig_addr = 0;
	}
#endif

	instance = scsi_host_alloc(&atari_scsi_template,
	                           sizeof(struct NCR5380_hostdata));
	if (!instance) {
		error = -ENOMEM;
		goto fail_alloc;
	}
	atari_scsi_host = instance;

#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
	atari_scsi_reset_boot();
#endif

	instance->irq = irq->start;

	NCR5380_init(instance, 0);

	if (IS_A_TT()) {
		error = request_irq(instance->irq, scsi_tt_intr, 0,
		                    "NCR5380", instance);
		if (error) {
			pr_err(PFX "request irq %d failed, aborting\n",
			       instance->irq);
			goto fail_irq;
		}
		tt_mfp.active_edge |= 0x80;	/* SCSI int on L->H */
#ifdef REAL_DMA
		tt_scsi_dma.dma_ctrl = 0;
		atari_dma_residual = 0;

		/* While the read overruns (described by Drew Eckhardt in
		 * NCR5380.c) never happened on TTs, they do in fact on the
		 * Medusa (This was the cause why SCSI didn't work right for
		 * so long there.) Since handling the overruns slows down
		 * a bit, I turned the #ifdef's into a runtime condition.
		 *
		 * In principle it should be sufficient to do max. 1 byte with
		 * PIO, but there is another problem on the Medusa with the DMA
		 * rest data register. So 'atari_read_overruns' is currently set
		 * to 4 to avoid having transfers that aren't a multiple of 4.
		 * If the rest data bug is fixed, this can be lowered to 1.
		 */
		if (MACH_IS_MEDUSA)
			atari_read_overruns = 4;
#endif
	} else {
		/* Nothing to do for the interrupt: the ST-DMA is initialized
		 * already.
		 */
#ifdef REAL_DMA
		atari_dma_residual = 0;
		atari_dma_active = 0;
		atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000
					: 0xff000000);
#endif
	}

	error = scsi_add_host(instance, NULL);
	if (error)
		goto fail_host;

	platform_set_drvdata(pdev, instance);

	scsi_scan_host(instance);
	return 0;

fail_host:
	if (IS_A_TT())
		free_irq(instance->irq, instance);
fail_irq:
	NCR5380_exit(instance);
	scsi_host_put(instance);
fail_alloc:
	if (atari_dma_buffer)
		atari_stram_free(atari_dma_buffer);
	return error;
}

static int __exit atari_scsi_remove(struct platform_device *pdev)
{
	struct Scsi_Host *instance = platform_get_drvdata(pdev);

	scsi_remove_host(instance);
	if (IS_A_TT())
		free_irq(instance->irq, instance);
	NCR5380_exit(instance);
	scsi_host_put(instance);
	if (atari_dma_buffer)
		atari_stram_free(atari_dma_buffer);
	return 0;
}

static struct platform_driver atari_scsi_driver = {
	.remove = __exit_p(atari_scsi_remove),
	.driver = {
		.name	= DRV_MODULE_NAME,
		.owner	= THIS_MODULE,
	},
};


#include "scsi_module.c"
module_platform_driver_probe(atari_scsi_driver, atari_scsi_probe);


MODULE_ALIAS("platform:" DRV_MODULE_NAME);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL");
+0 −17
Original line number Original line Diff line number Diff line
@@ -18,23 +18,6 @@
/* (I_HAVE_OVERRUNS stuff removed) */
/* (I_HAVE_OVERRUNS stuff removed) */


#ifndef ASM
#ifndef ASM
/* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary. Higher
 * values should work, too; try it! (but cmd_per_lun costs memory!) */

/* But there seems to be a bug somewhere that requires CAN_QUEUE to be
 * 2*CMD_PER_LUN. At least on a TT, no spurious timeouts seen since
 * changed CMD_PER_LUN... */

/* Note: The Falcon currently uses 8/1 setting due to unsolved problems with
 * cmd_per_lun != 1 */

#define ATARI_TT_CAN_QUEUE		16
#define ATARI_TT_CMD_PER_LUN		8
#define ATARI_TT_SG_TABLESIZE		SG_ALL

#define ATARI_FALCON_CAN_QUEUE		8
#define ATARI_FALCON_CMD_PER_LUN	1
#define ATARI_FALCON_SG_TABLESIZE	SG_NONE


#define	NCR5380_implementation_fields	/* none */
#define	NCR5380_implementation_fields	/* none */