Merge remote-tracking branch 'scsi-queue/drivers-for-3.19' into for-linus

Conflicts:
	drivers/scsi/scsi_debug.c

Agreed and tested resolution to a merge problem between a fix in scsi_debug
and a driver update

Signed-off-by: James Bottomley <[email protected]>
This commit is contained in:
James Bottomley 2014-12-08 07:42:02 -08:00
commit 096cbc35ea
154 changed files with 7010 additions and 11822 deletions

View file

@ -189,19 +189,6 @@ static ssize_t twa_show_stats(struct device *dev,
return len;
} /* End twa_show_stats() */
/* This function will set a devices queue depth */
static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth,
int reason)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth > TW_Q_LENGTH-2)
queue_depth = TW_Q_LENGTH-2;
scsi_adjust_queue_depth(sdev, queue_depth);
return queue_depth;
} /* End twa_change_queue_depth() */
/* Create sysfs 'stats' entry */
static struct device_attribute twa_host_stats_attr = {
.attr = {
@ -2016,7 +2003,7 @@ static struct scsi_host_template driver_template = {
.queuecommand = twa_scsi_queue,
.eh_host_reset_handler = twa_scsi_eh_reset,
.bios_param = twa_scsi_biosparam,
.change_queue_depth = twa_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.can_queue = TW_Q_LENGTH-2,
.slave_configure = twa_slave_configure,
.this_id = -1,

View file

@ -191,19 +191,6 @@ static ssize_t twl_show_stats(struct device *dev,
return len;
} /* End twl_show_stats() */
/* This function will set a devices queue depth */
static int twl_change_queue_depth(struct scsi_device *sdev, int queue_depth,
int reason)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth > TW_Q_LENGTH-2)
queue_depth = TW_Q_LENGTH-2;
scsi_adjust_queue_depth(sdev, queue_depth);
return queue_depth;
} /* End twl_change_queue_depth() */
/* stats sysfs attribute initializer */
static struct device_attribute twl_host_stats_attr = {
.attr = {
@ -1590,7 +1577,7 @@ static struct scsi_host_template driver_template = {
.queuecommand = twl_scsi_queue,
.eh_host_reset_handler = twl_scsi_eh_reset,
.bios_param = twl_scsi_biosparam,
.change_queue_depth = twl_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.can_queue = TW_Q_LENGTH-2,
.slave_configure = twl_slave_configure,
.this_id = -1,

View file

@ -523,19 +523,6 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
return len;
} /* End tw_show_stats() */
/* This function will set a devices queue depth */
static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth,
int reason)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth > TW_Q_LENGTH-2)
queue_depth = TW_Q_LENGTH-2;
scsi_adjust_queue_depth(sdev, queue_depth);
return queue_depth;
} /* End tw_change_queue_depth() */
/* Create sysfs 'stats' entry */
static struct device_attribute tw_host_stats_attr = {
.attr = {
@ -2270,7 +2257,7 @@ static struct scsi_host_template driver_template = {
.queuecommand = tw_scsi_queue,
.eh_host_reset_handler = tw_scsi_eh_reset,
.bios_param = tw_scsi_biosparam,
.change_queue_depth = tw_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.can_queue = TW_Q_LENGTH-2,
.slave_configure = tw_slave_configure,
.this_id = -1,

View file

@ -175,7 +175,7 @@ STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt);
STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth, int reason);
static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth);
static int NCR_700_change_queue_type(struct scsi_device *SDpnt, int depth);
STATIC struct device_attribute *NCR_700_dev_attrs[];
@ -904,7 +904,7 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata
hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
SCp->device->tagged_supported = 0;
scsi_adjust_queue_depth(SCp->device, host->cmd_per_lun);
scsi_change_queue_depth(SCp->device, host->cmd_per_lun);
scsi_set_tag_type(SCp->device, 0);
} else {
shost_printk(KERN_WARNING, host,
@ -2052,7 +2052,7 @@ NCR_700_slave_configure(struct scsi_device *SDp)
/* to do here: allocate memory; build a queue_full list */
if(SDp->tagged_supported) {
scsi_adjust_queue_depth(SDp, NCR_700_DEFAULT_TAGS);
scsi_change_queue_depth(SDp, NCR_700_DEFAULT_TAGS);
NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION);
}
@ -2075,16 +2075,11 @@ NCR_700_slave_destroy(struct scsi_device *SDp)
}
static int
NCR_700_change_queue_depth(struct scsi_device *SDp, int depth, int reason)
NCR_700_change_queue_depth(struct scsi_device *SDp, int depth)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (depth > NCR_700_MAX_TAGS)
depth = NCR_700_MAX_TAGS;
scsi_adjust_queue_depth(SDp, depth);
return depth;
return scsi_change_queue_depth(SDp, depth);
}
static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type)
@ -2105,12 +2100,12 @@ static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type)
if (!tag_type) {
/* shift back to the default unqueued number of commands
* (the user can still raise this) */
scsi_adjust_queue_depth(SDp, SDp->host->cmd_per_lun);
scsi_change_queue_depth(SDp, SDp->host->cmd_per_lun);
hostdata->tag_negotiated &= ~(1 << sdev_id(SDp));
} else {
/* Here, we cleared the negotiation flag above, so this
* will force the driver to renegotiate */
scsi_adjust_queue_depth(SDp, SDp->queue_depth);
scsi_change_queue_depth(SDp, SDp->queue_depth);
if (change_tag)
NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION);
}

View file

@ -2327,12 +2327,12 @@ static int blogic_slaveconfig(struct scsi_device *dev)
if (qdepth == 0)
qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH;
adapter->qdepth[tgt_id] = qdepth;
scsi_adjust_queue_depth(dev, qdepth);
scsi_change_queue_depth(dev, qdepth);
} else {
adapter->tagq_ok &= ~(1 << tgt_id);
qdepth = adapter->untag_qdepth;
adapter->qdepth[tgt_id] = qdepth;
scsi_adjust_queue_depth(dev, qdepth);
scsi_change_queue_depth(dev, qdepth);
}
qdepth = 0;
for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)

View file

@ -1341,13 +1341,15 @@ config SCSI_DC395x
To compile this driver as a module, choose M here: the
module will be called dc395x.
config SCSI_DC390T
tristate "Tekram DC390(T) and Am53/79C974 SCSI support"
config SCSI_AM53C974
tristate "Tekram DC390(T) and Am53/79C974 SCSI support (new driver)"
depends on PCI && SCSI
select SCSI_SPI_ATTRS
---help---
This driver supports PCI SCSI host adapters based on the Am53C974A
chip, e.g. Tekram DC390(T), DawiControl 2974 and some onboard
PCscsi/PCnet (Am53/79C974) solutions.
This is a new implementation base on the generic esp_scsi driver.
Documentation can be found in <file:Documentation/scsi/tmscsim.txt>.
@ -1355,7 +1357,7 @@ config SCSI_DC390T
based on NCR/Symbios chips. Use "NCR53C8XX SCSI support" for those.
To compile this driver as a module, choose M here: the
module will be called tmscsim.
module will be called am53c974.
config SCSI_T128
tristate "Trantor T128/T128F/T228 SCSI support"
@ -1451,6 +1453,14 @@ config SCSI_NSP32
To compile this driver as a module, choose M here: the
module will be called nsp32.
config SCSI_WD719X
tristate "Western Digital WD7193/7197/7296 support"
depends on PCI && SCSI
select EEPROM_93CX6
---help---
This is a driver for Western Digital WD7193, WD7197 and WD7296 PCI
SCSI controllers (based on WD33C296A chip).
config SCSI_DEBUG
tristate "SCSI debugging host simulator"
depends on SCSI
@ -1615,7 +1625,7 @@ config ATARI_SCSI_RESET_BOOT
that leave the devices with SCSI operations partway completed.
config MAC_SCSI
bool "Macintosh NCR5380 SCSI"
tristate "Macintosh NCR5380 SCSI"
depends on MAC && SCSI=y
select SCSI_SPI_ATTRS
help

View file

@ -100,7 +100,7 @@ obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o
obj-$(CONFIG_SCSI_7000FASST) += wd7000.o
obj-$(CONFIG_SCSI_EATA) += eata.o
obj-$(CONFIG_SCSI_DC395x) += dc395x.o
obj-$(CONFIG_SCSI_DC390T) += tmscsim.o
obj-$(CONFIG_SCSI_AM53C974) += esp_scsi.o am53c974.o
obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
obj-$(CONFIG_MEGARAID_SAS) += megaraid/
@ -143,6 +143,7 @@ obj-$(CONFIG_SCSI_VIRTIO) += virtio_scsi.o
obj-$(CONFIG_VMWARE_PVSCSI) += vmw_pvscsi.o
obj-$(CONFIG_XEN_SCSI_FRONTEND) += xen-scsifront.o
obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o
obj-$(CONFIG_SCSI_WD719X) += wd719x.o
obj-$(CONFIG_ARM) += arm/

View file

@ -11,8 +11,6 @@
* drew@colorado.edu
* +1 (303) 666-5836
*
* DISTRIBUTION RELEASE 6.
*
* For more information, please consult
*
* NCR 5380 Family
@ -279,7 +277,7 @@ static void do_reset(struct Scsi_Host *host);
* Set up the internal fields in the SCSI command.
*/
static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
static inline void initialize_SCp(struct scsi_cmnd *cmd)
{
/*
* Initialize the Scsi Pointer field so that all of the commands in the
@ -574,12 +572,12 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
int trying_irqs, i, mask;
NCR5380_setup(instance);
for (trying_irqs = i = 0, mask = 1; i < 16; ++i, mask <<= 1)
for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1)
if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0))
trying_irqs |= mask;
timeout = jiffies + (250 * HZ / 1000);
probe_irq = SCSI_IRQ_NONE;
probe_irq = NO_IRQ;
/*
* A interrupt is triggered whenever BSY = false, SEL = true
@ -596,13 +594,13 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
while (probe_irq == SCSI_IRQ_NONE && time_before(jiffies, timeout))
while (probe_irq == NO_IRQ && time_before(jiffies, timeout))
schedule_timeout_uninterruptible(1);
NCR5380_write(SELECT_ENABLE_REG, 0);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
for (i = 0, mask = 1; i < 16; ++i, mask <<= 1)
for (i = 1, mask = 2; i < 16; ++i, mask <<= 1)
if (trying_irqs & mask)
free_irq(i, NULL);
@ -610,50 +608,70 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
}
/**
* NCR58380_print_options - show options
* @instance: unused for now
* NCR58380_info - report driver and host information
* @instance: relevant scsi host instance
*
* Called by probe code indicating the NCR5380 driver options that
* were selected. At some point this will switch to runtime options
* read from the adapter in question
* For use as the host template info() handler.
*
* Locks: none
*/
static void __init __maybe_unused
NCR5380_print_options(struct Scsi_Host *instance)
static const char *NCR5380_info(struct Scsi_Host *instance)
{
printk(" generic options"
#ifdef AUTOPROBE_IRQ
" AUTOPROBE_IRQ"
struct NCR5380_hostdata *hostdata = shost_priv(instance);
return hostdata->info;
}
static void prepare_info(struct Scsi_Host *instance)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
snprintf(hostdata->info, sizeof(hostdata->info),
"%s, io_port 0x%lx, n_io_port %d, "
"base 0x%lx, irq %d, "
"can_queue %d, cmd_per_lun %d, "
"sg_tablesize %d, this_id %d, "
"flags { %s%s%s}, "
#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
"USLEEP_POLL %d, USLEEP_WAITLONG %d, "
#endif
#ifdef AUTOSENSE
" AUTOSENSE"
"options { %s} ",
instance->hostt->name, instance->io_port, instance->n_io_port,
instance->base, instance->irq,
instance->can_queue, instance->cmd_per_lun,
instance->sg_tablesize, instance->this_id,
hostdata->flags & FLAG_NCR53C400 ? "NCR53C400 " : "",
hostdata->flags & FLAG_DTC3181E ? "DTC3181E " : "",
hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
USLEEP_POLL, USLEEP_WAITLONG,
#endif
#ifdef AUTOPROBE_IRQ
"AUTOPROBE_IRQ "
#endif
#ifdef DIFFERENTIAL
" DIFFERENTIAL"
"DIFFERENTIAL "
#endif
#ifdef REAL_DMA
" REAL DMA"
"REAL_DMA "
#endif
#ifdef REAL_DMA_POLL
" REAL DMA POLL"
"REAL_DMA_POLL "
#endif
#ifdef PARITY
" PARITY"
"PARITY "
#endif
#ifdef PSEUDO_DMA
" PSEUDO DMA"
"PSEUDO_DMA "
#endif
#ifdef UNSAFE
" UNSAFE "
"UNSAFE "
#endif
);
printk(" USLEEP, USLEEP_POLL=%d USLEEP_SLEEP=%d", USLEEP_POLL, USLEEP_SLEEP);
printk(" generic release=%d", NCR5380_PUBLIC_RELEASE);
if (((struct NCR5380_hostdata *) instance->hostdata)->flags & FLAG_NCR53C400) {
printk(" ncr53c400 release=%d", NCR53C400_PUBLIC_RELEASE);
}
#ifdef NCR53C400
"NCR53C400 "
#endif
"");
}
/**
@ -672,6 +690,7 @@ static void NCR5380_print_status(struct Scsi_Host *instance)
NCR5380_dprint_phase(NDEBUG_ANY, instance);
}
#ifdef PSEUDO_DMA
/******************************************/
/*
* /proc/scsi/[dtc pas16 t128 generic]/[0-ASC_NUM_BOARD_SUPPORTED]
@ -689,19 +708,18 @@ static void NCR5380_print_status(struct Scsi_Host *instance)
static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
char *buffer, int length)
{
#ifdef DTC_PUBLIC_RELEASE
dtc_wmaxi = dtc_maxi = 0;
#endif
#ifdef PAS16_PUBLIC_RELEASE
pas_wmaxi = pas_maxi = 0;
#endif
return (-ENOSYS); /* Currently this is a no-op */
struct NCR5380_hostdata *hostdata = shost_priv(instance);
hostdata->spin_max_r = 0;
hostdata->spin_max_w = 0;
return 0;
}
#endif
#undef SPRINTF
#define SPRINTF(args...) seq_printf(m, ## args)
static
void lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, struct seq_file *m);
void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m);
static
void lprint_command(unsigned char *cmd, struct seq_file *m);
static
@ -711,56 +729,31 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m,
struct Scsi_Host *instance)
{
struct NCR5380_hostdata *hostdata;
Scsi_Cmnd *ptr;
struct scsi_cmnd *ptr;
hostdata = (struct NCR5380_hostdata *) instance->hostdata;
SPRINTF("NCR5380 core release=%d. ", NCR5380_PUBLIC_RELEASE);
if (((struct NCR5380_hostdata *) instance->hostdata)->flags & FLAG_NCR53C400)
SPRINTF("ncr53c400 release=%d. ", NCR53C400_PUBLIC_RELEASE);
#ifdef DTC_PUBLIC_RELEASE
SPRINTF("DTC 3180/3280 release %d", DTC_PUBLIC_RELEASE);
#endif
#ifdef T128_PUBLIC_RELEASE
SPRINTF("T128 release %d", T128_PUBLIC_RELEASE);
#endif
#ifdef GENERIC_NCR5380_PUBLIC_RELEASE
SPRINTF("Generic5380 release %d", GENERIC_NCR5380_PUBLIC_RELEASE);
#endif
#ifdef PAS16_PUBLIC_RELEASE
SPRINTF("PAS16 release=%d", PAS16_PUBLIC_RELEASE);
#endif
SPRINTF("\nBase Addr: 0x%05lX ", (long) instance->base);
SPRINTF("io_port: %04x ", (int) instance->io_port);
if (instance->irq == SCSI_IRQ_NONE)
SPRINTF("IRQ: None.\n");
else
SPRINTF("IRQ: %d.\n", instance->irq);
#ifdef DTC_PUBLIC_RELEASE
SPRINTF("Highwater I/O busy_spin_counts -- write: %d read: %d\n", dtc_wmaxi, dtc_maxi);
#endif
#ifdef PAS16_PUBLIC_RELEASE
SPRINTF("Highwater I/O busy_spin_counts -- write: %d read: %d\n", pas_wmaxi, pas_maxi);
#ifdef PSEUDO_DMA
SPRINTF("Highwater I/O busy spin counts: write %d, read %d\n",
hostdata->spin_max_w, hostdata->spin_max_r);
#endif
spin_lock_irq(instance->host_lock);
if (!hostdata->connected)
SPRINTF("scsi%d: no currently connected command\n", instance->host_no);
else
lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, m);
lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m);
SPRINTF("scsi%d: issue_queue\n", instance->host_no);
for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
lprint_Scsi_Cmnd(ptr, m);
SPRINTF("scsi%d: disconnected_queue\n", instance->host_no);
for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
lprint_Scsi_Cmnd(ptr, m);
spin_unlock_irq(instance->host_lock);
return 0;
}
static void lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, struct seq_file *m)
static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m)
{
SPRINTF("scsi%d : destination target %d, lun %llu\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun);
SPRINTF(" command = ");
@ -836,18 +829,6 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main);
#ifdef NCR5380_STATS
for (i = 0; i < 8; ++i) {
hostdata->time_read[i] = 0;
hostdata->time_write[i] = 0;
hostdata->bytes_read[i] = 0;
hostdata->bytes_write[i] = 0;
}
hostdata->timebase = 0;
hostdata->pendingw = 0;
hostdata->pendingr = 0;
#endif
/* The CHECK code seems to break the 53C400. Will check it later maybe */
if (flags & FLAG_NCR53C400)
hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
@ -857,11 +838,7 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
hostdata->host = instance;
hostdata->time_expires = 0;
#ifndef AUTOSENSE
if ((instance->cmd_per_lun > 1) || instance->can_queue > 1)
printk(KERN_WARNING "scsi%d : WARNING : support for multiple outstanding commands enabled\n" " without AUTOSENSE option, contingent allegiance conditions may\n"
" be incorrectly cleared.\n", instance->host_no);
#endif /* def AUTOSENSE */
prepare_info(instance);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_write(MODE_REG, MR_BASE);
@ -935,11 +912,11 @@ static void NCR5380_exit(struct Scsi_Host *instance)
* Locks: host lock taken by caller
*/
static int NCR5380_queue_command_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd, void (*done) (struct scsi_cmnd *))
{
struct Scsi_Host *instance = cmd->device->host;
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
Scsi_Cmnd *tmp;
struct scsi_cmnd *tmp;
#if (NDEBUG & NDEBUG_NO_WRITE)
switch (cmd->cmnd[0]) {
@ -952,25 +929,6 @@ static int NCR5380_queue_command_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)
}
#endif /* (NDEBUG & NDEBUG_NO_WRITE) */
#ifdef NCR5380_STATS
switch (cmd->cmnd[0]) {
case WRITE:
case WRITE_6:
case WRITE_10:
hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase);
hostdata->bytes_write[cmd->device->id] += scsi_bufflen(cmd);
hostdata->pendingw++;
break;
case READ:
case READ_6:
case READ_10:
hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase);
hostdata->bytes_read[cmd->device->id] += scsi_bufflen(cmd);
hostdata->pendingr++;
break;
}
#endif
/*
* We use the host_scribble field as a pointer to the next command
* in a queue
@ -992,7 +950,7 @@ static int NCR5380_queue_command_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)
cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
hostdata->issue_queue = cmd;
} else {
for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (Scsi_Cmnd *) tmp->host_scribble);
for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble);
LIST(cmd, tmp);
tmp->host_scribble = (unsigned char *) cmd;
}
@ -1023,7 +981,7 @@ static void NCR5380_main(struct work_struct *work)
struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, coroutine.work);
struct Scsi_Host *instance = hostdata->host;
Scsi_Cmnd *tmp, *prev;
struct scsi_cmnd *tmp, *prev;
int done;
spin_lock_irq(instance->host_lock);
@ -1036,7 +994,7 @@ static void NCR5380_main(struct work_struct *work)
* Search through the issue_queue for a command destined
* for a target that's not busy.
*/
for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
{
if (prev != tmp)
dprintk(NDEBUG_LISTS, "MAIN tmp=%p target=%d busy=%d lun=%llu\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
@ -1048,7 +1006,7 @@ static void NCR5380_main(struct work_struct *work)
prev->host_scribble = tmp->host_scribble;
} else {
REMOVE(-1, hostdata->issue_queue, tmp, tmp->host_scribble);
hostdata->issue_queue = (Scsi_Cmnd *) tmp->host_scribble;
hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble;
}
tmp->host_scribble = NULL;
@ -1073,14 +1031,14 @@ static void NCR5380_main(struct work_struct *work)
hostdata->selecting = NULL;
/* RvC: have to preset this to indicate a new command is being performed */
if (!NCR5380_select(instance, tmp,
/*
* REQUEST SENSE commands are issued without tagged
* queueing, even on SCSI-II devices because the
* contingent allegiance condition exists for the
* entire unit.
*/
(tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE : TAG_NEXT)) {
/*
* REQUEST SENSE commands are issued without tagged
* queueing, even on SCSI-II devices because the
* contingent allegiance condition exists for the
* entire unit.
*/
if (!NCR5380_select(instance, tmp)) {
break;
} else {
LIST(tmp, hostdata->issue_queue);
@ -1095,9 +1053,9 @@ static void NCR5380_main(struct work_struct *work)
/* exited locked */
} /* if (!hostdata->connected) */
if (hostdata->selecting) {
tmp = (Scsi_Cmnd *) hostdata->selecting;
tmp = (struct scsi_cmnd *) hostdata->selecting;
/* Selection will drop and retake the lock */
if (!NCR5380_select(instance, tmp, (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE : TAG_NEXT)) {
if (!NCR5380_select(instance, tmp)) {
/* Ok ?? */
} else {
/* RvC: device failed, so we wait a long time
@ -1216,47 +1174,16 @@ static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
#endif
/**
* collect_stats - collect stats on a scsi command
* @hostdata: adapter
* @cmd: command being issued
*
* Update the statistical data by parsing the command in question
*/
static void collect_stats(struct NCR5380_hostdata *hostdata, Scsi_Cmnd * cmd)
{
#ifdef NCR5380_STATS
switch (cmd->cmnd[0]) {
case WRITE:
case WRITE_6:
case WRITE_10:
hostdata->time_write[scmd_id(cmd)] += (jiffies - hostdata->timebase);
hostdata->pendingw--;
break;
case READ:
case READ_6:
case READ_10:
hostdata->time_read[scmd_id(cmd)] += (jiffies - hostdata->timebase);
hostdata->pendingr--;
break;
}
#endif
}
/*
* Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
* int tag);
* Function : int NCR5380_select(struct Scsi_Host *instance,
* struct scsi_cmnd *cmd)
*
* Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command,
* including ARBITRATION, SELECTION, and initial message out for
* IDENTIFY and queue messages.
*
* Inputs : instance - instantiation of the 5380 driver on which this
* target lives, cmd - SCSI command to execute, tag - set to TAG_NEXT for
* new tag, TAG_NONE for untagged queueing, otherwise set to the tag for
* the command that is presently connected.
* target lives, cmd - SCSI command to execute.
*
* Returns : -1 if selection could not execute for some reason,
* 0 if selection succeeded or failed because the target
@ -1278,7 +1205,7 @@ static void collect_stats(struct NCR5380_hostdata *hostdata, Scsi_Cmnd * cmd)
* Locks: caller holds hostdata lock in IRQ mode
*/
static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
{
NCR5380_local_declare();
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@ -1476,7 +1403,6 @@ part2:
return -1;
}
cmd->result = DID_BAD_TARGET << 16;
collect_stats(hostdata, cmd);
cmd->scsi_done(cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
@ -1513,7 +1439,7 @@ part2:
}
dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
tmp[0] = IDENTIFY(((instance->irq == SCSI_IRQ_NONE) ? 0 : 1), cmd->device->lun);
tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun);
len = 1;
cmd->tag = 0;
@ -2086,7 +2012,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
#endif
unsigned char *data;
unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
/* RvC: we need to set the end of the polling time */
unsigned long poll_time = jiffies + USLEEP_POLL;
@ -2228,7 +2154,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
cmd->next_link->tag = cmd->tag;
cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun);
collect_stats(hostdata, cmd);
cmd->scsi_done(cmd);
cmd = hostdata->connected;
break;
@ -2263,7 +2188,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
else if (status_byte(cmd->SCp.Status) != GOOD)
cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
#ifdef AUTOSENSE
if ((cmd->cmnd[0] == REQUEST_SENSE) &&
hostdata->ses.cmd_len) {
scsi_eh_restore_cmnd(cmd, &hostdata->ses);
@ -2278,12 +2202,9 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
LIST(cmd, hostdata->issue_queue);
cmd->host_scribble = (unsigned char *)
hostdata->issue_queue;
hostdata->issue_queue = (Scsi_Cmnd *) cmd;
hostdata->issue_queue = (struct scsi_cmnd *) cmd;
dprintk(NDEBUG_QUEUES, "scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no);
} else
#endif /* def AUTOSENSE */
{
collect_stats(hostdata, cmd);
} else {
cmd->scsi_done(cmd);
}
@ -2430,7 +2351,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
hostdata->connected = NULL;
cmd->result = DID_ERROR << 16;
collect_stats(hostdata, cmd);
cmd->scsi_done(cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return;
@ -2479,7 +2399,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
* Function : void NCR5380_reselect (struct Scsi_Host *instance)
*
* Purpose : does reselection, initializing the instance->connected
* field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q
* field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q
* nexus has been reestablished,
*
* Inputs : instance - this instance of the NCR5380.
@ -2496,7 +2416,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
int len;
unsigned char msg[3];
unsigned char *data;
Scsi_Cmnd *tmp = NULL, *prev;
struct scsi_cmnd *tmp = NULL, *prev;
int abort = 0;
NCR5380_setup(instance);
@ -2562,7 +2482,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
*/
for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)
) {
if (prev) {
@ -2570,7 +2490,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
prev->host_scribble = tmp->host_scribble;
} else {
REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
hostdata->disconnected_queue = (Scsi_Cmnd *) tmp->host_scribble;
hostdata->disconnected_queue = (struct scsi_cmnd *) tmp->host_scribble;
}
tmp->host_scribble = NULL;
break;
@ -2601,7 +2521,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
*
* Inputs : instance - this instance of the NCR5380.
*
* Returns : pointer to the Scsi_Cmnd structure for which the I_T_L
* Returns : pointer to the scsi_cmnd structure for which the I_T_L
* nexus has been reestablished, on failure NULL is returned.
*/
@ -2643,11 +2563,11 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) {
#endif /* def REAL_DMA */
/*
* Function : int NCR5380_abort (Scsi_Cmnd *cmd)
* Function : int NCR5380_abort (struct scsi_cmnd *cmd)
*
* Purpose : abort a command
*
* Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the
* Inputs : cmd - the scsi_cmnd to abort, code - code to set the
* host byte of the result field to, if zero DID_ABORTED is
* used.
*
@ -2661,11 +2581,12 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) {
* Locks: host lock taken by caller
*/
static int NCR5380_abort(Scsi_Cmnd * cmd) {
static int NCR5380_abort(struct scsi_cmnd *cmd)
{
NCR5380_local_declare();
struct Scsi_Host *instance = cmd->device->host;
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
Scsi_Cmnd *tmp, **prev;
struct scsi_cmnd *tmp, **prev;
scmd_printk(KERN_WARNING, cmd, "aborting command\n");
@ -2713,10 +2634,10 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
*/
dprintk(NDEBUG_ABORT, "scsi%d : abort going into loop.\n", instance->host_no);
for (prev = (Scsi_Cmnd **) & (hostdata->issue_queue), tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp = (Scsi_Cmnd *) tmp->host_scribble)
for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
if (cmd == tmp) {
REMOVE(5, *prev, tmp, tmp->host_scribble);
(*prev) = (Scsi_Cmnd *) tmp->host_scribble;
(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
tmp->result = DID_ABORT << 16;
dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
@ -2769,20 +2690,20 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
* it from the disconnected queue.
*/
for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; tmp = (Scsi_Cmnd *) tmp->host_scribble)
for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; tmp = (struct scsi_cmnd *) tmp->host_scribble)
if (cmd == tmp) {
dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
if (NCR5380_select(instance, cmd, (int) cmd->tag))
if (NCR5380_select(instance, cmd))
return FAILED;
dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
do_abort(instance);
for (prev = (Scsi_Cmnd **) & (hostdata->disconnected_queue), tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp = (Scsi_Cmnd *) tmp->host_scribble)
for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
if (cmd == tmp) {
REMOVE(5, *prev, tmp, tmp->host_scribble);
*prev = (Scsi_Cmnd *) tmp->host_scribble;
*prev = (struct scsi_cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
tmp->result = DID_ABORT << 16;
tmp->scsi_done(tmp);
@ -2805,7 +2726,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
/*
* Function : int NCR5380_bus_reset (Scsi_Cmnd *cmd)
* Function : int NCR5380_bus_reset (struct scsi_cmnd *cmd)
*
* Purpose : reset the SCSI bus.
*
@ -2814,7 +2735,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
* Locks: host lock taken by caller
*/
static int NCR5380_bus_reset(Scsi_Cmnd * cmd)
static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
{
struct Scsi_Host *instance = cmd->device->host;

View file

@ -7,8 +7,6 @@
* drew@colorado.edu
* +1 (303) 666-5836
*
* DISTRIBUTION RELEASE 7
*
* For more information, please consult
*
* NCR 5380 Family
@ -25,13 +23,7 @@
#define NCR5380_H
#include <linux/interrupt.h>
#ifdef AUTOSENSE
#include <scsi/scsi_eh.h>
#endif
#define NCR5380_PUBLIC_RELEASE 7
#define NCR53C400_PUBLIC_RELEASE 2
#define NDEBUG_ARBITRATION 0x1
#define NDEBUG_AUTOSENSE 0x2
@ -224,33 +216,44 @@
#define DISCONNECT_LONG 2
/*
* These are "special" values for the tag parameter passed to NCR5380_select.
* "Special" value for the (unsigned char) command tag, to indicate
* I_T_L nexus instead of I_T_L_Q.
*/
#define TAG_NEXT -1 /* Use next free tag */
#define TAG_NONE -2 /*
* Establish I_T_L nexus instead of I_T_L_Q
* even on SCSI-II devices.
*/
#define TAG_NONE 0xff
/*
* These are "special" values for the irq and dma_channel fields of the
* Scsi_Host structure
*/
#define SCSI_IRQ_NONE 255
#define DMA_NONE 255
#define IRQ_AUTO 254
#define DMA_AUTO 254
#define PORT_AUTO 0xffff /* autoprobe io port for 53c400a */
#ifndef NO_IRQ
#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_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
#ifdef SUPPORT_TAGS
struct tag_alloc {
DECLARE_BITMAP(allocated, MAX_TAGS);
int nr_allocated;
int queue_size;
};
#endif
struct NCR5380_hostdata {
NCR5380_implementation_fields; /* implementation specific */
struct Scsi_Host *host; /* Host backpointer */
@ -263,9 +266,9 @@ struct NCR5380_hostdata {
volatile int dma_len; /* requested length of DMA */
#endif
volatile unsigned char last_message; /* last message OUT */
volatile Scsi_Cmnd *connected; /* currently connected command */
volatile Scsi_Cmnd *issue_queue; /* waiting to be issued */
volatile Scsi_Cmnd *disconnected_queue; /* waiting for reconnect */
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() */
@ -273,19 +276,21 @@ struct NCR5380_hostdata {
int flags;
unsigned long time_expires; /* in jiffies, set prior to sleeping */
int select_time; /* timer in select for target response */
volatile Scsi_Cmnd *selecting;
volatile struct scsi_cmnd *selecting;
struct delayed_work coroutine; /* our co-routine */
#ifdef NCR5380_STATS
unsigned timebase; /* Base for time calcs */
long time_read[8]; /* time to do reads */
long time_write[8]; /* time to do writes */
unsigned long bytes_read[8]; /* bytes read */
unsigned long bytes_write[8]; /* bytes written */
unsigned pendingr;
unsigned pendingw;
#endif
#ifdef AUTOSENSE
struct scsi_eh_save ses;
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
#ifdef PSEUDO_DMA
unsigned spin_max_r;
unsigned spin_max_w;
#endif
};
@ -296,7 +301,8 @@ struct NCR5380_hostdata {
#endif
#define dprintk(flg, fmt, ...) \
do { if ((NDEBUG) & (flg)) pr_debug(fmt, ## __VA_ARGS__); } while (0)
do { if ((NDEBUG) & (flg)) \
printk(KERN_DEBUG fmt, ## __VA_ARGS__); } while (0)
#if NDEBUG
#define NCR5380_dprint(flg, arg) \
@ -320,17 +326,9 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance);
static irqreturn_t NCR5380_intr(int irq, void *dev_id);
#endif
static void NCR5380_main(struct work_struct *work);
static void __maybe_unused NCR5380_print_options(struct Scsi_Host *instance);
static int NCR5380_abort(Scsi_Cmnd * cmd);
static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
static int NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int __maybe_unused NCR5380_show_info(struct seq_file *,
struct Scsi_Host *);
static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
char *buffer, int length);
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, Scsi_Cmnd * cmd, int tag);
static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd);
#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

View file

@ -462,9 +462,9 @@ static int aac_slave_configure(struct scsi_device *sdev)
depth = 256;
else if (depth < 2)
depth = 2;
scsi_adjust_queue_depth(sdev, depth);
scsi_change_queue_depth(sdev, depth);
} else
scsi_adjust_queue_depth(sdev, 1);
scsi_change_queue_depth(sdev, 1);
return 0;
}
@ -478,12 +478,8 @@ static int aac_slave_configure(struct scsi_device *sdev)
* total capacity and the queue depth supported by the target device.
*/
static int aac_change_queue_depth(struct scsi_device *sdev, int depth,
int reason)
static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
(sdev_channel(sdev) == CONTAINER_CHANNEL)) {
struct scsi_device * dev;
@ -504,10 +500,10 @@ static int aac_change_queue_depth(struct scsi_device *sdev, int depth,
depth = 256;
else if (depth < 2)
depth = 2;
scsi_adjust_queue_depth(sdev, depth);
} else
scsi_adjust_queue_depth(sdev, 1);
return sdev->queue_depth;
return scsi_change_queue_depth(sdev, depth);
}
return scsi_change_queue_depth(sdev, 1);
}
static ssize_t aac_show_raid_level(struct device *dev, struct device_attribute *attr, char *buf)

View file

@ -7706,7 +7706,7 @@ advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
asc_dvc->cfg->can_tagged_qng |= tid_bit;
asc_dvc->use_tagged_qng |= tid_bit;
}
scsi_adjust_queue_depth(sdev,
scsi_change_queue_depth(sdev,
asc_dvc->max_dvc_qng[sdev->id]);
}
} else {
@ -7847,10 +7847,8 @@ advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
}
}
if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
scsi_adjust_queue_depth(sdev,
adv_dvc->max_dvc_qng);
}
if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported)
scsi_change_queue_depth(sdev, adv_dvc->max_dvc_qng);
}
/*

View file

@ -1470,7 +1470,7 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
case AHD_DEV_Q_BASIC:
case AHD_DEV_Q_TAGGED:
scsi_adjust_queue_depth(sdev,
scsi_change_queue_depth(sdev,
dev->openings + dev->active);
break;
default:
@ -1480,7 +1480,7 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
* serially on the controller/device. This should
* remove some latency.
*/
scsi_adjust_queue_depth(sdev, 1);
scsi_change_queue_depth(sdev, 1);
break;
}
}

View file

@ -1336,7 +1336,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
case AHC_DEV_Q_BASIC:
case AHC_DEV_Q_TAGGED:
scsi_adjust_queue_depth(sdev,
scsi_change_queue_depth(sdev,
dev->openings + dev->active);
default:
/*
@ -1345,7 +1345,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
* serially on the controller/device. This should
* remove some latency.
*/
scsi_adjust_queue_depth(sdev, 2);
scsi_change_queue_depth(sdev, 2);
break;
}
}

View file

@ -78,7 +78,7 @@ void asd_dev_gone(struct domain_device *dev);
void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id);
int asd_execute_task(struct sas_task *, int num, gfp_t gfp_flags);
int asd_execute_task(struct sas_task *task, gfp_t gfp_flags);
void asd_set_dmamode(struct domain_device *dev);

View file

@ -1200,8 +1200,7 @@ static void asd_start_scb_timers(struct list_head *list)
* Case A: we can send the whole batch at once. Increment "pending"
* in the beginning of this function, when it is checked, in order to
* eliminate races when this function is called by multiple processes.
* Case B: should never happen if the managing layer considers
* lldd_queue_size.
* Case B: should never happen.
*/
int asd_post_ascb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
int num)

View file

@ -49,14 +49,6 @@ MODULE_PARM_DESC(use_msi, "\n"
"\tEnable(1) or disable(0) using PCI MSI.\n"
"\tDefault: 0");
static int lldd_max_execute_num = 0;
module_param_named(collector, lldd_max_execute_num, int, S_IRUGO);
MODULE_PARM_DESC(collector, "\n"
"\tIf greater than one, tells the SAS Layer to run in Task Collector\n"
"\tMode. If 1 or 0, tells the SAS Layer to run in Direct Mode.\n"
"\tThe aic94xx SAS LLDD supports both modes.\n"
"\tDefault: 0 (Direct Mode).\n");
static struct scsi_transport_template *aic94xx_transport_template;
static int asd_scan_finished(struct Scsi_Host *, unsigned long);
static void asd_scan_start(struct Scsi_Host *);
@ -84,6 +76,7 @@ static struct scsi_host_template aic94xx_sht = {
.target_destroy = sas_target_destroy,
.ioctl = sas_ioctl,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
static int asd_map_memio(struct asd_ha_struct *asd_ha)
@ -710,9 +703,6 @@ static int asd_register_sas_ha(struct asd_ha_struct *asd_ha)
asd_ha->sas_ha.sas_port= sas_ports;
asd_ha->sas_ha.num_phys= ASD_MAX_PHYS;
asd_ha->sas_ha.lldd_queue_size = asd_ha->seq.can_queue;
asd_ha->sas_ha.lldd_max_execute_num = lldd_max_execute_num;
return sas_register_ha(&asd_ha->sas_ha);
}

View file

@ -543,8 +543,7 @@ static int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
return res;
}
int asd_execute_task(struct sas_task *task, const int num,
gfp_t gfp_flags)
int asd_execute_task(struct sas_task *task, gfp_t gfp_flags)
{
int res = 0;
LIST_HEAD(alist);
@ -553,11 +552,11 @@ int asd_execute_task(struct sas_task *task, const int num,
struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
unsigned long flags;
res = asd_can_queue(asd_ha, num);
res = asd_can_queue(asd_ha, 1);
if (res)
return res;
res = num;
res = 1;
ascb = asd_ascb_alloc_list(asd_ha, &res, gfp_flags);
if (res) {
res = -ENOMEM;
@ -568,7 +567,7 @@ int asd_execute_task(struct sas_task *task, const int num,
list_for_each_entry(a, &alist, list) {
a->uldd_task = t;
t->lldd_task = a;
t = list_entry(t->list.next, struct sas_task, list);
break;
}
list_for_each_entry(a, &alist, list) {
t = a->uldd_task;
@ -601,7 +600,7 @@ int asd_execute_task(struct sas_task *task, const int num,
}
list_del_init(&alist);
res = asd_post_ascb_list(asd_ha, ascb, num);
res = asd_post_ascb_list(asd_ha, ascb, 1);
if (unlikely(res)) {
a = NULL;
__list_add(&alist, ascb->list.prev, &ascb->list);
@ -639,6 +638,6 @@ out_err_unmap:
out_err:
if (ascb)
asd_ascb_free_list(ascb);
asd_can_dequeue(asd_ha, num);
asd_can_dequeue(asd_ha, 1);
return res;
}

586
drivers/scsi/am53c974.c Normal file
View file

@ -0,0 +1,586 @@
/*
* AMD am53c974 driver.
* Copyright (c) 2014 Hannes Reinecke, SUSE Linux GmbH
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <scsi/scsi_host.h>
#include "esp_scsi.h"
#define DRV_MODULE_NAME "am53c974"
#define DRV_MODULE_VERSION "1.00"
static bool am53c974_debug;
static bool am53c974_fenab = true;
#define esp_dma_log(f, a...) \
do { \
if (am53c974_debug) \
shost_printk(KERN_DEBUG, esp->host, f, ##a); \
} while (0)
#define ESP_DMA_CMD 0x10
#define ESP_DMA_STC 0x11
#define ESP_DMA_SPA 0x12
#define ESP_DMA_WBC 0x13
#define ESP_DMA_WAC 0x14
#define ESP_DMA_STATUS 0x15
#define ESP_DMA_SMDLA 0x16
#define ESP_DMA_WMAC 0x17
#define ESP_DMA_CMD_IDLE 0x00
#define ESP_DMA_CMD_BLAST 0x01
#define ESP_DMA_CMD_ABORT 0x02
#define ESP_DMA_CMD_START 0x03
#define ESP_DMA_CMD_MASK 0x03
#define ESP_DMA_CMD_DIAG 0x04
#define ESP_DMA_CMD_MDL 0x10
#define ESP_DMA_CMD_INTE_P 0x20
#define ESP_DMA_CMD_INTE_D 0x40
#define ESP_DMA_CMD_DIR 0x80
#define ESP_DMA_STAT_PWDN 0x01
#define ESP_DMA_STAT_ERROR 0x02
#define ESP_DMA_STAT_ABORT 0x04
#define ESP_DMA_STAT_DONE 0x08
#define ESP_DMA_STAT_SCSIINT 0x10
#define ESP_DMA_STAT_BCMPLT 0x20
/* EEPROM is accessed with 16-bit values */
#define DC390_EEPROM_READ 0x80
#define DC390_EEPROM_LEN 0x40
/*
* DC390 EEPROM
*
* 8 * 4 bytes of per-device options
* followed by HBA specific options
*/
/* Per-device options */
#define DC390_EE_MODE1 0x00
#define DC390_EE_SPEED 0x01
/* HBA-specific options */
#define DC390_EE_ADAPT_SCSI_ID 0x40
#define DC390_EE_MODE2 0x41
#define DC390_EE_DELAY 0x42
#define DC390_EE_TAG_CMD_NUM 0x43
#define DC390_EE_MODE1_PARITY_CHK 0x01
#define DC390_EE_MODE1_SYNC_NEGO 0x02
#define DC390_EE_MODE1_EN_DISC 0x04
#define DC390_EE_MODE1_SEND_START 0x08
#define DC390_EE_MODE1_TCQ 0x10
#define DC390_EE_MODE2_MORE_2DRV 0x01
#define DC390_EE_MODE2_GREATER_1G 0x02
#define DC390_EE_MODE2_RST_SCSI_BUS 0x04
#define DC390_EE_MODE2_ACTIVE_NEGATION 0x08
#define DC390_EE_MODE2_NO_SEEK 0x10
#define DC390_EE_MODE2_LUN_CHECK 0x20
struct pci_esp_priv {
struct esp *esp;
u8 dma_status;
};
static void pci_esp_dma_drain(struct esp *esp);
static inline struct pci_esp_priv *pci_esp_get_priv(struct esp *esp)
{
struct pci_dev *pdev = esp->dev;
return pci_get_drvdata(pdev);
}
static void pci_esp_write8(struct esp *esp, u8 val, unsigned long reg)
{
iowrite8(val, esp->regs + (reg * 4UL));
}
static u8 pci_esp_read8(struct esp *esp, unsigned long reg)
{
return ioread8(esp->regs + (reg * 4UL));
}
static void pci_esp_write32(struct esp *esp, u32 val, unsigned long reg)
{
return iowrite32(val, esp->regs + (reg * 4UL));
}
static dma_addr_t pci_esp_map_single(struct esp *esp, void *buf,
size_t sz, int dir)
{
return pci_map_single(esp->dev, buf, sz, dir);
}
static int pci_esp_map_sg(struct esp *esp, struct scatterlist *sg,
int num_sg, int dir)
{
return pci_map_sg(esp->dev, sg, num_sg, dir);
}
static void pci_esp_unmap_single(struct esp *esp, dma_addr_t addr,
size_t sz, int dir)
{
pci_unmap_single(esp->dev, addr, sz, dir);
}
static void pci_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
int num_sg, int dir)
{
pci_unmap_sg(esp->dev, sg, num_sg, dir);
}
static int pci_esp_irq_pending(struct esp *esp)
{
struct pci_esp_priv *pep = pci_esp_get_priv(esp);
pep->dma_status = pci_esp_read8(esp, ESP_DMA_STATUS);
esp_dma_log("dma intr dreg[%02x]\n", pep->dma_status);
if (pep->dma_status & (ESP_DMA_STAT_ERROR |
ESP_DMA_STAT_ABORT |
ESP_DMA_STAT_DONE |
ESP_DMA_STAT_SCSIINT))
return 1;
return 0;
}
static void pci_esp_reset_dma(struct esp *esp)
{
/* Nothing to do ? */
}
static void pci_esp_dma_drain(struct esp *esp)
{
u8 resid;
int lim = 1000;
if ((esp->sreg & ESP_STAT_PMASK) == ESP_DOP ||
(esp->sreg & ESP_STAT_PMASK) == ESP_DIP)
/* Data-In or Data-Out, nothing to be done */
return;
while (--lim > 0) {
resid = pci_esp_read8(esp, ESP_FFLAGS) & ESP_FF_FBYTES;
if (resid <= 1)
break;
cpu_relax();
}
if (resid > 1) {
/* FIFO not cleared */
shost_printk(KERN_INFO, esp->host,
"FIFO not cleared, %d bytes left\n",
resid);
}
/*
* When there is a residual BCMPLT will never be set
* (obviously). But we still have to issue the BLAST
* command, otherwise the data will not being transferred.
* But we'll never know when the BLAST operation is
* finished. So check for some time and give up eventually.
*/
lim = 1000;
pci_esp_write8(esp, ESP_DMA_CMD_DIR | ESP_DMA_CMD_BLAST, ESP_DMA_CMD);
while (pci_esp_read8(esp, ESP_DMA_STATUS) & ESP_DMA_STAT_BCMPLT) {
if (--lim == 0)
break;
cpu_relax();
}
pci_esp_write8(esp, ESP_DMA_CMD_DIR | ESP_DMA_CMD_IDLE, ESP_DMA_CMD);
esp_dma_log("DMA blast done (%d tries, %d bytes left)\n", lim, resid);
/* BLAST residual handling is currently untested */
if (WARN_ON_ONCE(resid == 1)) {
struct esp_cmd_entry *ent = esp->active_cmd;
ent->flags |= ESP_CMD_FLAG_RESIDUAL;
}
}
static void pci_esp_dma_invalidate(struct esp *esp)
{
struct pci_esp_priv *pep = pci_esp_get_priv(esp);
esp_dma_log("invalidate DMA\n");
pci_esp_write8(esp, ESP_DMA_CMD_IDLE, ESP_DMA_CMD);
pep->dma_status = 0;
}
static int pci_esp_dma_error(struct esp *esp)
{
struct pci_esp_priv *pep = pci_esp_get_priv(esp);
if (pep->dma_status & ESP_DMA_STAT_ERROR) {
u8 dma_cmd = pci_esp_read8(esp, ESP_DMA_CMD);
if ((dma_cmd & ESP_DMA_CMD_MASK) == ESP_DMA_CMD_START)
pci_esp_write8(esp, ESP_DMA_CMD_ABORT, ESP_DMA_CMD);
return 1;
}
if (pep->dma_status & ESP_DMA_STAT_ABORT) {
pci_esp_write8(esp, ESP_DMA_CMD_IDLE, ESP_DMA_CMD);
pep->dma_status = pci_esp_read8(esp, ESP_DMA_CMD);
return 1;
}
return 0;
}
static void pci_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
u32 dma_count, int write, u8 cmd)
{
struct pci_esp_priv *pep = pci_esp_get_priv(esp);
u32 val = 0;
BUG_ON(!(cmd & ESP_CMD_DMA));
pep->dma_status = 0;
/* Set DMA engine to IDLE */
if (write)
/* DMA write direction logic is inverted */
val |= ESP_DMA_CMD_DIR;
pci_esp_write8(esp, ESP_DMA_CMD_IDLE | val, ESP_DMA_CMD);
pci_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
pci_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
if (esp->config2 & ESP_CONFIG2_FENAB)
pci_esp_write8(esp, (esp_count >> 16) & 0xff, ESP_TCHI);
pci_esp_write32(esp, esp_count, ESP_DMA_STC);
pci_esp_write32(esp, addr, ESP_DMA_SPA);
esp_dma_log("start dma addr[%x] count[%d:%d]\n",
addr, esp_count, dma_count);
scsi_esp_cmd(esp, cmd);
/* Send DMA Start command */
pci_esp_write8(esp, ESP_DMA_CMD_START | val, ESP_DMA_CMD);
}
static u32 pci_esp_dma_length_limit(struct esp *esp, u32 dma_addr, u32 dma_len)
{
int dma_limit = 16;
u32 base, end;
/*
* If CONFIG2_FENAB is set we can
* handle up to 24 bit addresses
*/
if (esp->config2 & ESP_CONFIG2_FENAB)
dma_limit = 24;
if (dma_len > (1U << dma_limit))
dma_len = (1U << dma_limit);
/*
* Prevent crossing a 24-bit address boundary.
*/
base = dma_addr & ((1U << 24) - 1U);
end = base + dma_len;
if (end > (1U << 24))
end = (1U <<24);
dma_len = end - base;
return dma_len;
}
static const struct esp_driver_ops pci_esp_ops = {
.esp_write8 = pci_esp_write8,
.esp_read8 = pci_esp_read8,
.map_single = pci_esp_map_single,
.map_sg = pci_esp_map_sg,
.unmap_single = pci_esp_unmap_single,
.unmap_sg = pci_esp_unmap_sg,
.irq_pending = pci_esp_irq_pending,
.reset_dma = pci_esp_reset_dma,
.dma_drain = pci_esp_dma_drain,
.dma_invalidate = pci_esp_dma_invalidate,
.send_dma_cmd = pci_esp_send_dma_cmd,
.dma_error = pci_esp_dma_error,
.dma_length_limit = pci_esp_dma_length_limit,
};
/*
* Read DC-390 eeprom
*/
static void dc390_eeprom_prepare_read(struct pci_dev *pdev, u8 cmd)
{
u8 carry_flag = 1, j = 0x80, bval;
int i;
for (i = 0; i < 9; i++) {
if (carry_flag) {
pci_write_config_byte(pdev, 0x80, 0x40);
bval = 0xc0;
} else
bval = 0x80;
udelay(160);
pci_write_config_byte(pdev, 0x80, bval);
udelay(160);
pci_write_config_byte(pdev, 0x80, 0);
udelay(160);
carry_flag = (cmd & j) ? 1 : 0;
j >>= 1;
}
}
static u16 dc390_eeprom_get_data(struct pci_dev *pdev)
{
int i;
u16 wval = 0;
u8 bval;
for (i = 0; i < 16; i++) {
wval <<= 1;
pci_write_config_byte(pdev, 0x80, 0x80);
udelay(160);
pci_write_config_byte(pdev, 0x80, 0x40);
udelay(160);
pci_read_config_byte(pdev, 0x00, &bval);
if (bval == 0x22)
wval |= 1;
}
return wval;
}
static void dc390_read_eeprom(struct pci_dev *pdev, u16 *ptr)
{
u8 cmd = DC390_EEPROM_READ, i;
for (i = 0; i < DC390_EEPROM_LEN; i++) {
pci_write_config_byte(pdev, 0xc0, 0);
udelay(160);
dc390_eeprom_prepare_read(pdev, cmd++);
*ptr++ = dc390_eeprom_get_data(pdev);
pci_write_config_byte(pdev, 0x80, 0);
pci_write_config_byte(pdev, 0x80, 0);
udelay(160);
}
}
static void dc390_check_eeprom(struct esp *esp)
{
u8 EEbuf[128];
u16 *ptr = (u16 *)EEbuf, wval = 0;
int i;
dc390_read_eeprom((struct pci_dev *)esp->dev, ptr);
for (i = 0; i < DC390_EEPROM_LEN; i++, ptr++)
wval += *ptr;
/* no Tekram EEprom found */
if (wval != 0x1234) {
struct pci_dev *pdev = esp->dev;
dev_printk(KERN_INFO, &pdev->dev,
"No valid Tekram EEprom found\n");
return;
}
esp->scsi_id = EEbuf[DC390_EE_ADAPT_SCSI_ID];
esp->num_tags = 2 << EEbuf[DC390_EE_TAG_CMD_NUM];
if (EEbuf[DC390_EE_MODE2] & DC390_EE_MODE2_ACTIVE_NEGATION)
esp->config4 |= ESP_CONFIG4_RADE | ESP_CONFIG4_RAE;
}
static int pci_esp_probe_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct scsi_host_template *hostt = &scsi_esp_template;
int err = -ENODEV;
struct Scsi_Host *shost;
struct esp *esp;
struct pci_esp_priv *pep;
if (pci_enable_device(pdev)) {
dev_printk(KERN_INFO, &pdev->dev, "cannot enable device\n");
return -ENODEV;
}
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
dev_printk(KERN_INFO, &pdev->dev,
"failed to set 32bit DMA mask\n");
goto fail_disable_device;
}
shost = scsi_host_alloc(hostt, sizeof(struct esp));
if (!shost) {
dev_printk(KERN_INFO, &pdev->dev,
"failed to allocate scsi host\n");
err = -ENOMEM;
goto fail_disable_device;
}
pep = kzalloc(sizeof(struct pci_esp_priv), GFP_KERNEL);
if (!pep) {
dev_printk(KERN_INFO, &pdev->dev,
"failed to allocate esp_priv\n");
err = -ENOMEM;
goto fail_host_alloc;
}
esp = shost_priv(shost);
esp->host = shost;
esp->dev = pdev;
esp->ops = &pci_esp_ops;
/*
* The am53c974 HBA has a design flaw of generating
* spurious DMA completion interrupts when using
* DMA for command submission.
*/
esp->flags |= ESP_FLAG_USE_FIFO;
/*
* Enable CONFIG2_FENAB to allow for large DMA transfers
*/
if (am53c974_fenab)
esp->config2 |= ESP_CONFIG2_FENAB;
pep->esp = esp;
if (pci_request_regions(pdev, DRV_MODULE_NAME)) {
dev_printk(KERN_ERR, &pdev->dev,
"pci memory selection failed\n");
goto fail_priv_alloc;
}
esp->regs = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
if (!esp->regs) {
dev_printk(KERN_ERR, &pdev->dev, "pci I/O map failed\n");
err = -EINVAL;
goto fail_release_regions;
}
esp->dma_regs = esp->regs;
pci_set_master(pdev);
esp->command_block = pci_alloc_consistent(pdev, 16,
&esp->command_block_dma);
if (!esp->command_block) {
dev_printk(KERN_ERR, &pdev->dev,
"failed to allocate command block\n");
err = -ENOMEM;
goto fail_unmap_regs;
}
err = request_irq(pdev->irq, scsi_esp_intr, IRQF_SHARED,
DRV_MODULE_NAME, esp);
if (err < 0) {
dev_printk(KERN_ERR, &pdev->dev, "failed to register IRQ\n");
goto fail_unmap_command_block;
}
esp->scsi_id = 7;
dc390_check_eeprom(esp);
shost->this_id = esp->scsi_id;
shost->max_id = 8;
shost->irq = pdev->irq;
shost->io_port = pci_resource_start(pdev, 0);
shost->n_io_port = pci_resource_len(pdev, 0);
shost->unique_id = shost->io_port;
esp->scsi_id_mask = (1 << esp->scsi_id);
/* Assume 40MHz clock */
esp->cfreq = 40000000;
pci_set_drvdata(pdev, pep);
err = scsi_esp_register(esp, &pdev->dev);
if (err)
goto fail_free_irq;
return 0;
fail_free_irq:
free_irq(pdev->irq, esp);
fail_unmap_command_block:
pci_free_consistent(pdev, 16, esp->command_block,
esp->command_block_dma);
fail_unmap_regs:
pci_iounmap(pdev, esp->regs);
fail_release_regions:
pci_release_regions(pdev);
fail_priv_alloc:
kfree(pep);
fail_host_alloc:
scsi_host_put(shost);
fail_disable_device:
pci_disable_device(pdev);
return err;
}
static void pci_esp_remove_one(struct pci_dev *pdev)
{
struct pci_esp_priv *pep = pci_get_drvdata(pdev);
struct esp *esp = pep->esp;
scsi_esp_unregister(esp);
free_irq(pdev->irq, esp);
pci_free_consistent(pdev, 16, esp->command_block,
esp->command_block_dma);
pci_iounmap(pdev, esp->regs);
pci_release_regions(pdev);
pci_disable_device(pdev);
kfree(pep);
scsi_host_put(esp->host);
}
static struct pci_device_id am53c974_pci_tbl[] = {
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SCSI,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ }
};
MODULE_DEVICE_TABLE(pci, am53c974_pci_tbl);
static struct pci_driver am53c974_driver = {
.name = DRV_MODULE_NAME,
.id_table = am53c974_pci_tbl,
.probe = pci_esp_probe_one,
.remove = pci_esp_remove_one,
};
static int __init am53c974_module_init(void)
{
return pci_register_driver(&am53c974_driver);
}
static void __exit am53c974_module_exit(void)
{
pci_unregister_driver(&am53c974_driver);
}
MODULE_DESCRIPTION("AM53C974 SCSI driver");
MODULE_AUTHOR("Hannes Reinecke <[email protected]>");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
MODULE_ALIAS("tmscsim");
module_param(am53c974_debug, bool, 0644);
MODULE_PARM_DESC(am53c974_debug, "Enable debugging");
module_param(am53c974_fenab, bool, 0444);
MODULE_PARM_DESC(am53c974_fenab, "Enable 24-bit DMA transfer sizes");
module_init(am53c974_module_init);
module_exit(am53c974_module_exit);

View file

@ -114,16 +114,11 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
static const char *arcmsr_info(struct Scsi_Host *);
static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *);
static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
int queue_depth, int reason)
static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
queue_depth = ARCMSR_MAX_CMD_PERLUN;
scsi_adjust_queue_depth(sdev, queue_depth);
return queue_depth;
return scsi_change_queue_depth(sdev, queue_depth);
}
static struct scsi_host_template arcmsr_scsi_host_template = {

View file

@ -13,16 +13,12 @@
#include <asm/ecard.h>
#include <asm/io.h>
#include "../scsi.h"
#include <scsi/scsi_host.h>
#include <scsi/scsicam.h>
#define AUTOSENSE
#define PSEUDO_DMA
#define CUMANASCSI_PUBLIC_RELEASE 1
#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_local_declare() struct Scsi_Host *_instance
#define NCR5380_setup(instance) _instance = instance
@ -30,6 +26,7 @@
#define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value)
#define NCR5380_intr cumanascsi_intr
#define NCR5380_queue_command cumanascsi_queue_command
#define NCR5380_info cumanascsi_info
#define NCR5380_implementation_fields \
unsigned ctrl; \
@ -42,11 +39,6 @@ void cumanascsi_setup(char *str, int *ints)
{
}
const char *cumanascsi_info(struct Scsi_Host *spnt)
{
return "";
}
#define CTRL 0x16fc
#define STAT 0x2004
#define L(v) (((v)<<16)|((v) & 0x0000ffff))
@ -267,14 +259,6 @@ static int cumanascsi1_probe(struct expansion_card *ec,
goto out_unmap;
}
printk("scsi%d: at port 0x%08lx irq %d",
host->host_no, host->io_port, host->irq);
printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
host->can_queue, host->cmd_per_lun, CUMANASCSI_PUBLIC_RELEASE);
printk("\nscsi%d:", host->host_no);
NCR5380_print_options(host);
printk("\n");
ret = scsi_add_host(host, &ec->dev);
if (ret)
goto out_free_irq;

View file

@ -14,13 +14,9 @@
#include <asm/ecard.h>
#include <asm/io.h>
#include "../scsi.h"
#include <scsi/scsi_host.h>
#define AUTOSENSE
/*#define PSEUDO_DMA*/
#define OAKSCSI_PUBLIC_RELEASE 1
#define DONT_USE_INTR
#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
@ -29,10 +25,9 @@
#define NCR5380_read(reg) readb(_base + ((reg) << 2))
#define NCR5380_write(reg, value) writeb(value, _base + ((reg) << 2))
#define NCR5380_intr oakscsi_intr
#define NCR5380_queue_command oakscsi_queue_command
#define NCR5380_info oakscsi_info
#define NCR5380_show_info oakscsi_show_info
#define NCR5380_write_info oakscsi_write_info
#define NCR5380_implementation_fields \
void __iomem *base
@ -42,11 +37,6 @@
#undef START_DMA_INITIATOR_RECEIVE_REG
#define START_DMA_INITIATOR_RECEIVE_REG (128 + 7)
const char * oakscsi_info (struct Scsi_Host *spnt)
{
return "";
}
#define STAT ((128 + 16) << 2)
#define DATA ((128 + 8) << 2)
@ -114,7 +104,6 @@ printk("reading %p len %d\n", addr, len);
static struct scsi_host_template oakscsi_template = {
.module = THIS_MODULE,
.show_info = oakscsi_show_info,
.write_info = oakscsi_write_info,
.name = "Oak 16-bit SCSI",
.info = oakscsi_info,
.queuecommand = oakscsi_queue_command,
@ -150,19 +139,11 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
goto unreg;
}
host->irq = IRQ_NONE;
host->irq = NO_IRQ;
host->n_io_port = 255;
NCR5380_init(host, 0);
printk("scsi%d: at port 0x%08lx irqs disabled",
host->host_no, host->io_port);
printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
host->can_queue, host->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE);
printk("\nscsi%d:", host->host_no);
NCR5380_print_options(host);
printk("\n");
ret = scsi_add_host(host, &ec->dev);
if (ret)
goto out_unmap;

File diff suppressed because it is too large Load diff

View file

@ -64,45 +64,57 @@
/**************************************************************************/
#include <linux/module.h>
#define AUTOSENSE
/* For the Atari version, use only polled IO or REAL_DMA */
#define REAL_DMA
/* Support tagged queuing? (on devices that are able to... :-) */
#define SUPPORT_TAGS
#define MAX_TAGS 32
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/nvram.h>
#include <linux/bitops.h>
#include <linux/wait.h>
#include <linux/platform_device.h>
#include <asm/setup.h>
#include <asm/atarihw.h>
#include <asm/atariints.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/traps.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "atari_scsi.h"
#include "NCR5380.h"
#include <asm/atari_stdma.h>
#include <asm/atari_stram.h>
#include <asm/io.h>
#include <linux/stat.h>
#include <scsi/scsi_host.h>
/* Definitions for the core NCR5380 driver. */
#define REAL_DMA
#define SUPPORT_TAGS
#define MAX_TAGS 32
#define DMA_MIN_SIZE 32
#define NCR5380_implementation_fields /* none */
#define NCR5380_read(reg) atari_scsi_reg_read(reg)
#define NCR5380_write(reg, value) atari_scsi_reg_write(reg, value)
#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) \
atari_scsi_dma_setup(instance, data, count, 0)
#define NCR5380_dma_write_setup(instance, data, count) \
atari_scsi_dma_setup(instance, data, count, 1)
#define NCR5380_dma_residual(instance) \
atari_scsi_dma_residual(instance)
#define NCR5380_dma_xfer_len(instance, cmd, phase) \
atari_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO))
#define NCR5380_acquire_dma_irq(instance) falcon_get_lock(instance)
#define NCR5380_release_dma_irq(instance) falcon_release_lock()
#include "NCR5380.h"
#define IS_A_TT() ATARIHW_PRESENT(TT_SCSI)
@ -149,23 +161,6 @@ static inline unsigned long SCSI_DMA_GETADR(void)
return adr;
}
static inline void ENABLE_IRQ(void)
{
if (IS_A_TT())
atari_enable_irq(IRQ_TT_MFP_SCSI);
else
atari_enable_irq(IRQ_MFP_FSCSI);
}
static inline void DISABLE_IRQ(void)
{
if (IS_A_TT())
atari_disable_irq(IRQ_TT_MFP_SCSI);
else
atari_disable_irq(IRQ_MFP_FSCSI);
}
#define HOSTDATA_DMALEN (((struct NCR5380_hostdata *) \
(atari_scsi_host->hostdata))->dma_len)
@ -178,30 +173,9 @@ static inline void DISABLE_IRQ(void)
#define AFTER_RESET_DELAY (5*HZ/2)
#endif
/***************************** Prototypes *****************************/
#ifdef REAL_DMA
static int scsi_dma_is_ignored_buserr(unsigned char dma_stat);
static void atari_scsi_fetch_restbytes(void);
static long atari_scsi_dma_residual(struct Scsi_Host *instance);
static int falcon_classify_cmd(Scsi_Cmnd *cmd);
static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
Scsi_Cmnd *cmd, int write_flag);
#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 void 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 unsigned char (*atari_scsi_reg_read)(unsigned char reg);
@ -226,8 +200,6 @@ static char *atari_dma_orig_addr;
/* mask for address bits that can't be used with the ST-DMA */
static unsigned long atari_dma_stram_mask;
#define STRAM_ADDR(a) (((a) & atari_dma_stram_mask) == 0)
/* number of bytes to cut from a transfer to handle NCR overruns */
static int atari_read_overruns;
#endif
static int setup_can_queue = -1;
@ -386,10 +358,6 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy)
NCR5380_intr(irq, dummy);
#if 0
/* To be sure the int is not masked */
atari_enable_irq(IRQ_TT_MFP_SCSI);
#endif
return IRQ_HANDLED;
}
@ -480,257 +448,35 @@ static void atari_scsi_fetch_restbytes(void)
#endif /* REAL_DMA */
static int falcon_got_lock = 0;
static DECLARE_WAIT_QUEUE_HEAD(falcon_fairness_wait);
static int falcon_trying_lock = 0;
static DECLARE_WAIT_QUEUE_HEAD(falcon_try_wait);
static int falcon_dont_release = 0;
/* This function releases the lock on the DMA chip if there is no
* connected command and the disconnected queue is empty. On
* releasing, instances of falcon_get_lock are awoken, that put
* themselves to sleep for fairness. They can now try to get the lock
* again (but others waiting longer more probably will win).
* connected command and the disconnected queue is empty.
*/
static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata)
static void falcon_release_lock(void)
{
unsigned long flags;
if (IS_A_TT())
return;
local_irq_save(flags);
if (falcon_got_lock && !hostdata->disconnected_queue &&
!hostdata->issue_queue && !hostdata->connected) {
if (falcon_dont_release) {
#if 0
printk("WARNING: Lock release not allowed. Ignored\n");
#endif
local_irq_restore(flags);
return;
}
falcon_got_lock = 0;
if (stdma_is_locked_by(scsi_falcon_intr))
stdma_release();
wake_up(&falcon_fairness_wait);
}
local_irq_restore(flags);
}
/* This function manages the locking of the ST-DMA.
* If the DMA isn't locked already for SCSI, it tries to lock it by
* calling stdma_lock(). But if the DMA is locked by the SCSI code and
* there are other drivers waiting for the chip, we do not issue the
* command immediately but wait on 'falcon_fairness_queue'. We will be
* waked up when the DMA is unlocked by some SCSI interrupt. After that
* we try to get the lock again.
* But we must be prepared that more than one instance of
* falcon_get_lock() is waiting on the fairness queue. They should not
* try all at once to call stdma_lock(), one is enough! For that, the
* first one sets 'falcon_trying_lock', others that see that variable
* set wait on the queue 'falcon_try_wait'.
* Complicated, complicated.... Sigh...
* command immediately but tell the SCSI mid-layer to defer.
*/
static void falcon_get_lock(void)
{
unsigned long flags;
if (IS_A_TT())
return;
local_irq_save(flags);
wait_event_cmd(falcon_fairness_wait,
in_interrupt() || !falcon_got_lock || !stdma_others_waiting(),
local_irq_restore(flags),
local_irq_save(flags));
while (!falcon_got_lock) {
if (in_irq())
panic("Falcon SCSI hasn't ST-DMA lock in interrupt");
if (!falcon_trying_lock) {
falcon_trying_lock = 1;
stdma_lock(scsi_falcon_intr, NULL);
falcon_got_lock = 1;
falcon_trying_lock = 0;
wake_up(&falcon_try_wait);
} else {
wait_event_cmd(falcon_try_wait,
falcon_got_lock && !falcon_trying_lock,
local_irq_restore(flags),
local_irq_save(flags));
}
}
local_irq_restore(flags);
if (!falcon_got_lock)
panic("Falcon SCSI: someone stole the lock :-(\n");
}
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 = DEFAULT_USE_TAGGED_QUEUING;
#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
}
printk(KERN_INFO "scsi%d: options CAN_QUEUE=%d CMD_PER_LUN=%d SCAT-GAT=%d "
#ifdef SUPPORT_TAGS
"TAGGED-QUEUING=%s "
#endif
"HOSTID=%d",
instance->host_no, instance->hostt->can_queue,
instance->hostt->cmd_per_lun,
instance->hostt->sg_tablesize,
#ifdef SUPPORT_TAGS
setup_use_tagged_queuing ? "yes" : "no",
#endif
instance->hostt->this_id );
NCR5380_print_options(instance);
printk("\n");
called = 1;
return 1;
}
static int atari_scsi_release(struct Scsi_Host *sh)
static int falcon_get_lock(struct Scsi_Host *instance)
{
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;
if (in_interrupt())
return stdma_try_lock(scsi_falcon_intr, instance);
stdma_lock(scsi_falcon_intr, instance);
return 1;
}
@ -739,7 +485,7 @@ static int __init atari_scsi_setup(char *str)
{
/* Format of atascsi parameter is:
* 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.
*/
int ints[6];
@ -750,36 +496,17 @@ static int __init atari_scsi_setup(char *str)
printk("atari_scsi_setup: no arguments!\n");
return 0;
}
if (ints[0] >= 1) {
if (ints[1] > 0)
/* no limits on this, just > 0 */
setup_can_queue = ints[1];
}
if (ints[0] >= 2) {
if (ints[2] > 0)
setup_cmd_per_lun = ints[2];
}
if (ints[0] >= 3) {
if (ints[3] >= 0) {
setup_sg_tablesize = ints[3];
/* Must be <= SG_ALL (255) */
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];
else if (ints[4] > 7)
printk("atari_scsi_setup: invalid host ID %d !\n", ints[4]);
}
if (ints[0] >= 1)
setup_can_queue = ints[1];
if (ints[0] >= 2)
setup_cmd_per_lun = ints[2];
if (ints[0] >= 3)
setup_sg_tablesize = ints[3];
if (ints[0] >= 4)
setup_hostid = ints[4];
#ifdef SUPPORT_TAGS
if (ints[0] >= 5) {
if (ints[5] >= 0)
setup_use_tagged_queuing = !!ints[5];
}
if (ints[0] >= 5)
setup_use_tagged_queuing = ints[5];
#endif
return 1;
@ -788,45 +515,6 @@ static int __init atari_scsi_setup(char *str)
__setup("atascsi=", atari_scsi_setup);
#endif /* !MODULE */
static int atari_scsi_bus_reset(Scsi_Cmnd *cmd)
{
int rv;
struct NCR5380_hostdata *hostdata =
(struct NCR5380_hostdata *)cmd->device->host->hostdata;
/* For doing the reset, SCSI interrupts must be disabled first,
* since the 5380 raises its IRQ line while _RST is active and we
* can't disable interrupts completely, since we need the timer.
*/
/* And abort a maybe active DMA transfer */
if (IS_A_TT()) {
atari_turnoff_irq(IRQ_TT_MFP_SCSI);
#ifdef REAL_DMA
tt_scsi_dma.dma_ctrl = 0;
#endif /* REAL_DMA */
} else {
atari_turnoff_irq(IRQ_MFP_FSCSI);
#ifdef REAL_DMA
st_dma.dma_mode_status = 0x90;
atari_dma_active = 0;
atari_dma_orig_addr = NULL;
#endif /* REAL_DMA */
}
rv = NCR5380_bus_reset(cmd);
/* Re-enable ints */
if (IS_A_TT()) {
atari_turnon_irq(IRQ_TT_MFP_SCSI);
} else {
atari_turnon_irq(IRQ_MFP_FSCSI);
}
if (rv == SUCCESS)
falcon_release_lock_if_possible(hostdata);
return rv;
}
#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
static void __init atari_scsi_reset_boot(void)
@ -860,15 +548,6 @@ static void __init atari_scsi_reset_boot(void)
}
#endif
static const char *atari_scsi_info(struct Scsi_Host *host)
{
/* atari_scsi_detect() is verbose enough... */
static const char string[] = "Atari native SCSI";
return string;
}
#if defined(REAL_DMA)
static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
@ -949,7 +628,7 @@ static long atari_scsi_dma_residual(struct Scsi_Host *instance)
#define CMD_SURELY_BYTE_MODE 1
#define CMD_MODE_UNKNOWN 2
static int falcon_classify_cmd(Scsi_Cmnd *cmd)
static int falcon_classify_cmd(struct scsi_cmnd *cmd)
{
unsigned char opcode = cmd->cmnd[0];
@ -981,7 +660,7 @@ static int falcon_classify_cmd(Scsi_Cmnd *cmd)
*/
static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
Scsi_Cmnd *cmd, int write_flag)
struct scsi_cmnd *cmd, int write_flag)
{
unsigned long possible_len, limit;
@ -1099,23 +778,247 @@ static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value)
#include "atari_NCR5380.c"
static struct scsi_host_template driver_template = {
static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
{
int rv;
unsigned long flags;
local_irq_save(flags);
#ifdef REAL_DMA
/* Abort a maybe active DMA transfer */
if (IS_A_TT()) {
tt_scsi_dma.dma_ctrl = 0;
} else {
st_dma.dma_mode_status = 0x90;
atari_dma_active = 0;
atari_dma_orig_addr = NULL;
}
#endif
rv = NCR5380_bus_reset(cmd);
/* The 5380 raises its IRQ line while _RST is active but the ST DMA
* "lock" has been released so this interrupt may end up handled by
* floppy or IDE driver (if one of them holds the lock). The NCR5380
* interrupt flag has been cleared already.
*/
local_irq_restore(flags);
return rv;
}
#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,
.name = "Atari native SCSI",
.detect = atari_scsi_detect,
.release = atari_scsi_release,
.info = atari_scsi_info,
.queuecommand = atari_scsi_queue_command,
.eh_abort_handler = atari_scsi_abort,
.eh_bus_reset_handler = atari_scsi_bus_reset,
.can_queue = 0, /* initialized at run-time */
.this_id = 0, /* initialized at run-time */
.sg_tablesize = 0, /* initialized at run-time */
.cmd_per_lun = 0, /* initialized at run-time */
.this_id = 7,
.use_clustering = DISABLE_CLUSTERING
};
static int __init atari_scsi_probe(struct platform_device *pdev)
{
struct Scsi_Host *instance;
int error;
struct resource *irq;
int host_flags = 0;
#include "scsi_module.c"
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 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;
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
NCR5380_init(instance, host_flags);
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 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) {
struct NCR5380_hostdata *hostdata =
shost_priv(instance);
hostdata->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,
},
};
module_platform_driver_probe(atari_scsi_driver, atari_scsi_probe);
MODULE_ALIAS("platform:" DRV_MODULE_NAME);
MODULE_LICENSE("GPL");

View file

@ -1,60 +0,0 @@
/*
* atari_scsi.h -- Header file for the Atari native SCSI driver
*
* Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
*
* (Loosely based on the work of Robert De Vries' team)
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*
*/
#ifndef ATARI_SCSI_H
#define ATARI_SCSI_H
/* (I_HAVE_OVERRUNS stuff removed) */
#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 DEFAULT_USE_TAGGED_QUEUING 0
#define NCR5380_implementation_fields /* none */
#define NCR5380_read(reg) atari_scsi_reg_read( reg )
#define NCR5380_write(reg, value) atari_scsi_reg_write( reg, value )
#define NCR5380_intr atari_scsi_intr
#define NCR5380_queue_command atari_scsi_queue_command
#define NCR5380_abort atari_scsi_abort
#define NCR5380_show_info atari_scsi_show_info
#define NCR5380_dma_read_setup(inst,d,c) atari_scsi_dma_setup (inst, d, c, 0)
#define NCR5380_dma_write_setup(inst,d,c) atari_scsi_dma_setup (inst, d, c, 1)
#define NCR5380_dma_residual(inst) atari_scsi_dma_residual( inst )
#define NCR5380_dma_xfer_len(i,cmd,phase) \
atari_dma_xfer_len(cmd->SCp.this_residual,cmd,((phase) & SR_IO) ? 0 : 1)
#endif /* ndef ASM */
#endif /* ATARI_SCSI_H */

View file

@ -556,7 +556,7 @@ static struct scsi_host_template beiscsi_sht = {
.name = "Emulex 10Gbe open-iscsi Initiator Driver",
.proc_name = DRV_NAME,
.queuecommand = iscsi_queuecommand,
.change_queue_depth = iscsi_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.slave_configure = beiscsi_slave_configure,
.target_alloc = iscsi_target_alloc,
.eh_abort_handler = beiscsi_eh_abort,
@ -570,7 +570,7 @@ static struct scsi_host_template beiscsi_sht = {
.cmd_per_lun = BEISCSI_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.vendor_id = SCSI_NL_VID_TYPE_PCI | BE_VENDOR_ID,
.track_queue_depth = 1,
};
static struct scsi_transport_template *beiscsi_scsi_transport;

View file

@ -260,18 +260,9 @@ bfad_debugfs_write_regrd(struct file *file, const char __user *buf,
unsigned long flags;
void *kern_buf;
kern_buf = kzalloc(nbytes, GFP_KERNEL);
if (!kern_buf) {
printk(KERN_INFO "bfad[%d]: Failed to allocate buffer\n",
bfad->inst_no);
return -ENOMEM;
}
if (copy_from_user(kern_buf, (void __user *)buf, nbytes)) {
kfree(kern_buf);
return -ENOMEM;
}
kern_buf = memdup_user(buf, nbytes);
if (IS_ERR(kern_buf))
return PTR_ERR(kern_buf);
rc = sscanf(kern_buf, "%x:%x", &addr, &len);
if (rc < 2) {
@ -336,18 +327,9 @@ bfad_debugfs_write_regwr(struct file *file, const char __user *buf,
unsigned long flags;
void *kern_buf;
kern_buf = kzalloc(nbytes, GFP_KERNEL);
if (!kern_buf) {
printk(KERN_INFO "bfad[%d]: Failed to allocate buffer\n",
bfad->inst_no);
return -ENOMEM;
}
if (copy_from_user(kern_buf, (void __user *)buf, nbytes)) {
kfree(kern_buf);
return -ENOMEM;
}
kern_buf = memdup_user(buf, nbytes);
if (IS_ERR(kern_buf))
return PTR_ERR(kern_buf);
rc = sscanf(kern_buf, "%x:%x", &addr, &val);
if (rc < 2) {

View file

@ -776,7 +776,7 @@ bfad_thread_workq(struct bfad_s *bfad)
static int
bfad_im_slave_configure(struct scsi_device *sdev)
{
scsi_adjust_queue_depth(sdev, bfa_lun_queue_depth);
scsi_change_queue_depth(sdev, bfa_lun_queue_depth);
return 0;
}
@ -866,7 +866,7 @@ bfad_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
if (bfa_lun_queue_depth > tmp_sdev->queue_depth) {
if (tmp_sdev->id != sdev->id)
continue;
scsi_adjust_queue_depth(tmp_sdev,
scsi_change_queue_depth(tmp_sdev,
tmp_sdev->queue_depth + 1);
itnim->last_ramp_up_time = jiffies;

View file

@ -1088,7 +1088,7 @@ static int bnx2fc_vport_create(struct fc_vport *vport, bool disabled)
mutex_unlock(&bnx2fc_dev_lock);
rtnl_unlock();
if (IS_ERR(vn_port)) {
if (!vn_port) {
printk(KERN_ERR PFX "bnx2fc_vport_create (%s) failed\n",
netdev->name);
return -EIO;
@ -2202,6 +2202,7 @@ static int _bnx2fc_create(struct net_device *netdev,
interface = bnx2fc_interface_create(hba, netdev, fip_mode);
if (!interface) {
printk(KERN_ERR PFX "bnx2fc_interface_create failed\n");
rc = -ENOMEM;
goto ifput_err;
}
@ -2790,7 +2791,7 @@ static struct scsi_host_template bnx2fc_shost_template = {
.eh_target_reset_handler = bnx2fc_eh_target_reset, /* tgt reset */
.eh_host_reset_handler = fc_eh_host_reset,
.slave_alloc = fc_slave_alloc,
.change_queue_depth = fc_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.change_queue_type = scsi_change_queue_type,
.this_id = -1,
.cmd_per_lun = 3,
@ -2798,6 +2799,7 @@ static struct scsi_host_template bnx2fc_shost_template = {
.sg_tablesize = BNX2FC_MAX_BDS_PER_CMD,
.max_sectors = 1024,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
static struct libfc_function_template bnx2fc_libfc_fcn_templ = {

View file

@ -2259,7 +2259,7 @@ static struct scsi_host_template bnx2i_host_template = {
.eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler = iscsi_eh_device_reset,
.eh_target_reset_handler = iscsi_eh_recover_target,
.change_queue_depth = iscsi_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.target_alloc = iscsi_target_alloc,
.can_queue = 2048,
.max_sectors = 127,
@ -2268,6 +2268,7 @@ static struct scsi_host_template bnx2i_host_template = {
.use_clustering = ENABLE_CLUSTERING,
.sg_tablesize = ISCSI_MAX_BDS_PER_CMD,
.shost_attrs = bnx2i_dev_attributes,
.track_queue_depth = 1,
};
struct iscsi_transport bnx2i_iscsi_transport = {

View file

@ -2241,7 +2241,7 @@ csio_slave_alloc(struct scsi_device *sdev)
static int
csio_slave_configure(struct scsi_device *sdev)
{
scsi_adjust_queue_depth(sdev, csio_lun_qdepth);
scsi_change_queue_depth(sdev, csio_lun_qdepth);
return 0;
}

View file

@ -86,7 +86,7 @@ static struct scsi_host_template cxgb3i_host_template = {
.proc_name = DRV_MODULE_NAME,
.can_queue = CXGB3I_SCSI_HOST_QDEPTH,
.queuecommand = iscsi_queuecommand,
.change_queue_depth = iscsi_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.sg_tablesize = SG_ALL,
.max_sectors = 0xFFFF,
.cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
@ -96,6 +96,7 @@ static struct scsi_host_template cxgb3i_host_template = {
.target_alloc = iscsi_target_alloc,
.use_clustering = DISABLE_CLUSTERING,
.this_id = -1,
.track_queue_depth = 1,
};
static struct iscsi_transport cxgb3i_iscsi_transport = {

View file

@ -89,7 +89,7 @@ static struct scsi_host_template cxgb4i_host_template = {
.proc_name = DRV_MODULE_NAME,
.can_queue = CXGB4I_SCSI_HOST_QDEPTH,
.queuecommand = iscsi_queuecommand,
.change_queue_depth = iscsi_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.sg_tablesize = SG_ALL,
.max_sectors = 0xFFFF,
.cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
@ -99,6 +99,7 @@ static struct scsi_host_template cxgb4i_host_template = {
.target_alloc = iscsi_target_alloc,
.use_clustering = DISABLE_CLUSTERING,
.this_id = -1,
.track_queue_depth = 1,
};
static struct iscsi_transport cxgb4i_iscsi_transport = {

View file

@ -33,20 +33,20 @@
/*
* Definitions for the generic 5380 driver.
*/
#define AUTOSENSE
#define DONT_USE_INTR
#define NCR5380_read(reg) inb(port + reg)
#define NCR5380_write(reg, value) outb(value, port + reg)
#define NCR5380_implementation_fields unsigned int port
#define NCR5380_local_declare() NCR5380_implementation_fields
#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 "scsi.h"
#include "NCR5380.h"
#include "NCR5380.c"
@ -58,6 +58,7 @@
static struct scsi_host_template dmx3191d_driver_template = {
.proc_name = DMX3191D_DRIVER_NAME,
.name = "Domex DMX3191D",
.info = NCR5380_info,
.queuecommand = NCR5380_queue_command,
.eh_abort_handler = NCR5380_abort,
.eh_bus_reset_handler = NCR5380_bus_reset,
@ -90,31 +91,23 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
if (!shost)
goto out_release_region;
shost->io_port = io;
shost->irq = pdev->irq;
/* This card does not seem to raise an interrupt on pdev->irq.
* Steam-powered SCSI controllers run without an IRQ anyway.
*/
shost->irq = NO_IRQ;
NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
if (request_irq(pdev->irq, NCR5380_intr, IRQF_SHARED,
DMX3191D_DRIVER_NAME, shost)) {
/*
* Steam powered scsi controllers run without an IRQ anyway
*/
printk(KERN_WARNING "dmx3191: IRQ %d not available - "
"switching to polled mode.\n", pdev->irq);
shost->irq = SCSI_IRQ_NONE;
}
pci_set_drvdata(pdev, shost);
error = scsi_add_host(shost, &pdev->dev);
if (error)
goto out_free_irq;
goto out_release_region;
scsi_scan_host(shost);
return 0;
out_free_irq:
free_irq(shost->irq, shost);
out_release_region:
release_region(io, DMX3191D_REGION_LEN);
out_disable_device:
@ -131,8 +124,6 @@ static void dmx3191d_remove_one(struct pci_dev *pdev)
NCR5380_exit(shost);
if (shost->irq != SCSI_IRQ_NONE)
free_irq(shost->irq, shost);
release_region(shost->io_port, DMX3191D_REGION_LEN);
pci_disable_device(pdev);

View file

@ -415,7 +415,7 @@ static int adpt_slave_configure(struct scsi_device * device)
pHba = (adpt_hba *) host->hostdata[0];
if (host->can_queue && device->tagged_supported) {
scsi_adjust_queue_depth(device,
scsi_change_queue_depth(device,
host->can_queue - 1);
}
return 0;

View file

@ -1,5 +1,4 @@
#define AUTOSENSE
#define PSEUDO_DMA
#define DONT_USE_INTR
#define UNSAFE /* Leave interrupts enabled during pseudo-dma I/O */
@ -18,29 +17,9 @@
* (Unix and Linux consulting and custom programming)
* drew@colorado.edu
* +1 (303) 440-4894
*
* DISTRIBUTION RELEASE 1.
*
* For more information, please consult
*
* NCR 5380 Family
* SCSI Protocol Controller
* Databook
*/
*/
/*
* Options :
* AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
* for commands that return with a CHECK CONDITION status.
*
* PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
* increase compared to polled I/O.
*
* PARITY - enable parity checking. Not supported.
*
* UNSAFE - leave interrupts enabled during pseudo-DMA transfers.
* You probably want this.
*
* The card is detected and initialized in one of several ways :
* 1. Autoprobe (default) - since the board is memory mapped,
* a BIOS signature is scanned for to locate the registers.
@ -79,15 +58,11 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "dtc.h"
#define AUTOPROBE_IRQ
#include "NCR5380.h"
#define DTC_PUBLIC_RELEASE 2
/*
* The DTC3180 & 3280 boards are memory mapped.
*
@ -173,10 +148,13 @@ static const struct signature {
*
*/
static void __init dtc_setup(char *str, int *ints)
static int __init dtc_setup(char *str)
{
static int commandline_current = 0;
int i;
int ints[10];
get_options(str, ARRAY_SIZE(ints), ints);
if (ints[0] != 2)
printk("dtc_setup: usage dtc=address,irq\n");
else if (commandline_current < NO_OVERRIDES) {
@ -189,7 +167,10 @@ static void __init dtc_setup(char *str, int *ints)
}
++commandline_current;
}
return 1;
}
__setup("dtc=", dtc_setup);
#endif
/*
@ -213,10 +194,6 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
void __iomem *base;
int sig, count;
tpnt->proc_name = "dtc3x80";
tpnt->show_info = dtc_show_info;
tpnt->write_info = dtc_write_info;
for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
addr = 0;
base = NULL;
@ -271,38 +248,33 @@ found:
else
instance->irq = NCR5380_probe_irq(instance, DTC_IRQS);
/* Compatibility with documented NCR5380 kernel parameters */
if (instance->irq == 255)
instance->irq = NO_IRQ;
#ifndef DONT_USE_INTR
/* With interrupts enabled, it will sometimes hang when doing heavy
* reads. So better not enable them until I finger it out. */
if (instance->irq != SCSI_IRQ_NONE)
if (instance->irq != NO_IRQ)
if (request_irq(instance->irq, dtc_intr, 0,
"dtc", instance)) {
printk(KERN_ERR "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
instance->irq = SCSI_IRQ_NONE;
instance->irq = NO_IRQ;
}
if (instance->irq == SCSI_IRQ_NONE) {
if (instance->irq == NO_IRQ) {
printk(KERN_WARNING "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
printk(KERN_WARNING "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
}
#else
if (instance->irq != SCSI_IRQ_NONE)
if (instance->irq != NO_IRQ)
printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
instance->irq = SCSI_IRQ_NONE;
instance->irq = NO_IRQ;
#endif
#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
#endif
printk(KERN_INFO "scsi%d : at 0x%05X", instance->host_no, (int) instance->base);
if (instance->irq == SCSI_IRQ_NONE)
printk(" interrupts disabled");
else
printk(" irq %d", instance->irq);
printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, DTC_PUBLIC_RELEASE);
NCR5380_print_options(instance);
printk("\n");
++current_override;
++count;
}
@ -354,20 +326,18 @@ static int dtc_biosparam(struct scsi_device *sdev, struct block_device *dev,
* timeout.
*/
static int dtc_maxi = 0;
static int dtc_wmaxi = 0;
static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
{
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 == SCSI_IRQ_NONE)
if (instance->irq == NO_IRQ)
NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
else
NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ | CSR_INT_BASE);
@ -391,8 +361,8 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
rtrc(0);
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
if (i > dtc_maxi)
dtc_maxi = i;
if (i > hostdata->spin_max_r)
hostdata->spin_max_r = i;
return (0);
}
@ -412,13 +382,14 @@ 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)
{
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 == SCSI_IRQ_NONE)
if (instance->irq == NO_IRQ)
NCR5380_write(DTC_CONTROL_REG, 0);
else
NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);
@ -444,8 +415,8 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
/* Check for parity error here. fixme. */
NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
rtrc(0);
if (i > dtc_wmaxi)
dtc_wmaxi = i;
if (i > hostdata->spin_max_w)
hostdata->spin_max_w = i;
return (0);
}
@ -457,7 +428,7 @@ static int dtc_release(struct Scsi_Host *shost)
{
NCR5380_local_declare();
NCR5380_setup(shost);
if (shost->irq)
if (shost->irq != NO_IRQ)
free_irq(shost->irq, shost);
NCR5380_exit(shost);
if (shost->io_port && shost->n_io_port)
@ -471,6 +442,10 @@ 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,

View file

@ -5,24 +5,6 @@
* (Unix and Linux consulting and custom programming)
* drew@colorado.edu
* +1 (303) 440-4894
*
* DISTRIBUTION RELEASE 2.
*
* For more information, please consult
*
*
*
* and
*
* NCR 5380 Family
* SCSI Protocol Controller
* Databook
*
* NCR Microelectronics
* 1635 Aeroplaza Drive
* Colorado Springs, CO 80916
* 1+ (719) 578-3400
* 1+ (800) 334-5454
*/
#ifndef DTC3280_H
@ -32,13 +14,6 @@
#define DTCDEBUG_INIT 0x1
#define DTCDEBUG_TRANSFER 0x2
static int dtc_abort(Scsi_Cmnd *);
static int dtc_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
static int dtc_detect(struct scsi_host_template *);
static int dtc_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int dtc_bus_reset(Scsi_Cmnd *);
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
@ -88,6 +63,7 @@ static int dtc_bus_reset(Scsi_Cmnd *);
#define NCR5380_queue_command dtc_queue_command
#define NCR5380_abort dtc_abort
#define NCR5380_bus_reset dtc_bus_reset
#define NCR5380_info dtc_info
#define NCR5380_show_info dtc_show_info
#define NCR5380_write_info dtc_write_info

View file

@ -952,12 +952,12 @@ static int eata2x_slave_configure(struct scsi_device *dev)
} else {
tag_suffix = ", no tags";
}
scsi_adjust_queue_depth(dev, tqd);
scsi_change_queue_depth(dev, tqd);
} else if (TLDEV(dev->type) && linked_comm) {
scsi_adjust_queue_depth(dev, tqd);
scsi_change_queue_depth(dev, tqd);
tag_suffix = ", untagged";
} else {
scsi_adjust_queue_depth(dev, utqd);
scsi_change_queue_depth(dev, utqd);
tag_suffix = "";
}

View file

@ -972,7 +972,6 @@ u8 handle_hba_ioctl(struct esas2r_adapter *a,
struct atto_ioctl *ioctl_hba);
int esas2r_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd);
int esas2r_show_info(struct seq_file *m, struct Scsi_Host *sh);
int esas2r_change_queue_depth(struct scsi_device *dev, int depth, int reason);
long esas2r_proc_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
/* SCSI error handler (eh) functions */

View file

@ -117,9 +117,8 @@ static void do_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi)
rq = esas2r_alloc_request(a);
if (rq == NULL) {
up(&a->fm_api_semaphore);
fi->status = FI_STAT_BUSY;
return;
goto free_sem;
}
if (fi == &a->firmware.header) {
@ -135,7 +134,7 @@ static void do_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi)
if (a->firmware.header_buff == NULL) {
esas2r_debug("failed to allocate header buffer!");
fi->status = FI_STAT_BUSY;
return;
goto free_req;
}
memcpy(a->firmware.header_buff, fi,
@ -171,9 +170,10 @@ all_done:
a->firmware.header_buff,
(dma_addr_t)a->firmware.header_buff_phys);
}
up(&a->fm_api_semaphore);
free_req:
esas2r_free_request(a, (struct esas2r_request *)rq);
free_sem:
up(&a->fm_api_semaphore);
return;
}
@ -1420,9 +1420,10 @@ int esas2r_ioctl_handler(void *hostdata, int cmd, void __user *arg)
rq = esas2r_alloc_request(a);
if (rq == NULL) {
up(&a->nvram_semaphore);
ioctl->data.prw.code = 0;
break;
kfree(ioctl);
esas2r_log(ESAS2R_LOG_WARN,
"could not allocate an internal request");
return -ENOMEM;
}
code = esas2r_write_params(a, rq,
@ -1523,9 +1524,12 @@ ioctl_done:
case -EINVAL:
ioctl->header.return_code = IOCTL_INVALID_PARAM;
break;
default:
ioctl->header.return_code = IOCTL_GENERAL_ERROR;
break;
}
ioctl->header.return_code = IOCTL_GENERAL_ERROR;
}
/* Always copy the buffer back, if only to pick up the status */

View file

@ -254,7 +254,7 @@ static struct scsi_host_template driver_template = {
.use_clustering = ENABLE_CLUSTERING,
.emulated = 0,
.proc_name = ESAS2R_DRVR_NAME,
.change_queue_depth = esas2r_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.change_queue_type = scsi_change_queue_type,
.max_sectors = 0xFFFF,
.use_blk_tags = 1,
@ -1257,15 +1257,6 @@ int esas2r_target_reset(struct scsi_cmnd *cmd)
return esas2r_dev_targ_reset(cmd, true);
}
int esas2r_change_queue_depth(struct scsi_device *dev, int depth, int reason)
{
esas2r_log(ESAS2R_LOG_INFO, "change_queue_depth %p, %d", dev, depth);
scsi_adjust_queue_depth(dev, depth);
return dev->queue_depth;
}
void esas2r_log_request_failure(struct esas2r_adapter *a,
struct esas2r_request *rq)
{

View file

@ -49,55 +49,67 @@ static u32 esp_debug;
#define ESP_DEBUG_DATADONE 0x00000100
#define ESP_DEBUG_RECONNECT 0x00000200
#define ESP_DEBUG_AUTOSENSE 0x00000400
#define ESP_DEBUG_EVENT 0x00000800
#define ESP_DEBUG_COMMAND 0x00001000
#define esp_log_intr(f, a...) \
do { if (esp_debug & ESP_DEBUG_INTR) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_reset(f, a...) \
do { if (esp_debug & ESP_DEBUG_RESET) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_msgin(f, a...) \
do { if (esp_debug & ESP_DEBUG_MSGIN) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_msgout(f, a...) \
do { if (esp_debug & ESP_DEBUG_MSGOUT) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_cmddone(f, a...) \
do { if (esp_debug & ESP_DEBUG_CMDDONE) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_disconnect(f, a...) \
do { if (esp_debug & ESP_DEBUG_DISCONNECT) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_datastart(f, a...) \
do { if (esp_debug & ESP_DEBUG_DATASTART) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_datadone(f, a...) \
do { if (esp_debug & ESP_DEBUG_DATADONE) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_reconnect(f, a...) \
do { if (esp_debug & ESP_DEBUG_RECONNECT) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_autosense(f, a...) \
do { if (esp_debug & ESP_DEBUG_AUTOSENSE) \
printk(f, ## a); \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_event(f, a...) \
do { if (esp_debug & ESP_DEBUG_EVENT) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_log_command(f, a...) \
do { if (esp_debug & ESP_DEBUG_COMMAND) \
shost_printk(KERN_DEBUG, esp->host, f, ## a); \
} while (0)
#define esp_read8(REG) esp->ops->esp_read8(esp, REG)
@ -126,10 +138,29 @@ void scsi_esp_cmd(struct esp *esp, u8 val)
esp->esp_event_cur = (idx + 1) & (ESP_EVENT_LOG_SZ - 1);
esp_log_command("cmd[%02x]\n", val);
esp_write8(val, ESP_CMD);
}
EXPORT_SYMBOL(scsi_esp_cmd);
static void esp_send_dma_cmd(struct esp *esp, int len, int max_len, int cmd)
{
if (esp->flags & ESP_FLAG_USE_FIFO) {
int i;
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
for (i = 0; i < len; i++)
esp_write8(esp->command_block[i], ESP_FDATA);
scsi_esp_cmd(esp, cmd);
} else {
if (esp->rev == FASHME)
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
cmd |= ESP_CMD_DMA;
esp->ops->send_dma_cmd(esp, esp->command_block_dma,
len, max_len, 0, cmd);
}
}
static void esp_event(struct esp *esp, u8 val)
{
struct esp_event_ent *p;
@ -150,19 +181,17 @@ static void esp_dump_cmd_log(struct esp *esp)
int idx = esp->esp_event_cur;
int stop = idx;
printk(KERN_INFO PFX "esp%d: Dumping command log\n",
esp->host->unique_id);
shost_printk(KERN_INFO, esp->host, "Dumping command log\n");
do {
struct esp_event_ent *p = &esp->esp_event_log[idx];
printk(KERN_INFO PFX "esp%d: ent[%d] %s ",
esp->host->unique_id, idx,
p->type == ESP_EVENT_TYPE_CMD ? "CMD" : "EVENT");
printk("val[%02x] sreg[%02x] seqreg[%02x] "
"sreg2[%02x] ireg[%02x] ss[%02x] event[%02x]\n",
p->val, p->sreg, p->seqreg,
p->sreg2, p->ireg, p->select_state, p->event);
shost_printk(KERN_INFO, esp->host,
"ent[%d] %s val[%02x] sreg[%02x] seqreg[%02x] "
"sreg2[%02x] ireg[%02x] ss[%02x] event[%02x]\n",
idx,
p->type == ESP_EVENT_TYPE_CMD ? "CMD" : "EVENT",
p->val, p->sreg, p->seqreg,
p->sreg2, p->ireg, p->select_state, p->event);
idx = (idx + 1) & (ESP_EVENT_LOG_SZ - 1);
} while (idx != stop);
@ -176,9 +205,8 @@ static void esp_flush_fifo(struct esp *esp)
while (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES) {
if (--lim == 0) {
printk(KERN_ALERT PFX "esp%d: ESP_FF_BYTES "
"will not clear!\n",
esp->host->unique_id);
shost_printk(KERN_ALERT, esp->host,
"ESP_FF_BYTES will not clear!\n");
break;
}
udelay(1);
@ -240,6 +268,19 @@ static void esp_reset_esp(struct esp *esp)
} else {
esp->min_period = ((5 * esp->ccycle) / 1000);
}
if (esp->rev == FAS236) {
/*
* The AM53c974 chip returns the same ID as FAS236;
* try to configure glitch eater.
*/
u8 config4 = ESP_CONFIG4_GE1;
esp_write8(config4, ESP_CFG4);
config4 = esp_read8(ESP_CFG4);
if (config4 & ESP_CONFIG4_GE1) {
esp->rev = PCSCSI;
esp_write8(esp->config4, ESP_CFG4);
}
}
esp->max_period = (esp->max_period + 3)>>2;
esp->min_period = (esp->min_period + 3)>>2;
@ -265,7 +306,8 @@ static void esp_reset_esp(struct esp *esp)
/* fallthrough... */
case FAS236:
/* Fast 236 or HME */
case PCSCSI:
/* Fast 236, AM53c974 or HME */
esp_write8(esp->config2, ESP_CFG2);
if (esp->rev == FASHME) {
u8 cfg3 = esp->target[0].esp_config3;
@ -383,12 +425,11 @@ static void esp_advance_dma(struct esp *esp, struct esp_cmd_entry *ent,
p->cur_residue -= len;
p->tot_residue -= len;
if (p->cur_residue < 0 || p->tot_residue < 0) {
printk(KERN_ERR PFX "esp%d: Data transfer overflow.\n",
esp->host->unique_id);
printk(KERN_ERR PFX "esp%d: cur_residue[%d] tot_residue[%d] "
"len[%u]\n",
esp->host->unique_id,
p->cur_residue, p->tot_residue, len);
shost_printk(KERN_ERR, esp->host,
"Data transfer overflow.\n");
shost_printk(KERN_ERR, esp->host,
"cur_residue[%d] tot_residue[%d] len[%u]\n",
p->cur_residue, p->tot_residue, len);
p->cur_residue = 0;
p->tot_residue = 0;
}
@ -604,9 +645,8 @@ static void esp_autosense(struct esp *esp, struct esp_cmd_entry *ent)
if (!ent->sense_ptr) {
esp_log_autosense("esp%d: Doing auto-sense for "
"tgt[%d] lun[%d]\n",
esp->host->unique_id, tgt, lun);
esp_log_autosense("Doing auto-sense for tgt[%d] lun[%d]\n",
tgt, lun);
ent->sense_ptr = cmd->sense_buffer;
ent->sense_dma = esp->ops->map_single(esp,
@ -642,10 +682,7 @@ static void esp_autosense(struct esp *esp, struct esp_cmd_entry *ent)
val = (p - esp->command_block);
if (esp->rev == FASHME)
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
esp->ops->send_dma_cmd(esp, esp->command_block_dma,
val, 16, 0, ESP_CMD_DMA | ESP_CMD_SELA);
esp_send_dma_cmd(esp, val, 16, ESP_CMD_SELA);
}
static struct esp_cmd_entry *find_and_prep_issuable_command(struct esp *esp)
@ -781,12 +818,12 @@ build_identify:
}
if (!(esp->flags & ESP_FLAG_DOING_SLOWCMD)) {
start_cmd = ESP_CMD_DMA | ESP_CMD_SELA;
start_cmd = ESP_CMD_SELA;
if (ent->tag[0]) {
*p++ = ent->tag[0];
*p++ = ent->tag[1];
start_cmd = ESP_CMD_DMA | ESP_CMD_SA3;
start_cmd = ESP_CMD_SA3;
}
for (i = 0; i < cmd->cmd_len; i++)
@ -806,7 +843,7 @@ build_identify:
esp->msg_out_len += 2;
}
start_cmd = ESP_CMD_DMA | ESP_CMD_SELAS;
start_cmd = ESP_CMD_SELAS;
esp->select_state = ESP_SELECT_MSGOUT;
}
val = tgt;
@ -826,10 +863,7 @@ build_identify:
printk("]\n");
}
if (esp->rev == FASHME)
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
esp->ops->send_dma_cmd(esp, esp->command_block_dma,
val, 16, 0, start_cmd);
esp_send_dma_cmd(esp, val, 16, start_cmd);
}
static struct esp_cmd_entry *esp_get_ent(struct esp *esp)
@ -953,8 +987,8 @@ static int esp_check_gross_error(struct esp *esp)
* - DMA programmed with wrong direction
* - improper phase change
*/
printk(KERN_ERR PFX "esp%d: Gross error sreg[%02x]\n",
esp->host->unique_id, esp->sreg);
shost_printk(KERN_ERR, esp->host,
"Gross error sreg[%02x]\n", esp->sreg);
/* XXX Reset the chip. XXX */
return 1;
}
@ -974,7 +1008,6 @@ static int esp_check_spur_intr(struct esp *esp)
default:
if (!(esp->sreg & ESP_STAT_INTR)) {
esp->ireg = esp_read8(ESP_INTRPT);
if (esp->ireg & ESP_INTR_SR)
return 1;
@ -982,14 +1015,13 @@ static int esp_check_spur_intr(struct esp *esp)
* ESP is not, the only possibility is a DMA error.
*/
if (!esp->ops->dma_error(esp)) {
printk(KERN_ERR PFX "esp%d: Spurious irq, "
"sreg=%02x.\n",
esp->host->unique_id, esp->sreg);
shost_printk(KERN_ERR, esp->host,
"Spurious irq, sreg=%02x.\n",
esp->sreg);
return -1;
}
printk(KERN_ERR PFX "esp%d: DMA error\n",
esp->host->unique_id);
shost_printk(KERN_ERR, esp->host, "DMA error\n");
/* XXX Reset the chip. XXX */
return -1;
@ -1002,7 +1034,7 @@ static int esp_check_spur_intr(struct esp *esp)
static void esp_schedule_reset(struct esp *esp)
{
esp_log_reset("ESP: esp_schedule_reset() from %pf\n",
esp_log_reset("esp_schedule_reset() from %pf\n",
__builtin_return_address(0));
esp->flags |= ESP_FLAG_RESETTING;
esp_event(esp, ESP_EVENT_RESET);
@ -1019,20 +1051,20 @@ static struct esp_cmd_entry *esp_reconnect_with_tag(struct esp *esp,
int i;
if (!lp->num_tagged) {
printk(KERN_ERR PFX "esp%d: Reconnect w/num_tagged==0\n",
esp->host->unique_id);
shost_printk(KERN_ERR, esp->host,
"Reconnect w/num_tagged==0\n");
return NULL;
}
esp_log_reconnect("ESP: reconnect tag, ");
esp_log_reconnect("reconnect tag, ");
for (i = 0; i < ESP_QUICKIRQ_LIMIT; i++) {
if (esp->ops->irq_pending(esp))
break;
}
if (i == ESP_QUICKIRQ_LIMIT) {
printk(KERN_ERR PFX "esp%d: Reconnect IRQ1 timeout\n",
esp->host->unique_id);
shost_printk(KERN_ERR, esp->host,
"Reconnect IRQ1 timeout\n");
return NULL;
}
@ -1043,14 +1075,14 @@ static struct esp_cmd_entry *esp_reconnect_with_tag(struct esp *esp,
i, esp->ireg, esp->sreg);
if (esp->ireg & ESP_INTR_DC) {
printk(KERN_ERR PFX "esp%d: Reconnect, got disconnect.\n",
esp->host->unique_id);
shost_printk(KERN_ERR, esp->host,
"Reconnect, got disconnect.\n");
return NULL;
}
if ((esp->sreg & ESP_STAT_PMASK) != ESP_MIP) {
printk(KERN_ERR PFX "esp%d: Reconnect, not MIP sreg[%02x].\n",
esp->host->unique_id, esp->sreg);
shost_printk(KERN_ERR, esp->host,
"Reconnect, not MIP sreg[%02x].\n", esp->sreg);
return NULL;
}
@ -1073,8 +1105,7 @@ static struct esp_cmd_entry *esp_reconnect_with_tag(struct esp *esp,
udelay(1);
}
if (i == ESP_RESELECT_TAG_LIMIT) {
printk(KERN_ERR PFX "esp%d: Reconnect IRQ2 timeout\n",
esp->host->unique_id);
shost_printk(KERN_ERR, esp->host, "Reconnect IRQ2 timeout\n");
return NULL;
}
esp->ops->dma_drain(esp);
@ -1087,17 +1118,17 @@ static struct esp_cmd_entry *esp_reconnect_with_tag(struct esp *esp,
if (esp->command_block[0] < SIMPLE_QUEUE_TAG ||
esp->command_block[0] > ORDERED_QUEUE_TAG) {
printk(KERN_ERR PFX "esp%d: Reconnect, bad tag "
"type %02x.\n",
esp->host->unique_id, esp->command_block[0]);
shost_printk(KERN_ERR, esp->host,
"Reconnect, bad tag type %02x.\n",
esp->command_block[0]);
return NULL;
}
ent = lp->tagged_cmds[esp->command_block[1]];
if (!ent) {
printk(KERN_ERR PFX "esp%d: Reconnect, no entry for "
"tag %02x.\n",
esp->host->unique_id, esp->command_block[1]);
shost_printk(KERN_ERR, esp->host,
"Reconnect, no entry for tag %02x.\n",
esp->command_block[1]);
return NULL;
}
@ -1163,9 +1194,9 @@ static int esp_reconnect(struct esp *esp)
tp = &esp->target[target];
dev = __scsi_device_lookup_by_target(tp->starget, lun);
if (!dev) {
printk(KERN_ERR PFX "esp%d: Reconnect, no lp "
"tgt[%u] lun[%u]\n",
esp->host->unique_id, target, lun);
shost_printk(KERN_ERR, esp->host,
"Reconnect, no lp tgt[%u] lun[%u]\n",
target, lun);
goto do_reset;
}
lp = dev->hostdata;
@ -1291,8 +1322,8 @@ static int esp_finish_select(struct esp *esp)
return 0;
}
printk("ESP: Unexpected selection completion ireg[%x].\n",
esp->ireg);
shost_printk(KERN_INFO, esp->host,
"Unexpected selection completion ireg[%x]\n", esp->ireg);
esp_schedule_reset(esp);
return 0;
}
@ -1312,11 +1343,42 @@ static int esp_data_bytes_sent(struct esp *esp, struct esp_cmd_entry *ent,
(((unsigned int)esp_read8(ESP_TCMED)) << 8));
if (esp->rev == FASHME)
ecount |= ((unsigned int)esp_read8(FAS_RLO)) << 16;
if (esp->rev == PCSCSI && (esp->config2 & ESP_CONFIG2_FENAB))
ecount |= ((unsigned int)esp_read8(ESP_TCHI)) << 16;
}
bytes_sent = esp->data_dma_len;
bytes_sent -= ecount;
/*
* The am53c974 has a DMA 'pecularity'. The doc states:
* In some odd byte conditions, one residual byte will
* be left in the SCSI FIFO, and the FIFO Flags will
* never count to '0 '. When this happens, the residual
* byte should be retrieved via PIO following completion
* of the BLAST operation.
*/
if (fifo_cnt == 1 && ent->flags & ESP_CMD_FLAG_RESIDUAL) {
size_t count = 1;
size_t offset = bytes_sent;
u8 bval = esp_read8(ESP_FDATA);
if (ent->flags & ESP_CMD_FLAG_AUTOSENSE)
ent->sense_ptr[bytes_sent] = bval;
else {
struct esp_cmd_priv *p = ESP_CMD_PRIV(cmd);
u8 *ptr;
ptr = scsi_kmap_atomic_sg(p->cur_sg, p->u.num_sg,
&offset, &count);
if (likely(ptr)) {
*(ptr + offset) = bval;
scsi_kunmap_atomic_sg(ptr);
}
}
bytes_sent += fifo_cnt;
ent->flags &= ~ESP_CMD_FLAG_RESIDUAL;
}
if (!(ent->flags & ESP_CMD_FLAG_WRITE))
bytes_sent -= fifo_cnt;
@ -1556,8 +1618,8 @@ static void esp_msgin_extended(struct esp *esp)
return;
}
printk("ESP: Unexpected extended msg type %x\n",
esp->msg_in[2]);
shost_printk(KERN_INFO, esp->host,
"Unexpected extended msg type %x\n", esp->msg_in[2]);
esp->msg_out[0] = ABORT_TASK_SET;
esp->msg_out_len = 1;
@ -1574,7 +1636,8 @@ static int esp_msgin_process(struct esp *esp)
if (msg0 & 0x80) {
/* Identify */
printk("ESP: Unexpected msgin identify\n");
shost_printk(KERN_INFO, esp->host,
"Unexpected msgin identify\n");
return 0;
}
@ -1640,10 +1703,12 @@ static int esp_msgin_process(struct esp *esp)
static int esp_process_event(struct esp *esp)
{
int write;
int write, i;
again:
write = 0;
esp_log_event("process event %d phase %x\n",
esp->event, esp->sreg & ESP_STAT_PMASK);
switch (esp->event) {
case ESP_EVENT_CHECK_PHASE:
switch (esp->sreg & ESP_STAT_PMASK) {
@ -1673,8 +1738,9 @@ again:
break;
default:
printk("ESP: Unexpected phase, sreg=%02x\n",
esp->sreg);
shost_printk(KERN_INFO, esp->host,
"Unexpected phase, sreg=%02x\n",
esp->sreg);
esp_schedule_reset(esp);
return 0;
}
@ -1708,18 +1774,17 @@ again:
esp->data_dma_len = dma_len;
if (!dma_len) {
printk(KERN_ERR PFX "esp%d: DMA length is zero!\n",
esp->host->unique_id);
printk(KERN_ERR PFX "esp%d: cur adr[%08llx] len[%08x]\n",
esp->host->unique_id,
(unsigned long long)esp_cur_dma_addr(ent, cmd),
esp_cur_dma_len(ent, cmd));
shost_printk(KERN_ERR, esp->host,
"DMA length is zero!\n");
shost_printk(KERN_ERR, esp->host,
"cur adr[%08llx] len[%08x]\n",
(unsigned long long)esp_cur_dma_addr(ent, cmd),
esp_cur_dma_len(ent, cmd));
esp_schedule_reset(esp);
return 0;
}
esp_log_datastart("ESP: start data addr[%08llx] len[%u] "
"write(%d)\n",
esp_log_datastart("start data addr[%08llx] len[%u] write(%d)\n",
(unsigned long long)dma_addr, dma_len, write);
esp->ops->send_dma_cmd(esp, dma_addr, dma_len, dma_len,
@ -1733,7 +1798,8 @@ again:
int bytes_sent;
if (esp->ops->dma_error(esp)) {
printk("ESP: data done, DMA error, resetting\n");
shost_printk(KERN_INFO, esp->host,
"data done, DMA error, resetting\n");
esp_schedule_reset(esp);
return 0;
}
@ -1749,14 +1815,15 @@ again:
/* We should always see exactly a bus-service
* interrupt at the end of a successful transfer.
*/
printk("ESP: data done, not BSERV, resetting\n");
shost_printk(KERN_INFO, esp->host,
"data done, not BSERV, resetting\n");
esp_schedule_reset(esp);
return 0;
}
bytes_sent = esp_data_bytes_sent(esp, ent, cmd);
esp_log_datadone("ESP: data done flgs[%x] sent[%d]\n",
esp_log_datadone("data done flgs[%x] sent[%d]\n",
ent->flags, bytes_sent);
if (bytes_sent < 0) {
@ -1785,8 +1852,9 @@ again:
}
if (ent->message != COMMAND_COMPLETE) {
printk("ESP: Unexpected message %x in status\n",
ent->message);
shost_printk(KERN_INFO, esp->host,
"Unexpected message %x in status\n",
ent->message);
esp_schedule_reset(esp);
return 0;
}
@ -1804,8 +1872,7 @@ again:
scsi_esp_cmd(esp, ESP_CMD_ESEL);
if (ent->message == COMMAND_COMPLETE) {
esp_log_cmddone("ESP: Command done status[%x] "
"message[%x]\n",
esp_log_cmddone("Command done status[%x] message[%x]\n",
ent->status, ent->message);
if (ent->status == SAM_STAT_TASK_SET_FULL)
esp_event_queue_full(esp, ent);
@ -1821,16 +1888,16 @@ again:
DID_OK));
}
} else if (ent->message == DISCONNECT) {
esp_log_disconnect("ESP: Disconnecting tgt[%d] "
"tag[%x:%x]\n",
esp_log_disconnect("Disconnecting tgt[%d] tag[%x:%x]\n",
cmd->device->id,
ent->tag[0], ent->tag[1]);
esp->active_cmd = NULL;
esp_maybe_execute_command(esp);
} else {
printk("ESP: Unexpected message %x in freebus\n",
ent->message);
shost_printk(KERN_INFO, esp->host,
"Unexpected message %x in freebus\n",
ent->message);
esp_schedule_reset(esp);
return 0;
}
@ -1862,6 +1929,10 @@ again:
if (esp->msg_out_len == 1) {
esp_write8(esp->msg_out[0], ESP_FDATA);
scsi_esp_cmd(esp, ESP_CMD_TI);
} else if (esp->flags & ESP_FLAG_USE_FIFO) {
for (i = 0; i < esp->msg_out_len; i++)
esp_write8(esp->msg_out[i], ESP_FDATA);
scsi_esp_cmd(esp, ESP_CMD_TI);
} else {
/* Use DMA. */
memcpy(esp->command_block,
@ -1917,7 +1988,7 @@ again:
val = esp_read8(ESP_FDATA);
esp->msg_in[esp->msg_in_len++] = val;
esp_log_msgin("ESP: Got msgin byte %x\n", val);
esp_log_msgin("Got msgin byte %x\n", val);
if (!esp_msgin_process(esp))
esp->msg_in_len = 0;
@ -1930,7 +2001,8 @@ again:
if (esp->event != ESP_EVENT_FREE_BUS)
esp_event(esp, ESP_EVENT_CHECK_PHASE);
} else {
printk("ESP: MSGIN neither BSERV not FDON, resetting");
shost_printk(KERN_INFO, esp->host,
"MSGIN neither BSERV not FDON, resetting");
esp_schedule_reset(esp);
return 0;
}
@ -1938,11 +2010,7 @@ again:
case ESP_EVENT_CMD_START:
memcpy(esp->command_block, esp->cmd_bytes_ptr,
esp->cmd_bytes_left);
if (esp->rev == FASHME)
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
esp->ops->send_dma_cmd(esp, esp->command_block_dma,
esp->cmd_bytes_left, 16, 0,
ESP_CMD_DMA | ESP_CMD_TI);
esp_send_dma_cmd(esp, esp->cmd_bytes_left, 16, ESP_CMD_TI);
esp_event(esp, ESP_EVENT_CMD_DONE);
esp->flags |= ESP_FLAG_QUICKIRQ_CHECK;
break;
@ -1961,8 +2029,8 @@ again:
break;
default:
printk("ESP: Unexpected event %x, resetting\n",
esp->event);
shost_printk(KERN_INFO, esp->host,
"Unexpected event %x, resetting\n", esp->event);
esp_schedule_reset(esp);
return 0;
break;
@ -2044,7 +2112,12 @@ static void __esp_interrupt(struct esp *esp)
int finish_reset, intr_done;
u8 phase;
/*
* Once INTRPT is read STATUS and SSTEP are cleared.
*/
esp->sreg = esp_read8(ESP_STATUS);
esp->seqreg = esp_read8(ESP_SSTEP);
esp->ireg = esp_read8(ESP_INTRPT);
if (esp->flags & ESP_FLAG_RESETTING) {
finish_reset = 1;
@ -2057,8 +2130,6 @@ static void __esp_interrupt(struct esp *esp)
return;
}
esp->ireg = esp_read8(ESP_INTRPT);
if (esp->ireg & ESP_INTR_SR)
finish_reset = 1;
@ -2085,14 +2156,15 @@ static void __esp_interrupt(struct esp *esp)
}
}
esp_log_intr("ESP: intr sreg[%02x] seqreg[%02x] "
esp_log_intr("intr sreg[%02x] seqreg[%02x] "
"sreg2[%02x] ireg[%02x]\n",
esp->sreg, esp->seqreg, esp->sreg2, esp->ireg);
intr_done = 0;
if (esp->ireg & (ESP_INTR_S | ESP_INTR_SATN | ESP_INTR_IC)) {
printk("ESP: unexpected IREG %02x\n", esp->ireg);
shost_printk(KERN_INFO, esp->host,
"unexpected IREG %02x\n", esp->ireg);
if (esp->ireg & ESP_INTR_IC)
esp_dump_cmd_log(esp);
@ -2149,46 +2221,50 @@ static void esp_get_revision(struct esp *esp)
u8 val;
esp->config1 = (ESP_CONFIG1_PENABLE | (esp->scsi_id & 7));
esp->config2 = (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY);
esp_write8(esp->config2, ESP_CFG2);
val = esp_read8(ESP_CFG2);
val &= ~ESP_CONFIG2_MAGIC;
if (val != (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY)) {
/* If what we write to cfg2 does not come back, cfg2 is not
* implemented, therefore this must be a plain esp100.
*/
esp->rev = ESP100;
} else {
esp->config2 = 0;
esp_set_all_config3(esp, 5);
esp->prev_cfg3 = 5;
if (esp->config2 == 0) {
esp->config2 = (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY);
esp_write8(esp->config2, ESP_CFG2);
esp_write8(0, ESP_CFG3);
val = esp_read8(ESP_CFG2);
val &= ~ESP_CONFIG2_MAGIC;
esp->config2 = 0;
if (val != (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY)) {
/*
* If what we write to cfg2 does not come back,
* cfg2 is not implemented.
* Therefore this must be a plain esp100.
*/
esp->rev = ESP100;
return;
}
}
esp_set_all_config3(esp, 5);
esp->prev_cfg3 = 5;
esp_write8(esp->config2, ESP_CFG2);
esp_write8(0, ESP_CFG3);
esp_write8(esp->prev_cfg3, ESP_CFG3);
val = esp_read8(ESP_CFG3);
if (val != 5) {
/* The cfg2 register is implemented, however
* cfg3 is not, must be esp100a.
*/
esp->rev = ESP100A;
} else {
esp_set_all_config3(esp, 0);
esp->prev_cfg3 = 0;
esp_write8(esp->prev_cfg3, ESP_CFG3);
val = esp_read8(ESP_CFG3);
if (val != 5) {
/* The cfg2 register is implemented, however
* cfg3 is not, must be esp100a.
*/
esp->rev = ESP100A;
/* All of cfg{1,2,3} implemented, must be one of
* the fas variants, figure out which one.
*/
if (esp->cfact == 0 || esp->cfact > ESP_CCF_F5) {
esp->rev = FAST;
esp->sync_defp = SYNC_DEFP_FAST;
} else {
esp_set_all_config3(esp, 0);
esp->prev_cfg3 = 0;
esp_write8(esp->prev_cfg3, ESP_CFG3);
/* All of cfg{1,2,3} implemented, must be one of
* the fas variants, figure out which one.
*/
if (esp->cfact == 0 || esp->cfact > ESP_CCF_F5) {
esp->rev = FAST;
esp->sync_defp = SYNC_DEFP_FAST;
} else {
esp->rev = ESP236;
}
esp->config2 = 0;
esp_write8(esp->config2, ESP_CFG2);
esp->rev = ESP236;
}
}
}
@ -2308,6 +2384,7 @@ static const char *esp_chip_names[] = {
"FAS100A",
"FAST",
"FASHME",
"AM53C974",
};
static struct scsi_transport_template *esp_transport_template;
@ -2317,6 +2394,10 @@ int scsi_esp_register(struct esp *esp, struct device *dev)
static int instance;
int err;
if (!esp->num_tags)
esp->num_tags = ESP_DEFAULT_TAGS;
else if (esp->num_tags >= ESP_MAX_TAG)
esp->num_tags = ESP_MAX_TAG - 1;
esp->host->transportt = esp_transport_template;
esp->host->max_lun = ESP_MAX_LUN;
esp->host->cmd_per_lun = 2;
@ -2330,12 +2411,13 @@ int scsi_esp_register(struct esp *esp, struct device *dev)
esp_bootup_reset(esp);
printk(KERN_INFO PFX "esp%u, regs[%1p:%1p] irq[%u]\n",
esp->host->unique_id, esp->regs, esp->dma_regs,
esp->host->irq);
printk(KERN_INFO PFX "esp%u is a %s, %u MHz (ccf=%u), SCSI ID %u\n",
esp->host->unique_id, esp_chip_names[esp->rev],
esp->cfreq / 1000000, esp->cfact, esp->scsi_id);
dev_printk(KERN_INFO, dev, "esp%u: regs[%1p:%1p] irq[%u]\n",
esp->host->unique_id, esp->regs, esp->dma_regs,
esp->host->irq);
dev_printk(KERN_INFO, dev,
"esp%u: is a %s, %u MHz (ccf=%u), SCSI ID %u\n",
esp->host->unique_id, esp_chip_names[esp->rev],
esp->cfreq / 1000000, esp->cfact, esp->scsi_id);
/* Let the SCSI bus reset settle. */
ssleep(esp_bus_reset_settle);
@ -2403,12 +2485,8 @@ static int esp_slave_configure(struct scsi_device *dev)
struct esp *esp = shost_priv(dev->host);
struct esp_target_data *tp = &esp->target[dev->id];
if (dev->tagged_supported) {
/* XXX make this configurable somehow XXX */
int goal_tags = min(ESP_DEFAULT_TAGS, ESP_MAX_TAG);
scsi_adjust_queue_depth(dev, goal_tags);
}
if (dev->tagged_supported)
scsi_change_queue_depth(dev, esp->num_tags);
tp->flags |= ESP_TGT_DISCONNECT;
@ -2437,19 +2515,20 @@ static int esp_eh_abort_handler(struct scsi_cmnd *cmd)
* XXX much for the final driver.
*/
spin_lock_irqsave(esp->host->host_lock, flags);
printk(KERN_ERR PFX "esp%d: Aborting command [%p:%02x]\n",
esp->host->unique_id, cmd, cmd->cmnd[0]);
shost_printk(KERN_ERR, esp->host, "Aborting command [%p:%02x]\n",
cmd, cmd->cmnd[0]);
ent = esp->active_cmd;
if (ent)
printk(KERN_ERR PFX "esp%d: Current command [%p:%02x]\n",
esp->host->unique_id, ent->cmd, ent->cmd->cmnd[0]);
shost_printk(KERN_ERR, esp->host,
"Current command [%p:%02x]\n",
ent->cmd, ent->cmd->cmnd[0]);
list_for_each_entry(ent, &esp->queued_cmds, list) {
printk(KERN_ERR PFX "esp%d: Queued command [%p:%02x]\n",
esp->host->unique_id, ent->cmd, ent->cmd->cmnd[0]);
shost_printk(KERN_ERR, esp->host, "Queued command [%p:%02x]\n",
ent->cmd, ent->cmd->cmnd[0]);
}
list_for_each_entry(ent, &esp->active_cmds, list) {
printk(KERN_ERR PFX "esp%d: Active command [%p:%02x]\n",
esp->host->unique_id, ent->cmd, ent->cmd->cmnd[0]);
shost_printk(KERN_ERR, esp->host, " Active command [%p:%02x]\n",
ent->cmd, ent->cmd->cmnd[0]);
}
esp_dump_cmd_log(esp);
spin_unlock_irqrestore(esp->host->host_lock, flags);

View file

@ -1,4 +1,4 @@
/* esp_scsi.h: Defines and structures for the ESP drier.
/* esp_scsi.h: Defines and structures for the ESP driver.
*
* Copyright (C) 2007 David S. Miller (davem@davemloft.net)
*/
@ -25,6 +25,7 @@
#define ESP_CTEST 0x0aUL /* wo Chip test register 0x28 */
#define ESP_CFG2 0x0bUL /* rw Second cfg register 0x2c */
#define ESP_CFG3 0x0cUL /* rw Third cfg register 0x30 */
#define ESP_CFG4 0x0dUL /* rw Fourth cfg register 0x34 */
#define ESP_TCHI 0x0eUL /* rw High bits transf count 0x38 */
#define ESP_UID ESP_TCHI /* ro Unique ID code 0x38 */
#define FAS_RLO ESP_TCHI /* rw HME extended counter 0x38 */
@ -76,6 +77,18 @@
#define ESP_CONFIG3_IMS 0x80 /* ID msg chk'ng (esp/fas236) */
#define ESP_CONFIG3_OBPUSH 0x80 /* Push odd-byte to dma (hme) */
/* ESP config register 4 read-write, found only on am53c974 chips */
#define ESP_CONFIG4_RADE 0x04 /* Active negation */
#define ESP_CONFIG4_RAE 0x08 /* Active negation on REQ and ACK */
#define ESP_CONFIG4_PWD 0x20 /* Reduced power feature */
#define ESP_CONFIG4_GE0 0x40 /* Glitch eater bit 0 */
#define ESP_CONFIG4_GE1 0x80 /* Glitch eater bit 1 */
#define ESP_CONFIG_GE_12NS (0)
#define ESP_CONFIG_GE_25NS (ESP_CONFIG_GE1)
#define ESP_CONFIG_GE_35NS (ESP_CONFIG_GE0)
#define ESP_CONFIG_GE_0NS (ESP_CONFIG_GE0 | ESP_CONFIG_GE1)
/* ESP command register read-write */
/* Group 1 commands: These may be sent at any point in time to the ESP
* chip. None of them can generate interrupts 'cept
@ -254,6 +267,7 @@ enum esp_rev {
FAS100A = 0x04,
FAST = 0x05,
FASHME = 0x06,
PCSCSI = 0x07, /* AM53c974 */
};
struct esp_cmd_entry {
@ -269,6 +283,7 @@ struct esp_cmd_entry {
#define ESP_CMD_FLAG_WRITE 0x01 /* DMA is a write */
#define ESP_CMD_FLAG_ABORT 0x02 /* being aborted */
#define ESP_CMD_FLAG_AUTOSENSE 0x04 /* Doing automatic REQUEST_SENSE */
#define ESP_CMD_FLAG_RESIDUAL 0x08 /* AM53c974 BLAST residual */
u8 tag[2];
u8 orig_tag[2];
@ -283,7 +298,6 @@ struct esp_cmd_entry {
struct completion *eh_done;
};
/* XXX make this configurable somehow XXX */
#define ESP_DEFAULT_TAGS 16
#define ESP_MAX_TARGET 16
@ -445,7 +459,7 @@ struct esp {
u8 prev_soff;
u8 prev_stp;
u8 prev_cfg3;
u8 __pad;
u8 num_tags;
struct list_head esp_cmd_pool;
@ -466,6 +480,7 @@ struct esp {
u8 bursts;
u8 config1;
u8 config2;
u8 config4;
u8 scsi_id;
u32 scsi_id_mask;
@ -479,6 +494,7 @@ struct esp {
#define ESP_FLAG_WIDE_CAPABLE 0x00000008
#define ESP_FLAG_QUICKIRQ_CHECK 0x00000010
#define ESP_FLAG_DISABLE_SYNC 0x00000020
#define ESP_FLAG_USE_FIFO 0x00000040
u8 select_state;
#define ESP_SELECT_NONE 0x00 /* Not selecting */

View file

@ -280,7 +280,7 @@ static struct scsi_host_template fcoe_shost_template = {
.eh_device_reset_handler = fc_eh_device_reset,
.eh_host_reset_handler = fc_eh_host_reset,
.slave_alloc = fc_slave_alloc,
.change_queue_depth = fc_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.change_queue_type = scsi_change_queue_type,
.this_id = -1,
.cmd_per_lun = 3,
@ -289,6 +289,7 @@ static struct scsi_host_template fcoe_shost_template = {
.sg_tablesize = SG_ALL,
.max_sectors = 0xffff,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
/**

View file

@ -39,7 +39,7 @@
#define DRV_NAME "fnic"
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
#define DRV_VERSION "1.6.0.11"
#define DRV_VERSION "1.6.0.16"
#define PFX DRV_NAME ": "
#define DFX DRV_NAME "%d: "

View file

@ -135,6 +135,11 @@ void fnic_handle_link(struct work_struct *work)
fnic->lport->host->host_no, FNIC_FC_LE,
"Link Status: UP_DOWN",
strlen("Link Status: UP_DOWN"));
if (fnic->config.flags & VFCF_FIP_CAPABLE) {
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
"deleting fip-timer during link-down\n");
del_timer_sync(&fnic->fip_timer);
}
fcoe_ctlr_link_down(&fnic->ctlr);
}

View file

@ -98,7 +98,7 @@ static int fnic_slave_alloc(struct scsi_device *sdev)
if (!rport || fc_remote_port_chkready(rport))
return -ENXIO;
scsi_adjust_queue_depth(sdev, fnic_max_qdepth);
scsi_change_queue_depth(sdev, fnic_max_qdepth);
return 0;
}
@ -110,7 +110,7 @@ static struct scsi_host_template fnic_host_template = {
.eh_device_reset_handler = fnic_device_reset,
.eh_host_reset_handler = fnic_host_reset,
.slave_alloc = fnic_slave_alloc,
.change_queue_depth = fc_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.change_queue_type = scsi_change_queue_type,
.this_id = -1,
.cmd_per_lun = 3,
@ -120,6 +120,7 @@ static struct scsi_host_template fnic_host_template = {
.max_sectors = 0xffff,
.shost_attrs = fnic_attrs,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
static void
@ -437,21 +438,30 @@ static int fnic_dev_wait(struct vnic_dev *vdev,
unsigned long time;
int done;
int err;
int count;
count = 0;
err = start(vdev, arg);
if (err)
return err;
/* Wait for func to complete...2 seconds max */
/* Wait for func to complete.
* Sometime schedule_timeout_uninterruptible take long time
* to wake up so we do not retry as we are only waiting for
* 2 seconds in while loop. By adding count, we make sure
* we try atleast three times before returning -ETIMEDOUT
*/
time = jiffies + (HZ * 2);
do {
err = finished(vdev, &done);
count++;
if (err)
return err;
if (done)
return 0;
schedule_timeout_uninterruptible(HZ / 10);
} while (time_after(time, jiffies));
} while (time_after(time, jiffies) || (count < 3));
return -ETIMEDOUT;
}

View file

@ -421,8 +421,10 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
int ret;
u64 cmd_trace;
int sg_count = 0;
unsigned long flags;
unsigned long flags = 0;
unsigned long ptr;
struct fc_rport_priv *rdata;
spinlock_t *io_lock = NULL;
if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED)))
return SCSI_MLQUEUE_HOST_BUSY;
@ -436,6 +438,16 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
return 0;
}
rdata = lp->tt.rport_lookup(lp, rport->port_id);
if (!rdata || (rdata->rp_state == RPORT_ST_DELETE)) {
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"returning IO as rport is removed\n");
atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
sc->result = DID_NO_CONNECT;
done(sc);
return 0;
}
if (lp->state != LPORT_ST_READY || !(lp->link_up))
return SCSI_MLQUEUE_HOST_BUSY;
@ -498,6 +510,13 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
}
}
/*
* Will acquire lock defore setting to IO initialized.
*/
io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags);
/* initialize rest of io_req */
io_req->port_id = rport->port_id;
io_req->start_time = jiffies;
@ -514,11 +533,9 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
* In case another thread cancelled the request,
* refetch the pointer under the lock.
*/
spinlock_t *io_lock = fnic_io_lock_hash(fnic, sc);
FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no,
sc->request->tag, sc, 0, 0, 0,
(((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc)));
spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc);
CMD_SP(sc) = NULL;
CMD_STATE(sc) = FNIC_IOREQ_CMD_COMPLETE;
@ -527,6 +544,10 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
fnic_release_ioreq_buf(fnic, io_req, sc);
mempool_free(io_req, fnic->io_req_pool);
}
atomic_dec(&fnic->in_flight);
/* acquire host lock before returning to SCSI */
spin_lock(lp->host->host_lock);
return ret;
} else {
atomic64_inc(&fnic_stats->io_stats.active_ios);
atomic64_inc(&fnic_stats->io_stats.num_ios);
@ -548,6 +569,11 @@ out:
sc->request->tag, sc, io_req,
sg_count, cmd_trace,
(((u64)CMD_FLAGS(sc) >> 32) | CMD_STATE(sc)));
/* if only we issued IO, will we have the io lock */
if (CMD_FLAGS(sc) & FNIC_IO_INITIALIZED)
spin_unlock_irqrestore(io_lock, flags);
atomic_dec(&fnic->in_flight);
/* acquire host lock before returning to SCSI */
spin_lock(lp->host->host_lock);

View file

@ -624,12 +624,12 @@ int fnic_fc_trace_set_data(u32 host_no, u8 frame_type,
if (frame_type == FNIC_FC_RECV) {
eth_fcoe_hdr_len = sizeof(struct ethhdr) +
sizeof(struct fcoe_hdr);
fc_trc_frame_len = fc_trc_frame_len + eth_fcoe_hdr_len;
memset((char *)fc_trace, 0xff, eth_fcoe_hdr_len);
/* Copy the rest of data frame */
memcpy((char *)(fc_trace + eth_fcoe_hdr_len), (void *)frame,
min_t(u8, fc_trc_frame_len,
(u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE)));
(u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE
- eth_fcoe_hdr_len)));
} else {
memcpy((char *)fc_trace, (void *)frame,
min_t(u8, fc_trc_frame_len,

View file

@ -18,20 +18,6 @@
*
* Added ISAPNP support for DTC436 adapters,
* Thomas Sailer, sailer@ife.ee.ethz.ch
*
* ALPHA RELEASE 1.
*
* For more information, please consult
*
* NCR 5380 Family
* SCSI Protocol Controller
* Databook
*
* NCR Microelectronics
* 1635 Aeroplaza Drive
* Colorado Springs, CO 80916
* 1+ (719) 578-3400
* 1+ (800) 334-5454
*/
/*
@ -40,14 +26,6 @@
*/
/*
* Options :
*
* PARITY - enable parity checking. Not supported.
*
* SCSI2 - enable support for SCSI-II tagged queueing. Untested.
*
* USLEEP - enable support for devices that don't disconnect. Untested.
*
* The card is detected and initialized in one of several ways :
* 1. With command line overrides - NCR5380=port,irq may be
* used on the LILO command line to override the defaults.
@ -79,27 +57,21 @@
*/
/* settings for DTC3181E card with only Mustek scanner attached */
#define USLEEP
#define USLEEP_POLL 1
#define USLEEP_SLEEP 20
#define USLEEP_WAITLONG 500
#define AUTOPROBE_IRQ
#define AUTOSENSE
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define NCR53C400_PSEUDO_DMA 1
#define PSEUDO_DMA
#define NCR53C400
#define NCR5380_STATS
#undef NCR5380_STAT_LIMIT
#endif
#include <asm/io.h>
#include <linux/signal.h>
#include <linux/blkdev.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "g_NCR5380.h"
#include "NCR5380.h"
@ -277,7 +249,7 @@ static int __init do_DTC3181E_setup(char *str)
* Locks: none
*/
int __init generic_NCR5380_detect(struct scsi_host_template * tpnt)
static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
{
static int current_override = 0;
int count;
@ -335,7 +307,7 @@ int __init generic_NCR5380_detect(struct scsi_host_template * tpnt)
if (pnp_irq_valid(dev, 0))
overrides[count].irq = pnp_irq(dev, 0);
else
overrides[count].irq = SCSI_IRQ_NONE;
overrides[count].irq = NO_IRQ;
if (pnp_dma_valid(dev, 0))
overrides[count].dma = pnp_dma(dev, 0);
else
@ -455,46 +427,28 @@ int __init generic_NCR5380_detect(struct scsi_host_template * tpnt)
else
instance->irq = NCR5380_probe_irq(instance, 0xffff);
if (instance->irq != SCSI_IRQ_NONE)
/* Compatibility with documented NCR5380 kernel parameters */
if (instance->irq == 255)
instance->irq = NO_IRQ;
if (instance->irq != NO_IRQ)
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 = SCSI_IRQ_NONE;
instance->irq = NO_IRQ;
}
if (instance->irq == SCSI_IRQ_NONE) {
if (instance->irq == NO_IRQ) {
printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
}
printk(KERN_INFO "scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int) instance->NCR5380_instance_name);
if (instance->irq == SCSI_IRQ_NONE)
printk(" interrupts disabled");
else
printk(" irq %d", instance->irq);
printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, GENERIC_NCR5380_PUBLIC_RELEASE);
NCR5380_print_options(instance);
printk("\n");
++current_override;
++count;
}
return count;
}
/**
* generic_NCR5380_info - reporting string
* @host: NCR5380 to report on
*
* Report driver information for the NCR5380
*/
const char *generic_NCR5380_info(struct Scsi_Host *host)
{
static const char string[] = "Generic NCR5380/53C400 Driver";
return string;
}
/**
* generic_NCR5380_release_resources - free resources
* @instance: host adapter to clean up
@ -504,12 +458,12 @@ const char *generic_NCR5380_info(struct Scsi_Host *host)
* Locks: none
*/
int generic_NCR5380_release_resources(struct Scsi_Host *instance)
static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
{
NCR5380_local_declare();
NCR5380_setup(instance);
if (instance->irq != SCSI_IRQ_NONE)
if (instance->irq != NO_IRQ)
free_irq(instance->irq, instance);
NCR5380_exit(instance);
@ -741,163 +695,9 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
#include "NCR5380.c"
#define PRINTP(x) seq_printf(m, x)
#define ANDP ,
static void sprint_opcode(struct seq_file *m, int opcode)
{
PRINTP("0x%02x " ANDP opcode);
}
static void sprint_command(struct seq_file *m, unsigned char *command)
{
int i, s;
sprint_opcode(m, command[0]);
for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
PRINTP("%02x " ANDP command[i]);
PRINTP("\n");
}
/**
* sprintf_Scsi_Cmnd - print a scsi command
* @m: seq_fil to print into
* @cmd: SCSI command block
*
* Print out the target and command data in hex
*/
static void sprint_Scsi_Cmnd(struct seq_file *m, Scsi_Cmnd * cmd)
{
PRINTP("host number %d destination target %d, lun %llu\n" ANDP cmd->device->host->host_no ANDP cmd->device->id ANDP cmd->device->lun);
PRINTP(" command = ");
sprint_command(m, cmd->cmnd);
}
/**
* generic_NCR5380_proc_info - /proc for NCR5380 driver
* @buffer: buffer to print into
* @start: start position
* @offset: offset into buffer
* @len: length
* @hostno: instance to affect
* @inout: read/write
*
* Provide the procfs information for the 5380 controller. We fill
* this with useful debugging information including the commands
* being executed, disconnected command queue and the statistical
* data
*
* Locks: global cli/lock for queue walk
*/
static int generic_NCR5380_show_info(struct seq_file *m, struct Scsi_Host *scsi_ptr)
{
NCR5380_local_declare();
unsigned long flags;
unsigned char status;
int i;
Scsi_Cmnd *ptr;
struct NCR5380_hostdata *hostdata;
#ifdef NCR5380_STATS
struct scsi_device *dev;
#endif
NCR5380_setup(scsi_ptr);
hostdata = (struct NCR5380_hostdata *) scsi_ptr->hostdata;
spin_lock_irqsave(scsi_ptr->host_lock, flags);
PRINTP("SCSI host number %d : %s\n" ANDP scsi_ptr->host_no ANDP scsi_ptr->hostt->name);
PRINTP("Generic NCR5380 driver version %d\n" ANDP GENERIC_NCR5380_PUBLIC_RELEASE);
PRINTP("NCR5380 core version %d\n" ANDP NCR5380_PUBLIC_RELEASE);
#ifdef NCR53C400
PRINTP("NCR53C400 extension version %d\n" ANDP NCR53C400_PUBLIC_RELEASE);
PRINTP("NCR53C400 card%s detected\n" ANDP(((struct NCR5380_hostdata *) scsi_ptr->hostdata)->flags & FLAG_NCR53C400) ? "" : " not");
# if NCR53C400_PSEUDO_DMA
PRINTP("NCR53C400 pseudo DMA used\n");
# endif
#else
PRINTP("NO NCR53C400 driver extensions\n");
#endif
PRINTP("Using %s mapping at %s 0x%lx, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name);
if (scsi_ptr->irq == SCSI_IRQ_NONE)
PRINTP("no interrupt\n");
else
PRINTP("on interrupt %d\n" ANDP scsi_ptr->irq);
#ifdef NCR5380_STATS
if (hostdata->connected || hostdata->issue_queue || hostdata->disconnected_queue)
PRINTP("There are commands pending, transfer rates may be crud\n");
if (hostdata->pendingr)
PRINTP(" %d pending reads" ANDP hostdata->pendingr);
if (hostdata->pendingw)
PRINTP(" %d pending writes" ANDP hostdata->pendingw);
if (hostdata->pendingr || hostdata->pendingw)
PRINTP("\n");
shost_for_each_device(dev, scsi_ptr) {
unsigned long br = hostdata->bytes_read[dev->id];
unsigned long bw = hostdata->bytes_write[dev->id];
long tr = hostdata->time_read[dev->id] / HZ;
long tw = hostdata->time_write[dev->id] / HZ;
PRINTP(" T:%d %s " ANDP dev->id ANDP scsi_device_type(dev->type));
for (i = 0; i < 8; i++)
if (dev->vendor[i] >= 0x20)
seq_putc(m, dev->vendor[i]);
seq_putc(m, ' ');
for (i = 0; i < 16; i++)
if (dev->model[i] >= 0x20)
seq_putc(m, dev->model[i]);
seq_putc(m, ' ');
for (i = 0; i < 4; i++)
if (dev->rev[i] >= 0x20)
seq_putc(m, dev->rev[i]);
seq_putc(m, ' ');
PRINTP("\n%10ld kb read in %5ld secs" ANDP br / 1024 ANDP tr);
if (tr)
PRINTP(" @ %5ld bps" ANDP br / tr);
PRINTP("\n%10ld kb written in %5ld secs" ANDP bw / 1024 ANDP tw);
if (tw)
PRINTP(" @ %5ld bps" ANDP bw / tw);
PRINTP("\n");
}
#endif
status = NCR5380_read(STATUS_REG);
if (!(status & SR_REQ))
PRINTP("REQ not asserted, phase unknown.\n");
else {
for (i = 0; (phases[i].value != PHASE_UNKNOWN) && (phases[i].value != (status & PHASE_MASK)); ++i);
PRINTP("Phase %s\n" ANDP phases[i].name);
}
if (!hostdata->connected) {
PRINTP("No currently connected command\n");
} else {
sprint_Scsi_Cmnd(m, (Scsi_Cmnd *) hostdata->connected);
}
PRINTP("issue_queue\n");
for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
sprint_Scsi_Cmnd(m, ptr);
PRINTP("disconnected_queue\n");
for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
sprint_Scsi_Cmnd(m, ptr);
spin_unlock_irqrestore(scsi_ptr->host_lock, flags);
return 0;
}
#undef PRINTP
#undef ANDP
static struct scsi_host_template driver_template = {
.show_info = generic_NCR5380_show_info,
.name = "Generic NCR5380/NCR53C400 Scsi Driver",
.name = "Generic NCR5380/NCR53C400 SCSI",
.detect = generic_NCR5380_detect,
.release = generic_NCR5380_release_resources,
.info = generic_NCR5380_info,

View file

@ -9,28 +9,11 @@
*
* NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin
* K.Lentin@cs.monash.edu.au
*
* ALPHA RELEASE 1.
*
* For more information, please consult
*
* NCR 5380 Family
* SCSI Protocol Controller
* Databook
*
* NCR Microelectronics
* 1635 Aeroplaza Drive
* Colorado Springs, CO 80916
* 1+ (719) 578-3400
* 1+ (800) 334-5454
*/
#ifndef GENERIC_NCR5380_H
#define GENERIC_NCR5380_H
#define GENERIC_NCR5380_PUBLIC_RELEASE 1
#ifdef NCR53C400
#define BIOSPARAM
#define NCR5380_BIOSPARAM generic_NCR5380_biosparam
@ -39,12 +22,6 @@
#endif
#ifndef ASM
static int generic_NCR5380_abort(Scsi_Cmnd *);
static int generic_NCR5380_detect(struct scsi_host_template *);
static int generic_NCR5380_release_resources(struct Scsi_Host *);
static int generic_NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int generic_NCR5380_bus_reset(Scsi_Cmnd *);
static const char* generic_NCR5380_info(struct Scsi_Host *);
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
@ -118,7 +95,8 @@ static const char* generic_NCR5380_info(struct Scsi_Host *);
#define NCR5380_bus_reset generic_NCR5380_bus_reset
#define NCR5380_pread generic_NCR5380_pread
#define NCR5380_pwrite generic_NCR5380_pwrite
#define NCR5380_proc_info notyet_generic_proc_info
#define NCR5380_info generic_NCR5380_info
#define NCR5380_show_info generic_NCR5380_show_info
#define BOARD_NCR5380 0
#define BOARD_NCR53C400 1

File diff suppressed because it is too large Load diff

View file

@ -118,7 +118,7 @@ struct ctlr_info {
struct CfgTable __iomem *cfgtable;
int interrupts_enabled;
int max_commands;
int commands_outstanding;
atomic_t commands_outstanding;
# define PERF_MODE_INT 0
# define DOORBELL_INT 1
# define SIMPLE_MODE_INT 2
@ -164,7 +164,7 @@ struct ctlr_info {
*/
u32 trans_support;
u32 trans_offset;
struct TransTable_struct *transtable;
struct TransTable_struct __iomem *transtable;
unsigned long transMethod;
/* cap concurrent passthrus at some reasonable maximum */
@ -181,7 +181,7 @@ struct ctlr_info {
u32 *blockFetchTable;
u32 *ioaccel1_blockFetchTable;
u32 *ioaccel2_blockFetchTable;
u32 *ioaccel2_bft2_regs;
u32 __iomem *ioaccel2_bft2_regs;
unsigned char *hba_inquiry_data;
u32 driver_support;
u32 fw_support;
@ -192,7 +192,7 @@ struct ctlr_info {
u64 last_heartbeat_timestamp;
u32 heartbeat_sample_interval;
atomic_t firmware_flash_in_progress;
u32 *lockup_detected;
u32 __percpu *lockup_detected;
struct delayed_work monitor_ctlr_work;
int remove_in_progress;
u32 fifo_recently_full;
@ -395,7 +395,7 @@ static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val)
static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q)
{
struct reply_queue_buffer *rq = &h->reply_queue[q];
unsigned long flags, register_value = FIFO_EMPTY;
unsigned long register_value = FIFO_EMPTY;
/* msi auto clears the interrupt pending bit. */
if (!(h->msi_vector || h->msix_vector)) {
@ -413,9 +413,7 @@ static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q)
if ((rq->head[rq->current_entry] & 1) == rq->wraparound) {
register_value = rq->head[rq->current_entry];
rq->current_entry++;
spin_lock_irqsave(&h->lock, flags);
h->commands_outstanding--;
spin_unlock_irqrestore(&h->lock, flags);
atomic_dec(&h->commands_outstanding);
} else {
register_value = FIFO_EMPTY;
}
@ -433,11 +431,7 @@ static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q)
*/
static unsigned long SA5_fifo_full(struct ctlr_info *h)
{
if (h->commands_outstanding >= h->max_commands)
return 1;
else
return 0;
return atomic_read(&h->commands_outstanding) >= h->max_commands;
}
/*
* returns value read from hardware.
@ -448,13 +442,9 @@ static unsigned long SA5_completed(struct ctlr_info *h,
{
unsigned long register_value
= readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
unsigned long flags;
if (register_value != FIFO_EMPTY) {
spin_lock_irqsave(&h->lock, flags);
h->commands_outstanding--;
spin_unlock_irqrestore(&h->lock, flags);
}
if (register_value != FIFO_EMPTY)
atomic_dec(&h->commands_outstanding);
#ifdef HPSA_DEBUG
if (register_value != FIFO_EMPTY)
@ -510,7 +500,6 @@ static unsigned long SA5_ioaccel_mode1_completed(struct ctlr_info *h, u8 q)
{
u64 register_value;
struct reply_queue_buffer *rq = &h->reply_queue[q];
unsigned long flags;
BUG_ON(q >= h->nreply_queues);
@ -528,9 +517,7 @@ static unsigned long SA5_ioaccel_mode1_completed(struct ctlr_info *h, u8 q)
wmb();
writel((q << 24) | rq->current_entry, h->vaddr +
IOACCEL_MODE1_CONSUMER_INDEX);
spin_lock_irqsave(&h->lock, flags);
h->commands_outstanding--;
spin_unlock_irqrestore(&h->lock, flags);
atomic_dec(&h->commands_outstanding);
}
return (unsigned long) register_value;
}

View file

@ -252,7 +252,7 @@ struct ReportExtendedLUNdata {
u8 LUNListLength[4];
u8 extended_response_flag;
u8 reserved[3];
struct ext_report_lun_entry LUN[HPSA_MAX_LUN];
struct ext_report_lun_entry LUN[HPSA_MAX_PHYS_LUN];
};
struct SenseSubsystem_info {
@ -314,28 +314,36 @@ struct CommandListHeader {
u8 ReplyQueue;
u8 SGList;
u16 SGTotal;
struct vals32 Tag;
u64 tag;
union LUNAddr LUN;
};
struct RequestBlock {
u8 CDBLen;
struct {
u8 Type:3;
u8 Attribute:3;
u8 Direction:2;
} Type;
/*
* type_attr_dir:
* type: low 3 bits
* attr: middle 3 bits
* dir: high 2 bits
*/
u8 type_attr_dir;
#define TYPE_ATTR_DIR(t, a, d) ((((d) & 0x03) << 6) |\
(((a) & 0x07) << 3) |\
((t) & 0x07))
#define GET_TYPE(tad) ((tad) & 0x07)
#define GET_ATTR(tad) (((tad) >> 3) & 0x07)
#define GET_DIR(tad) (((tad) >> 6) & 0x03)
u16 Timeout;
u8 CDB[16];
};
struct ErrDescriptor {
struct vals32 Addr;
u64 Addr;
u32 Len;
};
struct SGDescriptor {
struct vals32 Addr;
u64 Addr;
u32 Len;
u32 Ext;
};
@ -434,8 +442,8 @@ struct io_accel1_cmd {
u16 timeout_sec; /* 0x62 - 0x63 */
u8 ReplyQueue; /* 0x64 */
u8 reserved9[3]; /* 0x65 - 0x67 */
struct vals32 Tag; /* 0x68 - 0x6F */
struct vals32 host_addr; /* 0x70 - 0x77 */
u64 tag; /* 0x68 - 0x6F */
u64 host_addr; /* 0x70 - 0x77 */
u8 CISS_LUN[8]; /* 0x78 - 0x7F */
struct SGDescriptor SG[IOACCEL1_MAXSGENTRIES];
} __aligned(IOACCEL1_COMMANDLIST_ALIGNMENT);
@ -555,8 +563,8 @@ struct hpsa_tmf_struct {
u8 reserved1; /* byte 3 Reserved */
u32 it_nexus; /* SCSI I-T Nexus */
u8 lun_id[8]; /* LUN ID for TMF request */
struct vals32 Tag; /* cciss tag associated w/ request */
struct vals32 abort_tag;/* cciss tag of SCSI cmd or task to abort */
u64 tag; /* cciss tag associated w/ request */
u64 abort_tag; /* cciss tag of SCSI cmd or task to abort */
u64 error_ptr; /* Error Pointer */
u32 error_len; /* Error Length */
};

View file

@ -1118,17 +1118,13 @@ static int hptiop_reset(struct scsi_cmnd *scp)
}
static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev,
int queue_depth, int reason)
int queue_depth)
{
struct hptiop_hba *hba = (struct hptiop_hba *)sdev->host->hostdata;
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth > hba->max_requests)
queue_depth = hba->max_requests;
scsi_adjust_queue_depth(sdev, queue_depth);
return queue_depth;
return scsi_change_queue_depth(sdev, queue_depth);
}
static ssize_t hptiop_show_version(struct device *dev,

View file

@ -2900,17 +2900,12 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev)
* Return value:
* actual depth set
**/
static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth,
int reason)
static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (qdepth > IBMVFC_MAX_CMDS_PER_LUN)
qdepth = IBMVFC_MAX_CMDS_PER_LUN;
scsi_adjust_queue_depth(sdev, qdepth);
return sdev->queue_depth;
return scsi_change_queue_depth(sdev, qdepth);
}
static ssize_t ibmvfc_show_host_partition_name(struct device *dev,
@ -3103,6 +3098,7 @@ static struct scsi_host_template driver_template = {
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = ibmvfc_attrs,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
/**

View file

@ -1941,17 +1941,11 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev)
* Return value:
* actual depth set
**/
static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth,
int reason)
static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (qdepth > IBMVSCSI_MAX_CMDS_PER_LUN)
qdepth = IBMVSCSI_MAX_CMDS_PER_LUN;
scsi_adjust_queue_depth(sdev, qdepth);
return sdev->queue_depth;
return scsi_change_queue_depth(sdev, qdepth);
}
/* ------------------------------------------------------------

View file

@ -3942,8 +3942,9 @@ static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg,
return -EIO;
}
sglist->num_dma_sg = pci_map_sg(ioa_cfg->pdev, sglist->scatterlist,
sglist->num_sg, DMA_TO_DEVICE);
sglist->num_dma_sg = dma_map_sg(&ioa_cfg->pdev->dev,
sglist->scatterlist, sglist->num_sg,
DMA_TO_DEVICE);
if (!sglist->num_dma_sg) {
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@ -4327,16 +4328,12 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { return 0; };
* Return value:
* actual depth set
**/
static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth,
int reason)
static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
struct ipr_resource_entry *res;
unsigned long lock_flags = 0;
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
res = (struct ipr_resource_entry *)sdev->hostdata;
@ -4344,7 +4341,7 @@ static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth,
qdepth = IPR_MAX_CMD_PER_ATA_LUN;
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
scsi_adjust_queue_depth(sdev, qdepth);
scsi_change_queue_depth(sdev, qdepth);
return sdev->queue_depth;
}
@ -4751,7 +4748,7 @@ static int ipr_slave_configure(struct scsi_device *sdev)
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
if (ap) {
scsi_adjust_queue_depth(sdev, IPR_MAX_CMD_PER_ATA_LUN);
scsi_change_queue_depth(sdev, IPR_MAX_CMD_PER_ATA_LUN);
ata_sas_slave_configure(sdev, ap);
}
@ -5571,7 +5568,7 @@ static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg,
nseg = scsi_dma_map(scsi_cmd);
if (nseg < 0) {
if (printk_ratelimit())
dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
dev_err(&ioa_cfg->pdev->dev, "scsi_dma_map failed!\n");
return -1;
}
@ -5622,7 +5619,7 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
nseg = scsi_dma_map(scsi_cmd);
if (nseg < 0) {
dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
dev_err(&ioa_cfg->pdev->dev, "scsi_dma_map failed!\n");
return -1;
}
@ -8392,7 +8389,7 @@ static int ipr_reset_ucode_download_done(struct ipr_cmnd *ipr_cmd)
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_sglist *sglist = ioa_cfg->ucode_sglist;
pci_unmap_sg(ioa_cfg->pdev, sglist->scatterlist,
dma_unmap_sg(&ioa_cfg->pdev->dev, sglist->scatterlist,
sglist->num_sg, DMA_TO_DEVICE);
ipr_cmd->job_step = ipr_reset_alert;
@ -8832,7 +8829,7 @@ static void ipr_free_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
for (i = 0; i < IPR_NUM_CMD_BLKS; i++) {
if (ioa_cfg->ipr_cmnd_list[i])
pci_pool_free(ioa_cfg->ipr_cmd_pool,
dma_pool_free(ioa_cfg->ipr_cmd_pool,
ioa_cfg->ipr_cmnd_list[i],
ioa_cfg->ipr_cmnd_list_dma[i]);
@ -8840,7 +8837,7 @@ static void ipr_free_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
}
if (ioa_cfg->ipr_cmd_pool)
pci_pool_destroy(ioa_cfg->ipr_cmd_pool);
dma_pool_destroy(ioa_cfg->ipr_cmd_pool);
kfree(ioa_cfg->ipr_cmnd_list);
kfree(ioa_cfg->ipr_cmnd_list_dma);
@ -8861,25 +8858,24 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
int i;
kfree(ioa_cfg->res_entries);
pci_free_consistent(ioa_cfg->pdev, sizeof(struct ipr_misc_cbs),
ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
dma_free_coherent(&ioa_cfg->pdev->dev, sizeof(struct ipr_misc_cbs),
ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
ipr_free_cmd_blks(ioa_cfg);
for (i = 0; i < ioa_cfg->hrrq_num; i++)
pci_free_consistent(ioa_cfg->pdev,
sizeof(u32) * ioa_cfg->hrrq[i].size,
ioa_cfg->hrrq[i].host_rrq,
ioa_cfg->hrrq[i].host_rrq_dma);
dma_free_coherent(&ioa_cfg->pdev->dev,
sizeof(u32) * ioa_cfg->hrrq[i].size,
ioa_cfg->hrrq[i].host_rrq,
ioa_cfg->hrrq[i].host_rrq_dma);
pci_free_consistent(ioa_cfg->pdev, ioa_cfg->cfg_table_size,
ioa_cfg->u.cfg_table,
ioa_cfg->cfg_table_dma);
dma_free_coherent(&ioa_cfg->pdev->dev, ioa_cfg->cfg_table_size,
ioa_cfg->u.cfg_table, ioa_cfg->cfg_table_dma);
for (i = 0; i < IPR_NUM_HCAMS; i++) {
pci_free_consistent(ioa_cfg->pdev,
sizeof(struct ipr_hostrcb),
ioa_cfg->hostrcb[i],
ioa_cfg->hostrcb_dma[i]);
dma_free_coherent(&ioa_cfg->pdev->dev,
sizeof(struct ipr_hostrcb),
ioa_cfg->hostrcb[i],
ioa_cfg->hostrcb_dma[i]);
}
ipr_free_dump(ioa_cfg);
@ -8940,7 +8936,7 @@ static int ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
dma_addr_t dma_addr;
int i, entries_each_hrrq, hrrq_id = 0;
ioa_cfg->ipr_cmd_pool = pci_pool_create(IPR_NAME, ioa_cfg->pdev,
ioa_cfg->ipr_cmd_pool = dma_pool_create(IPR_NAME, &ioa_cfg->pdev->dev,
sizeof(struct ipr_cmnd), 512, 0);
if (!ioa_cfg->ipr_cmd_pool)
@ -8990,7 +8986,7 @@ static int ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
}
for (i = 0; i < IPR_NUM_CMD_BLKS; i++) {
ipr_cmd = pci_pool_alloc(ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr);
ipr_cmd = dma_pool_alloc(ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr);
if (!ipr_cmd) {
ipr_free_cmd_blks(ioa_cfg);
@ -9061,9 +9057,10 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
}
ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev,
sizeof(struct ipr_misc_cbs),
&ioa_cfg->vpd_cbs_dma);
ioa_cfg->vpd_cbs = dma_alloc_coherent(&pdev->dev,
sizeof(struct ipr_misc_cbs),
&ioa_cfg->vpd_cbs_dma,
GFP_KERNEL);
if (!ioa_cfg->vpd_cbs)
goto out_free_res_entries;
@ -9072,13 +9069,14 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
goto out_free_vpd_cbs;
for (i = 0; i < ioa_cfg->hrrq_num; i++) {
ioa_cfg->hrrq[i].host_rrq = pci_alloc_consistent(ioa_cfg->pdev,
ioa_cfg->hrrq[i].host_rrq = dma_alloc_coherent(&pdev->dev,
sizeof(u32) * ioa_cfg->hrrq[i].size,
&ioa_cfg->hrrq[i].host_rrq_dma);
&ioa_cfg->hrrq[i].host_rrq_dma,
GFP_KERNEL);
if (!ioa_cfg->hrrq[i].host_rrq) {
while (--i > 0)
pci_free_consistent(pdev,
dma_free_coherent(&pdev->dev,
sizeof(u32) * ioa_cfg->hrrq[i].size,
ioa_cfg->hrrq[i].host_rrq,
ioa_cfg->hrrq[i].host_rrq_dma);
@ -9087,17 +9085,19 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
ioa_cfg->hrrq[i].ioa_cfg = ioa_cfg;
}
ioa_cfg->u.cfg_table = pci_alloc_consistent(ioa_cfg->pdev,
ioa_cfg->cfg_table_size,
&ioa_cfg->cfg_table_dma);
ioa_cfg->u.cfg_table = dma_alloc_coherent(&pdev->dev,
ioa_cfg->cfg_table_size,
&ioa_cfg->cfg_table_dma,
GFP_KERNEL);
if (!ioa_cfg->u.cfg_table)
goto out_free_host_rrq;
for (i = 0; i < IPR_NUM_HCAMS; i++) {
ioa_cfg->hostrcb[i] = pci_alloc_consistent(ioa_cfg->pdev,
sizeof(struct ipr_hostrcb),
&ioa_cfg->hostrcb_dma[i]);
ioa_cfg->hostrcb[i] = dma_alloc_coherent(&pdev->dev,
sizeof(struct ipr_hostrcb),
&ioa_cfg->hostrcb_dma[i],
GFP_KERNEL);
if (!ioa_cfg->hostrcb[i])
goto out_free_hostrcb_dma;
@ -9121,25 +9121,24 @@ out:
out_free_hostrcb_dma:
while (i-- > 0) {
pci_free_consistent(pdev, sizeof(struct ipr_hostrcb),
ioa_cfg->hostrcb[i],
ioa_cfg->hostrcb_dma[i]);
dma_free_coherent(&pdev->dev, sizeof(struct ipr_hostrcb),
ioa_cfg->hostrcb[i],
ioa_cfg->hostrcb_dma[i]);
}
pci_free_consistent(pdev, ioa_cfg->cfg_table_size,
ioa_cfg->u.cfg_table,
ioa_cfg->cfg_table_dma);
dma_free_coherent(&pdev->dev, ioa_cfg->cfg_table_size,
ioa_cfg->u.cfg_table, ioa_cfg->cfg_table_dma);
out_free_host_rrq:
for (i = 0; i < ioa_cfg->hrrq_num; i++) {
pci_free_consistent(pdev,
sizeof(u32) * ioa_cfg->hrrq[i].size,
ioa_cfg->hrrq[i].host_rrq,
ioa_cfg->hrrq[i].host_rrq_dma);
dma_free_coherent(&pdev->dev,
sizeof(u32) * ioa_cfg->hrrq[i].size,
ioa_cfg->hrrq[i].host_rrq,
ioa_cfg->hrrq[i].host_rrq_dma);
}
out_ipr_free_cmd_blocks:
ipr_free_cmd_blks(ioa_cfg);
out_free_vpd_cbs:
pci_free_consistent(pdev, sizeof(struct ipr_misc_cbs),
ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
dma_free_coherent(&pdev->dev, sizeof(struct ipr_misc_cbs),
ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
out_free_res_entries:
kfree(ioa_cfg->res_entries);
goto out;
@ -9579,16 +9578,17 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
ipr_init_regs(ioa_cfg);
if (ioa_cfg->sis64) {
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (rc < 0) {
dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n");
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
dev_dbg(&pdev->dev, "Failed to set 64 bit DMA mask\n");
rc = dma_set_mask_and_coherent(&pdev->dev,
DMA_BIT_MASK(32));
}
} else
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (rc < 0) {
dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
dev_err(&pdev->dev, "Failed to set DMA mask\n");
goto cleanup_nomem;
}

View file

@ -1549,7 +1549,7 @@ struct ipr_ioa_cfg {
struct ipr_misc_cbs *vpd_cbs;
dma_addr_t vpd_cbs_dma;
struct pci_pool *ipr_cmd_pool;
struct dma_pool *ipr_cmd_pool;
struct ipr_cmnd *reset_cmd;
int (*reset) (struct ipr_cmnd *);

View file

@ -1210,7 +1210,7 @@ ips_slave_configure(struct scsi_device * SDptr)
min = ha->max_cmds / 2;
if (ha->enq->ucLogDriveCount <= 2)
min = ha->max_cmds - 1;
scsi_adjust_queue_depth(SDptr, min);
scsi_change_queue_depth(SDptr, min);
}
SDptr->skip_ms_page_8 = 1;

View file

@ -173,6 +173,7 @@ static struct scsi_host_template isci_sht = {
.ioctl = sas_ioctl,
.shost_attrs = isci_host_attrs,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
static struct sas_domain_function_template isci_transport_ops = {
@ -259,8 +260,6 @@ static int isci_register_sas_ha(struct isci_host *isci_host)
sas_ha->sas_port = sas_ports;
sas_ha->num_phys = SCI_MAX_PHYS;
sas_ha->lldd_queue_size = ISCI_CAN_QUEUE_VAL;
sas_ha->lldd_max_execute_num = 1;
sas_ha->strict_wide_ports = 1;
sas_register_ha(sas_ha);

View file

@ -117,104 +117,97 @@ static inline int isci_device_io_ready(struct isci_remote_device *idev,
* functions. This function is called by libsas to send a task down to
* hardware.
* @task: This parameter specifies the SAS task to send.
* @num: This parameter specifies the number of tasks to queue.
* @gfp_flags: This parameter specifies the context of this call.
*
* status, zero indicates success.
*/
int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
int isci_task_execute_task(struct sas_task *task, gfp_t gfp_flags)
{
struct isci_host *ihost = dev_to_ihost(task->dev);
struct isci_remote_device *idev;
unsigned long flags;
enum sci_status status = SCI_FAILURE;
bool io_ready;
u16 tag;
dev_dbg(&ihost->pdev->dev, "%s: num=%d\n", __func__, num);
spin_lock_irqsave(&ihost->scic_lock, flags);
idev = isci_lookup_device(task->dev);
io_ready = isci_device_io_ready(idev, task);
tag = isci_alloc_tag(ihost);
spin_unlock_irqrestore(&ihost->scic_lock, flags);
for_each_sas_task(num, task) {
enum sci_status status = SCI_FAILURE;
dev_dbg(&ihost->pdev->dev,
"task: %p, dev: %p idev: %p:%#lx cmd = %p\n",
task, task->dev, idev, idev ? idev->flags : 0,
task->uldd_task);
spin_lock_irqsave(&ihost->scic_lock, flags);
idev = isci_lookup_device(task->dev);
io_ready = isci_device_io_ready(idev, task);
tag = isci_alloc_tag(ihost);
spin_unlock_irqrestore(&ihost->scic_lock, flags);
if (!idev) {
isci_task_refuse(ihost, task, SAS_TASK_UNDELIVERED,
SAS_DEVICE_UNKNOWN);
} else if (!io_ready || tag == SCI_CONTROLLER_INVALID_IO_TAG) {
/* Indicate QUEUE_FULL so that the scsi midlayer
* retries.
*/
isci_task_refuse(ihost, task, SAS_TASK_COMPLETE,
SAS_QUEUE_FULL);
} else {
/* There is a device and it's ready for I/O. */
spin_lock_irqsave(&task->task_state_lock, flags);
dev_dbg(&ihost->pdev->dev,
"task: %p, num: %d dev: %p idev: %p:%#lx cmd = %p\n",
task, num, task->dev, idev, idev ? idev->flags : 0,
task->uldd_task);
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
/* The I/O was aborted. */
spin_unlock_irqrestore(&task->task_state_lock, flags);
if (!idev) {
isci_task_refuse(ihost, task, SAS_TASK_UNDELIVERED,
SAS_DEVICE_UNKNOWN);
} else if (!io_ready || tag == SCI_CONTROLLER_INVALID_IO_TAG) {
/* Indicate QUEUE_FULL so that the scsi midlayer
* retries.
*/
isci_task_refuse(ihost, task, SAS_TASK_COMPLETE,
SAS_QUEUE_FULL);
isci_task_refuse(ihost, task,
SAS_TASK_UNDELIVERED,
SAM_STAT_TASK_ABORTED);
} else {
/* There is a device and it's ready for I/O. */
spin_lock_irqsave(&task->task_state_lock, flags);
task->task_state_flags |= SAS_TASK_AT_INITIATOR;
spin_unlock_irqrestore(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
/* The I/O was aborted. */
spin_unlock_irqrestore(&task->task_state_lock,
flags);
/* build and send the request. */
status = isci_request_execute(ihost, idev, task, tag);
isci_task_refuse(ihost, task,
SAS_TASK_UNDELIVERED,
SAM_STAT_TASK_ABORTED);
} else {
task->task_state_flags |= SAS_TASK_AT_INITIATOR;
if (status != SCI_SUCCESS) {
spin_lock_irqsave(&task->task_state_lock, flags);
/* Did not really start this command. */
task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
spin_unlock_irqrestore(&task->task_state_lock, flags);
/* build and send the request. */
status = isci_request_execute(ihost, idev, task, tag);
if (status != SCI_SUCCESS) {
spin_lock_irqsave(&task->task_state_lock, flags);
/* Did not really start this command. */
task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
spin_unlock_irqrestore(&task->task_state_lock, flags);
if (test_bit(IDEV_GONE, &idev->flags)) {
/* Indicate that the device
* is gone.
*/
isci_task_refuse(ihost, task,
SAS_TASK_UNDELIVERED,
SAS_DEVICE_UNKNOWN);
} else {
/* Indicate QUEUE_FULL so that
* the scsi midlayer retries.
* If the request failed for
* remote device reasons, it
* gets returned as
* SAS_TASK_UNDELIVERED next
* time through.
*/
isci_task_refuse(ihost, task,
SAS_TASK_COMPLETE,
SAS_QUEUE_FULL);
}
if (test_bit(IDEV_GONE, &idev->flags)) {
/* Indicate that the device
* is gone.
*/
isci_task_refuse(ihost, task,
SAS_TASK_UNDELIVERED,
SAS_DEVICE_UNKNOWN);
} else {
/* Indicate QUEUE_FULL so that
* the scsi midlayer retries.
* If the request failed for
* remote device reasons, it
* gets returned as
* SAS_TASK_UNDELIVERED next
* time through.
*/
isci_task_refuse(ihost, task,
SAS_TASK_COMPLETE,
SAS_QUEUE_FULL);
}
}
}
if (status != SCI_SUCCESS && tag != SCI_CONTROLLER_INVALID_IO_TAG) {
spin_lock_irqsave(&ihost->scic_lock, flags);
/* command never hit the device, so just free
* the tci and skip the sequence increment
*/
isci_tci_free(ihost, ISCI_TAG_TCI(tag));
spin_unlock_irqrestore(&ihost->scic_lock, flags);
}
isci_put_device(idev);
}
if (status != SCI_SUCCESS && tag != SCI_CONTROLLER_INVALID_IO_TAG) {
spin_lock_irqsave(&ihost->scic_lock, flags);
/* command never hit the device, so just free
* the tci and skip the sequence increment
*/
isci_tci_free(ihost, ISCI_TAG_TCI(tag));
spin_unlock_irqrestore(&ihost->scic_lock, flags);
}
isci_put_device(idev);
return 0;
}

View file

@ -131,7 +131,6 @@ static inline void isci_print_tmf(struct isci_host *ihost, struct isci_tmf *tmf)
int isci_task_execute_task(
struct sas_task *task,
int num,
gfp_t gfp_flags);
int isci_task_abort_task(

View file

@ -952,7 +952,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
.module = THIS_MODULE,
.name = "iSCSI Initiator over TCP/IP",
.queuecommand = iscsi_queuecommand,
.change_queue_depth = iscsi_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1,
.sg_tablesize = 4096,
.max_sectors = 0xFFFF,
@ -966,6 +966,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
.target_alloc = iscsi_target_alloc,
.proc_name = "iscsi_tcp",
.this_id = -1,
.track_queue_depth = 1,
};
static struct iscsi_transport iscsi_sw_tcp_transport = {

View file

@ -2160,36 +2160,11 @@ int fc_slave_alloc(struct scsi_device *sdev)
if (!rport || fc_remote_port_chkready(rport))
return -ENXIO;
scsi_adjust_queue_depth(sdev, FC_FCP_DFLT_QUEUE_DEPTH);
scsi_change_queue_depth(sdev, FC_FCP_DFLT_QUEUE_DEPTH);
return 0;
}
EXPORT_SYMBOL(fc_slave_alloc);
/**
* fc_change_queue_depth() - Change a device's queue depth
* @sdev: The SCSI device whose queue depth is to change
* @qdepth: The new queue depth
* @reason: The resason for the change
*/
int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
{
switch (reason) {
case SCSI_QDEPTH_DEFAULT:
scsi_adjust_queue_depth(sdev, qdepth);
break;
case SCSI_QDEPTH_QFULL:
scsi_track_queue_full(sdev, qdepth);
break;
case SCSI_QDEPTH_RAMP_UP:
scsi_adjust_queue_depth(sdev, qdepth);
break;
default:
return -EOPNOTSUPP;
}
return sdev->queue_depth;
}
EXPORT_SYMBOL(fc_change_queue_depth);
/**
* fc_fcp_destory() - Tear down the FCP layer for a given local port
* @lport: The local port that no longer needs the FCP layer

View file

@ -1771,25 +1771,6 @@ fault:
}
EXPORT_SYMBOL_GPL(iscsi_queuecommand);
int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
{
switch (reason) {
case SCSI_QDEPTH_DEFAULT:
scsi_adjust_queue_depth(sdev, depth);
break;
case SCSI_QDEPTH_QFULL:
scsi_track_queue_full(sdev, depth);
break;
case SCSI_QDEPTH_RAMP_UP:
scsi_adjust_queue_depth(sdev, depth);
break;
default:
return -EOPNOTSUPP;
}
return sdev->queue_depth;
}
EXPORT_SYMBOL_GPL(iscsi_change_queue_depth);
int iscsi_target_alloc(struct scsi_target *starget)
{
struct iscsi_cls_session *cls_session = starget_to_session(starget);

View file

@ -171,7 +171,6 @@ static void sas_ata_task_done(struct sas_task *task)
spin_unlock_irqrestore(ap->lock, flags);
qc_already_gone:
list_del_init(&task->list);
sas_free_task(task);
}
@ -244,12 +243,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
if (qc->scsicmd)
ASSIGN_SAS_TASK(qc->scsicmd, task);
if (sas_ha->lldd_max_execute_num < 2)
ret = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC);
else
ret = sas_queue_up(task);
/* Examine */
ret = i->dft->lldd_execute_task(task, GFP_ATOMIC);
if (ret) {
SAS_DPRINTK("lldd_execute_task returned: %d\n", ret);
@ -485,7 +479,6 @@ static void sas_ata_internal_abort(struct sas_task *task)
return;
out:
list_del_init(&task->list);
sas_free_task(task);
}

View file

@ -96,7 +96,7 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
task->slow_task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
add_timer(&task->slow_task->timer);
res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
res = i->dft->lldd_execute_task(task, GFP_KERNEL);
if (res) {
del_timer(&task->slow_task->timer);

View file

@ -45,7 +45,6 @@ struct sas_task *sas_alloc_task(gfp_t flags)
struct sas_task *task = kmem_cache_zalloc(sas_task_cache, flags);
if (task) {
INIT_LIST_HEAD(&task->list);
spin_lock_init(&task->task_state_lock);
task->task_state_flags = SAS_TASK_STATE_PENDING;
}
@ -77,7 +76,6 @@ EXPORT_SYMBOL_GPL(sas_alloc_slow_task);
void sas_free_task(struct sas_task *task)
{
if (task) {
BUG_ON(!list_empty(&task->list));
kfree(task->slow_task);
kmem_cache_free(sas_task_cache, task);
}
@ -127,11 +125,6 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
spin_lock_init(&sas_ha->phy_port_lock);
sas_hash_addr(sas_ha->hashed_sas_addr, sas_ha->sas_addr);
if (sas_ha->lldd_queue_size == 0)
sas_ha->lldd_queue_size = 1;
else if (sas_ha->lldd_queue_size == -1)
sas_ha->lldd_queue_size = 128; /* Sanity */
set_bit(SAS_HA_REGISTERED, &sas_ha->state);
spin_lock_init(&sas_ha->lock);
mutex_init(&sas_ha->drain_mutex);
@ -157,15 +150,6 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
goto Undo_ports;
}
if (sas_ha->lldd_max_execute_num > 1) {
error = sas_init_queue(sas_ha);
if (error) {
printk(KERN_NOTICE "couldn't start queue thread:%d, "
"running in direct mode\n", error);
sas_ha->lldd_max_execute_num = 1;
}
}
INIT_LIST_HEAD(&sas_ha->eh_done_q);
INIT_LIST_HEAD(&sas_ha->eh_ata_q);
@ -201,11 +185,6 @@ int sas_unregister_ha(struct sas_ha_struct *sas_ha)
__sas_drain_work(sas_ha);
mutex_unlock(&sas_ha->drain_mutex);
if (sas_ha->lldd_max_execute_num > 1) {
sas_shutdown_queue(sas_ha);
sas_ha->lldd_max_execute_num = 1;
}
return 0;
}

View file

@ -66,9 +66,7 @@ void sas_unregister_ports(struct sas_ha_struct *sas_ha);
enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *);
int sas_init_queue(struct sas_ha_struct *sas_ha);
int sas_init_events(struct sas_ha_struct *sas_ha);
void sas_shutdown_queue(struct sas_ha_struct *sas_ha);
void sas_disable_revalidation(struct sas_ha_struct *ha);
void sas_enable_revalidation(struct sas_ha_struct *ha);
void __sas_drain_work(struct sas_ha_struct *ha);

View file

@ -112,7 +112,6 @@ static void sas_end_task(struct scsi_cmnd *sc, struct sas_task *task)
sc->result = (hs << 16) | stat;
ASSIGN_SAS_TASK(sc, NULL);
list_del_init(&task->list);
sas_free_task(task);
}
@ -138,7 +137,6 @@ static void sas_scsi_task_done(struct sas_task *task)
if (unlikely(!sc)) {
SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
list_del_init(&task->list);
sas_free_task(task);
return;
}
@ -179,31 +177,10 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
return task;
}
int sas_queue_up(struct sas_task *task)
{
struct sas_ha_struct *sas_ha = task->dev->port->ha;
struct scsi_core *core = &sas_ha->core;
unsigned long flags;
LIST_HEAD(list);
spin_lock_irqsave(&core->task_queue_lock, flags);
if (sas_ha->lldd_queue_size < core->task_queue_size + 1) {
spin_unlock_irqrestore(&core->task_queue_lock, flags);
return -SAS_QUEUE_FULL;
}
list_add_tail(&task->list, &core->task_queue);
core->task_queue_size += 1;
spin_unlock_irqrestore(&core->task_queue_lock, flags);
wake_up_process(core->queue_thread);
return 0;
}
int sas_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
{
struct sas_internal *i = to_sas_internal(host->transportt);
struct domain_device *dev = cmd_to_domain_dev(cmd);
struct sas_ha_struct *sas_ha = dev->port->ha;
struct sas_task *task;
int res = 0;
@ -224,12 +201,7 @@ int sas_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
if (!task)
return SCSI_MLQUEUE_HOST_BUSY;
/* Queue up, Direct Mode or Task Collector Mode. */
if (sas_ha->lldd_max_execute_num < 2)
res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC);
else
res = sas_queue_up(task);
res = i->dft->lldd_execute_task(task, GFP_ATOMIC);
if (res)
goto out_free_task;
return 0;
@ -323,37 +295,17 @@ enum task_disposition {
TASK_IS_DONE,
TASK_IS_ABORTED,
TASK_IS_AT_LU,
TASK_IS_NOT_AT_HA,
TASK_IS_NOT_AT_LU,
TASK_ABORT_FAILED,
};
static enum task_disposition sas_scsi_find_task(struct sas_task *task)
{
struct sas_ha_struct *ha = task->dev->port->ha;
unsigned long flags;
int i, res;
struct sas_internal *si =
to_sas_internal(task->dev->port->ha->core.shost->transportt);
if (ha->lldd_max_execute_num > 1) {
struct scsi_core *core = &ha->core;
struct sas_task *t, *n;
mutex_lock(&core->task_queue_flush);
spin_lock_irqsave(&core->task_queue_lock, flags);
list_for_each_entry_safe(t, n, &core->task_queue, list)
if (task == t) {
list_del_init(&t->list);
break;
}
spin_unlock_irqrestore(&core->task_queue_lock, flags);
mutex_unlock(&core->task_queue_flush);
if (task == t)
return TASK_IS_NOT_AT_HA;
}
for (i = 0; i < 5; i++) {
SAS_DPRINTK("%s: aborting task 0x%p\n", __func__, task);
res = si->dft->lldd_abort_task(task);
@ -667,14 +619,6 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head *
cmd->eh_eflags = 0;
switch (res) {
case TASK_IS_NOT_AT_HA:
SAS_DPRINTK("%s: task 0x%p is not at ha: %s\n",
__func__, task,
cmd->retries ? "retry" : "aborted");
if (cmd->retries)
cmd->retries--;
sas_eh_finish_cmd(cmd);
continue;
case TASK_IS_DONE:
SAS_DPRINTK("%s: task 0x%p is done\n", __func__,
task);
@ -836,9 +780,6 @@ retry:
scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q);
out:
if (ha->lldd_max_execute_num > 1)
wake_up_process(ha->core.queue_thread);
sas_eh_handle_resets(shost);
/* now link into libata eh --- if we have any ata devices */
@ -940,12 +881,12 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
sas_read_port_mode_page(scsi_dev);
if (scsi_dev->tagged_supported) {
scsi_adjust_queue_depth(scsi_dev, SAS_DEF_QD);
scsi_change_queue_depth(scsi_dev, SAS_DEF_QD);
} else {
SAS_DPRINTK("device %llx, LUN %llx doesn't support "
"TCQ\n", SAS_ADDR(dev->sas_addr),
scsi_dev->lun);
scsi_adjust_queue_depth(scsi_dev, 1);
scsi_change_queue_depth(scsi_dev, 1);
}
scsi_dev->allow_restart = 1;
@ -953,29 +894,16 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
return 0;
}
int sas_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
int sas_change_queue_depth(struct scsi_device *sdev, int depth)
{
struct domain_device *dev = sdev_to_domain_dev(sdev);
if (dev_is_sata(dev))
return __ata_change_queue_depth(dev->sata_dev.ap, sdev, depth,
reason);
return __ata_change_queue_depth(dev->sata_dev.ap, sdev, depth);
switch (reason) {
case SCSI_QDEPTH_DEFAULT:
case SCSI_QDEPTH_RAMP_UP:
if (!sdev->tagged_supported)
depth = 1;
scsi_adjust_queue_depth(sdev, depth);
break;
case SCSI_QDEPTH_QFULL:
scsi_track_queue_full(sdev, depth);
break;
default:
return -EOPNOTSUPP;
}
return depth;
if (!sdev->tagged_supported)
depth = 1;
return scsi_change_queue_depth(sdev, depth);
}
int sas_change_queue_type(struct scsi_device *scsi_dev, int type)
@ -997,121 +925,6 @@ int sas_bios_param(struct scsi_device *scsi_dev,
return 0;
}
/* ---------- Task Collector Thread implementation ---------- */
static void sas_queue(struct sas_ha_struct *sas_ha)
{
struct scsi_core *core = &sas_ha->core;
unsigned long flags;
LIST_HEAD(q);
int can_queue;
int res;
struct sas_internal *i = to_sas_internal(core->shost->transportt);
mutex_lock(&core->task_queue_flush);
spin_lock_irqsave(&core->task_queue_lock, flags);
while (!kthread_should_stop() &&
!list_empty(&core->task_queue) &&
!test_bit(SAS_HA_FROZEN, &sas_ha->state)) {
can_queue = sas_ha->lldd_queue_size - core->task_queue_size;
if (can_queue >= 0) {
can_queue = core->task_queue_size;
list_splice_init(&core->task_queue, &q);
} else {
struct list_head *a, *n;
can_queue = sas_ha->lldd_queue_size;
list_for_each_safe(a, n, &core->task_queue) {
list_move_tail(a, &q);
if (--can_queue == 0)
break;
}
can_queue = sas_ha->lldd_queue_size;
}
core->task_queue_size -= can_queue;
spin_unlock_irqrestore(&core->task_queue_lock, flags);
{
struct sas_task *task = list_entry(q.next,
struct sas_task,
list);
list_del_init(&q);
res = i->dft->lldd_execute_task(task, can_queue,
GFP_KERNEL);
if (unlikely(res))
__list_add(&q, task->list.prev, &task->list);
}
spin_lock_irqsave(&core->task_queue_lock, flags);
if (res) {
list_splice_init(&q, &core->task_queue); /*at head*/
core->task_queue_size += can_queue;
}
}
spin_unlock_irqrestore(&core->task_queue_lock, flags);
mutex_unlock(&core->task_queue_flush);
}
/**
* sas_queue_thread -- The Task Collector thread
* @_sas_ha: pointer to struct sas_ha
*/
static int sas_queue_thread(void *_sas_ha)
{
struct sas_ha_struct *sas_ha = _sas_ha;
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
sas_queue(sas_ha);
if (kthread_should_stop())
break;
}
return 0;
}
int sas_init_queue(struct sas_ha_struct *sas_ha)
{
struct scsi_core *core = &sas_ha->core;
spin_lock_init(&core->task_queue_lock);
mutex_init(&core->task_queue_flush);
core->task_queue_size = 0;
INIT_LIST_HEAD(&core->task_queue);
core->queue_thread = kthread_run(sas_queue_thread, sas_ha,
"sas_queue_%d", core->shost->host_no);
if (IS_ERR(core->queue_thread))
return PTR_ERR(core->queue_thread);
return 0;
}
void sas_shutdown_queue(struct sas_ha_struct *sas_ha)
{
unsigned long flags;
struct scsi_core *core = &sas_ha->core;
struct sas_task *task, *n;
kthread_stop(core->queue_thread);
if (!list_empty(&core->task_queue))
SAS_DPRINTK("HA: %llx: scsi core task queue is NOT empty!?\n",
SAS_ADDR(sas_ha->sas_addr));
spin_lock_irqsave(&core->task_queue_lock, flags);
list_for_each_entry_safe(task, n, &core->task_queue, list) {
struct scsi_cmnd *cmd = task->uldd_task;
list_del_init(&task->list);
ASSIGN_SAS_TASK(cmd, NULL);
sas_free_task(task);
cmd->result = DID_ABORT << 16;
cmd->scsi_done(cmd);
}
spin_unlock_irqrestore(&core->task_queue_lock, flags);
}
/*
* Tell an upper layer that it needs to initiate an abort for a given task.
* This should only ever be called by an LLDD.

View file

@ -242,108 +242,6 @@ lpfc_update_stats(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
spin_unlock_irqrestore(shost->host_lock, flags);
}
/**
* lpfc_send_sdev_queuedepth_change_event - Posts a queuedepth change event
* @phba: Pointer to HBA context object.
* @vport: Pointer to vport object.
* @ndlp: Pointer to FC node associated with the target.
* @lun: Lun number of the scsi device.
* @old_val: Old value of the queue depth.
* @new_val: New value of the queue depth.
*
* This function sends an event to the mgmt application indicating
* there is a change in the scsi device queue depth.
**/
static void
lpfc_send_sdev_queuedepth_change_event(struct lpfc_hba *phba,
struct lpfc_vport *vport,
struct lpfc_nodelist *ndlp,
uint64_t lun,
uint32_t old_val,
uint32_t new_val)
{
struct lpfc_fast_path_event *fast_path_evt;
unsigned long flags;
fast_path_evt = lpfc_alloc_fast_evt(phba);
if (!fast_path_evt)
return;
fast_path_evt->un.queue_depth_evt.scsi_event.event_type =
FC_REG_SCSI_EVENT;
fast_path_evt->un.queue_depth_evt.scsi_event.subcategory =
LPFC_EVENT_VARQUEDEPTH;
/* Report all luns with change in queue depth */
fast_path_evt->un.queue_depth_evt.scsi_event.lun = lun;
if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
memcpy(&fast_path_evt->un.queue_depth_evt.scsi_event.wwpn,
&ndlp->nlp_portname, sizeof(struct lpfc_name));
memcpy(&fast_path_evt->un.queue_depth_evt.scsi_event.wwnn,
&ndlp->nlp_nodename, sizeof(struct lpfc_name));
}
fast_path_evt->un.queue_depth_evt.oldval = old_val;
fast_path_evt->un.queue_depth_evt.newval = new_val;
fast_path_evt->vport = vport;
fast_path_evt->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT;
spin_lock_irqsave(&phba->hbalock, flags);
list_add_tail(&fast_path_evt->work_evt.evt_listp, &phba->work_list);
spin_unlock_irqrestore(&phba->hbalock, flags);
lpfc_worker_wake_up(phba);
return;
}
/**
* lpfc_change_queue_depth - Alter scsi device queue depth
* @sdev: Pointer the scsi device on which to change the queue depth.
* @qdepth: New queue depth to set the sdev to.
* @reason: The reason for the queue depth change.
*
* This function is called by the midlayer and the LLD to alter the queue
* depth for a scsi device. This function sets the queue depth to the new
* value and sends an event out to log the queue depth change.
**/
static int
lpfc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
{
struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
struct lpfc_hba *phba = vport->phba;
struct lpfc_rport_data *rdata;
unsigned long new_queue_depth, old_queue_depth;
old_queue_depth = sdev->queue_depth;
switch (reason) {
case SCSI_QDEPTH_DEFAULT:
/* change request from sysfs, fall through */
case SCSI_QDEPTH_RAMP_UP:
scsi_adjust_queue_depth(sdev, qdepth);
break;
case SCSI_QDEPTH_QFULL:
if (scsi_track_queue_full(sdev, qdepth) == 0)
return sdev->queue_depth;
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
"0711 detected queue full - lun queue "
"depth adjusted to %d.\n", sdev->queue_depth);
break;
default:
return -EOPNOTSUPP;
}
new_queue_depth = sdev->queue_depth;
rdata = lpfc_rport_data_from_scsi_device(sdev);
if (rdata)
lpfc_send_sdev_queuedepth_change_event(phba, vport,
rdata->pnode, sdev->lun,
old_queue_depth,
new_queue_depth);
return sdev->queue_depth;
}
/**
* lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread
* @phba: The Hba for which this call is being executed.
@ -429,8 +327,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
else
new_queue_depth = sdev->queue_depth -
new_queue_depth;
lpfc_change_queue_depth(sdev, new_queue_depth,
SCSI_QDEPTH_DEFAULT);
scsi_change_queue_depth(sdev, new_queue_depth);
}
}
lpfc_destroy_vport_work_array(phba, vports);
@ -5598,7 +5495,7 @@ lpfc_slave_configure(struct scsi_device *sdev)
struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
struct lpfc_hba *phba = vport->phba;
scsi_adjust_queue_depth(sdev, vport->cfg_lun_queue_depth);
scsi_change_queue_depth(sdev, vport->cfg_lun_queue_depth);
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
lpfc_sli_handle_fast_ring_event(phba,
@ -5981,9 +5878,10 @@ struct scsi_host_template lpfc_template = {
.shost_attrs = lpfc_hba_attrs,
.max_sectors = 0xFFFF,
.vendor_id = LPFC_NL_VENDOR_ID,
.change_queue_depth = lpfc_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.change_queue_type = scsi_change_queue_type,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
struct scsi_host_template lpfc_vport_template = {
@ -6005,7 +5903,8 @@ struct scsi_host_template lpfc_vport_template = {
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = lpfc_vport_attrs,
.max_sectors = 0xFFFF,
.change_queue_depth = lpfc_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.change_queue_type = scsi_change_queue_type,
.use_blk_tags = 1,
.track_queue_depth = 1,
};

View file

@ -9,69 +9,62 @@
* Generic Generic NCR5380 driver
*
* Copyright 1995, Russell King
*
* ALPHA RELEASE 1.
*
* For more information, please consult
*
* NCR 5380 Family
* SCSI Protocol Controller
* Databook
*
* NCR Microelectronics
* 1635 Aeroplaza Drive
* Colorado Springs, CO 80916
* 1+ (719) 578-3400
* 1+ (800) 334-5454
*/
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/hwtest.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/macintosh.h>
#include <asm/macints.h>
#include <asm/mac_via.h>
#include <asm/setup.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "mac_scsi.h"
/* These control the behaviour of the generic 5380 core */
#define AUTOSENSE
/* Definitions for the core NCR5380 driver. */
#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_pread macscsi_pread
#define NCR5380_pwrite macscsi_pwrite
#define NCR5380_intr macscsi_intr
#define NCR5380_queue_command macscsi_queue_command
#define NCR5380_abort macscsi_abort
#define NCR5380_bus_reset macscsi_bus_reset
#define NCR5380_info macscsi_info
#define NCR5380_show_info macscsi_show_info
#define NCR5380_write_info macscsi_write_info
#include "NCR5380.h"
#define RESET_BOOT
#define DRIVER_SETUP
extern void via_scsi_clear(void);
#ifdef RESET_BOOT
static void mac_scsi_reset_boot(struct Scsi_Host *instance);
#endif
static int setup_called = 0;
static int setup_can_queue = -1;
module_param(setup_can_queue, int, 0);
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);
static int setup_use_pdma = -1;
#ifdef SUPPORT_TAGS
module_param(setup_use_pdma, int, 0);
static int setup_use_tagged_queuing = -1;
#endif
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
@ -84,232 +77,48 @@ static int setup_hostid = -1;
#define AFTER_RESET_DELAY (HZ/2)
#endif
static volatile unsigned char *mac_scsi_regp = NULL;
static volatile unsigned char *mac_scsi_drq = NULL;
static volatile unsigned char *mac_scsi_nodrq = NULL;
/*
* NCR 5380 register access functions
*/
#if 0
/* Debug versions */
#define CTRL(p,v) (*ctrl = (v))
static char macscsi_read(struct Scsi_Host *instance, int reg)
static inline char macscsi_read(struct Scsi_Host *instance, int reg)
{
int iobase = instance->io_port;
int i;
int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
CTRL(iobase, 0);
i = in_8(iobase + (reg<<4));
CTRL(iobase, 0x40);
return i;
return in_8(instance->base + (reg << 4));
}
static void macscsi_write(struct Scsi_Host *instance, int reg, int value)
static inline void macscsi_write(struct Scsi_Host *instance, int reg, int value)
{
int iobase = instance->io_port;
int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
CTRL(iobase, 0);
out_8(iobase + (reg<<4), value);
CTRL(iobase, 0x40);
}
#else
/* Fast versions */
static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg)
{
return in_8(instance->io_port + (reg<<4));
out_8(instance->base + (reg << 4), value);
}
static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value)
#ifndef MODULE
static int __init mac_scsi_setup(char *str)
{
out_8(instance->io_port + (reg<<4), value);
}
#endif
/*
* Function : mac_scsi_setup(char *str)
*
* Purpose : booter command line initialization of the overrides array,
*
* Inputs : str - comma delimited list of options
*
*/
static int __init mac_scsi_setup(char *str) {
#ifdef DRIVER_SETUP
int ints[7];
(void)get_options( str, ARRAY_SIZE(ints), ints);
if (setup_called++ || ints[0] < 1 || ints[0] > 6) {
printk(KERN_WARNING "scsi: <mac5380>"
" Usage: mac5380=<can_queue>[,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>,<use_pdma>]\n");
printk(KERN_ALERT "scsi: <mac5380> Bad Penguin parameters?\n");
return 0;
(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");
return 0;
}
if (ints[0] >= 1) {
if (ints[1] > 0)
/* no limits on this, just > 0 */
setup_can_queue = ints[1];
}
if (ints[0] >= 2) {
if (ints[2] > 0)
setup_cmd_per_lun = ints[2];
}
if (ints[0] >= 3) {
if (ints[3] >= 0) {
setup_sg_tablesize = ints[3];
/* Must be <= SG_ALL (255) */
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];
else if (ints[4] > 7)
printk(KERN_WARNING "mac_scsi_setup: invalid host ID %d !\n", ints[4] );
}
#ifdef SUPPORT_TAGS
if (ints[0] >= 5) {
if (ints[5] >= 0)
setup_use_tagged_queuing = !!ints[5];
}
if (ints[0] == 6) {
if (ints[6] >= 0)
if (ints[0] >= 1)
setup_can_queue = ints[1];
if (ints[0] >= 2)
setup_cmd_per_lun = ints[2];
if (ints[0] >= 3)
setup_sg_tablesize = ints[3];
if (ints[0] >= 4)
setup_hostid = ints[4];
if (ints[0] >= 5)
setup_use_tagged_queuing = ints[5];
if (ints[0] >= 6)
setup_use_pdma = ints[6];
}
#else
if (ints[0] == 5) {
if (ints[5] >= 0)
setup_use_pdma = ints[5];
}
#endif /* SUPPORT_TAGS */
#endif /* DRIVER_SETUP */
return 1;
}
__setup("mac5380=", mac_scsi_setup);
/*
* Function : int macscsi_detect(struct scsi_host_template * tpnt)
*
* Purpose : initializes mac NCR5380 driver based on the
* command line / compile time port and irq definitions.
*
* Inputs : tpnt - template for this SCSI adapter.
*
* Returns : 1 if a host adapter was found, 0 if not.
*
*/
int __init macscsi_detect(struct scsi_host_template * tpnt)
{
static int called = 0;
int flags = 0;
struct Scsi_Host *instance;
if (!MACH_IS_MAC || called)
return( 0 );
if (macintosh_config->scsi_type != MAC_SCSI_OLD)
return( 0 );
/* setup variables */
tpnt->can_queue =
(setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE;
tpnt->cmd_per_lun =
(setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN;
tpnt->sg_tablesize =
(setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE;
if (setup_hostid >= 0)
tpnt->this_id = setup_hostid;
else {
/* use 7 as default */
tpnt->this_id = 7;
}
#ifdef SUPPORT_TAGS
if (setup_use_tagged_queuing < 0)
setup_use_tagged_queuing = USE_TAGGED_QUEUING;
#endif
/* Once we support multiple 5380s (e.g. DuoDock) we'll do
something different here */
instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
if (instance == NULL)
return 0;
if (macintosh_config->ident == MAC_MODEL_IIFX) {
mac_scsi_regp = via1+0x8000;
mac_scsi_drq = via1+0xE000;
mac_scsi_nodrq = via1+0xC000;
/* The IIFX should be able to do true DMA, but pseudo-dma doesn't work */
flags = FLAG_NO_PSEUDO_DMA;
} else {
mac_scsi_regp = via1+0x10000;
mac_scsi_drq = via1+0x6000;
mac_scsi_nodrq = via1+0x12000;
}
if (! setup_use_pdma)
flags = FLAG_NO_PSEUDO_DMA;
instance->io_port = (unsigned long) mac_scsi_regp;
instance->irq = IRQ_MAC_SCSI;
#ifdef RESET_BOOT
mac_scsi_reset_boot(instance);
#endif
NCR5380_init(instance, flags);
instance->n_io_port = 255;
((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0;
if (instance->irq != SCSI_IRQ_NONE)
if (request_irq(instance->irq, NCR5380_intr, 0, "ncr5380", instance)) {
printk(KERN_WARNING "scsi%d: IRQ%d not free, interrupts disabled\n",
instance->host_no, instance->irq);
instance->irq = SCSI_IRQ_NONE;
}
printk(KERN_INFO "scsi%d: generic 5380 at port %lX irq", instance->host_no, instance->io_port);
if (instance->irq == SCSI_IRQ_NONE)
printk (KERN_INFO "s disabled");
else
printk (KERN_INFO " %d", instance->irq);
printk(KERN_INFO " options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
instance->can_queue, instance->cmd_per_lun, MACSCSI_PUBLIC_RELEASE);
printk(KERN_INFO "\nscsi%d:", instance->host_no);
NCR5380_print_options(instance);
printk("\n");
called = 1;
return 1;
}
int macscsi_release (struct Scsi_Host *shpnt)
{
if (shpnt->irq != SCSI_IRQ_NONE)
free_irq(shpnt->irq, shpnt);
NCR5380_exit(shpnt);
return 0;
}
#endif /* !MODULE */
#ifdef RESET_BOOT
/*
@ -349,10 +158,7 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance)
}
#endif
const char * macscsi_info (struct Scsi_Host *spnt) {
return "";
}
#ifdef PSEUDO_DMA
/*
Pseudo-DMA: (Ove Edlund)
The code attempts to catch bus errors that occur if one for example
@ -422,38 +228,39 @@ __asm__ __volatile__ \
: "0"(s), "1"(d), "2"(len) \
: "d0")
static int macscsi_pread (struct Scsi_Host *instance,
unsigned char *dst, int len)
static int macscsi_pread(struct Scsi_Host *instance,
unsigned char *dst, int len)
{
unsigned char *d;
volatile unsigned char *s;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char *d;
unsigned char *s;
NCR5380_local_declare();
NCR5380_setup(instance);
NCR5380_local_declare();
NCR5380_setup(instance);
s = mac_scsi_drq+0x60;
d = dst;
s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
d = dst;
/* These conditions are derived from MacOS */
/* These conditions are derived from MacOS */
while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)
&& !(NCR5380_read(STATUS_REG) & SR_REQ))
;
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)
&& (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
printk(KERN_ERR "Error in macscsi_pread\n");
return -1;
}
while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
!(NCR5380_read(STATUS_REG) & SR_REQ))
;
CP_IO_TO_MEM(s, d, len);
if (len != 0) {
printk(KERN_NOTICE "Bus error in macscsi_pread\n");
return -1;
}
return 0;
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
pr_err("Error in macscsi_pread\n");
return -1;
}
CP_IO_TO_MEM(s, d, len);
if (len != 0) {
pr_notice("Bus error in macscsi_pread\n");
return -1;
}
return 0;
}
@ -515,59 +322,172 @@ __asm__ __volatile__ \
: "0"(s), "1"(d), "2"(len) \
: "d0")
static int macscsi_pwrite (struct Scsi_Host *instance,
unsigned char *src, int len)
static int macscsi_pwrite(struct Scsi_Host *instance,
unsigned char *src, int len)
{
unsigned char *s;
volatile unsigned char *d;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char *s;
unsigned char *d;
NCR5380_local_declare();
NCR5380_setup(instance);
NCR5380_local_declare();
NCR5380_setup(instance);
s = src;
d = mac_scsi_drq;
/* These conditions are derived from MacOS */
s = src;
d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)
&& (!(NCR5380_read(STATUS_REG) & SR_REQ)
|| (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)))
;
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)) {
printk(KERN_ERR "Error in macscsi_pwrite\n");
return -1;
}
/* These conditions are derived from MacOS */
CP_MEM_TO_IO(s, d, len);
while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
(!(NCR5380_read(STATUS_REG) & SR_REQ) ||
(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)))
;
if (len != 0) {
printk(KERN_NOTICE "Bus error in macscsi_pwrite\n");
return -1;
}
return 0;
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)) {
pr_err("Error in macscsi_pwrite\n");
return -1;
}
CP_MEM_TO_IO(s, d, len);
if (len != 0) {
pr_notice("Bus error in macscsi_pwrite\n");
return -1;
}
return 0;
}
#endif
#include "NCR5380.c"
static struct scsi_host_template driver_template = {
.proc_name = "Mac5380",
#define DRV_MODULE_NAME "mac_scsi"
#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",
.detect = macscsi_detect,
.release = macscsi_release,
.info = macscsi_info,
.queuecommand = macscsi_queue_command,
.eh_abort_handler = macscsi_abort,
.eh_bus_reset_handler = macscsi_bus_reset,
.can_queue = CAN_QUEUE,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING
};
static int __init mac_scsi_probe(struct platform_device *pdev)
{
struct Scsi_Host *instance;
int error;
int host_flags = 0;
struct resource *irq, *pio_mem, *pdma_mem = NULL;
#include "scsi_module.c"
pio_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!pio_mem)
return -ENODEV;
#ifdef PSEUDO_DMA
pdma_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
#endif
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!hwreg_present((unsigned char *)pio_mem->start +
(STATUS_REG << 4))) {
pr_info(PFX "no device detected at %pap\n", &pio_mem->start);
return -ENODEV;
}
if (setup_can_queue > 0)
mac_scsi_template.can_queue = setup_can_queue;
if (setup_cmd_per_lun > 0)
mac_scsi_template.cmd_per_lun = setup_cmd_per_lun;
if (setup_sg_tablesize >= 0)
mac_scsi_template.sg_tablesize = setup_sg_tablesize;
if (setup_hostid >= 0)
mac_scsi_template.this_id = setup_hostid & 7;
if (setup_use_pdma < 0)
setup_use_pdma = 0;
instance = scsi_host_alloc(&mac_scsi_template,
sizeof(struct NCR5380_hostdata));
if (!instance)
return -ENOMEM;
instance->base = pio_mem->start;
if (irq)
instance->irq = irq->start;
else
instance->irq = NO_IRQ;
if (pdma_mem && setup_use_pdma) {
struct NCR5380_hostdata *hostdata = shost_priv(instance);
hostdata->pdma_base = (unsigned char *)pdma_mem->start;
} 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
NCR5380_init(instance, host_flags);
if (instance->irq != NO_IRQ) {
error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED,
"NCR5380", instance);
if (error)
goto fail_irq;
}
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 (instance->irq != NO_IRQ)
free_irq(instance->irq, instance);
fail_irq:
NCR5380_exit(instance);
scsi_host_put(instance);
return error;
}
static int __exit mac_scsi_remove(struct platform_device *pdev)
{
struct Scsi_Host *instance = platform_get_drvdata(pdev);
scsi_remove_host(instance);
if (instance->irq != NO_IRQ)
free_irq(instance->irq, instance);
NCR5380_exit(instance);
scsi_host_put(instance);
return 0;
}
static struct platform_driver mac_scsi_driver = {
.remove = __exit_p(mac_scsi_remove),
.driver = {
.name = DRV_MODULE_NAME,
.owner = THIS_MODULE,
},
};
module_platform_driver_probe(mac_scsi_driver, mac_scsi_probe);
MODULE_ALIAS("platform:" DRV_MODULE_NAME);
MODULE_LICENSE("GPL");

View file

@ -1,74 +0,0 @@
/*
* Cumana Generic NCR5380 driver defines
*
* Copyright 1993, Drew Eckhardt
* Visionary Computing
* (Unix and Linux consulting and custom programming)
* drew@colorado.edu
* +1 (303) 440-4894
*
* ALPHA RELEASE 1.
*
* For more information, please consult
*
* NCR 5380 Family
* SCSI Protocol Controller
* Databook
*
* NCR Microelectronics
* 1635 Aeroplaza Drive
* Colorado Springs, CO 80916
* 1+ (719) 578-3400
* 1+ (800) 334-5454
*/
#ifndef MAC_NCR5380_H
#define MAC_NCR5380_H
#define MACSCSI_PUBLIC_RELEASE 2
#ifndef ASM
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
#ifndef CAN_QUEUE
#define CAN_QUEUE 16
#endif
#ifndef SG_TABLESIZE
#define SG_TABLESIZE SG_NONE
#endif
#ifndef USE_TAGGED_QUEUING
#define USE_TAGGED_QUEUING 0
#endif
#include <scsi/scsicam.h>
#define NCR5380_implementation_fields \
int port, ctrl
#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_pread macscsi_pread
#define NCR5380_pwrite macscsi_pwrite
#define NCR5380_intr macscsi_intr
#define NCR5380_queue_command macscsi_queue_command
#define NCR5380_abort macscsi_abort
#define NCR5380_bus_reset macscsi_bus_reset
#define NCR5380_show_info macscsi_show_info
#define NCR5380_write_info macscsi_write_info
#endif /* ndef ASM */
#endif /* MAC_NCR5380_H */

View file

@ -332,27 +332,6 @@ static struct device_attribute *megaraid_sdev_attrs[] = {
NULL,
};
/**
* megaraid_change_queue_depth - Change the device's queue depth
* @sdev: scsi device struct
* @qdepth: depth to set
* @reason: calling context
*
* Return value:
* actual depth set
*/
static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth,
int reason)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (qdepth > MBOX_MAX_SCSI_CMDS)
qdepth = MBOX_MAX_SCSI_CMDS;
scsi_adjust_queue_depth(sdev, qdepth);
return sdev->queue_depth;
}
/*
* Scsi host template for megaraid unified driver
*/
@ -365,7 +344,7 @@ static struct scsi_host_template megaraid_template_g = {
.eh_device_reset_handler = megaraid_reset_handler,
.eh_bus_reset_handler = megaraid_reset_handler,
.eh_host_reset_handler = megaraid_reset_handler,
.change_queue_depth = megaraid_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.use_clustering = ENABLE_CLUSTERING,
.no_write_same = 1,
.sdev_attrs = megaraid_sdev_attrs,

View file

@ -1,7 +1,8 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
* Copyright (c) 2003-2012 LSI Corporation.
* Copyright (c) 2003-2013 LSI Corporation
* Copyright (c) 2013-2014 Avago Technologies
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -14,17 +15,18 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* FILE: megaraid_sas.h
*
* Authors: LSI Corporation
* Authors: Avago Technologies
* Kashyap Desai <kashyap.desai@avagotech.com>
* Sumit Saxena <sumit.saxena@avagotech.com>
*
* Send feedback to: <megaraidlinux@lsi.com>
* Send feedback to: megaraidlinux.pdl@avagotech.com
*
* Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
* ATTN: Linuxraid
* Mail to: Avago Technologies, 350 West Trimble Road, Building 90,
* San Jose, California 95131
*/
#ifndef LSI_MEGARAID_SAS_H
@ -33,9 +35,7 @@
/*
* MegaRAID SAS Driver meta data
*/
#define MEGASAS_VERSION "06.805.06.00-rc1"
#define MEGASAS_RELDATE "Sep. 4, 2014"
#define MEGASAS_EXT_VERSION "Thu. Sep. 4 17:00:00 PDT 2014"
#define MEGASAS_VERSION "06.805.06.01-rc1"
/*
* Device IDs
@ -1931,8 +1931,7 @@ u16 get_updated_dev_handle(struct megasas_instance *instance,
struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info);
void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
struct LD_LOAD_BALANCE_INFO *lbInfo);
int megasas_get_ctrl_info(struct megasas_instance *instance,
struct megasas_ctrl_info *ctrl_info);
int megasas_get_ctrl_info(struct megasas_instance *instance);
int megasas_set_crash_dump_params(struct megasas_instance *instance,
u8 crash_buf_state);
void megasas_free_host_crash_buffer(struct megasas_instance *instance);

View file

@ -1,7 +1,8 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
* Copyright (c) 2003-2012 LSI Corporation.
* Copyright (c) 2003-2013 LSI Corporation
* Copyright (c) 2013-2014 Avago Technologies
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -14,22 +15,20 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* FILE: megaraid_sas_base.c
* Version : 06.805.06.00-rc1
*
* Authors: LSI Corporation
* Authors: Avago Technologies
* Sreenivas Bagalkote
* Sumant Patro
* Bo Yang
* Adam Radford <linuxraid@lsi.com>
* Adam Radford
* Kashyap Desai <kashyap.desai@avagotech.com>
* Sumit Saxena <sumit.saxena@avagotech.com>
*
* Send feedback to: <megaraidlinux@lsi.com>
* Send feedback to: megaraidlinux.pdl@avagotech.com
*
* Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
* ATTN: Linuxraid
* Mail to: Avago Technologies, 350 West Trimble Road, Building 90,
* San Jose, California 95131
*/
#include <linux/kernel.h>
@ -1008,7 +1007,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr));
cmd->sync_cmd = 1;
cmd->cmd_status = 0xFF;
cmd->cmd_status = ENODATA;
instance->instancet->issue_dcmd(instance, cmd);
@ -1572,6 +1571,12 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
instance = (struct megasas_instance *)
scmd->device->host->hostdata;
if (instance->unload == 1) {
scmd->result = DID_NO_CONNECT << 16;
scmd->scsi_done(scmd);
return 0;
}
if (instance->issuepend_done == 0)
return SCSI_MLQUEUE_HOST_BUSY;
@ -2586,19 +2591,6 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
}
}
static int megasas_change_queue_depth(struct scsi_device *sdev,
int queue_depth, int reason)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth > sdev->host->can_queue)
queue_depth = sdev->host->can_queue;
scsi_adjust_queue_depth(sdev, queue_depth);
return queue_depth;
}
static ssize_t
megasas_fw_crash_buffer_store(struct device *cdev,
struct device_attribute *attr, const char *buf, size_t count)
@ -2763,7 +2755,7 @@ static struct scsi_host_template megasas_template = {
.shost_attrs = megaraid_host_attrs,
.bios_param = megasas_bios_param,
.use_clustering = ENABLE_CLUSTERING,
.change_queue_depth = megasas_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.no_write_same = 1,
};
@ -4027,25 +4019,83 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
return ret;
}
/*
* megasas_update_ext_vd_details : Update details w.r.t Extended VD
* instance : Controller's instance
*/
static void megasas_update_ext_vd_details(struct megasas_instance *instance)
{
struct fusion_context *fusion;
u32 old_map_sz;
u32 new_map_sz;
fusion = instance->ctrl_context;
/* For MFI based controllers return dummy success */
if (!fusion)
return;
instance->supportmax256vd =
instance->ctrl_info->adapterOperations3.supportMaxExtLDs;
/* Below is additional check to address future FW enhancement */
if (instance->ctrl_info->max_lds > 64)
instance->supportmax256vd = 1;
instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS
* MEGASAS_MAX_DEV_PER_CHANNEL;
instance->drv_supported_pd_count = MEGASAS_MAX_PD_CHANNELS
* MEGASAS_MAX_DEV_PER_CHANNEL;
if (instance->supportmax256vd) {
instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT;
instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
} else {
instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
}
dev_info(&instance->pdev->dev, "Firmware supports %d VD %d PD\n",
instance->fw_supported_vd_count,
instance->fw_supported_pd_count);
dev_info(&instance->pdev->dev, "Driver supports %d VD %d PD\n",
instance->drv_supported_vd_count,
instance->drv_supported_pd_count);
old_map_sz = sizeof(struct MR_FW_RAID_MAP) +
(sizeof(struct MR_LD_SPAN_MAP) *
(instance->fw_supported_vd_count - 1));
new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) +
(sizeof(struct MR_LD_SPAN_MAP) *
(instance->drv_supported_vd_count - 1));
fusion->max_map_sz = max(old_map_sz, new_map_sz);
if (instance->supportmax256vd)
fusion->current_map_sz = new_map_sz;
else
fusion->current_map_sz = old_map_sz;
}
/**
* megasas_get_controller_info - Returns FW's controller structure
* @instance: Adapter soft state
* @ctrl_info: Controller information structure
*
* Issues an internal command (DCMD) to get the FW's controller structure.
* This information is mainly used to find out the maximum IO transfer per
* command supported by the FW.
*/
int
megasas_get_ctrl_info(struct megasas_instance *instance,
struct megasas_ctrl_info *ctrl_info)
megasas_get_ctrl_info(struct megasas_instance *instance)
{
int ret = 0;
struct megasas_cmd *cmd;
struct megasas_dcmd_frame *dcmd;
struct megasas_ctrl_info *ci;
struct megasas_ctrl_info *ctrl_info;
dma_addr_t ci_h = 0;
ctrl_info = instance->ctrl_info;
cmd = megasas_get_cmd(instance);
if (!cmd) {
@ -4085,8 +4135,13 @@ megasas_get_ctrl_info(struct megasas_instance *instance,
else
ret = megasas_issue_polled(instance, cmd);
if (!ret)
if (!ret) {
memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info));
le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties);
le32_to_cpus((u32 *)&ctrl_info->adapterOperations2);
le32_to_cpus((u32 *)&ctrl_info->adapterOperations3);
megasas_update_ext_vd_details(instance);
}
pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
ci, ci_h);
@ -4288,7 +4343,7 @@ megasas_init_adapter_mfi(struct megasas_instance *instance)
if (megasas_issue_init_mfi(instance))
goto fail_fw_init;
if (megasas_get_ctrl_info(instance, instance->ctrl_info)) {
if (megasas_get_ctrl_info(instance)) {
dev_err(&instance->pdev->dev, "(%d): Could get controller info "
"Fail from %s %d\n", instance->unique_id,
__func__, __LINE__);
@ -4526,12 +4581,8 @@ static int megasas_init_fw(struct megasas_instance *instance)
dev_info(&instance->pdev->dev,
"Controller type: iMR\n");
}
/* OnOffProperties are converted into CPU arch*/
le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties);
instance->disableOnlineCtrlReset =
ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
/* adapterOperations2 are converted into CPU arch*/
le32_to_cpus((u32 *)&ctrl_info->adapterOperations2);
instance->mpio = ctrl_info->adapterOperations2.mpio;
instance->UnevenSpanSupport =
ctrl_info->adapterOperations2.supportUnevenSpans;
@ -4561,7 +4612,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
"requestorId %d\n", instance->requestorId);
}
le32_to_cpus((u32 *)&ctrl_info->adapterOperations3);
instance->crash_dump_fw_support =
ctrl_info->adapterOperations3.supportCrashDump;
instance->crash_dump_drv_support =
@ -4586,8 +4636,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
instance->max_sectors_per_req = tmp_sectors;
kfree(ctrl_info);
/* Check for valid throttlequeuedepth module parameter */
if (instance->is_imr) {
if (throttlequeuedepth > (instance->max_fw_cmds -
@ -4956,10 +5004,6 @@ static int megasas_io_attach(struct megasas_instance *instance)
return -ENODEV;
}
/*
* Trigger SCSI to scan our drives
*/
scsi_scan_host(host);
return 0;
}
@ -5082,6 +5126,8 @@ static int megasas_probe_one(struct pci_dev *pdev,
goto fail_alloc_dma_buf;
}
fusion = instance->ctrl_context;
memset(fusion, 0,
((1 << PAGE_SHIFT) << instance->ctrl_context_pages));
INIT_LIST_HEAD(&fusion->cmd_pool);
spin_lock_init(&fusion->mpt_pool_lock);
memset(fusion->load_balance_info, 0,
@ -5287,6 +5333,10 @@ retry_irq_register:
goto fail_io_attach;
instance->unload = 0;
/*
* Trigger SCSI to scan our drives
*/
scsi_scan_host(host);
/*
* Initiate AEN (Asynchronous Event Notification)
@ -6050,6 +6100,11 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
megasas_issue_blocked_cmd(instance, cmd, 0);
cmd->sync_cmd = 0;
if (instance->unload == 1) {
dev_info(&instance->pdev->dev, "Driver unload is in progress "
"don't submit data to application\n");
goto out;
}
/*
* copy out the kernel buffers to user buffers
*/
@ -6398,16 +6453,6 @@ static ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf)
static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL);
static ssize_t
megasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
{
return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
MEGASAS_RELDATE);
}
static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
NULL);
static ssize_t
megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
{
@ -6711,8 +6756,7 @@ static int __init megasas_init(void)
/*
* Announce driver version and other information
*/
printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
MEGASAS_EXT_VERSION);
pr_info("megasas: %s\n", MEGASAS_VERSION);
spin_lock_init(&poll_aen_lock);
@ -6747,10 +6791,6 @@ static int __init megasas_init(void)
&driver_attr_version);
if (rval)
goto err_dcf_attr_ver;
rval = driver_create_file(&megasas_pci_driver.driver,
&driver_attr_release_date);
if (rval)
goto err_dcf_rel_date;
rval = driver_create_file(&megasas_pci_driver.driver,
&driver_attr_support_poll_for_event);
@ -6774,12 +6814,7 @@ err_dcf_support_device_change:
err_dcf_dbg_lvl:
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_support_poll_for_event);
err_dcf_support_poll_for_event:
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_release_date);
err_dcf_rel_date:
driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
err_dcf_attr_ver:
pci_unregister_driver(&megasas_pci_driver);
@ -6799,8 +6834,6 @@ static void __exit megasas_exit(void)
&driver_attr_support_poll_for_event);
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_support_device_change);
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_release_date);
driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
pci_unregister_driver(&megasas_pci_driver);

View file

@ -1,7 +1,8 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
* Copyright (c) 2009-2012 LSI Corporation.
* Copyright (c) 2009-2013 LSI Corporation
* Copyright (c) 2013-2014 Avago Technologies
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -14,20 +15,21 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* FILE: megaraid_sas_fp.c
*
* Authors: LSI Corporation
* Authors: Avago Technologies
* Sumant Patro
* Varad Talamacki
* Manoj Jose
* Kashyap Desai <kashyap.desai@avagotech.com>
* Sumit Saxena <sumit.saxena@avagotech.com>
*
* Send feedback to: <megaraidlinux@lsi.com>
* Send feedback to: megaraidlinux.pdl@avagotech.com
*
* Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
* ATTN: Linuxraid
* Mail to: Avago Technologies, 350 West Trimble Road, Building 90,
* San Jose, California 95131
*/
#include <linux/kernel.h>
@ -183,14 +185,15 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
/* New Raid map will not set totalSize, so keep expected value
* for legacy code in ValidateMapInfo
*/
pDrvRaidMap->totalSize = sizeof(struct MR_FW_RAID_MAP_EXT);
pDrvRaidMap->totalSize =
cpu_to_le32(sizeof(struct MR_FW_RAID_MAP_EXT));
} else {
fw_map_old = (struct MR_FW_RAID_MAP_ALL *)
fusion->ld_map[(instance->map_id & 1)];
pFwRaidMap = &fw_map_old->raidMap;
#if VD_EXT_DEBUG
for (i = 0; i < pFwRaidMap->ldCount; i++) {
for (i = 0; i < le16_to_cpu(pFwRaidMap->ldCount); i++) {
dev_dbg(&instance->pdev->dev, "(%d) :Index 0x%x "
"Target Id 0x%x Seq Num 0x%x Size 0/%llx\n",
instance->unique_id, i,
@ -202,12 +205,12 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
memset(drv_map, 0, fusion->drv_map_sz);
pDrvRaidMap->totalSize = pFwRaidMap->totalSize;
pDrvRaidMap->ldCount = pFwRaidMap->ldCount;
pDrvRaidMap->ldCount = (__le16)pFwRaidMap->ldCount;
pDrvRaidMap->fpPdIoTimeoutSec = pFwRaidMap->fpPdIoTimeoutSec;
for (i = 0; i < MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS; i++)
pDrvRaidMap->ldTgtIdToLd[i] =
(u8)pFwRaidMap->ldTgtIdToLd[i];
for (i = 0; i < pDrvRaidMap->ldCount; i++) {
for (i = 0; i < le16_to_cpu(pDrvRaidMap->ldCount); i++) {
pDrvRaidMap->ldSpanMap[i] = pFwRaidMap->ldSpanMap[i];
#if VD_EXT_DEBUG
dev_dbg(&instance->pdev->dev,
@ -268,7 +271,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
else
expected_size =
(sizeof(struct MR_FW_RAID_MAP) - sizeof(struct MR_LD_SPAN_MAP) +
(sizeof(struct MR_LD_SPAN_MAP) * le32_to_cpu(pDrvRaidMap->ldCount)));
(sizeof(struct MR_LD_SPAN_MAP) * le16_to_cpu(pDrvRaidMap->ldCount)));
if (le32_to_cpu(pDrvRaidMap->totalSize) != expected_size) {
dev_err(&instance->pdev->dev, "map info structure size 0x%x is not matching with ld count\n",
@ -284,7 +287,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
mr_update_load_balance_params(drv_map, lbInfo);
num_lds = le32_to_cpu(drv_map->raidMap.ldCount);
num_lds = le16_to_cpu(drv_map->raidMap.ldCount);
/*Convert Raid capability values to CPU arch */
for (ldCount = 0; ldCount < num_lds; ldCount++) {
@ -457,7 +460,7 @@ u32 mr_spanset_get_span_block(struct megasas_instance *instance,
quad = &map->raidMap.ldSpanMap[ld].
spanBlock[span].
block_span_info.quad[info];
if (le32_to_cpu(quad->diff == 0))
if (le32_to_cpu(quad->diff) == 0)
return SPAN_INVALID;
if (le64_to_cpu(quad->logStart) <= row &&
row <= le64_to_cpu(quad->logEnd) &&
@ -520,7 +523,7 @@ static u64 get_row_from_strip(struct megasas_instance *instance,
span_set->span_row_data_width) * span_set->diff;
for (span = 0, span_offset = 0; span < raid->spanDepth; span++)
if (le32_to_cpu(map->raidMap.ldSpanMap[ld].spanBlock[span].
block_span_info.noElements >= info+1)) {
block_span_info.noElements) >= info+1) {
if (strip_offset >=
span_set->strip_offset[span])
span_offset++;

View file

@ -1,7 +1,8 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
* Copyright (c) 2009-2012 LSI Corporation.
* Copyright (c) 2009-2013 LSI Corporation
* Copyright (c) 2013-2014 Avago Technologies
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -14,19 +15,20 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* FILE: megaraid_sas_fusion.c
*
* Authors: LSI Corporation
* Authors: Avago Technologies
* Sumant Patro
* Adam Radford <linuxraid@lsi.com>
* Adam Radford
* Kashyap Desai <kashyap.desai@avagotech.com>
* Sumit Saxena <sumit.saxena@avagotech.com>
*
* Send feedback to: <megaraidlinux@lsi.com>
* Send feedback to: megaraidlinux.pdl@avagotech.com
*
* Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
* ATTN: Linuxraid
* Mail to: Avago Technologies, 350 West Trimble Road, Building 90,
* San Jose, California 95131
*/
#include <linux/kernel.h>
@ -880,7 +882,7 @@ megasas_sync_map_info(struct megasas_instance *instance)
map = fusion->ld_drv_map[instance->map_id & 1];
num_lds = le32_to_cpu(map->raidMap.ldCount);
num_lds = le16_to_cpu(map->raidMap.ldCount);
dcmd = &cmd->frame->dcmd;
@ -1065,48 +1067,16 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
goto fail_ioc_init;
megasas_display_intel_branding(instance);
if (megasas_get_ctrl_info(instance, instance->ctrl_info)) {
if (megasas_get_ctrl_info(instance)) {
dev_err(&instance->pdev->dev,
"Could not get controller info. Fail from %s %d\n",
__func__, __LINE__);
goto fail_ioc_init;
}
instance->supportmax256vd =
instance->ctrl_info->adapterOperations3.supportMaxExtLDs;
/* Below is additional check to address future FW enhancement */
if (instance->ctrl_info->max_lds > 64)
instance->supportmax256vd = 1;
instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS
* MEGASAS_MAX_DEV_PER_CHANNEL;
instance->drv_supported_pd_count = MEGASAS_MAX_PD_CHANNELS
* MEGASAS_MAX_DEV_PER_CHANNEL;
if (instance->supportmax256vd) {
instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT;
instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
} else {
instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
}
dev_info(&instance->pdev->dev, "Firmware supports %d VDs %d PDs\n"
"Driver supports %d VDs %d PDs\n",
instance->fw_supported_vd_count,
instance->fw_supported_pd_count,
instance->drv_supported_vd_count,
instance->drv_supported_pd_count);
instance->flag_ieee = 1;
fusion->fast_path_io = 0;
fusion->old_map_sz =
sizeof(struct MR_FW_RAID_MAP) + (sizeof(struct MR_LD_SPAN_MAP) *
(instance->fw_supported_vd_count - 1));
fusion->new_map_sz =
sizeof(struct MR_FW_RAID_MAP_EXT);
fusion->drv_map_sz =
sizeof(struct MR_DRV_RAID_MAP) + (sizeof(struct MR_LD_SPAN_MAP) *
(instance->drv_supported_vd_count - 1));
fusion->drv_map_pages = get_order(fusion->drv_map_sz);
for (i = 0; i < 2; i++) {
fusion->ld_map[i] = NULL;
@ -1121,16 +1091,10 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
fusion->drv_map_pages);
goto fail_ioc_init;
}
memset(fusion->ld_drv_map[i], 0,
((1 << PAGE_SHIFT) << fusion->drv_map_pages));
}
fusion->max_map_sz = max(fusion->old_map_sz, fusion->new_map_sz);
if (instance->supportmax256vd)
fusion->current_map_sz = fusion->new_map_sz;
else
fusion->current_map_sz = fusion->old_map_sz;
for (i = 0; i < 2; i++) {
fusion->ld_map[i] = dma_alloc_coherent(&instance->pdev->dev,
fusion->max_map_sz,
@ -1173,9 +1137,10 @@ megasas_fire_cmd_fusion(struct megasas_instance *instance,
struct megasas_register_set __iomem *regs)
{
#if defined(writeq) && defined(CONFIG_64BIT)
u64 req_data = (((u64)req_desc_hi << 32) | (u32)req_desc_lo);
u64 req_data = (((u64)le32_to_cpu(req_desc_hi) << 32) |
le32_to_cpu(req_desc_lo));
writeq(le64_to_cpu(req_data), &(regs)->inbound_low_queue_port);
writeq(req_data, &(regs)->inbound_low_queue_port);
#else
unsigned long flags;
@ -1373,7 +1338,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len,
/* Logical block reference tag */
io_request->CDB.EEDP32.PrimaryReferenceTag =
cpu_to_be32(ref_tag);
io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0xffff;
io_request->CDB.EEDP32.PrimaryApplicationTagMask = cpu_to_be16(0xffff);
io_request->IoFlags = cpu_to_le16(32); /* Specify 32-byte cdb */
/* Transfer length */
@ -1769,7 +1734,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
/* set RAID context values */
pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
pRAID_Context->timeoutValue = raid->fpIoTimeoutForLd;
pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd);
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
pRAID_Context->regLockRowLBA = 0;
pRAID_Context->regLockLength = 0;
@ -2254,7 +2219,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
* megasas_complete_cmd
*/
if (frame_hdr->flags & MFI_FRAME_DONT_POST_IN_REPLY_QUEUE)
if (frame_hdr->flags & cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE))
cmd->flags = MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
fusion = instance->ctrl_context;
@ -2385,6 +2350,8 @@ megasas_alloc_host_crash_buffer(struct megasas_instance *instance)
"memory allocation failed at index %d\n", i);
break;
}
memset(instance->crash_buf[i], 0,
((1 << PAGE_SHIFT) << instance->crash_buf_pages));
}
instance->drv_buf_alloc = i;
}
@ -2837,11 +2804,15 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
}
}
clear_bit(MEGASAS_FUSION_IN_RESET,
&instance->reset_flags);
instance->instancet->enable_intr(instance);
instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
if (megasas_get_ctrl_info(instance)) {
dev_info(&instance->pdev->dev,
"Failed from %s %d\n",
__func__, __LINE__);
instance->adprecovery =
MEGASAS_HW_CRITICAL_ERROR;
megaraid_sas_kill_hba(instance);
retval = FAILED;
}
/* Reset load balance info */
memset(fusion->load_balance_info, 0,
sizeof(struct LD_LOAD_BALANCE_INFO)
@ -2850,6 +2821,11 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
if (!megasas_get_map_info(instance))
megasas_sync_map_info(instance);
clear_bit(MEGASAS_FUSION_IN_RESET,
&instance->reset_flags);
instance->instancet->enable_intr(instance);
instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
/* Restart SR-IOV heartbeat */
if (instance->requestorId) {
if (!megasas_sriov_start_heartbeat(instance, 0))
@ -2866,14 +2842,14 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
"successful for scsi%d.\n",
instance->host->host_no);
if (instance->crash_dump_drv_support) {
if (instance->crash_dump_app_support)
megasas_set_crash_dump_params(instance,
MR_CRASH_BUF_TURN_ON);
else
megasas_set_crash_dump_params(instance,
MR_CRASH_BUF_TURN_OFF);
}
if (instance->crash_dump_drv_support &&
instance->crash_dump_app_support)
megasas_set_crash_dump_params(instance,
MR_CRASH_BUF_TURN_ON);
else
megasas_set_crash_dump_params(instance,
MR_CRASH_BUF_TURN_OFF);
retval = SUCCESS;
goto out;
}

View file

@ -1,7 +1,8 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
* Copyright (c) 2009-2012 LSI Corporation.
* Copyright (c) 2009-2013 LSI Corporation
* Copyright (c) 2013-2014 Avago Technologies
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -14,19 +15,20 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* FILE: megaraid_sas_fusion.h
*
* Authors: LSI Corporation
* Authors: Avago Technologies
* Manoj Jose
* Sumant Patro
* Kashyap Desai <kashyap.desai@avagotech.com>
* Sumit Saxena <sumit.saxena@avagotech.com>
*
* Send feedback to: <megaraidlinux@lsi.com>
* Send feedback to: megaraidlinux.pdl@avagotech.com
*
* Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
* ATTN: Linuxraid
* Mail to: Avago Technologies, 350 West Trimble Road, Building 90,
* San Jose, California 95131
*/
#ifndef _MEGARAID_SAS_FUSION_H_
@ -834,8 +836,6 @@ struct fusion_context {
u32 max_map_sz;
u32 current_map_sz;
u32 old_map_sz;
u32 new_map_sz;
u32 drv_map_sz;
u32 drv_map_pages;
u8 fast_path_io;

View file

@ -1179,15 +1179,14 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
}
/**
* _scsih_adjust_queue_depth - setting device queue depth
* _scsih_change_queue_depth - setting device queue depth
* @sdev: scsi device struct
* @qdepth: requested queue depth
*
*
* Returns nothing
* Returns queue depth.
*/
static void
_scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth)
static int
_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
struct Scsi_Host *shost = sdev->host;
int max_depth;
@ -1217,41 +1216,11 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth)
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
not_sata:
if (!sdev->tagged_supported)
max_depth = 1;
if (qdepth > max_depth)
qdepth = max_depth;
scsi_adjust_queue_depth(sdev, qdepth);
}
/**
* _scsih_change_queue_depth - setting device queue depth
* @sdev: scsi device struct
* @qdepth: requested queue depth
* @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP
* (see include/scsi/scsi_host.h for definition)
*
* Returns queue depth.
*/
static int
_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
{
if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP)
_scsih_adjust_queue_depth(sdev, qdepth);
else if (reason == SCSI_QDEPTH_QFULL)
scsi_track_queue_full(sdev, qdepth);
else
return -EOPNOTSUPP;
if (sdev->inquiry_len > 7)
sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), "
"simple(%d), scsi_level(%d), cmd_que(%d)\n",
sdev->queue_depth, sdev->tagged_supported, sdev->simple_tags,
sdev->scsi_level,
(sdev->inquiry[7] & 2) >> 1);
return sdev->queue_depth;
return scsi_change_queue_depth(sdev, qdepth);
}
/**
@ -2082,7 +2051,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
r_level, raid_device->handle,
(unsigned long long)raid_device->wwid,
raid_device->num_pds, ds);
_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
_scsih_change_queue_depth(sdev, qdepth);
/* raid transport support */
if (!ioc->is_warpdrive)
_scsih_set_level(sdev, raid_device->volume_type);
@ -2147,7 +2116,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
_scsih_display_sata_capabilities(ioc, handle, sdev);
_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
_scsih_change_queue_depth(sdev, qdepth);
if (ssp_target) {
sas_read_port_mode_page(sdev);
@ -7637,6 +7606,7 @@ static struct scsi_host_template scsih_driver_template = {
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = mpt2sas_host_attrs,
.sdev_attrs = mpt2sas_dev_attrs,
.track_queue_depth = 1,
};
/**

View file

@ -1053,9 +1053,15 @@ _scsih_scsi_lookup_find_by_lun(struct MPT3SAS_ADAPTER *ioc, int id,
return found;
}
static void
_scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth)
/**
* _scsih_change_queue_depth - setting device queue depth
* @sdev: scsi device struct
* @qdepth: requested queue depth
*
* Returns queue depth.
*/
static int
_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
struct Scsi_Host *shost = sdev->host;
int max_depth;
@ -1090,36 +1096,7 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth)
max_depth = 1;
if (qdepth > max_depth)
qdepth = max_depth;
scsi_adjust_queue_depth(sdev, qdepth);
}
/**
* _scsih_change_queue_depth - setting device queue depth
* @sdev: scsi device struct
* @qdepth: requested queue depth
* @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP
* (see include/scsi/scsi_host.h for definition)
*
* Returns queue depth.
*/
static int
_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
{
if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP)
_scsih_adjust_queue_depth(sdev, qdepth);
else if (reason == SCSI_QDEPTH_QFULL)
scsi_track_queue_full(sdev, qdepth);
else
return -EOPNOTSUPP;
if (sdev->inquiry_len > 7)
sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), " \
"simple(%d), scsi_level(%d), cmd_que(%d)\n",
sdev->queue_depth, sdev->tagged_supported, sdev->simple_tags,
sdev->scsi_level,
(sdev->inquiry[7] & 2) >> 1);
return sdev->queue_depth;
return scsi_change_queue_depth(sdev, qdepth);
}
/**
@ -1739,7 +1716,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
raid_device->num_pds, ds);
_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
_scsih_change_queue_depth(sdev, qdepth);
/* raid transport support */
_scsih_set_level(sdev, raid_device->volume_type);
@ -1805,7 +1782,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
_scsih_display_sata_capabilities(ioc, handle, sdev);
_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
_scsih_change_queue_depth(sdev, qdepth);
if (ssp_target) {
sas_read_port_mode_page(sdev);
@ -7266,6 +7243,7 @@ static struct scsi_host_template scsih_driver_template = {
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = mpt3sas_host_attrs,
.sdev_attrs = mpt3sas_dev_attrs,
.track_queue_depth = 1,
};
/**

View file

@ -26,18 +26,9 @@
#include "mv_sas.h"
static int lldd_max_execute_num = 1;
module_param_named(collector, lldd_max_execute_num, int, S_IRUGO);
MODULE_PARM_DESC(collector, "\n"
"\tIf greater than one, tells the SAS Layer to run in Task Collector\n"
"\tMode. If 1 or 0, tells the SAS Layer to run in Direct Mode.\n"
"\tThe mvsas SAS LLDD supports both modes.\n"
"\tDefault: 1 (Direct Mode).\n");
int interrupt_coalescing = 0x80;
static struct scsi_transport_template *mvs_stt;
struct kmem_cache *mvs_task_list_cache;
static const struct mvs_chip_info mvs_chips[] = {
[chip_6320] = { 1, 2, 0x400, 17, 16, 6, 9, &mvs_64xx_dispatch, },
[chip_6440] = { 1, 4, 0x400, 17, 16, 6, 9, &mvs_64xx_dispatch, },
@ -77,6 +68,7 @@ static struct scsi_host_template mvs_sht = {
.ioctl = sas_ioctl,
.shost_attrs = mvst_host_attrs,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
static struct sas_domain_function_template mvs_transport_ops = {
@ -512,14 +504,11 @@ static void mvs_post_sas_ha_init(struct Scsi_Host *shost,
sha->num_phys = nr_core * chip_info->n_phy;
sha->lldd_max_execute_num = lldd_max_execute_num;
if (mvi->flags & MVF_FLAG_SOC)
can_queue = MVS_SOC_CAN_QUEUE;
else
can_queue = MVS_CHIP_SLOT_SZ;
sha->lldd_queue_size = can_queue;
shost->sg_tablesize = min_t(u16, SG_ALL, MVS_MAX_SG);
shost->can_queue = can_queue;
mvi->shost->cmd_per_lun = MVS_QUEUE_SIZE;
@ -832,16 +821,7 @@ static int __init mvs_init(void)
if (!mvs_stt)
return -ENOMEM;
mvs_task_list_cache = kmem_cache_create("mvs_task_list", sizeof(struct mvs_task_list),
0, SLAB_HWCACHE_ALIGN, NULL);
if (!mvs_task_list_cache) {
rc = -ENOMEM;
mv_printk("%s: mvs_task_list_cache alloc failed! \n", __func__);
goto err_out;
}
rc = pci_register_driver(&mvs_pci_driver);
if (rc)
goto err_out;
@ -856,7 +836,6 @@ static void __exit mvs_exit(void)
{
pci_unregister_driver(&mvs_pci_driver);
sas_release_transport(mvs_stt);
kmem_cache_destroy(mvs_task_list_cache);
}
struct device_attribute *mvst_host_attrs[] = {

View file

@ -852,43 +852,7 @@ prep_out:
return rc;
}
static struct mvs_task_list *mvs_task_alloc_list(int *num, gfp_t gfp_flags)
{
struct mvs_task_list *first = NULL;
for (; *num > 0; --*num) {
struct mvs_task_list *mvs_list = kmem_cache_zalloc(mvs_task_list_cache, gfp_flags);
if (!mvs_list)
break;
INIT_LIST_HEAD(&mvs_list->list);
if (!first)
first = mvs_list;
else
list_add_tail(&mvs_list->list, &first->list);
}
return first;
}
static inline void mvs_task_free_list(struct mvs_task_list *mvs_list)
{
LIST_HEAD(list);
struct list_head *pos, *a;
struct mvs_task_list *mlist = NULL;
__list_add(&list, mvs_list->list.prev, &mvs_list->list);
list_for_each_safe(pos, a, &list) {
list_del_init(pos);
mlist = list_entry(pos, struct mvs_task_list, list);
kmem_cache_free(mvs_task_list_cache, mlist);
}
}
static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
static int mvs_task_exec(struct sas_task *task, gfp_t gfp_flags,
struct completion *completion, int is_tmf,
struct mvs_tmf_task *tmf)
{
@ -912,74 +876,9 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
return rc;
}
static int mvs_collector_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
struct completion *completion, int is_tmf,
struct mvs_tmf_task *tmf)
int mvs_queue_command(struct sas_task *task, gfp_t gfp_flags)
{
struct domain_device *dev = task->dev;
struct mvs_prv_info *mpi = dev->port->ha->lldd_ha;
struct mvs_info *mvi = NULL;
struct sas_task *t = task;
struct mvs_task_list *mvs_list = NULL, *a;
LIST_HEAD(q);
int pass[2] = {0};
u32 rc = 0;
u32 n = num;
unsigned long flags = 0;
mvs_list = mvs_task_alloc_list(&n, gfp_flags);
if (n) {
printk(KERN_ERR "%s: mvs alloc list failed.\n", __func__);
rc = -ENOMEM;
goto free_list;
}
__list_add(&q, mvs_list->list.prev, &mvs_list->list);
list_for_each_entry(a, &q, list) {
a->task = t;
t = list_entry(t->list.next, struct sas_task, list);
}
list_for_each_entry(a, &q , list) {
t = a->task;
mvi = ((struct mvs_device *)t->dev->lldd_dev)->mvi_info;
spin_lock_irqsave(&mvi->lock, flags);
rc = mvs_task_prep(t, mvi, is_tmf, tmf, &pass[mvi->id]);
if (rc)
dev_printk(KERN_ERR, mvi->dev, "mvsas exec failed[%d]!\n", rc);
spin_unlock_irqrestore(&mvi->lock, flags);
}
if (likely(pass[0]))
MVS_CHIP_DISP->start_delivery(mpi->mvi[0],
(mpi->mvi[0]->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
if (likely(pass[1]))
MVS_CHIP_DISP->start_delivery(mpi->mvi[1],
(mpi->mvi[1]->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
list_del_init(&q);
free_list:
if (mvs_list)
mvs_task_free_list(mvs_list);
return rc;
}
int mvs_queue_command(struct sas_task *task, const int num,
gfp_t gfp_flags)
{
struct mvs_device *mvi_dev = task->dev->lldd_dev;
struct sas_ha_struct *sas = mvi_dev->mvi_info->sas;
if (sas->lldd_max_execute_num < 2)
return mvs_task_exec(task, num, gfp_flags, NULL, 0, NULL);
else
return mvs_collector_task_exec(task, num, gfp_flags, NULL, 0, NULL);
return mvs_task_exec(task, gfp_flags, NULL, 0, NULL);
}
static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc)
@ -1411,7 +1310,7 @@ static int mvs_exec_internal_tmf_task(struct domain_device *dev,
task->slow_task->timer.expires = jiffies + MVS_TASK_TIMEOUT*HZ;
add_timer(&task->slow_task->timer);
res = mvs_task_exec(task, 1, GFP_KERNEL, NULL, 1, tmf);
res = mvs_task_exec(task, GFP_KERNEL, NULL, 1, tmf);
if (res) {
del_timer(&task->slow_task->timer);

View file

@ -65,7 +65,6 @@ extern struct mvs_tgt_initiator mvs_tgt;
extern struct mvs_info *tgt_mvi;
extern const struct mvs_dispatch mvs_64xx_dispatch;
extern const struct mvs_dispatch mvs_94xx_dispatch;
extern struct kmem_cache *mvs_task_list_cache;
#define DEV_IS_EXPANDER(type) \
((type == SAS_EDGE_EXPANDER_DEVICE) || (type == SAS_FANOUT_EXPANDER_DEVICE))
@ -440,12 +439,6 @@ struct mvs_task_exec_info {
int n_elem;
};
struct mvs_task_list {
struct sas_task *task;
struct list_head list;
};
/******************** function prototype *********************/
void mvs_get_sas_addr(void *buf, u32 buflen);
void mvs_tag_clear(struct mvs_info *mvi, u32 tag);
@ -462,8 +455,7 @@ void mvs_set_sas_addr(struct mvs_info *mvi, int port_id, u32 off_lo,
u32 off_hi, u64 sas_addr);
void mvs_scan_start(struct Scsi_Host *shost);
int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time);
int mvs_queue_command(struct sas_task *task, const int num,
gfp_t gfp_flags);
int mvs_queue_command(struct sas_task *task, gfp_t gfp_flags);
int mvs_abort_task(struct sas_task *task);
int mvs_abort_task_set(struct domain_device *dev, u8 *lun);
int mvs_clear_aca(struct domain_device *dev, u8 *lun);

View file

@ -7997,7 +7997,7 @@ static int ncr53c8xx_slave_configure(struct scsi_device *device)
if (depth_to_use > MAX_TAGS)
depth_to_use = MAX_TAGS;
scsi_adjust_queue_depth(device, depth_to_use);
scsi_change_queue_depth(device, depth_to_use);
/*
** Since the queue depth is not tunable under Linux,

View file

@ -1,6 +1,4 @@
#define AUTOSENSE
#define PSEUDO_DMA
#define FOO
#define UNSAFE /* Not unsafe for PAS16 -- use it */
#define PDEBUG 0
@ -24,47 +22,9 @@
* Media Vision
* (510) 770-8600
* (800) 348-7116
*
* and
*
* NCR 5380 Family
* SCSI Protocol Controller
* Databook
*
* NCR Microelectronics
* 1635 Aeroplaza Drive
* Colorado Springs, CO 80916
* 1+ (719) 578-3400
* 1+ (800) 334-5454
*/
/*
* Options :
* AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
* for commands that return with a CHECK CONDITION status.
*
* LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512
* bytes at a time. Since interrupts are disabled by default during
* these transfers, we might need this to give reasonable interrupt
* service time if the transfer size gets too large.
*
* PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
* increase compared to polled I/O.
*
* PARITY - enable parity checking. Not supported.
*
* SCSI2 - enable support for SCSI-II tagged queueing. Untested.
*
* UNSAFE - leave interrupts enabled during pseudo-DMA transfers. This
* parameter comes from the NCR5380 code. It is NOT unsafe with
* the PAS16 and you should use it. If you don't you will have
* a problem with dropped characters during high speed
* communications during SCSI transfers. If you really don't
* want to use UNSAFE you can try defining LIMIT_TRANSFERSIZE or
* twiddle with the transfer size in the high level code.
*
* USLEEP - enable support for devices that don't disconnect. Untested.
*
* The card is detected and initialized in one of several ways :
* 1. Autoprobe (default) - There are many different models of
* the Pro Audio Spectrum/Studio 16, and I only have one of
@ -102,13 +62,11 @@
* If you have problems with your card not being recognized, use
* the LILO command line override. Try to get it recognized without
* interrupts. Ie, for a board at the default 0x388 base port,
* boot: linux pas16=0x388,255
* boot: linux pas16=0x388,0
*
* SCSI_IRQ_NONE (255) should be specified for no interrupt,
* NO_IRQ (0) should be specified for no interrupt,
* IRQ_AUTO (254) to autoprobe for an IRQ line if overridden
* on the command line.
*
* (IRQ_AUTO == 254, SCSI_IRQ_NONE == 255 in NCR5380.h)
*/
#include <linux/module.h>
@ -123,15 +81,12 @@
#include <linux/stat.h>
#include <linux/init.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "pas16.h"
#define AUTOPROBE_IRQ
#include "NCR5380.h"
static int pas_maxi = 0;
static int pas_wmaxi = 0;
static unsigned short pas16_addr = 0;
static int pas16_irq = 0;
@ -337,6 +292,7 @@ static int __init
}
#ifndef MODULE
/*
* Function : pas16_setup(char *str, int *ints)
*
@ -347,10 +303,13 @@ static int __init
*
*/
void __init pas16_setup(char *str, int *ints)
static int __init pas16_setup(char *str)
{
static int commandline_current = 0;
int i;
int ints[10];
get_options(str, ARRAY_SIZE(ints), ints);
if (ints[0] != 2)
printk("pas16_setup : usage pas16=io_port,irq\n");
else
@ -364,8 +323,12 @@ void __init pas16_setup(char *str, int *ints)
}
++commandline_current;
}
return 1;
}
__setup("pas16=", pas16_setup);
#endif
/*
* Function : int pas16_detect(struct scsi_host_template * tpnt)
*
@ -379,7 +342,7 @@ void __init pas16_setup(char *str, int *ints)
*
*/
int __init pas16_detect(struct scsi_host_template * tpnt)
static int __init pas16_detect(struct scsi_host_template *tpnt)
{
static int current_override = 0;
static unsigned short current_base = 0;
@ -387,10 +350,6 @@ int __init pas16_detect(struct scsi_host_template * tpnt)
unsigned short io_port;
int count;
tpnt->proc_name = "pas16";
tpnt->show_info = pas16_show_info;
tpnt->write_info = pas16_write_info;
if (pas16_addr != 0) {
overrides[0].io_port = pas16_addr;
/*
@ -452,15 +411,19 @@ int __init pas16_detect(struct scsi_host_template * tpnt)
else
instance->irq = NCR5380_probe_irq(instance, PAS16_IRQS);
if (instance->irq != SCSI_IRQ_NONE)
/* Compatibility with documented NCR5380 kernel parameters */
if (instance->irq == 255)
instance->irq = NO_IRQ;
if (instance->irq != NO_IRQ)
if (request_irq(instance->irq, pas16_intr, 0,
"pas16", instance)) {
printk("scsi%d : IRQ%d not free, interrupts disabled\n",
instance->host_no, instance->irq);
instance->irq = SCSI_IRQ_NONE;
instance->irq = NO_IRQ;
}
if (instance->irq == SCSI_IRQ_NONE) {
if (instance->irq == NO_IRQ) {
printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
/* Disable 5380 interrupts, leave drive params the same */
@ -472,17 +435,6 @@ int __init pas16_detect(struct scsi_host_template * tpnt)
printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
#endif
printk("scsi%d : at 0x%04x", instance->host_no, (int)
instance->io_port);
if (instance->irq == SCSI_IRQ_NONE)
printk (" interrupts disabled");
else
printk (" irq %d", instance->irq);
printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
CAN_QUEUE, CMD_PER_LUN, PAS16_PUBLIC_RELEASE);
NCR5380_print_options(instance);
printk("\n");
++current_override;
++count;
}
@ -509,8 +461,8 @@ int __init pas16_detect(struct scsi_host_template * tpnt)
* and matching the H_C_S coordinates to what DOS uses.
*/
int pas16_biosparam(struct scsi_device *sdev, struct block_device *dev,
sector_t capacity, int * ip)
static int pas16_biosparam(struct scsi_device *sdev, struct block_device *dev,
sector_t capacity, int *ip)
{
int size = capacity;
ip[0] = 64;
@ -547,6 +499,7 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
P_DATA_REG_OFFSET);
register int i = len;
int ii = 0;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
while ( !(inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY) )
++ii;
@ -559,8 +512,8 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
instance->host_no);
return -1;
}
if (ii > pas_maxi)
pas_maxi = ii;
if (ii > hostdata->spin_max_r)
hostdata->spin_max_r = ii;
return 0;
}
@ -583,6 +536,7 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET);
register int i = len;
int ii = 0;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
while ( !((inb(instance->io_port + P_STATUS_REG_OFFSET)) & P_ST_RDY) )
++ii;
@ -595,8 +549,8 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
instance->host_no);
return -1;
}
if (ii > pas_maxi)
pas_wmaxi = ii;
if (ii > hostdata->spin_max_w)
hostdata->spin_max_w = ii;
return 0;
}
@ -604,7 +558,7 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
static int pas16_release(struct Scsi_Host *shost)
{
if (shost->irq)
if (shost->irq != NO_IRQ)
free_irq(shost->irq, shost);
NCR5380_exit(shost);
if (shost->io_port && shost->n_io_port)
@ -617,6 +571,10 @@ 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,

View file

@ -18,26 +18,12 @@
* Media Vision
* (510) 770-8600
* (800) 348-7116
*
* and
*
* NCR 5380 Family
* SCSI Protocol Controller
* Databook
*
* NCR Microelectronics
* 1635 Aeroplaza Drive
* Colorado Springs, CO 80916
* 1+ (719) 578-3400
* 1+ (800) 334-5454
*/
#ifndef PAS16_H
#define PAS16_H
#define PAS16_PUBLIC_RELEASE 3
#define PDEBUG_INIT 0x1
#define PDEBUG_TRANSFER 0x2
@ -114,12 +100,6 @@
#ifndef ASM
static int pas16_abort(Scsi_Cmnd *);
static int pas16_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
static int pas16_detect(struct scsi_host_template *);
static int pas16_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int pas16_bus_reset(Scsi_Cmnd *);
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
@ -161,6 +141,7 @@ static int pas16_bus_reset(Scsi_Cmnd *);
#define NCR5380_queue_command pas16_queue_command
#define NCR5380_abort pas16_abort
#define NCR5380_bus_reset pas16_bus_reset
#define NCR5380_info pas16_info
#define NCR5380_show_info pas16_show_info
#define NCR5380_write_info pas16_write_info

View file

@ -90,6 +90,7 @@ static struct scsi_host_template pm8001_sht = {
.ioctl = sas_ioctl,
.shost_attrs = pm8001_host_attrs,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
/**
@ -600,8 +601,6 @@ static void pm8001_post_sas_ha_init(struct Scsi_Host *shost,
sha->lldd_module = THIS_MODULE;
sha->sas_addr = &pm8001_ha->sas_addr[0];
sha->num_phys = chip_info->n_phy;
sha->lldd_max_execute_num = 1;
sha->lldd_queue_size = PM8001_CAN_QUEUE;
sha->core.shost = shost;
}

View file

@ -350,7 +350,7 @@ static int sas_find_local_port_id(struct domain_device *dev)
*/
#define DEV_IS_GONE(pm8001_dev) \
((!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED)))
static int pm8001_task_exec(struct sas_task *task, const int num,
static int pm8001_task_exec(struct sas_task *task,
gfp_t gfp_flags, int is_tmf, struct pm8001_tmf_task *tmf)
{
struct domain_device *dev = task->dev;
@ -360,7 +360,6 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
struct sas_task *t = task;
struct pm8001_ccb_info *ccb;
u32 tag = 0xdeadbeef, rc, n_elem = 0;
u32 n = num;
unsigned long flags = 0;
if (!dev->port) {
@ -387,18 +386,12 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
spin_unlock_irqrestore(&pm8001_ha->lock, flags);
t->task_done(t);
spin_lock_irqsave(&pm8001_ha->lock, flags);
if (n > 1)
t = list_entry(t->list.next,
struct sas_task, list);
continue;
} else {
struct task_status_struct *ts = &t->task_status;
ts->resp = SAS_TASK_UNDELIVERED;
ts->stat = SAS_PHY_DOWN;
t->task_done(t);
if (n > 1)
t = list_entry(t->list.next,
struct sas_task, list);
continue;
}
}
@ -460,9 +453,7 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
t->task_state_flags |= SAS_TASK_AT_INITIATOR;
spin_unlock(&t->task_state_lock);
pm8001_dev->running_req++;
if (n > 1)
t = list_entry(t->list.next, struct sas_task, list);
} while (--n);
} while (0);
rc = 0;
goto out_done;
@ -483,14 +474,11 @@ out_done:
* pm8001_queue_command - register for upper layer used, all IO commands sent
* to HBA are from this interface.
* @task: the task to be execute.
* @num: if can_queue great than 1, the task can be queued up. for SMP task,
* we always execute one one time
* @gfp_flags: gfp_flags
*/
int pm8001_queue_command(struct sas_task *task, const int num,
gfp_t gfp_flags)
int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags)
{
return pm8001_task_exec(task, num, gfp_flags, 0, NULL);
return pm8001_task_exec(task, gfp_flags, 0, NULL);
}
/**
@ -708,7 +696,7 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev,
task->slow_task->timer.expires = jiffies + PM8001_TASK_TIMEOUT*HZ;
add_timer(&task->slow_task->timer);
res = pm8001_task_exec(task, 1, GFP_KERNEL, 1, tmf);
res = pm8001_task_exec(task, GFP_KERNEL, 1, tmf);
if (res) {
del_timer(&task->slow_task->timer);

View file

@ -623,8 +623,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
void *funcdata);
void pm8001_scan_start(struct Scsi_Host *shost);
int pm8001_scan_finished(struct Scsi_Host *shost, unsigned long time);
int pm8001_queue_command(struct sas_task *task, const int num,
gfp_t gfp_flags);
int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags);
int pm8001_abort_task(struct sas_task *task);
int pm8001_abort_task_set(struct domain_device *dev, u8 *lun);
int pm8001_clear_aca(struct domain_device *dev, u8 *lun);

View file

@ -285,23 +285,15 @@ static void pmcraid_slave_destroy(struct scsi_device *scsi_dev)
* pmcraid_change_queue_depth - Change the device's queue depth
* @scsi_dev: scsi device struct
* @depth: depth to set
* @reason: calling context
*
* Return value
* actual depth set
*/
static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth,
int reason)
static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth)
{
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (depth > PMCRAID_MAX_CMD_PER_LUN)
depth = PMCRAID_MAX_CMD_PER_LUN;
scsi_adjust_queue_depth(scsi_dev, depth);
return scsi_dev->queue_depth;
return scsi_change_queue_depth(scsi_dev, depth);
}
/**

View file

@ -1224,9 +1224,9 @@ qla1280_slave_configure(struct scsi_device *device)
if (device->tagged_supported &&
(ha->bus_settings[bus].qtag_enables & (BIT_0 << target))) {
scsi_adjust_queue_depth(device, ha->bus_settings[bus].hiwat);
scsi_change_queue_depth(device, ha->bus_settings[bus].hiwat);
} else {
scsi_adjust_queue_depth(device, default_depth);
scsi_change_queue_depth(device, default_depth);
}
nv->bus[bus].target[target].parameter.enable_sync = device->sdtr;

View file

@ -752,8 +752,6 @@ extern void qla8044_set_idc_dontreset(struct scsi_qla_host *ha);
extern int qla8044_rd_direct(struct scsi_qla_host *vha, const uint32_t crb_reg);
extern void qla8044_wr_direct(struct scsi_qla_host *vha,
const uint32_t crb_reg, const uint32_t value);
extern inline void qla8044_set_qsnt_ready(struct scsi_qla_host *vha);
extern inline void qla8044_need_reset_handler(struct scsi_qla_host *vha);
extern int qla8044_device_state_handler(struct scsi_qla_host *vha);
extern void qla8044_clear_qsnt_ready(struct scsi_qla_host *vha);
extern void qla8044_clear_drv_active(struct qla_hw_data *);

View file

@ -238,7 +238,7 @@ qla8044_rmw_crb_reg(struct scsi_qla_host *vha,
return;
}
inline void
static inline void
qla8044_set_qsnt_ready(struct scsi_qla_host *vha)
{
uint32_t qsnt_state;

View file

@ -236,7 +236,6 @@ static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
static int qla2x00_change_queue_depth(struct scsi_device *, int, int);
static void qla2x00_clear_drv_active(struct qla_hw_data *);
static void qla2x00_free_device(scsi_qla_host_t *);
static void qla83xx_disable_laser(scsi_qla_host_t *vha);
@ -258,7 +257,7 @@ struct scsi_host_template qla2xxx_driver_template = {
.slave_destroy = qla2xxx_slave_destroy,
.scan_finished = qla2xxx_scan_finished,
.scan_start = qla2xxx_scan_start,
.change_queue_depth = qla2x00_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.change_queue_type = scsi_change_queue_type,
.this_id = -1,
.cmd_per_lun = 3,
@ -270,6 +269,7 @@ struct scsi_host_template qla2xxx_driver_template = {
.supported_mode = MODE_INITIATOR,
.use_blk_tags = 1,
.track_queue_depth = 1,
};
static struct scsi_transport_template *qla2xxx_transport_template = NULL;
@ -1405,7 +1405,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
if (IS_T10_PI_CAPABLE(vha->hw))
blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
scsi_adjust_queue_depth(sdev, req->max_q_depth);
scsi_change_queue_depth(sdev, req->max_q_depth);
return 0;
}
@ -1415,58 +1415,6 @@ qla2xxx_slave_destroy(struct scsi_device *sdev)
sdev->hostdata = NULL;
}
static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth)
{
fc_port_t *fcport = (struct fc_port *) sdev->hostdata;
if (!scsi_track_queue_full(sdev, qdepth))
return;
ql_dbg(ql_dbg_io, fcport->vha, 0x3029,
"Queue depth adjusted-down to %d for nexus=%ld:%d:%llu.\n",
sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun);
}
static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth)
{
fc_port_t *fcport = sdev->hostdata;
struct scsi_qla_host *vha = fcport->vha;
struct req_que *req = NULL;
req = vha->req;
if (!req)
return;
if (req->max_q_depth <= sdev->queue_depth || req->max_q_depth < qdepth)
return;
scsi_adjust_queue_depth(sdev, qdepth);
ql_dbg(ql_dbg_io, vha, 0x302a,
"Queue depth adjusted-up to %d for nexus=%ld:%d:%llu.\n",
sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun);
}
static int
qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
{
switch (reason) {
case SCSI_QDEPTH_DEFAULT:
scsi_adjust_queue_depth(sdev, qdepth);
break;
case SCSI_QDEPTH_QFULL:
qla2x00_handle_queue_full(sdev, qdepth);
break;
case SCSI_QDEPTH_RAMP_UP:
qla2x00_adjust_sdev_qdepth_up(sdev, qdepth);
break;
default:
return -EOPNOTSUPP;
}
return sdev->queue_depth;
}
/**
* qla2x00_config_dma_addressing() - Configure OS DMA addressing method.
* @ha: HA context

View file

@ -164,8 +164,6 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd);
static int qla4xxx_slave_alloc(struct scsi_device *device);
static umode_t qla4_attr_is_visible(int param_type, int param);
static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type);
static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth,
int reason);
/*
* iSCSI Flash DDB sysfs entry points
@ -203,7 +201,7 @@ static struct scsi_host_template qla4xxx_driver_template = {
.eh_timed_out = qla4xxx_eh_cmd_timed_out,
.slave_alloc = qla4xxx_slave_alloc,
.change_queue_depth = qla4xxx_change_queue_depth,
.change_queue_depth = scsi_change_queue_depth,
.this_id = -1,
.cmd_per_lun = 3,
@ -9061,19 +9059,10 @@ static int qla4xxx_slave_alloc(struct scsi_device *sdev)
if (ql4xmaxqdepth != 0 && ql4xmaxqdepth <= 0xffffU)
queue_depth = ql4xmaxqdepth;
scsi_adjust_queue_depth(sdev, queue_depth);
scsi_change_queue_depth(sdev, queue_depth);
return 0;
}
static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth,
int reason)
{
if (!ql4xqfulltracking)
return -EOPNOTSUPP;
return iscsi_change_queue_depth(sdev, qdepth, reason);
}
/**
* qla4xxx_del_from_active_array - returns an active srb
* @ha: Pointer to host adapter structure.
@ -9873,6 +9862,9 @@ static int __init qla4xxx_module_init(void)
{
int ret;
if (ql4xqfulltracking)
qla4xxx_driver_template.track_queue_depth = 1;
/* Allocate cache for SRBs. */
srb_cachep = kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0,
SLAB_HWCACHE_ALIGN, NULL);

View file

@ -661,30 +661,18 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
}
/**
* scsi_adjust_queue_depth - Let low level drivers change a device's queue depth
* scsi_change_queue_depth - change a device's queue depth
* @sdev: SCSI Device in question
* @tags: Number of tags allowed if tagged queueing enabled,
* or number of commands the low level driver can
* queue up in non-tagged mode (as per cmd_per_lun).
* @depth: number of commands allowed to be queued to the driver
*
* Returns: Nothing
*
* Lock Status: None held on entry
*
* Notes: Low level drivers may call this at any time and we will do
* the right thing depending on whether or not the device is
* currently active and whether or not it even has the
* command blocks built yet.
* Sets the device queue depth and returns the new value.
*/
void scsi_adjust_queue_depth(struct scsi_device *sdev, int tags)
int scsi_change_queue_depth(struct scsi_device *sdev, int depth)
{
unsigned long flags;
/*
* refuse to set tagged depth to an unworkable size
*/
if (tags <= 0)
return;
if (depth <= 0)
goto out;
spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
@ -699,15 +687,17 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tags)
*/
if (!shost_use_blk_mq(sdev->host) && !sdev->host->bqt) {
if (blk_queue_tagged(sdev->request_queue) &&
blk_queue_resize_tags(sdev->request_queue, tags) != 0)
goto out;
blk_queue_resize_tags(sdev->request_queue, depth) != 0)
goto out_unlock;
}
sdev->queue_depth = tags;
out:
sdev->queue_depth = depth;
out_unlock:
spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
out:
return sdev->queue_depth;
}
EXPORT_SYMBOL(scsi_adjust_queue_depth);
EXPORT_SYMBOL(scsi_change_queue_depth);
/**
* scsi_track_queue_full - track QUEUE_FULL events to adjust queue depth
@ -752,12 +742,11 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
if (sdev->last_queue_full_depth < 8) {
/* Drop back to untagged */
scsi_set_tag_type(sdev, 0);
scsi_adjust_queue_depth(sdev, sdev->host->cmd_per_lun);
scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun);
return -1;
}
scsi_adjust_queue_depth(sdev, depth);
return depth;
return scsi_change_queue_depth(sdev, depth);
}
EXPORT_SYMBOL(scsi_track_queue_full);

File diff suppressed because it is too large Load diff

View file

@ -610,7 +610,7 @@ static void scsi_handle_queue_ramp_up(struct scsi_device *sdev)
struct scsi_host_template *sht = sdev->host->hostt;
struct scsi_device *tmp_sdev;
if (!sht->change_queue_depth ||
if (!sht->track_queue_depth ||
sdev->queue_depth >= sdev->max_queue_depth)
return;
@ -631,12 +631,8 @@ static void scsi_handle_queue_ramp_up(struct scsi_device *sdev)
tmp_sdev->id != sdev->id ||
tmp_sdev->queue_depth == sdev->max_queue_depth)
continue;
/*
* call back into LLD to increase queue_depth by one
* with ramp up reason code.
*/
sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1,
SCSI_QDEPTH_RAMP_UP);
scsi_change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1);
sdev->last_queue_ramp_up = jiffies;
}
}
@ -646,7 +642,7 @@ static void scsi_handle_queue_full(struct scsi_device *sdev)
struct scsi_host_template *sht = sdev->host->hostt;
struct scsi_device *tmp_sdev;
if (!sht->change_queue_depth)
if (!sht->track_queue_depth)
return;
shost_for_each_device(tmp_sdev, sdev->host) {
@ -658,8 +654,7 @@ static void scsi_handle_queue_full(struct scsi_device *sdev)
* the device when we got the queue full so we start
* from the highest possible value and work our way down.
*/
sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth - 1,
SCSI_QDEPTH_QFULL);
scsi_track_queue_full(tmp_sdev, tmp_sdev->queue_depth - 1);
}
}

View file

@ -292,7 +292,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
blk_queue_init_tags(sdev->request_queue,
sdev->host->cmd_per_lun, shost->bqt);
}
scsi_adjust_queue_depth(sdev, sdev->host->cmd_per_lun);
scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun);
scsi_sysfs_device_initialize(sdev);

Some files were not shown because too many files have changed in this diff Show more