Commit 4adea1fd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull more SCSI updates from James Bottomley:
 "This is mostly stuff which missed the first pull request because it
  needed to incubate longer.  It's mainly made up of the ncr 5380 rework
  but also has a few assorted bug fixes"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (88 commits)
  imm: Use new parport device model
  megaraid: Fix possible NULL pointer deference in mraid_mm_ioctl
  storvsc: Fix typo in MODULE_PARM_DESC
  cxgbi: Typo in MODULE_PARM_DESC
  3w-xxxx: Pass through compat mode ioctls
  hisi_sas: Use u64 for qw0 in free_device_v1_hw()
  hisi_sas: Fix typo in setup_itct_v1_hw()
  hisi_sas: Fix v1 itct masks
  ipr: Fix out-of-bounds null overwrite
  scsi: add Synology to 1024 sector blacklist
  ncr5380: Add support for HP C2502
  ncr5380: Fix wait for 53C80 registers registers after PDMA
  ncr5380: Enable PDMA for DTC chips
  ncr5380: Enable PDMA for NCR53C400A
  ncr5380: Use runtime register mapping
  ncr5380: Fix pseudo DMA transfers on 53C400
  ncr5380: Cleanup whitespace and parentheses
  atari_NCR5380: Merge changes from NCR5380.c
  ncr5380: Merge changes from atari_NCR5380.c
  ncr5380: Fix whitespace in comments using regexp
  ...
parents 2c9b3ebd 60539fa3
......@@ -1045,6 +1045,9 @@ static int tw_chrdev_open(struct inode *inode, struct file *file)
static const struct file_operations tw_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = tw_chrdev_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = tw_chrdev_ioctl,
#endif
.open = tw_chrdev_open,
.release = NULL,
.llseek = noop_llseek,
......
......@@ -1620,23 +1620,6 @@ config ATARI_SCSI
ST-DMA, replacing ACSI). It does NOT support other schemes, like
in the Hades (without DMA).
config ATARI_SCSI_TOSHIBA_DELAY
bool "Long delays for Toshiba CD-ROMs"
depends on ATARI_SCSI
help
This option increases the delay after a SCSI arbitration to
accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
use a Toshiba CD-ROM drive; otherwise, the option is not needed and
would impact performance a bit, so say N.
config ATARI_SCSI_RESET_BOOT
bool "Reset SCSI-devices at boottime"
depends on ATARI_SCSI
help
Reset the devices on your Atari whenever it boots. This makes the
boot process fractionally longer but may assist recovery from errors
that leave the devices with SCSI operations partway completed.
config MAC_SCSI
tristate "Macintosh NCR5380 SCSI"
depends on MAC && SCSI=y
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -22,8 +22,13 @@
#ifndef NCR5380_H
#define NCR5380_H
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/workqueue.h>
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_transport_spi.h>
#define NDEBUG_ARBITRATION 0x1
#define NDEBUG_AUTOSENSE 0x2
......@@ -158,8 +163,7 @@
/* Write any value to this register to start an ini mode DMA receive */
#define START_DMA_INITIATOR_RECEIVE_REG 7 /* wo */
#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8 /* rw */
/* NCR 53C400(A) Control Status Register bits: */
#define CSR_RESET 0x80 /* wo Resets 53c400 */
#define CSR_53C80_REG 0x80 /* ro 5380 registers busy */
#define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */
......@@ -176,16 +180,6 @@
#define CSR_BASE CSR_53C80_INTR
#endif
/* Number of 128-byte blocks to be transferred */
#define C400_BLOCK_COUNTER_REG NCR53C400_register_offset-7 /* rw */
/* Resume transfer after disconnect */
#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6 /* wo */
/* Access to host buffer stack */
#define C400_HOST_BUFFER NCR53C400_register_offset-4 /* rw */
/* Note : PHASE_* macros are based on the values of the STATUS register */
#define PHASE_MASK (SR_MSG | SR_CD | SR_IO)
......@@ -205,16 +199,6 @@
#define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
/*
* The internal should_disconnect() function returns these based on the
* expected length of a disconnect if a device supports disconnect/
* reconnect.
*/
#define DISCONNECT_NONE 0
#define DISCONNECT_TIME_TO_DATA 1
#define DISCONNECT_LONG 2
/*
* "Special" value for the (unsigned char) command tag, to indicate
* I_T_L nexus instead of I_T_L_Q.
......@@ -236,15 +220,11 @@
#define NO_IRQ 0
#endif
#define FLAG_HAS_LAST_BYTE_SENT 1 /* NCR53c81 or better */
#define FLAG_CHECK_LAST_BYTE_SENT 2 /* Only test once */
#define FLAG_NCR53C400 4 /* NCR53c400 */
#define FLAG_NO_DMA_FIXUP 1 /* No DMA errata workarounds */
#define FLAG_NO_PSEUDO_DMA 8 /* Inhibit DMA */
#define FLAG_DTC3181E 16 /* DTC3181E */
#define FLAG_LATE_DMA_SETUP 32 /* Setup NCR before DMA H/W */
#define FLAG_TAGGED_QUEUING 64 /* as X3T9.2 spelled it */
#ifndef ASM
#define FLAG_TOSHIBA_DELAY 128 /* Allow for borken CD-ROMs */
#ifdef SUPPORT_TAGS
struct tag_alloc {
......@@ -258,33 +238,24 @@ struct NCR5380_hostdata {
NCR5380_implementation_fields; /* implementation specific */
struct Scsi_Host *host; /* Host backpointer */
unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
unsigned char targets_present; /* targets we have connected
to, so we can call a select
failure a retryable condition */
volatile unsigned char busy[8]; /* index = target, bit = lun */
unsigned char busy[8]; /* index = target, bit = lun */
#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
volatile int dma_len; /* requested length of DMA */
int dma_len; /* requested length of DMA */
#endif
volatile unsigned char last_message; /* last message OUT */
volatile struct scsi_cmnd *connected; /* currently connected command */
volatile struct scsi_cmnd *issue_queue; /* waiting to be issued */
volatile struct scsi_cmnd *disconnected_queue; /* waiting for reconnect */
volatile int restart_select; /* we have disconnected,
used to restart
NCR5380_select() */
volatile unsigned aborted:1; /* flag, says aborted */
unsigned char last_message; /* last message OUT */
struct scsi_cmnd *connected; /* currently connected cmnd */
struct scsi_cmnd *selecting; /* cmnd to be connected */
struct list_head unissued; /* waiting to be issued */
struct list_head autosense; /* priority issue queue */
struct list_head disconnected; /* waiting for reconnect */
spinlock_t lock; /* protects this struct */
int flags;
unsigned long time_expires; /* in jiffies, set prior to sleeping */
int select_time; /* timer in select for target response */
volatile struct scsi_cmnd *selecting;
struct delayed_work coroutine; /* our co-routine */
struct scsi_eh_save ses;
struct scsi_cmnd *sensing;
char info[256];
int read_overruns; /* number of bytes to cut from a
* transfer to handle chip overruns */
int retain_dma_intr;
struct work_struct main_task;
volatile int main_running;
#ifdef SUPPORT_TAGS
struct tag_alloc TagAlloc[8][8]; /* 8 targets and 8 LUNs */
#endif
......@@ -292,10 +263,23 @@ struct NCR5380_hostdata {
unsigned spin_max_r;
unsigned spin_max_w;
#endif
struct workqueue_struct *work_q;
unsigned long accesses_per_ms; /* chip register accesses per ms */
};
#ifdef __KERNEL__
struct NCR5380_cmd {
struct list_head list;
};
#define NCR5380_CMD_SIZE (sizeof(struct NCR5380_cmd))
static inline struct scsi_cmnd *NCR5380_to_scmd(struct NCR5380_cmd *ncmd_ptr)
{
return ((struct scsi_cmnd *)ncmd_ptr) - 1;
}
#ifndef NDEBUG
#define NDEBUG (0)
#endif
......@@ -304,6 +288,11 @@ struct NCR5380_hostdata {
do { if ((NDEBUG) & (flg)) \
printk(KERN_DEBUG fmt, ## __VA_ARGS__); } while (0)
#define dsprintk(flg, host, fmt, ...) \
do { if ((NDEBUG) & (flg)) \
shost_printk(KERN_DEBUG, host, fmt, ## __VA_ARGS__); \
} while (0)
#if NDEBUG
#define NCR5380_dprint(flg, arg) \
do { if ((NDEBUG) & (flg)) NCR5380_print(arg); } while (0)
......@@ -320,6 +309,7 @@ static void NCR5380_print(struct Scsi_Host *instance);
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
#endif
static int NCR5380_init(struct Scsi_Host *instance, int flags);
static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
static void NCR5380_exit(struct Scsi_Host *instance);
static void NCR5380_information_transfer(struct Scsi_Host *instance);
#ifndef DONT_USE_INTR
......@@ -328,7 +318,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id);
static void NCR5380_main(struct work_struct *work);
static const char *NCR5380_info(struct Scsi_Host *instance);
static void NCR5380_reselect(struct Scsi_Host *instance);
static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd);
static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
#if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
#endif
......@@ -443,5 +433,4 @@ static __inline__ int NCR5380_pc_dma_residual(struct Scsi_Host *instance)
#endif /* defined(i386) || defined(__alpha__) */
#endif /* defined(REAL_DMA) */
#endif /* __KERNEL__ */
#endif /* ndef ASM */
#endif /* NCR5380_H */
......@@ -4,9 +4,7 @@
* Copyright 1995-2002, Russell King
*/
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/init.h>
......@@ -15,15 +13,14 @@
#include <scsi/scsi_host.h>
#include <scsi/scsicam.h>
#define PSEUDO_DMA
#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_local_declare() struct Scsi_Host *_instance
#define NCR5380_setup(instance) _instance = instance
#define NCR5380_read(reg) cumanascsi_read(_instance, reg)
#define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value)
#define NCR5380_read(reg) cumanascsi_read(instance, reg)
#define NCR5380_write(reg, value) cumanascsi_write(instance, reg, value)
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize)
#define NCR5380_intr cumanascsi_intr
#define NCR5380_queue_command cumanascsi_queue_command
#define NCR5380_info cumanascsi_info
......@@ -211,6 +208,8 @@ static struct scsi_host_template cumanascsi_template = {
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "CumanaSCSI-1",
.cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128,
};
static int cumanascsi1_probe(struct expansion_card *ec,
......@@ -240,23 +239,21 @@ static int cumanascsi1_probe(struct expansion_card *ec,
host->irq = ec->irq;
NCR5380_init(host, 0);
ret = NCR5380_init(host, 0);
if (ret)
goto out_unmap;
NCR5380_maybe_reset_bus(host);
priv(host)->ctrl = 0;
writeb(0, priv(host)->base + CTRL);
host->n_io_port = 255;
if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
ret = -EBUSY;
goto out_unmap;
}
ret = request_irq(host->irq, cumanascsi_intr, 0,
"CumanaSCSI-1", host);
if (ret) {
printk("scsi%d: IRQ%d not free: %d\n",
host->host_no, host->irq, ret);
goto out_unmap;
goto out_exit;
}
ret = scsi_add_host(host, &ec->dev);
......@@ -268,6 +265,8 @@ static int cumanascsi1_probe(struct expansion_card *ec,
out_free_irq:
free_irq(host->irq, host);
out_exit:
NCR5380_exit(host);
out_unmap:
iounmap(priv(host)->base);
iounmap(priv(host)->dma);
......
......@@ -5,9 +5,7 @@
*/
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/init.h>
......@@ -20,14 +18,16 @@
#define DONT_USE_INTR
#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_local_declare() void __iomem *_base
#define NCR5380_setup(host) _base = priv(host)->base
#define NCR5380_read(reg) readb(_base + ((reg) << 2))
#define NCR5380_write(reg, value) writeb(value, _base + ((reg) << 2))
#define NCR5380_read(reg) \
readb(priv(instance)->base + ((reg) << 2))
#define NCR5380_write(reg, value) \
writeb(value, priv(instance)->base + ((reg) << 2))
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize)
#define NCR5380_queue_command oakscsi_queue_command
#define NCR5380_info oakscsi_info
#define NCR5380_show_info oakscsi_show_info
#define NCR5380_implementation_fields \
void __iomem *base
......@@ -103,7 +103,6 @@ printk("reading %p len %d\n", addr, len);
static struct scsi_host_template oakscsi_template = {
.module = THIS_MODULE,
.show_info = oakscsi_show_info,
.name = "Oak 16-bit SCSI",
.info = oakscsi_info,
.queuecommand = oakscsi_queue_command,
......@@ -115,6 +114,8 @@ static struct scsi_host_template oakscsi_template = {
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "oakscsi",
.cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128,
};
static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
......@@ -142,15 +143,21 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
host->irq = NO_IRQ;
host->n_io_port = 255;
NCR5380_init(host, 0);
ret = NCR5380_init(host, 0);
if (ret)
goto out_unmap;
NCR5380_maybe_reset_bus(host);
ret = scsi_add_host(host, &ec->dev);
if (ret)
goto out_unmap;
goto out_exit;
scsi_scan_host(host);
goto out;
out_exit:
NCR5380_exit(host);
out_unmap:
iounmap(priv(host)->base);
unreg:
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -66,7 +66,6 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/init.h>
......@@ -98,7 +97,6 @@
#define NCR5380_queue_command atari_scsi_queue_command
#define NCR5380_abort atari_scsi_abort
#define NCR5380_show_info atari_scsi_show_info
#define NCR5380_info atari_scsi_info
#define NCR5380_dma_read_setup(instance, data, count) \
......@@ -161,23 +159,10 @@ static inline unsigned long SCSI_DMA_GETADR(void)
return adr;
}
#define HOSTDATA_DMALEN (((struct NCR5380_hostdata *) \
(atari_scsi_host->hostdata))->dma_len)
/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
* we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
* need ten times the standard value... */
#ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
#define AFTER_RESET_DELAY (HZ/2)
#else
#define AFTER_RESET_DELAY (5*HZ/2)
#endif
#ifdef REAL_DMA
static void atari_scsi_fetch_restbytes(void);
#endif
static struct Scsi_Host *atari_scsi_host;
static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
......@@ -208,12 +193,12 @@ static int setup_cmd_per_lun = -1;
module_param(setup_cmd_per_lun, int, 0);
static int setup_sg_tablesize = -1;
module_param(setup_sg_tablesize, int, 0);
#ifdef SUPPORT_TAGS
static int setup_use_tagged_queuing = -1;
module_param(setup_use_tagged_queuing, int, 0);
#endif
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
static int setup_toshiba_delay = -1;
module_param(setup_toshiba_delay, int, 0);
#if defined(REAL_DMA)
......@@ -273,15 +258,17 @@ static void scsi_dma_buserr(int irq, void *dummy)
#endif
static irqreturn_t scsi_tt_intr(int irq, void *dummy)
static irqreturn_t scsi_tt_intr(int irq, void *dev)
{
#ifdef REAL_DMA
struct Scsi_Host *instance = dev;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int dma_stat;
dma_stat = tt_scsi_dma.dma_ctrl;
dprintk(NDEBUG_INTR, "scsi%d: NCR5380 interrupt, DMA status = %02x\n",
atari_scsi_host->host_no, dma_stat & 0xff);
dsprintk(NDEBUG_INTR, instance, "NCR5380 interrupt, DMA status = %02x\n",
dma_stat & 0xff);
/* Look if it was the DMA that has interrupted: First possibility
* is that a bus error occurred...
......@@ -304,7 +291,8 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy)
* data reg!
*/
if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
atari_dma_residual = hostdata->dma_len -
(SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
atari_dma_residual);
......@@ -356,15 +344,17 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy)
#endif /* REAL_DMA */
NCR5380_intr(irq, dummy);
NCR5380_intr(irq, dev);
return IRQ_HANDLED;
}
static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
static irqreturn_t scsi_falcon_intr(int irq, void *dev)
{
#ifdef REAL_DMA
struct Scsi_Host *instance = dev;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int dma_stat;
/* Turn off DMA and select sector counter register before
......@@ -399,7 +389,7 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
printk(KERN_ERR "SCSI DMA error: %ld bytes lost in "
"ST-DMA fifo\n", transferred & 15);
atari_dma_residual = HOSTDATA_DMALEN - transferred;
atari_dma_residual = hostdata->dma_len - transferred;
dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
atari_dma_residual);
} else
......@@ -411,13 +401,14 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
* data to the original destination address.
*/
memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr),
HOSTDATA_DMALEN - atari_dma_residual);
hostdata->dma_len - atari_dma_residual);
atari_dma_orig_addr = NULL;
}
#endif /* REAL_DMA */
NCR5380_intr(irq, dummy);
NCR5380_intr(irq, dev);
return IRQ_HANDLED;
}
......@@ -488,7 +479,7 @@ static int __init atari_scsi_setup(char *str)
* Defaults depend on TT or Falcon, determined at run time.
* Negative values mean don't change.
*/
int ints[6];
int ints[8];
get_options(str, ARRAY_SIZE(ints), ints);
......@@ -504,10 +495,11 @@ static int __init atari_scsi_setup(char *str)
setup_sg_tablesize = ints[3];
if (ints[0] >= 4)
setup_hostid = ints[4];
#ifdef SUPPORT_TAGS
if (ints[0] >= 5)
setup_use_tagged_queuing = ints[5];
#endif
/* ints[6] (use_pdma) is ignored */
if (ints[0] >= 7)
setup_toshiba_delay = ints[7];
return 1;
}
......@@ -516,38 +508,6 @@ __setup("atascsi=", atari_scsi_setup);
#endif /* !MODULE */
#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
static void __init atari_scsi_reset_boot(void)
{
unsigned long end;
/*
* Do a SCSI reset to clean up the bus during initialization. No messing
* with the queues, interrupts, or locks necessary here.
*/
printk("Atari SCSI: resetting the SCSI bus...");
/* get in phase */
NCR5380_write(TARGET_COMMAND_REG,
PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
/* assert RST */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
/* The min. reset hold time is 25us, so 40us should be enough */
udelay(50);
/* reset RST and interrupt */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
end = jiffies + AFTER_RESET_DELAY;
while (time_before(jiffies, end))
barrier();
printk(" done\n");
}
#endif
#if defined(REAL_DMA)
static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
......@@ -815,14 +775,14 @@ static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
static struct scsi_host_template atari_scsi_template = {
.module = THIS_MODULE,
.proc_name = DRV_MODULE_NAME,
.show_info = atari_scsi_show_info,
.name = "Atari native SCSI",
.info = atari_scsi_info,
.queuecommand = atari_scsi_queue_command,
.eh_abort_handler = atari_scsi_abort,
.eh_bus_reset_handler = atari_scsi_bus_reset,
.this_id = 7,
.use_clustering = DISABLE_CLUSTERING
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
};
static int __init atari_scsi_probe(struct platform_device *pdev)
......@@ -880,7 +840,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
} 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);
unsigned char b = nvram_read_byte(16);
/* Arbitration enabled? (for TOS)
* If yes, use configured host ID
......@@ -915,21 +875,18 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
error = -ENOMEM;
goto fail_alloc;
}
atari_scsi_host = instance;
#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
atari_scsi_reset_boot();
#endif
instance->irq = irq->start;
host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP;
#ifdef SUPPORT_TAGS
host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
#endif
host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
NCR5380_init(instance, host_flags);
error = NCR5380_init(instance, host_flags);
if (error)
goto fail_init;
if (IS_A_TT()) {
error = request_irq(instance->irq, scsi_tt_intr, 0,
......@@ -975,6 +932,8 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
#endif
}
NCR5380_maybe_reset_bus(instance);
error = scsi_add_host(instance, NULL);
if (error)
goto fail_host;
......@@ -989,6 +948,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
free_irq(instance->irq, instance);
fail_irq:
NCR5380_exit(instance);
fail_init:
scsi_host_put(instance);
fail_alloc:
if (atari_dma_buffer)
......
......@@ -57,7 +57,7 @@ MODULE_PARM_DESC(cxgb3i_snd_win, "TCP send window in bytes (default=128KB)");
static int cxgb3i_rx_credit_thres = 10 * 1024;
module_param(cxgb3i_rx_credit_thres, int, 0644);
MODULE_PARM_DESC(rx_credit_thres,
MODULE_PARM_DESC(cxgb3i_rx_credit_thres,
"RX credits return threshold in bytes (default=10KB)");
static unsigned int cxgb3i_max_connect = 8 * 1024;
......
......@@ -36,17 +36,10 @@
#define DONT_USE_INTR
#define NCR5380_read(reg) inb(port + reg)
#define NCR5380_write(reg, value) outb(value, port + reg)
#define NCR5380_read(reg) inb(instance->io_port + reg)
#define NCR5380_write(reg, value) outb(value, instance->io_port + reg)
#define NCR5380_implementation_fields /* none */
#define NCR5380_local_declare() unsigned int port
#define NCR5380_setup(instance) port = instance->io_port
/*
* Includes needed for NCR5380.[ch] (XXX: Move them to NCR5380.h)
*/
#include <linux/delay.h>
#include "NCR5380.h"
#include "NCR5380.c"
......@@ -56,6 +49,7 @@
static struct scsi_host_template dmx3191d_driver_template = {
.module = THIS_MODULE,
.proc_name = DMX3191D_DRIVER_NAME,
.name = "Domex DMX3191D",
.info = NCR5380_info,
......@@ -67,6 +61,8 @@ static struct scsi_host_template dmx3191d_driver_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128,
};
static int dmx3191d_probe_one(struct pci_dev *pdev,
......@@ -97,17 +93,25 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
*/
shost->irq = NO_IRQ;
NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA);
if (error)
goto out_host_put;
NCR5380_maybe_reset_bus(shost);
pci_set_drvdata(pdev, shost);
error = scsi_add_host(shost, &pdev->dev);
if (error)
goto out_release_region;
goto out_exit;
scsi_scan_host(shost);
return 0;
out_exit:
NCR5380_exit(shost);
out_host_put:
scsi_host_put(shost);
out_release_region:
release_region(io, DMX3191D_REGION_LEN);
out_disable_device:
......@@ -119,15 +123,14 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
static void dmx3191d_remove_one(struct pci_dev *pdev)
{
struct Scsi_Host *shost = pci_get_drvdata(pdev);
unsigned long io = shost->io_port;
scsi_remove_host(shost);
NCR5380_exit(shost);
release_region(shost->io_port, DMX3191D_REGION_LEN);
pci_disable_device(pdev);
scsi_host_put(shost);
release_region(io, DMX3191D_REGION_LEN);
pci_disable_device(pdev);
}
static struct pci_device_id dmx3191d_pci_tbl[] = {
......
#define PSEUDO_DMA
#define DONT_USE_INTR
#define UNSAFE /* Leave interrupts enabled during pseudo-dma I/O */
#define DMA_WORKS_RIGHT
/*
* DTC 3180/3280 driver, by
......@@ -50,15 +46,13 @@
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <scsi/scsi_host.h>
#include "dtc.h"
#define AUTOPROBE_IRQ
#include "NCR5380.h"
......@@ -150,7 +144,7 @@ static const struct signature {
static int __init dtc_setup(char *str)
{
static int commandline_current = 0;
static int commandline_current;
int i;
int ints[10];
......@@ -188,7 +182,7 @@ __setup("dtc=", dtc_setup);
static int __init dtc_detect(struct scsi_host_template * tpnt)
{
static int current_override = 0, current_base = 0;
static int current_override, current_base;
struct Scsi_Host *instance;
unsigned int addr;
void __iomem *base;
......@@ -205,9 +199,8 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
addr = 0;
} else
for (; !addr && (current_base < NO_BASES); ++current_base) {
#if (DTCDEBUG & DTCDEBUG_INIT)
printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address);
#endif
dprintk(NDEBUG_INIT, "dtc: probing address 0x%08x\n",
(unsigned int)bases[current_base].address);
if (bases[current_base].noauto)
continue;
base = ioremap(bases[current_base].address, 0x2000);
......@@ -216,18 +209,14 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
for (sig = 0; sig < NO_SIGNATURES; ++sig) {
if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
addr = bases[current_base].address;
#if (DTCDEBUG & DTCDEBUG_INIT)
printk(KERN_DEBUG "scsi-dtc : detected board.\n");
#endif
dprintk(NDEBUG_INIT, "dtc: detected board\n");
goto found;
}
}
iounmap(base);
}
#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr);
#endif
dprintk(NDEBUG_INIT, "dtc: addr = 0x%08x\n", addr);
if (!addr)
break;
......@@ -235,12 +224,15 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
found:
instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
if (instance == NULL)
break;
goto out_unmap;
instance->base = addr;
((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
NCR5380_init(instance, 0);
if (NCR5380_init(instance, FLAG_NO_DMA_FIXUP))
goto out_unregister;
NCR5380_maybe_reset_bus(instance);
NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */
if (overrides[current_override].irq != IRQ_AUTO)
......@@ -271,14 +263,19 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
instance->irq = NO_IRQ;
#endif
#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
#endif
dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
instance->host_no, instance->irq);
++current_override;
++count;
}
return count;
out_unregister:
scsi_unregister(instance);
out_unmap:
iounmap(base);
return count;
}
/*
......@@ -331,12 +328,8 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
unsigned char *d = dst;
int i; /* For counting time spent in the poll-loop */
struct NCR5380_hostdata *hostdata = shost_priv(instance);
NCR5380_local_declare();
NCR5380_setup(instance);
i = 0;
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
if (instance->irq == NO_IRQ)
NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
else
......@@ -348,7 +341,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
++i;
rtrc(3);
memcpy_fromio(d, base + DTC_DATA_BUF, 128);
memcpy_fromio(d, hostdata->base + DTC_DATA_BUF, 128);
d += 128;
len -= 128;
rtrc(7);
......@@ -358,9 +351,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
rtrc(4);
while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
++i;
NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
rtrc(0);
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
if (i > hostdata->spin_max_r)
hostdata->spin_max_r = i;
return (0);
......@@ -383,12 +374,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
{
int i;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
NCR5380_local_declare();
NCR5380_setup(instance);
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
/* set direction (write) */
if (instance->irq == NO_IRQ)
NCR5380_write(DTC_CONTROL_REG, 0);
else
......@@ -400,7 +386,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
++i;
rtrc(3);
memcpy_toio(base + DTC_DATA_BUF, src, 128);
memcpy_toio(hostdata->base + DTC_DATA_BUF, src, 128);
src += 128;
len -= 128;
}
......@@ -413,47 +399,60 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
++i;
rtrc(7);
/* Check for parity error here. fixme. */
NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
rtrc(0);
if (i > hostdata->spin_max_w)
hostdata->spin_max_w = i;
return (0);
}
static int dtc_dma_xfer_len(struct scsi_cmnd *cmd)
{
int transfersize = cmd->transfersize;
/* Limit transfers to 32K, for xx400 & xx406
* pseudoDMA that transfers in 128 bytes blocks.
*/
if (transfersize > 32 * 1024 && cmd->SCp.this_residual &&
!(cmd->SCp.this_residual % transfersize))
transfersize = 32 * 1024;
return transfersize;
}
MODULE_LICENSE("GPL");
#include "NCR5380.c"
static int dtc_release(struct Scsi_Host *shost)
{
NCR5380_local_declare();
NCR5380_setup(shost);
struct NCR5380_hostdata *hostdata = shost_priv(shost);
if (shost->irq != NO_IRQ)
free_irq(shost->irq, shost);
NCR5380_exit(shost);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
iounmap(base);
iounmap(hostdata->base);
return 0;
}
static struct scsi_host_template driver_template = {
.name = "DTC 3180/3280 ",
.detect = dtc_detect,
.release = dtc_release,
.proc_name = "dtc3x80",
.show_info = dtc_show_info,
.write_info = dtc_write_info,
.info = dtc_info,
.queuecommand = dtc_queue_command,
.eh_abort_handler = dtc_abort,
.eh_bus_reset_handler = dtc_bus_reset,
.bios_param = dtc_biosparam,
.can_queue = CAN_QUEUE,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN,
.use_clustering = DISABLE_CLUSTERING,
.name = "DTC 3180/3280",
.detect = dtc_detect,
.release = dtc_release,
.proc_name = "dtc3x80",
.show_info = dtc_show_info,
.write_info = dtc_write_info,
.info = dtc_info,
.queuecommand = dtc_queue_command,
.eh_abort_handler = dtc_abort,
.eh_bus_reset_handler = dtc_bus_reset,
.bios_param = dtc_biosparam,
.can_queue = 32,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128,
};
#include "scsi_module.c"
......@@ -10,54 +10,17 @@
#ifndef DTC3280_H
#define DTC3280_H
#define DTCDEBUG 0
#define DTCDEBUG_INIT 0x1
#define DTCDEBUG_TRANSFER 0x2
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
#ifndef CAN_QUEUE
#define CAN_QUEUE 32
#endif
#define NCR5380_implementation_fields \
void __iomem *base
#define NCR5380_local_declare() \
void __iomem *base
#define NCR5380_setup(instance) \
base = ((struct NCR5380_hostdata *)(instance)->hostdata)->base
#define DTC_address(reg) \
(((struct NCR5380_hostdata *)shost_priv(instance))->base + DTC_5380_OFFSET + reg)
#define DTC_address(reg) (base + DTC_5380_OFFSET + reg)
#define dbNCR5380_read(reg) \
(rval=readb(DTC_address(reg)), \
(((unsigned char) printk("DTC : read register %d at addr %p is: %02x\n"\
, (reg), DTC_address(reg), rval)), rval ) )
#define dbNCR5380_write(reg, value) do { \
printk("DTC : write %02x to register %d at address %p\n", \
(value), (reg), DTC_address(reg)); \
writeb(value, DTC_address(reg));} while(0)
#if !(DTCDEBUG & DTCDEBUG_TRANSFER)
#define NCR5380_read(reg) (readb(DTC_address(reg)))
#define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
#else
#define NCR5380_read(reg) (readb(DTC_address(reg)))
#define xNCR5380_read(reg) \
(((unsigned char) printk("DTC : read register %d at address %p\n"\
, (reg), DTC_address(reg))), readb(DTC_address(reg)))
#define NCR5380_write(reg, value) do { \
printk("DTC : write %02x to register %d at address %p\n", \
(value), (reg), DTC_address(reg)); \
writeb(value, DTC_address(reg));} while(0)
#endif
#define NCR5380_dma_xfer_len(instance, cmd, phase) \
dtc_dma_xfer_len(cmd)
#define NCR5380_intr dtc_intr
#define NCR5380_queue_command dtc_queue_command
......
......@@ -56,40 +56,31 @@
*
*/
/* settings for DTC3181E card with only Mustek scanner attached */
#define USLEEP_POLL msecs_to_jiffies(10)
#define USLEEP_SLEEP msecs_to_jiffies(200)
#define USLEEP_WAITLONG msecs_to_jiffies(5000)
#define AUTOPROBE_IRQ
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define NCR53C400_PSEUDO_DMA 1
#define PSEUDO_DMA
#define NCR53C400
#endif
#include <asm/io.h>
#include <linux/signal.h>
#include <linux/blkdev.h>
#include <linux/module.h>
#include <scsi/scsi_host.h>
#include "g_NCR5380.h"
#include "NCR5380.h"
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/isapnp.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#define NCR_NOT_SET 0
static int ncr_irq = NCR_NOT_SET;
static int ncr_dma = NCR_NOT_SET;
static int ncr_addr = NCR_NOT_SET;
static int ncr_5380 = NCR_NOT_SET;
static int ncr_53c400 = NCR_NOT_SET;
static int ncr_53c400a = NCR_NOT_SET;
static int dtc_3181e = NCR_NOT_SET;
static int ncr_irq;
static int ncr_dma;
static int ncr_addr;
static int ncr_5380;
static int ncr_53c400;
static int ncr_53c400a;
static int dtc_3181e;
static int hp_c2502;
static struct override {
NCR5380_map_type NCR5380_map_name;
......@@ -121,7 +112,7 @@ static struct override {
static void __init internal_setup(int board, char *str, int *ints)
{
static int commandline_current = 0;
static int commandline_current;
switch (board) {
case BOARD_NCR5380:
if (ints[0] != 2 && ints[0] != 3) {
......@@ -235,6 +226,30 @@ static int __init do_DTC3181E_setup(char *str)
#endif
#ifndef SCSI_G_NCR5380_MEM
/*
* Configure I/O address of 53C400A or DTC436 by writing magic numbers
* to ports 0x779 and 0x379.
*/
static void magic_configure(int idx, u8 irq, u8 magic[])
{
u8 cfg = 0;
outb(magic[0], 0x779);
outb(magic[1], 0x379);
outb(magic[2], 0x379);
outb(magic[3], 0x379);
outb(magic[4], 0x379);
/* allowed IRQs for HP C2502 */
if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
irq = 0;
if (idx >= 0 && idx <= 7)
cfg = 0x80 | idx | (irq << 4);
outb(cfg, 0x379);
}
#endif
/**
* generic_NCR5380_detect - look for NCR5380 controllers
* @tpnt: the scsi template
......@@ -243,19 +258,18 @@ static int __init do_DTC3181E_setup(char *str)
* and DTC436(ISAPnP) controllers. If overrides have been set we use
* them.
*
* The caller supplied NCR5380_init function is invoked from here, before
* the interrupt line is taken.
*
* Locks: none
*/
static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
{
static int current_override = 0;
static int current_override;
int count;
unsigned int *ports;
u8 *magic = NULL;
#ifndef SCSI_G_NCR5380_MEM
int i;
int port_idx = -1;
unsigned long region_size = 16;
#endif
static unsigned int __initdata ncr_53c400a_ports[] = {
......@@ -264,27 +278,36 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
static unsigned int __initdata dtc_3181e_ports[] = {
0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
};
int flags = 0;
static u8 ncr_53c400a_magic[] __initdata = { /* 53C400A & DTC436 */
0x59, 0xb9, 0xc5, 0xae, 0xa6
};
static u8 hp_c2502_magic[] __initdata = { /* HP C2502 */
0x0f, 0x22, 0xf0, 0x20, 0x80
};
int flags;
struct Scsi_Host *instance;
struct NCR5380_hostdata *hostdata;
#ifdef SCSI_G_NCR5380_MEM
unsigned long base;
void __iomem *iomem;
#endif
if (ncr_irq != NCR_NOT_SET)
if (ncr_irq)
overrides[0].irq = ncr_irq;
if (ncr_dma != NCR_NOT_SET)
if (ncr_dma)
overrides[0].dma = ncr_dma;
if (ncr_addr != NCR_NOT_SET)
if (ncr_addr)
overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
if (ncr_5380 != NCR_NOT_SET)
if (ncr_5380)
overrides[0].board = BOARD_NCR5380;
else if (ncr_53c400 != NCR_NOT_SET)
else if (ncr_53c400)
overrides[0].board = BOARD_NCR53C400;
else if (ncr_53c400a != NCR_NOT_SET)
else if (ncr_53c400a)
overrides[0].board = BOARD_NCR53C400A;
else if (dtc_3181e != NCR_NOT_SET)
else if (dtc_3181e)
overrides[0].board = BOARD_DTC3181E;
else if (hp_c2502)
overrides[0].board = BOARD_HP_C2502;
#ifndef SCSI_G_NCR5380_MEM
if (!current_override && isapnp_present()) {
struct pnp_dev *dev = NULL;
......@@ -318,41 +341,45 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
}
}
#endif
tpnt->proc_name = "g_NCR5380";
for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
if (!(overrides[current_override].NCR5380_map_name))
continue;
ports = NULL;
flags = 0;
switch (overrides[current_override].board) {
case BOARD_NCR5380:
flags = FLAG_NO_PSEUDO_DMA;
break;
case BOARD_NCR53C400:
flags = FLAG_NCR53C400;
#ifdef PSEUDO_DMA
flags = FLAG_NO_DMA_FIXUP;
#endif
break;
case BOARD_NCR53C400A:
flags = FLAG_NO_PSEUDO_DMA;
flags = FLAG_NO_DMA_FIXUP;
ports = ncr_53c400a_ports;
magic = ncr_53c400a_magic;
break;
case BOARD_HP_C2502:
flags = FLAG_NO_DMA_FIXUP;
ports = ncr_53c400a_ports;
magic = hp_c2502_magic;
break;
case BOARD_DTC3181E:
flags = FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E;
flags = FLAG_NO_DMA_FIXUP;
ports = dtc_3181e_ports;
magic = ncr_53c400a_magic;
break;
}
#ifndef SCSI_G_NCR5380_MEM
if (ports) {
if (ports && magic) {
/* wakeup sequence for the NCR53C400A and DTC3181E */
/* Disable the adapter and look for a free io port */
outb(0x59, 0x779);
outb(0xb9, 0x379);
outb(0xc5, 0x379);
outb(0xae, 0x379);
outb(0xa6, 0x379);
outb(0x00, 0x379);
magic_configure(-1, 0, magic);
if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
for (i = 0; ports[i]; i++) {
......@@ -371,17 +398,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
}
if (ports[i]) {
/* At this point we have our region reserved */
outb(0x59, 0x779);
outb(0xb9, 0x379);
outb(0xc5, 0x379);
outb(0xae, 0x379);
outb(0xa6, 0x379);
outb(0x80 | i, 0x379); /* set io port to be used */
magic_configure(i, 0, magic); /* no IRQ yet */
outb(0xc0, ports[i] + 9);
if (inb(ports[i] + 9) != 0x80)
continue;
else
overrides[current_override].NCR5380_map_name = ports[i];
overrides[current_override].NCR5380_map_name = ports[i];
port_idx = i;
} else
continue;
}
......@@ -403,24 +425,65 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
}
#endif
instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
if (instance == NULL) {
#ifndef SCSI_G_NCR5380_MEM
release_region(overrides[current_override].NCR5380_map_name, region_size);
#else
iounmap(iomem);
release_mem_region(base, NCR5380_region_size);
#endif
continue;
}
if (instance == NULL)
goto out_release;
hostdata = shost_priv(instance);
instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
#ifndef SCSI_G_NCR5380_MEM
instance->io_port = overrides[current_override].NCR5380_map_name;
instance->n_io_port = region_size;
hostdata->io_width = 1; /* 8-bit PDMA by default */
/*
* On NCR53C400 boards, NCR5380 registers are mapped 8 past
* the base address.
*/
switch (overrides[current_override].board) {
case BOARD_NCR53C400:
instance->io_port += 8;
hostdata->c400_ctl_status = 0;
hostdata->c400_blk_cnt = 1;
hostdata->c400_host_buf = 4;
break;
case BOARD_DTC3181E:
hostdata->io_width = 2; /* 16-bit PDMA */
/* fall through */
case BOARD_NCR53C400A:
case BOARD_HP_C2502:
hostdata->c400_ctl_status = 9;
hostdata->c400_blk_cnt = 10;
hostdata->c400_host_buf = 8;
break;
}
#else
((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
instance->base = overrides[current_override].NCR5380_map_name;
hostdata->iomem = iomem;
switch (overrides[current_override].board) {
case BOARD_NCR53C400:
hostdata->c400_ctl_status = 0x100;
hostdata->c400_blk_cnt = 0x101;
hostdata->c400_host_buf = 0x104;
break;
case BOARD_DTC3181E:
case BOARD_NCR53C400A:
case BOARD_HP_C2502:
pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
goto out_unregister;
}
#endif
NCR5380_init(instance, flags);
if (NCR5380_init(instance, flags))
goto out_unregister;
switch (overrides[current_override].board) {
case BOARD_NCR53C400:
case BOARD_DTC3181E:
case BOARD_NCR53C400A:
case BOARD_HP_C2502:
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
}
NCR5380_maybe_reset_bus(instance);
if (overrides[current_override].irq != IRQ_AUTO)
instance->irq = overrides[current_override].irq;
......@@ -431,12 +494,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
if (instance->irq == 255)
instance->irq = NO_IRQ;
if (instance->irq != NO_IRQ)
if (instance->irq != NO_IRQ) {
#ifndef SCSI_G_NCR5380_MEM
/* set IRQ for HP C2502 */
if (overrides[current_override].board == BOARD_HP_C2502)
magic_configure(port_idx, instance->irq, magic);
#endif
if (request_irq(instance->irq, generic_NCR5380_intr,
0, "NCR5380", instance)) {
printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
instance->irq = NO_IRQ;
}
}
if (instance->irq == NO_IRQ) {
printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
......@@ -447,6 +516,17 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
++count;
}
return count;
out_unregister:
scsi_unregister(instance);
out_release:
#ifndef SCSI_G_NCR5380_MEM
release_region(overrides[current_override].NCR5380_map_name, region_size);
#else
iounmap(iomem);
release_mem_region(base, NCR5380_region_size);
#endif
return count;
}
/**
......@@ -460,21 +540,15 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
{
NCR5380_local_declare();
NCR5380_setup(instance);
if (instance->irq != NO_IRQ)
free_irq(instance->irq, instance);
NCR5380_exit(instance);
#ifndef SCSI_G_NCR5380_MEM
release_region(instance->NCR5380_instance_name, instance->n_io_port);
release_region(instance->io_port, instance->n_io_port);
#else
iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size);
release_mem_region(instance->base, NCR5380_region_size);
#endif
return 0;
}
......@@ -507,7 +581,7 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
}
#endif
#ifdef NCR53C400_PSEUDO_DMA
#ifdef PSEUDO_DMA
/**
* NCR5380_pread - pseudo DMA read
......@@ -521,75 +595,68 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int blocks = len / 128;
int start = 0;
int bl;
NCR5380_local_declare();
NCR5380_setup(instance);
NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
NCR5380_write(hostdata->c400_blk_cnt, blocks);
while (1) {
if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
break;
}
if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
return -1;
}
while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
; /* FIXME - no timeout */
#ifndef SCSI_G_NCR5380_MEM
{
int i;
for (i = 0; i < 128; i++)
dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
}
if (hostdata->io_width == 2)
insw(instance->io_port + hostdata->c400_host_buf,
dst + start, 64);
else
insb(instance->io_port + hostdata->c400_host_buf,
dst + start, 128);
#else
/* implies SCSI_G_NCR5380_MEM */
memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
memcpy_fromio(dst + start,
hostdata->iomem + NCR53C400_host_buffer, 128);
#endif
start += 128;
blocks--;
}
if (blocks) {
while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
{
// FIXME - no timeout
}
while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
; /* FIXME - no timeout */
#ifndef SCSI_G_NCR5380_MEM
{
int i;
for (i = 0; i < 128; i++)
dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
}
if (hostdata->io_width == 2)
insw(instance->io_port + hostdata->c400_host_buf,
dst + start, 64);
else
insb(instance->io_port + hostdata->c400_host_buf,
dst + start, 128);
#else
/* implies SCSI_G_NCR5380_MEM */
memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
memcpy_fromio(dst + start,
hostdata->iomem + NCR53C400_host_buffer, 128);
#endif
start += 128;
blocks--;
}
if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
printk("53C400r: no 53C80 gated irq after transfer");
#if 0
/*
* DON'T DO THIS - THEY NEVER ARRIVE!
*/
printk("53C400r: Waiting for 53C80 registers\n");
while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
/* wait for 53C80 registers to be available */
while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
;
#endif
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
printk(KERN_ERR "53C400r: no end dma signal\n");
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
return 0;
}
......@@ -605,89 +672,91 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int blocks = len / 128;
int start = 0;
int bl;
int i;
NCR5380_local_declare();
NCR5380_setup(instance);
NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
NCR5380_write(hostdata->c400_blk_cnt, blocks);
while (1) {
if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
return -1;
}
if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
break;
}
while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
; // FIXME - timeout
#ifndef SCSI_G_NCR5380_MEM
{
for (i = 0; i < 128; i++)
NCR5380_write(C400_HOST_BUFFER, src[start + i]);
}
if (hostdata->io_width == 2)
outsw(instance->io_port + hostdata->c400_host_buf,
src + start, 64);
else
outsb(instance->io_port + hostdata->c400_host_buf,
src + start, 128);
#else
/* implies SCSI_G_NCR5380_MEM */
memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
src + start, 128);
#endif
start += 128;
blocks--;
}
if (blocks) {
while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
; // FIXME - no timeout
#ifndef SCSI_G_NCR5380_MEM
{
for (i = 0; i < 128; i++)
NCR5380_write(C400_HOST_BUFFER, src[start + i]);
}
if (hostdata->io_width == 2)
outsw(instance->io_port + hostdata->c400_host_buf,
src + start, 64);
else
outsb(instance->io_port + hostdata->c400_host_buf,
src + start, 128);
#else
/* implies SCSI_G_NCR5380_MEM */
memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
src + start, 128);
#endif
start += 128;
blocks--;
}
#if 0
printk("53C400w: waiting for registers to be available\n");
THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG);
printk("53C400w: Got em\n");
#endif
/* Let's wait for this instead - could be ugly */
/* All documentation says to check for this. Maybe my hardware is too
* fast. Waiting for it seems to work fine! KLL
*/
while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
; // FIXME - no timeout
/*
* I know. i is certainly != 0 here but the loop is new. See previous
* comment.
*/
if (i) {
if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
} else
printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n");
/* wait for 53C80 registers to be available */
while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
udelay(4); /* DTC436 chip hangs without this */
/* FIXME - no timeout */
}
#if 0
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
printk(KERN_ERR "53C400w: no end dma signal\n");
}
#endif
while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
; // TIMEOUT
return 0;
}
#endif /* PSEUDO_DMA */
static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
{
int transfersize = cmd->transfersize;
/* Limit transfers to 32K, for xx400 & xx406
* pseudoDMA that transfers in 128 bytes blocks.
*/
if (transfersize > 32 * 1024 && cmd->SCp.this_residual &&
!(cmd->SCp.this_residual % transfersize))
transfersize = 32 * 1024;
/* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
if (transfersize % 128)
transfersize = 0;
return transfersize;
}
#endif /* PSEUDO_DMA */
/*
* Include the NCR5380 core code that we build our driver around
......@@ -696,22 +765,24 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
#include "NCR5380.c"
static struct scsi_host_template driver_template = {
.show_info = generic_NCR5380_show_info,
.name = "Generic NCR5380/NCR53C400 SCSI",
.detect = generic_NCR5380_detect,
.release = generic_NCR5380_release_resources,
.info = generic_NCR5380_info,
.queuecommand = generic_NCR5380_queue_command,
.proc_name = DRV_MODULE_NAME,
.name = "Generic NCR5380/NCR53C400 SCSI",
.detect = generic_NCR5380_detect,
.release = generic_NCR5380_release_resources,
.info = generic_NCR5380_info,
.queuecommand = generic_NCR5380_queue_command,
.eh_abort_handler = generic_NCR5380_abort,
.eh_bus_reset_handler = generic_NCR5380_bus_reset,
.bios_param = NCR5380_BIOSPARAM,
.can_queue = CAN_QUEUE,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN,
.use_clustering = DISABLE_CLUSTERING,
.bios_param = NCR5380_BIOSPARAM,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128,
};
#include <linux/module.h>
#include "scsi_module.c"
module_param(ncr_irq, int, 0);
......@@ -721,6 +792,7 @@ module_param(ncr_5380, int, 0);
module_param(ncr_53c400, int, 0);
module_param(ncr_53c400a, int, 0);
module_param(dtc_3181e, int, 0);
module_param(hp_c2502, int, 0);
MODULE_LICENSE("GPL");
#if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
......
......@@ -14,81 +14,67 @@
#ifndef GENERIC_NCR5380_H
#define GENERIC_NCR5380_H
#ifdef NCR53C400
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define BIOSPARAM
#define NCR5380_BIOSPARAM generic_NCR5380_biosparam
#else
#define NCR5380_BIOSPARAM NULL
#endif
#ifndef ASM
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
#ifndef CAN_QUEUE
#define CAN_QUEUE 16
#endif
#define __STRVAL(x) #x
#define STRVAL(x) __STRVAL(x)
#ifndef SCSI_G_NCR5380_MEM
#define DRV_MODULE_NAME "g_NCR5380"
#define NCR5380_map_config port
#define NCR5380_map_type int
#define NCR5380_map_name port
#define NCR5380_instance_name io_port
#define NCR53C400_register_offset 0
#define NCR53C400_address_adjust 8
#ifdef NCR53C400
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define NCR5380_region_size 16
#else
#define NCR5380_region_size 8
#endif
#define NCR5380_read(reg) (inb(NCR5380_map_name + (reg)))
#define NCR5380_write(reg, value) (outb((value), (NCR5380_map_name + (reg))))
#define NCR5380_read(reg) \
inb(instance->io_port + (reg))
#define NCR5380_write(reg, value) \
outb(value, instance->io_port + (reg))
#define NCR5380_implementation_fields \
NCR5380_map_type NCR5380_map_name
#define NCR5380_local_declare() \
register NCR5380_implementation_fields
#define NCR5380_setup(instance) \
NCR5380_map_name = (NCR5380_map_type)((instance)->NCR5380_instance_name)
int c400_ctl_status; \
int c400_blk_cnt; \
int c400_host_buf; \
int io_width;
#else
/* therefore SCSI_G_NCR5380_MEM */
#define DRV_MODULE_NAME "g_NCR5380_mmio"
#define NCR5380_map_config memory
#define NCR5380_map_type unsigned long
#define NCR5380_map_name base
#define NCR5380_instance_name base
#define NCR53C400_register_offset 0x108
#define NCR53C400_address_adjust 0
#define NCR53C400_mem_base 0x3880
#define NCR53C400_host_buffer 0x3900
#define NCR5380_region_size 0x3a00
#define NCR5380_read(reg) readb(iomem + NCR53C400_mem_base + (reg))
#define NCR5380_write(reg, value) writeb(value, iomem + NCR53C400_mem_base + (reg))
#define NCR5380_read(reg) \
readb(((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
NCR53C400_mem_base + (reg))
#define NCR5380_write(reg, value) \
writeb(value, ((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
NCR53C400_mem_base + (reg))
#define NCR5380_implementation_fields \
NCR5380_map_type NCR5380_map_name; \
void __iomem *iomem;
#define NCR5380_local_declare() \
register void __iomem *iomem
#define NCR5380_setup(instance) \
iomem = (((struct NCR5380_hostdata *)(instance)->hostdata)->iomem)
void __iomem *iomem; \
int c400_ctl_status; \
int c400_blk_cnt; \
int c400_host_buf;
#endif
#define NCR5380_dma_xfer_len(instance, cmd, phase) \
generic_NCR5380_dma_xfer_len(cmd)
#define NCR5380_intr generic_NCR5380_intr
#define NCR5380_queue_command generic_NCR5380_queue_command
#define NCR5380_abort generic_NCR5380_abort
......@@ -102,7 +88,7 @@
#define BOARD_NCR53C400 1
#define BOARD_NCR53C400A 2
#define BOARD_DTC3181E 3
#define BOARD_HP_C2502 4
#endif /* ndef ASM */
#endif /* GENERIC_NCR5380_H */
......@@ -247,41 +247,36 @@
/* ITCT header */
/* qw0 */
#define ITCT_HDR_DEV_TYPE_OFF 0
#define ITCT_HDR_DEV_TYPE_MSK (0x3 << ITCT_HDR_DEV_TYPE_OFF)
#define ITCT_HDR_DEV_TYPE_MSK (0x3ULL << ITCT_HDR_DEV_TYPE_OFF)
#define ITCT_HDR_VALID_OFF 2
#define ITCT_HDR_VALID_MSK (0x1 << ITCT_HDR_VALID_OFF)
#define ITCT_HDR_BREAK_REPLY_ENA_OFF 3
#define ITCT_HDR_BREAK_REPLY_ENA_MSK (0x1 << ITCT_HDR_BREAK_REPLY_ENA_OFF)
#define ITCT_HDR_VALID_MSK (0x1ULL << ITCT_HDR_VALID_OFF)
#define ITCT_HDR_AWT_CONTROL_OFF 4
#define ITCT_HDR_AWT_CONTROL_MSK (0x1 << ITCT_HDR_AWT_CONTROL_OFF)
#define ITCT_HDR_AWT_CONTROL_MSK (0x1ULL << ITCT_HDR_AWT_CONTROL_OFF)
#define ITCT_HDR_MAX_CONN_RATE_OFF 5
#define ITCT_HDR_MAX_CONN_RATE_MSK (0xf << ITCT_HDR_MAX_CONN_RATE_OFF)
#define ITCT_HDR_MAX_CONN_RATE_MSK (0xfULL << ITCT_HDR_MAX_CONN_RATE_OFF)
#define ITCT_HDR_VALID_LINK_NUM_OFF 9
#define ITCT_HDR_VALID_LINK_NUM_MSK (0xf << ITCT_HDR_VALID_LINK_NUM_OFF)
#define ITCT_HDR_VALID_LINK_NUM_MSK (0xfULL << ITCT_HDR_VALID_LINK_NUM_OFF)
#define ITCT_HDR_PORT_ID_OFF 13
#define ITCT_HDR_PORT_ID_MSK (0x7 << ITCT_HDR_PORT_ID_OFF)
#define ITCT_HDR_PORT_ID_MSK (0x7ULL << ITCT_HDR_PORT_ID_OFF)
#define ITCT_HDR_SMP_TIMEOUT_OFF 16
#define ITCT_HDR_SMP_TIMEOUT_MSK (0xffff << ITCT_HDR_SMP_TIMEOUT_OFF)
#define ITCT_HDR_MAX_BURST_BYTES_OFF 16
#define ITCT_HDR_MAX_BURST_BYTES_MSK (0xffffffff << \
ITCT_MAX_BURST_BYTES_OFF)
#define ITCT_HDR_SMP_TIMEOUT_MSK (0xffffULL << ITCT_HDR_SMP_TIMEOUT_OFF)
/* qw1 */
#define ITCT_HDR_MAX_SAS_ADDR_OFF 0
#define ITCT_HDR_MAX_SAS_ADDR_MSK (0xffffffffffffffff << \
ITCT_HDR_MAX_SAS_ADDR_OFF)
/* qw2 */
#define ITCT_HDR_IT_NEXUS_LOSS_TL_OFF 0
#define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK (0xffff << \
#define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK (0xffffULL << \
ITCT_HDR_IT_NEXUS_LOSS_TL_OFF)
#define ITCT_HDR_BUS_INACTIVE_TL_OFF 16
#define ITCT_HDR_BUS_INACTIVE_TL_MSK (0xffff << \
#define ITCT_HDR_BUS_INACTIVE_TL_MSK (0xffffULL << \
ITCT_HDR_BUS_INACTIVE_TL_OFF)
#define ITCT_HDR_MAX_CONN_TL_OFF 32
#define ITCT_HDR_MAX_CONN_TL_MSK (0xffff << \
#define ITCT_HDR_MAX_CONN_TL_MSK (0xffffULL << \
ITCT_HDR_MAX_CONN_TL_OFF)
#define ITCT_HDR_REJ_OPEN_TL_OFF 48
#define ITCT_HDR_REJ_OPEN_TL_MSK (0xffff << \
ITCT_REJ_OPEN_TL_OFF)
#define ITCT_HDR_REJ_OPEN_TL_MSK (0xffffULL << \
ITCT_HDR_REJ_OPEN_TL_OFF)
/* Err record header */
#define ERR_HDR_DMA_TX_ERR_TYPE_OFF 0
......@@ -533,10 +528,10 @@ static void setup_itct_v1_hw(struct hisi_hba *hisi_hba,
itct->sas_addr = __swab64(itct->sas_addr);
/* qw2 */
itct->qw2 = cpu_to_le64((500 < ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
(0xff00 < ITCT_HDR_BUS_INACTIVE_TL_OFF) |
(0xff00 < ITCT_HDR_MAX_CONN_TL_OFF) |
(0xff00 < ITCT_HDR_REJ_OPEN_TL_OFF));
itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
(0xff00ULL << ITCT_HDR_BUS_INACTIVE_TL_OFF) |
(0xff00ULL << ITCT_HDR_MAX_CONN_TL_OFF) |
(0xff00ULL << ITCT_HDR_REJ_OPEN_TL_OFF));
}
static void free_device_v1_hw(struct hisi_hba *hisi_hba,
......@@ -544,7 +539,8 @@ static void free_device_v1_hw(struct hisi_hba *hisi_hba,
{
u64 dev_id = sas_dev->device_id;
struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id];
u32 qw0, reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME);
u64 qw0;
u32 reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME);
reg_val |= CFG_AGING_TIME_ITCT_REL_MSK;
hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val);
......
......@@ -43,6 +43,7 @@ typedef struct {
unsigned dp:1; /* Data phase present */
unsigned rd:1; /* Read data in data phase */
unsigned wanted:1; /* Parport sharing busy flag */
unsigned int dev_no; /* Device number */
wait_queue_head_t *waiting;
struct Scsi_Host *host;
struct list_head list;
......@@ -1120,15 +1121,40 @@ static struct scsi_host_template imm_template = {
static LIST_HEAD(imm_hosts);
/*
* Finds the first available device number that can be alloted to the
* new imm device and returns the address of the previous node so that
* we can add to the tail and have a list in the ascending order.
*/
static inline imm_struct *find_parent(void)
{
imm_struct *dev, *par = NULL;
unsigned int cnt = 0;
if (list_empty(&imm_hosts))
return NULL;
list_for_each_entry(dev, &imm_hosts, list) {
if (dev->dev_no != cnt)
return par;
cnt++;
par = dev;
}
return par;
}
static int __imm_attach(struct parport *pb)
{
struct Scsi_Host *host;
imm_struct *dev;
imm_struct *dev, *temp;
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
DEFINE_WAIT(wait);
int ports;
int modes, ppb;
int err = -ENOMEM;
struct pardev_cb imm_cb;
init_waitqueue_head(&waiting);
......@@ -1141,9 +1167,15 @@ static int __imm_attach(struct parport *pb)
dev->mode = IMM_AUTODETECT;
INIT_LIST_HEAD(&dev->list);
dev->dev = parport_register_device(pb, "imm", NULL, imm_wakeup,
NULL, 0, dev);
temp = find_parent();
if (temp)
dev->dev_no = temp->dev_no + 1;
memset(&imm_cb, 0, sizeof(imm_cb));
imm_cb.private = dev;
imm_cb.wakeup = imm_wakeup;
dev->dev = parport_register_dev_model(pb, "imm", &imm_cb, dev->dev_no);
if (!dev->dev)
goto out;
......@@ -1207,7 +1239,10 @@ static int __imm_attach(struct parport *pb)
host->unique_id = pb->number;
*(imm_struct **)&host->hostdata = dev;
dev->host = host;
list_add_tail(&dev->list, &imm_hosts);
if (!temp)
list_add_tail(&dev->list, &imm_hosts);
else
list_add_tail(&dev->list, &temp->list);
err = scsi_add_host(host, NULL);
if (err)
goto out2;
......@@ -1245,9 +1280,10 @@ static void imm_detach(struct parport *pb)
}
static struct parport_driver imm_driver = {
.name = "imm",
.attach = imm_attach,
.detach = imm_detach,
.name = "imm",
.match_port = imm_attach,
.detach = imm_detach,
.devmodel = true,
};
static int __init imm_driver_init(void)
......
......@@ -4003,13 +4003,12 @@ static ssize_t ipr_store_update_fw(struct device *dev,
struct ipr_sglist *sglist;
char fname[100];
char *src;
int len, result, dnld_size;
int result, dnld_size;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
len = snprintf(fname, 99, "%s", buf);
fname[len-1] = '\0';
snprintf(fname, sizeof(fname), "%s", buf);
if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) {
dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname);
......
......@@ -12,7 +12,6 @@
*/
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/init.h>
......@@ -32,14 +31,13 @@
#define PSEUDO_DMA
#define NCR5380_implementation_fields unsigned char *pdma_base
#define NCR5380_local_declare() struct Scsi_Host *_instance
#define NCR5380_setup(instance) _instance = instance
#define NCR5380_read(reg) macscsi_read(_instance, reg)
#define NCR5380_write(reg, value) macscsi_write(_instance, reg, value)
#define NCR5380_read(reg) macscsi_read(instance, reg)
#define NCR5380_write(reg, value) macscsi_write(instance, reg, value)
#define NCR5380_pread macscsi_pread
#define NCR5380_pwrite macscsi_pwrite
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize)
#define NCR5380_intr macscsi_intr
#define NCR5380_queue_command macscsi_queue_command
......@@ -51,8 +49,6 @@
#include "NCR5380.h"
#define RESET_BOOT
static int setup_can_queue = -1;
module_param(setup_can_queue, int, 0);
static int setup_cmd_per_lun = -1;
......@@ -65,17 +61,8 @@ static int setup_use_tagged_queuing = -1;
module_param(setup_use_tagged_queuing, int, 0);
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
* we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
* need ten times the standard value... */
#define TOSHIBA_DELAY
#ifdef TOSHIBA_DELAY
#define AFTER_RESET_DELAY (5*HZ/2)
#else
#define AFTER_RESET_DELAY (HZ/2)
#endif
static int setup_toshiba_delay = -1;
module_param(setup_toshiba_delay, int, 0);
/*
* NCR 5380 register access functions
......@@ -94,12 +81,12 @@ static inline void macscsi_write(struct Scsi_Host *instance, int reg, int value)
#ifndef MODULE
static int __init mac_scsi_setup(char *str)
{
int ints[7];
int ints[8];
(void)get_options(str, ARRAY_SIZE(ints), ints);
if (ints[0] < 1 || ints[0] > 6) {
pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>]]]]]\n");
if (ints[0] < 1) {
pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>[,<toshiba_delay>]]]]]]\n");
return 0;
}
if (ints[0] >= 1)
......@@ -114,50 +101,14 @@ static int __init mac_scsi_setup(char *str)
setup_use_tagged_queuing = ints[5];
if (ints[0] >= 6)
setup_use_pdma = ints[6];
if (ints[0] >= 7)
setup_toshiba_delay = ints[7];
return 1;
}
__setup("mac5380=", mac_scsi_setup);
#endif /* !MODULE */
#ifdef RESET_BOOT
/*
* Our 'bus reset on boot' function
*/
static void mac_scsi_reset_boot(struct Scsi_Host *instance)
{
unsigned long end;
NCR5380_local_declare();
NCR5380_setup(instance);
/*
* Do a SCSI reset to clean up the bus during initialization. No messing
* with the queues, interrupts, or locks necessary here.
*/
printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
/* get in phase */
NCR5380_write( TARGET_COMMAND_REG,
PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
/* assert RST */
NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
/* The min. reset hold time is 25us, so 40us should be enough */
udelay( 50 );
/* reset RST and interrupt */
NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
NCR5380_read( RESET_PARITY_INTERRUPT_REG );
for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
barrier();
printk(KERN_INFO " done\n" );
}
#endif
#ifdef PSEUDO_DMA
/*
Pseudo-DMA: (Ove Edlund)
......@@ -235,9 +186,6 @@ static int macscsi_pread(struct Scsi_Host *instance,
unsigned char *d;
unsigned char *s;
NCR5380_local_declare();
NCR5380_setup(instance);
s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
d = dst;
......@@ -329,9 +277,6 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
unsigned char *s;
unsigned char *d;
NCR5380_local_declare();
NCR5380_setup(instance);
s = src;
d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
......@@ -364,20 +309,22 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
#define PFX DRV_MODULE_NAME ": "
static struct scsi_host_template mac_scsi_template = {
.module = THIS_MODULE,
.proc_name = DRV_MODULE_NAME,
.show_info = macscsi_show_info,
.write_info = macscsi_write_info,
.name = "Macintosh NCR5380 SCSI",
.info = macscsi_info,
.queuecommand = macscsi_queue_command,
.eh_abort_handler = macscsi_abort,
.eh_bus_reset_handler = macscsi_bus_reset,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING
.module = THIS_MODULE,
.proc_name = DRV_MODULE_NAME,
.show_info = macscsi_show_info,
.write_info = macscsi_write_info,
.name = "Macintosh NCR5380 SCSI",
.info = macscsi_info,
.queuecommand = macscsi_queue_command,
.eh_abort_handler = macscsi_abort,
.eh_bus_reset_handler = macscsi_bus_reset,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128,
};
static int __init mac_scsi_probe(struct platform_device *pdev)
......@@ -432,15 +379,14 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
} else
host_flags |= FLAG_NO_PSEUDO_DMA;
#ifdef RESET_BOOT
mac_scsi_reset_boot(instance);
#endif
#ifdef SUPPORT_TAGS
host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
#endif
host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
NCR5380_init(instance, host_flags);
error = NCR5380_init(instance, host_flags);
if (error)
goto fail_init;
if (instance->irq != NO_IRQ) {
error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED,
......@@ -449,6 +395,8 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
goto fail_irq;
}
NCR5380_maybe_reset_bus(instance);
error = scsi_add_host(instance, NULL);
if (error)
goto fail_host;
......@@ -463,6 +411,7 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
free_irq(instance->irq, instance);
fail_irq:
NCR5380_exit(instance);
fail_init:
scsi_host_put(instance);
return error;
}
......
......@@ -179,8 +179,12 @@ mraid_mm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
/*
* The following call will block till a kioc is available
* or return NULL if the list head is empty for the pointer
* of type mraid_mmapt passed to mraid_mm_alloc_kioc
*/
kioc = mraid_mm_alloc_kioc(adp);
if (!kioc)
return -ENXIO;
/*
* User sent the old mimd_t ioctl packet. Convert it to uioc_t.
......
#define PSEUDO_DMA
#define UNSAFE /* Not unsafe for PAS16 -- use it */
#define PDEBUG 0
/*
* This driver adapted from Drew Eckhardt's Trantor T128 driver
......@@ -71,14 +69,10 @@
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/proc_fs.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <scsi/scsi_host.h>
......@@ -87,8 +81,8 @@
#include "NCR5380.h"
static unsigned short pas16_addr = 0;
static int pas16_irq = 0;
static unsigned short pas16_addr;
static int pas16_irq;
static const int scsi_irq_translate[] =
......@@ -146,22 +140,6 @@ static const unsigned short pas16_offset[ 8 ] =
* START_DMA_INITIATOR_RECEIVE_REG wo
*/
};
/*----------------------------------------------------------------*/
/* the following will set the monitor border color (useful to find
where something crashed or gets stuck at */
/* 1 = blue
2 = green
3 = cyan
4 = red
5 = magenta
6 = yellow
7 = white
*/
#if 1
#define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);}
#else
#define rtrc(i) {}
#endif
/*
......@@ -205,7 +183,7 @@ static void __init
outb( 0x01, io_port + P_TIMEOUT_STATUS_REG_OFFSET ); /* Reset TC */
outb( 0x01, io_port + WAIT_STATE ); /* 1 Wait state */
NCR5380_read( RESET_PARITY_INTERRUPT_REG );
inb(io_port + pas16_offset[RESET_PARITY_INTERRUPT_REG]);
/* Set the SCSI interrupt pointer without mucking up the sound
* interrupt pointer in the same byte.
......@@ -280,13 +258,13 @@ static int __init
* put in an additional test to try to weed them out.
*/
outb( 0x01, io_port + WAIT_STATE ); /* 1 Wait state */
NCR5380_write( MODE_REG, 0x20 ); /* Is it really SCSI? */
if( NCR5380_read( MODE_REG ) != 0x20 ) /* Write to a reg. */
return 0; /* and try to read */
NCR5380_write( MODE_REG, 0x00 ); /* it back. */
if( NCR5380_read( MODE_REG ) != 0x00 )
return 0;
outb(0x01, io_port + WAIT_STATE); /* 1 Wait state */
outb(0x20, io_port + pas16_offset[MODE_REG]); /* Is it really SCSI? */
if (inb(io_port + pas16_offset[MODE_REG]) != 0x20) /* Write to a reg. */
return 0; /* and try to read */
outb(0x00, io_port + pas16_offset[MODE_REG]); /* it back. */
if (inb(io_port + pas16_offset[MODE_REG]) != 0x00)
return 0;
return 1;
}
......@@ -305,7 +283,7 @@ static int __init
static int __init pas16_setup(char *str)
{
static int commandline_current = 0;
static int commandline_current;
int i;
int ints[10];
......@@ -344,8 +322,8 @@ __setup("pas16=", pas16_setup);
static int __init pas16_detect(struct scsi_host_template *tpnt)
{
static int current_override = 0;
static unsigned short current_base = 0;
static int current_override;
static unsigned short current_base;
struct Scsi_Host *instance;
unsigned short io_port;
int count;
......@@ -377,34 +355,32 @@ static int __init pas16_detect(struct scsi_host_template *tpnt)
}
else
for (; !io_port && (current_base < NO_BASES); ++current_base) {
#if (PDEBUG & PDEBUG_INIT)
printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port);
#endif
dprintk(NDEBUG_INIT, "pas16: probing io_port 0x%04x\n",
(unsigned int)bases[current_base].io_port);
if ( !bases[current_base].noauto &&
pas16_hw_detect( current_base ) ){
io_port = bases[current_base].io_port;
init_board( io_port, default_irqs[ current_base ], 0 );
#if (PDEBUG & PDEBUG_INIT)
printk("scsi-pas16 : detected board.\n");
#endif
dprintk(NDEBUG_INIT, "pas16: detected board\n");
}
}
#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port);
#endif
dprintk(NDEBUG_INIT, "pas16: io_port = 0x%04x\n",
(unsigned int)io_port);
if (!io_port)
break;
instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
if(instance == NULL)
break;
goto out;
instance->io_port = io_port;
NCR5380_init(instance, 0);
if (NCR5380_init(instance, 0))
goto out_unregister;
NCR5380_maybe_reset_bus(instance);
if (overrides[current_override].irq != IRQ_AUTO)
instance->irq = overrides[current_override].irq;
......@@ -431,14 +407,18 @@ static int __init pas16_detect(struct scsi_host_template *tpnt)
outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 );
}
#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
#endif
dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
instance->host_no, instance->irq);
++current_override;
++count;
}
return count;
out_unregister:
scsi_unregister(instance);
out:
return count;
}
/*
......@@ -561,29 +541,29 @@ static int pas16_release(struct Scsi_Host *shost)
if (shost->irq != NO_IRQ)
free_irq(shost->irq, shost);
NCR5380_exit(shost);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static struct scsi_host_template driver_template = {
.name = "Pro Audio Spectrum-16 SCSI",
.detect = pas16_detect,
.release = pas16_release,
.proc_name = "pas16",
.show_info = pas16_show_info,
.write_info = pas16_write_info,
.info = pas16_info,
.queuecommand = pas16_queue_command,
.eh_abort_handler = pas16_abort,
.eh_bus_reset_handler = pas16_bus_reset,
.bios_param = pas16_biosparam,
.can_queue = CAN_QUEUE,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN,
.use_clustering = DISABLE_CLUSTERING,
.name = "Pro Audio Spectrum-16 SCSI",
.detect = pas16_detect,
.release = pas16_release,
.proc_name = "pas16",
.show_info = pas16_show_info,
.write_info = pas16_write_info,
.info = pas16_info,
.queuecommand = pas16_queue_command,
.eh_abort_handler = pas16_abort,
.eh_bus_reset_handler = pas16_bus_reset,
.bios_param = pas16_biosparam,
.can_queue = 32,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128,
};
#include "scsi_module.c"
......
......@@ -24,9 +24,6 @@
#ifndef PAS16_H
#define PAS16_H
#define PDEBUG_INIT 0x1
#define PDEBUG_TRANSFER 0x2
#define PAS16_DEFAULT_BASE_1 0x388
#define PAS16_DEFAULT_BASE_2 0x384
#define PAS16_DEFAULT_BASE_3 0x38c
......@@ -98,46 +95,16 @@
#define OPERATION_MODE_1 0xec03
#define IO_CONFIG_3 0xf002
#define NCR5380_implementation_fields /* none */
#ifndef ASM
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
#ifndef CAN_QUEUE
#define CAN_QUEUE 32
#endif
#define NCR5380_implementation_fields \
volatile unsigned short io_port
#define NCR5380_local_declare() \
volatile unsigned short io_port
#define PAS16_io_port(reg) (instance->io_port + pas16_offset[(reg)])
#define NCR5380_setup(instance) \
io_port = (instance)->io_port
#define PAS16_io_port(reg) ( io_port + pas16_offset[(reg)] )
#if !(PDEBUG & PDEBUG_TRANSFER)
#define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
#define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
#else
#define NCR5380_read(reg) \
(((unsigned char) printk("scsi%d : read register %d at io_port %04x\n"\
, instance->hostno, (reg), PAS16_io_port(reg))), inb( PAS16_io_port(reg)) )
#define NCR5380_write(reg, value) \
(printk("scsi%d : write %02x to register %d at io_port %04x\n", \
instance->hostno, (value), (reg), PAS16_io_port(reg)), \
outb( (value),PAS16_io_port(reg) ) )
#endif
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize)
#define NCR5380_intr pas16_intr
#define do_NCR5380_intr do_pas16_intr
#define NCR5380_queue_command pas16_queue_command
#define NCR5380_abort pas16_abort
#define NCR5380_bus_reset pas16_bus_reset
......@@ -150,5 +117,4 @@
#define PAS16_IRQS 0xd4a8
#endif /* ndef ASM */
#endif /* PAS16_H */
......@@ -227,6 +227,7 @@ static struct {
{"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
{"Promise", "", NULL, BLIST_SPARSELUN},
{"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024},
{"SYNOLOGY", "iSCSI Storage", NULL, BLIST_MAX_1024},
{"QUANTUM", "XP34301", "1071", BLIST_NOTQ},
{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
......
......@@ -390,7 +390,7 @@ module_param(storvsc_ringbuffer_size, int, S_IRUGO);
MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
MODULE_PARM_DESC(vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
/*
* Timeout in seconds for all devices managed by this driver.
*/
......
......@@ -53,13 +53,12 @@
#define NCR5380_queue_command sun3scsi_queue_command
#define NCR5380_bus_reset sun3scsi_bus_reset
#define NCR5380_abort sun3scsi_abort
#define NCR5380_show_info sun3scsi_show_info
#define NCR5380_info sun3scsi_info
#define NCR5380_dma_read_setup(instance, data, count) \
sun3scsi_dma_setup(data, count, 0)
sun3scsi_dma_setup(instance, data, count, 0)
#define NCR5380_dma_write_setup(instance, data, count) \
sun3scsi_dma_setup(data, count, 1)
sun3scsi_dma_setup(instance, data, count, 1)
#define NCR5380_dma_residual(instance) \
sun3scsi_dma_residual(instance)
#define NCR5380_dma_xfer_len(instance, cmd, phase) \
......@@ -86,10 +85,6 @@ module_param(setup_use_tagged_queuing, int, 0);
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
/* #define RESET_BOOT */
#define AFTER_RESET_DELAY (HZ/2)
/* ms to wait after hitting dma regs */
#define SUN3_DMA_DELAY 10
......@@ -100,11 +95,10 @@ static struct scsi_cmnd *sun3_dma_setup_done;
static unsigned char *sun3_scsi_regp;
static volatile struct sun3_dma_regs *dregs;
static struct sun3_udc_regs *udc_regs;
static unsigned char *sun3_dma_orig_addr = NULL;
static unsigned long sun3_dma_orig_count = 0;
static int sun3_dma_active = 0;
static unsigned long last_residual = 0;
static struct Scsi_Host *default_instance;
static unsigned char *sun3_dma_orig_addr;
static unsigned long sun3_dma_orig_count;
static int sun3_dma_active;
static unsigned long last_residual;
/*
* NCR 5380 register access functions
......@@ -144,50 +138,12 @@ static inline void sun3_udc_write(unsigned short val, unsigned char reg)
}
#endif
#ifdef RESET_BOOT
static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
{
unsigned long end;
/*
* Do a SCSI reset to clean up the bus during initialization. No
* messing with the queues, interrupts, or locks necessary here.
*/
printk( "Sun3 SCSI: resetting the SCSI bus..." );
/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
// sun3_disable_irq( IRQ_SUN3_SCSI );
/* get in phase */
NCR5380_write( TARGET_COMMAND_REG,
PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
/* assert RST */
NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
/* The min. reset hold time is 25us, so 40us should be enough */
udelay( 50 );
/* reset RST and interrupt */
NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
NCR5380_read( RESET_PARITY_INTERRUPT_REG );
for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
barrier();
/* switch on SCSI IRQ again */
// sun3_enable_irq( IRQ_SUN3_SCSI );
printk( " done\n" );
}
#endif
// safe bits for the CSR
#define CSR_GOOD 0x060f
static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
static irqreturn_t scsi_sun3_intr(int irq, void *dev)
{
struct Scsi_Host *instance = dev;
unsigned short csr = dregs->csr;
int handled = 0;
......@@ -196,46 +152,24 @@ static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
#endif
if(csr & ~CSR_GOOD) {
if(csr & CSR_DMA_BUSERR) {
printk("scsi%d: bus error in dma\n", default_instance->host_no);
}
if(csr & CSR_DMA_CONFLICT) {
printk("scsi%d: dma conflict\n", default_instance->host_no);
}
if (csr & CSR_DMA_BUSERR)
shost_printk(KERN_ERR, instance, "bus error in DMA\n");
if (csr & CSR_DMA_CONFLICT)
shost_printk(KERN_ERR, instance, "DMA conflict\n");
handled = 1;
}
if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
NCR5380_intr(irq, dummy);
NCR5380_intr(irq, dev);
handled = 1;
}
return IRQ_RETVAL(handled);
}
/*
* Debug stuff - to be called on NMI, or sysrq key. Use at your own risk;
* reentering NCR5380_print_status seems to have ugly side effects
*/
/* this doesn't seem to get used at all -- sam */
#if 0
void sun3_sun3_debug (void)
{
unsigned long flags;
if (default_instance) {
local_irq_save(flags);
NCR5380_print_status(default_instance);
local_irq_restore(flags);
}
}
#endif
/* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */
static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag)
static unsigned long sun3scsi_dma_setup(struct Scsi_Host *instance,
void *data, unsigned long count, int write_flag)
{
void *addr;
......@@ -287,10 +221,9 @@ static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int wri
dregs->csr |= CSR_FIFO;
if(dregs->fifo_count != count) {
printk("scsi%d: fifo_mismatch %04x not %04x\n",
default_instance->host_no, dregs->fifo_count,
(unsigned int) count);
NCR5380_dprint(NDEBUG_DMA, default_instance);
shost_printk(KERN_ERR, instance, "FIFO mismatch %04x not %04x\n",
dregs->fifo_count, (unsigned int) count);
NCR5380_dprint(NDEBUG_DMA, instance);
}
/* setup udc */
......@@ -325,21 +258,6 @@ static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int wri
}
#ifndef SUN3_SCSI_VME
static inline unsigned long sun3scsi_dma_count(struct Scsi_Host *instance)
{
unsigned short resid;
dregs->udc_addr = 0x32;
udelay(SUN3_DMA_DELAY);
resid = dregs->udc_data;
udelay(SUN3_DMA_DELAY);
resid *= 2;
return (unsigned long) resid;
}
#endif
static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
{
return last_residual;
......@@ -437,7 +355,10 @@ static int sun3scsi_dma_finish(int write_flag)
}
}
count = sun3scsi_dma_count(default_instance);
dregs->udc_addr = 0x32;
udelay(SUN3_DMA_DELAY);
count = 2 * dregs->udc_data;
udelay(SUN3_DMA_DELAY);
fifo = dregs->fifo_count;
last_residual = fifo;
......@@ -502,17 +423,17 @@ static int sun3scsi_dma_finish(int write_flag)
static struct scsi_host_template sun3_scsi_template = {
.module = THIS_MODULE,
.proc_name = DRV_MODULE_NAME,
.show_info = sun3scsi_show_info,
.name = SUN3_SCSI_NAME,
.info = sun3scsi_info,
.queuecommand = sun3scsi_queue_command,
.eh_abort_handler = sun3scsi_abort,
.eh_bus_reset_handler = sun3scsi_bus_reset,
.eh_abort_handler = sun3scsi_abort,
.eh_bus_reset_handler = sun3scsi_bus_reset,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_NONE,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
};
static int __init sun3_scsi_probe(struct platform_device *pdev)
......@@ -591,7 +512,6 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
error = -ENOMEM;
goto fail_alloc;
}
default_instance = instance;
instance->io_port = (unsigned long)ioaddr;
instance->irq = irq->start;
......@@ -600,7 +520,9 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
#endif
NCR5380_init(instance, host_flags);
error = NCR5380_init(instance, host_flags);
if (error)
goto fail_init;
error = request_irq(instance->irq, scsi_sun3_intr, 0,
"NCR5380", instance);
......@@ -631,9 +553,7 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
#endif
#ifdef RESET_BOOT
sun3_scsi_reset_boot(instance);
#endif
NCR5380_maybe_reset_bus(instance);
error = scsi_add_host(instance, NULL);
if (error)
......@@ -649,6 +569,7 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
free_irq(instance->irq, instance);
fail_irq:
NCR5380_exit(instance);
fail_init:
scsi_host_put(instance);
fail_alloc:
if (udc_regs)
......
......@@ -68,14 +68,11 @@
* 15 9-11
*/
#include <linux/signal.h>
#include <linux/io.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include "t128.h"
......@@ -126,7 +123,7 @@ static struct signature {
static int __init t128_setup(char *str)
{
static int commandline_current = 0;
static int commandline_current;
int i;
int ints[10];
......@@ -165,7 +162,7 @@ __setup("t128=", t128_setup);
static int __init t128_detect(struct scsi_host_template *tpnt)
{
static int current_override = 0, current_base = 0;
static int current_override, current_base;
struct Scsi_Host *instance;
unsigned long base;
void __iomem *p;
......@@ -182,9 +179,8 @@ static int __init t128_detect(struct scsi_host_template *tpnt)
base = 0;
} else
for (; !base && (current_base < NO_BASES); ++current_base) {
#if (TDEBUG & TDEBUG_INIT)
printk("scsi-t128 : probing address %08x\n", bases[current_base].address);
#endif
dprintk(NDEBUG_INIT, "t128: probing address 0x%08x\n",
bases[current_base].address);
if (bases[current_base].noauto)
continue;
p = ioremap(bases[current_base].address, 0x2000);
......@@ -195,17 +191,13 @@ static int __init t128_detect(struct scsi_host_template *tpnt)
signatures[sig].string,
strlen(signatures[sig].string))) {
base = bases[current_base].address;
#if (TDEBUG & TDEBUG_INIT)
printk("scsi-t128 : detected board.\n");
#endif
dprintk(NDEBUG_INIT, "t128: detected board\n");
goto found;
}
iounmap(p);
}
#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
printk("scsi-t128 : base = %08x\n", (unsigned int) base);
#endif
dprintk(NDEBUG_INIT, "t128: base = 0x%08x\n", (unsigned int)base);
if (!base)
break;
......@@ -213,12 +205,15 @@ static int __init t128_detect(struct scsi_host_template *tpnt)
found:
instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
if(instance == NULL)
break;
goto out_unmap;
instance->base = base;
((struct NCR5380_hostdata *)instance->hostdata)->base = p;
NCR5380_init(instance, 0);
if (NCR5380_init(instance, 0))
goto out_unregister;
NCR5380_maybe_reset_bus(instance);
if (overrides[current_override].irq != IRQ_AUTO)
instance->irq = overrides[current_override].irq;
......@@ -242,27 +237,30 @@ static int __init t128_detect(struct scsi_host_template *tpnt)
printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
}
#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
#endif
dprintk(NDEBUG_INIT, "scsi%d: irq = %d\n",
instance->host_no, instance->irq);
++current_override;
++count;
}
return count;
out_unregister:
scsi_unregister(instance);
out_unmap:
iounmap(p);
return count;
}
static int t128_release(struct Scsi_Host *shost)
{
NCR5380_local_declare();
NCR5380_setup(shost);
struct NCR5380_hostdata *hostdata = shost_priv(shost);
if (shost->irq != NO_IRQ)
free_irq(shost->irq, shost);
NCR5380_exit(shost);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
iounmap(base);
iounmap(hostdata->base);
return 0;
}
......@@ -308,14 +306,14 @@ static int t128_biosparam(struct scsi_device *sdev, struct block_device *bdev,
* timeout.
*/
static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
int len) {
NCR5380_local_declare();
void __iomem *reg;
static inline int
NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
void __iomem *reg, *base = hostdata->base;
unsigned char *d = dst;
register int i = len;
NCR5380_setup(instance);
reg = base + T_DATA_REG_OFFSET;
#if 0
......@@ -354,14 +352,14 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
* timeout.
*/
static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
int len) {
NCR5380_local_declare();
void __iomem *reg;
static inline int
NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
void __iomem *reg, *base = hostdata->base;
unsigned char *s = src;
register int i = len;
NCR5380_setup(instance);
reg = base + T_DATA_REG_OFFSET;
#if 0
......@@ -392,21 +390,23 @@ MODULE_LICENSE("GPL");
#include "NCR5380.c"
static struct scsi_host_template driver_template = {
.name = "Trantor T128/T128F/T228",
.detect = t128_detect,
.release = t128_release,
.proc_name = "t128",
.show_info = t128_show_info,
.write_info = t128_write_info,
.info = t128_info,
.queuecommand = t128_queue_command,
.eh_abort_handler = t128_abort,
.eh_bus_reset_handler = t128_bus_reset,
.bios_param = t128_biosparam,
.can_queue = CAN_QUEUE,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN,
.use_clustering = DISABLE_CLUSTERING,
.name = "Trantor T128/T128F/T228",
.detect = t128_detect,
.release = t128_release,
.proc_name = "t128",
.show_info = t128_show_info,
.write_info = t128_write_info,
.info = t128_info,
.queuecommand = t128_queue_command,
.eh_abort_handler = t128_abort,
.eh_bus_reset_handler = t128_bus_reset,
.bios_param = t128_biosparam,
.can_queue = 32,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128,
};
#include "scsi_module.c"
......@@ -23,10 +23,6 @@
#ifndef T128_H
#define T128_H
#define TDEBUG 0
#define TDEBUG_INIT 0x1
#define TDEBUG_TRANSFER 0x2
/*
* The trantor boards are memory mapped. They use an NCR5380 or
* equivalent (my sample board had part second sourced from ZILOG).
......@@ -71,44 +67,18 @@
#define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */
#ifndef ASM
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
#ifndef CAN_QUEUE
#define CAN_QUEUE 32
#endif
#define NCR5380_implementation_fields \
void __iomem *base
#define NCR5380_local_declare() \
void __iomem *base
#define NCR5380_setup(instance) \
base = ((struct NCR5380_hostdata *)(instance->hostdata))->base
#define T128_address(reg) \
(((struct NCR5380_hostdata *)shost_priv(instance))->base + T_5380_OFFSET + ((reg) * 0x20))
#define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20))
#if !(TDEBUG & TDEBUG_TRANSFER)
#define NCR5380_read(reg) readb(T128_address(reg))
#define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
#else
#define NCR5380_read(reg) \
(((unsigned char) printk("scsi%d : read register %d at address %08x\n"\
, instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg)))
#define NCR5380_write(reg, value) { \
printk("scsi%d : write %02x to register %d at address %08x\n", \
instance->hostno, (value), (reg), T128_address(reg)); \
writeb((value), (T128_address(reg))); \
}
#endif
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize)
#define NCR5380_intr t128_intr
#define do_NCR5380_intr do_t128_intr
#define NCR5380_queue_command t128_queue_command
#define NCR5380_abort t128_abort
#define NCR5380_bus_reset t128_bus_reset
......@@ -121,5 +91,4 @@
#define T128_IRQS 0xc4a8
#endif /* ndef ASM */
#endif /* T128_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment