Commit a4326635 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] megaraid_sas: intercept cmd timeout and throttle io
  [SCSI] fusion: Fix |/|| confusion
  [SCSI] aic94xx: asd_clear_nexus should fail if the cleared task does not complete
  [SCSI] aic7xxx: fix aicasm build failure with gcc-3.4.6
  [SCSI] aacraid: apply commit config for reset_devices flag
  [SCSI] sd: fix refcounting regression in suspend/resume routines
  [SCSI] aacraid: fix panic on short Inquiry
  [SCSI] aacraid: Correct sa platform support. (Was: [Bug 8469] Bad EIP value on pentium3 SMP kernel-2.6.21.1)
  [SCSI] NCR53C9x: correct spelling mistake in deprecation notice
  [SCSI] tgt: fix a rdma indirect transfer error bug
  [SCSI] MegaRAID: Update MAINTAINERS email-id
  [SCSI] stex: minor cleanup and version update
  [SCSI] stex: fix reset recovery for console device
  [SCSI] stex: extend hard reset wait time
  [SCSI] stex: fix id mapping issue
  [SCSI] ipr: Proper return codes for eh_dev_reset for SATA devices
  [SCSI] zfcp: IO stall after deleting and path checker changes after reenabling zfcp devices
  [SCSI] zfcp: avoid clutter in erp_dbf
parents d5d4db70 05e9ebbe
...@@ -62,7 +62,7 @@ Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de> ...@@ -62,7 +62,7 @@ Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
What: old NCR53C9x driver What: old NCR53C9x driver
When: October 2007 When: October 2007
Why: Replaced by the much better esp_scsi driver. Actual low-level Why: Replaced by the much better esp_scsi driver. Actual low-level
driver can ported over almost trivially. driver can be ported over almost trivially.
Who: David Miller <davem@davemloft.net> Who: David Miller <davem@davemloft.net>
Christoph Hellwig <hch@lst.de> Christoph Hellwig <hch@lst.de>
......
...@@ -2334,7 +2334,7 @@ S: Maintained ...@@ -2334,7 +2334,7 @@ S: Maintained
MEGARAID SCSI DRIVERS MEGARAID SCSI DRIVERS
P: Neela Syam Kolli P: Neela Syam Kolli
M: Neela.Kolli@engenio.com M: megaraidlinux@lsi.com
S: linux-scsi@vger.kernel.org S: linux-scsi@vger.kernel.org
W: http://megaraid.lsilogic.com W: http://megaraid.lsilogic.com
S: Maintained S: Maintained
......
...@@ -436,7 +436,7 @@ typedef struct _MPT_SAS_MGMT { ...@@ -436,7 +436,7 @@ typedef struct _MPT_SAS_MGMT {
typedef struct _mpt_ioctl_events { typedef struct _mpt_ioctl_events {
u32 event; /* Specified by define above */ u32 event; /* Specified by define above */
u32 eventContext; /* Index or counter */ u32 eventContext; /* Index or counter */
int data[2]; /* First 8 bytes of Event Data */ u32 data[2]; /* First 8 bytes of Event Data */
} MPT_IOCTL_EVENTS; } MPT_IOCTL_EVENTS;
/* /*
......
...@@ -2463,11 +2463,11 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR ...@@ -2463,11 +2463,11 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
ioc->events[idx].eventContext = ioc->eventContext; ioc->events[idx].eventContext = ioc->eventContext;
ioc->events[idx].data[0] = (pReq->LUN[1] << 24) || ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) || (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
(sc->device->channel << 8) || sc->device->id; (sc->device->channel << 8) | sc->device->id;
ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
ioc->eventContext++; ioc->eventContext++;
if (hd->ioc->pcidev->vendor == if (hd->ioc->pcidev->vendor ==
......
...@@ -1127,6 +1127,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) ...@@ -1127,6 +1127,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
int retval = 0; int retval = 0;
unsigned long flags; unsigned long flags;
zfcp_adapter_scsi_unregister(adapter);
device_unregister(&adapter->generic_services); device_unregister(&adapter->generic_services);
zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
dev_set_drvdata(&adapter->ccw_device->dev, NULL); dev_set_drvdata(&adapter->ccw_device->dev, NULL);
......
...@@ -189,9 +189,7 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) ...@@ -189,9 +189,7 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
* @ccw_device: pointer to belonging ccw device * @ccw_device: pointer to belonging ccw device
* *
* This function gets called by the common i/o layer and sets an adapter * This function gets called by the common i/o layer and sets an adapter
* into state offline. Setting an fcp device offline means that it will be * into state offline.
* unregistered from the SCSI stack and that the adapter will be shut down
* asynchronously.
*/ */
static int static int
zfcp_ccw_set_offline(struct ccw_device *ccw_device) zfcp_ccw_set_offline(struct ccw_device *ccw_device)
...@@ -202,7 +200,6 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device) ...@@ -202,7 +200,6 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device)
adapter = dev_get_drvdata(&ccw_device->dev); adapter = dev_get_drvdata(&ccw_device->dev);
zfcp_erp_adapter_shutdown(adapter, 0); zfcp_erp_adapter_shutdown(adapter, 0);
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
zfcp_adapter_scsi_unregister(adapter);
zfcp_erp_thread_kill(adapter); zfcp_erp_thread_kill(adapter);
zfcp_adapter_debug_unregister(adapter); zfcp_adapter_debug_unregister(adapter);
up(&zfcp_data.config_sema); up(&zfcp_data.config_sema);
......
...@@ -156,44 +156,30 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req) ...@@ -156,44 +156,30 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
kfree(fsf_req); kfree(fsf_req);
} }
/** /*
* zfcp_fsf_req_dismiss - dismiss a single fsf request * Never ever call this without shutting down the adapter first.
*/ * Otherwise the adapter would continue using and corrupting s390 storage.
static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter, * Included BUG_ON() call to ensure this is done.
struct zfcp_fsf_req *fsf_req, * ERP is supposed to be the only user of this function.
unsigned int counter)
{
u64 dbg_tmp[2];
dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
dbg_tmp[1] = (u64) counter;
debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
list_del(&fsf_req->list);
fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
zfcp_fsf_req_complete(fsf_req);
}
/**
* zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
*/ */
void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
{ {
struct zfcp_fsf_req *request, *tmp; struct zfcp_fsf_req *fsf_req, *tmp;
unsigned long flags; unsigned long flags;
LIST_HEAD(remove_queue); LIST_HEAD(remove_queue);
unsigned int i, counter; unsigned int i;
BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status));
spin_lock_irqsave(&adapter->req_list_lock, flags); spin_lock_irqsave(&adapter->req_list_lock, flags);
atomic_set(&adapter->reqs_active, 0); atomic_set(&adapter->reqs_active, 0);
for (i=0; i<REQUEST_LIST_SIZE; i++) for (i = 0; i < REQUEST_LIST_SIZE; i++)
list_splice_init(&adapter->req_list[i], &remove_queue); list_splice_init(&adapter->req_list[i], &remove_queue);
spin_unlock_irqrestore(&adapter->req_list_lock, flags); spin_unlock_irqrestore(&adapter->req_list_lock, flags);
counter = 0; list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
list_for_each_entry_safe(request, tmp, &remove_queue, list) { list_del(&fsf_req->list);
zfcp_fsf_req_dismiss(adapter, request, counter); fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
counter++; zfcp_fsf_req_complete(fsf_req);
} }
} }
......
...@@ -569,6 +569,9 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) ...@@ -569,6 +569,9 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
int retval = 0; int retval = 0;
static unsigned int unique_id = 0; static unsigned int unique_id = 0;
if (adapter->scsi_host)
goto out;
/* register adapter as SCSI host with mid layer of SCSI stack */ /* register adapter as SCSI host with mid layer of SCSI stack */
adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template, adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template,
sizeof (struct zfcp_adapter *)); sizeof (struct zfcp_adapter *));
......
...@@ -146,7 +146,7 @@ static char *aac_get_status_string(u32 status); ...@@ -146,7 +146,7 @@ static char *aac_get_status_string(u32 status);
static int nondasd = -1; static int nondasd = -1;
static int dacmode = -1; static int dacmode = -1;
static int commit = -1; int aac_commit = -1;
int startup_timeout = 180; int startup_timeout = 180;
int aif_timeout = 120; int aif_timeout = 120;
...@@ -154,7 +154,7 @@ module_param(nondasd, int, S_IRUGO|S_IWUSR); ...@@ -154,7 +154,7 @@ module_param(nondasd, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
module_param(dacmode, int, S_IRUGO|S_IWUSR); module_param(dacmode, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on"); MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
module_param(commit, int, S_IRUGO|S_IWUSR); module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on"); MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
module_param(startup_timeout, int, S_IRUGO|S_IWUSR); module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS."); MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS.");
...@@ -173,6 +173,9 @@ int expose_physicals = -1; ...@@ -173,6 +173,9 @@ int expose_physicals = -1;
module_param(expose_physicals, int, S_IRUGO|S_IWUSR); module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on"); MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on");
int aac_reset_devices = 0;
module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
static inline int aac_valid_context(struct scsi_cmnd *scsicmd, static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
struct fib *fibptr) { struct fib *fibptr) {
...@@ -246,7 +249,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) ...@@ -246,7 +249,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
aac_fib_complete(fibptr); aac_fib_complete(fibptr);
/* Send a CT_COMMIT_CONFIG to enable discovery of devices */ /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
if (status >= 0) { if (status >= 0) {
if ((commit == 1) || commit_flag) { if ((aac_commit == 1) || commit_flag) {
struct aac_commit_config * dinfo; struct aac_commit_config * dinfo;
aac_fib_init(fibptr); aac_fib_init(fibptr);
dinfo = (struct aac_commit_config *) fib_data(fibptr); dinfo = (struct aac_commit_config *) fib_data(fibptr);
...@@ -261,7 +264,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) ...@@ -261,7 +264,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
1, 1, 1, 1,
NULL, NULL); NULL, NULL);
aac_fib_complete(fibptr); aac_fib_complete(fibptr);
} else if (commit == 0) { } else if (aac_commit == 0) {
printk(KERN_WARNING printk(KERN_WARNING
"aac_get_config_status: Foreign device configurations are being ignored\n"); "aac_get_config_status: Foreign device configurations are being ignored\n");
} }
...@@ -340,7 +343,7 @@ int aac_get_containers(struct aac_dev *dev) ...@@ -340,7 +343,7 @@ int aac_get_containers(struct aac_dev *dev)
static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
{ {
void *buf; void *buf;
unsigned int transfer_len; int transfer_len;
struct scatterlist *sg = scsicmd->request_buffer; struct scatterlist *sg = scsicmd->request_buffer;
if (scsicmd->use_sg) { if (scsicmd->use_sg) {
...@@ -351,7 +354,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne ...@@ -351,7 +354,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
transfer_len = min(scsicmd->request_bufflen, len + offset); transfer_len = min(scsicmd->request_bufflen, len + offset);
} }
transfer_len -= offset; transfer_len -= offset;
if (buf && transfer_len) if (buf && transfer_len > 0)
memcpy(buf + offset, data, transfer_len); memcpy(buf + offset, data, transfer_len);
if (scsicmd->use_sg) if (scsicmd->use_sg)
......
...@@ -1823,9 +1823,12 @@ int aac_send_shutdown(struct aac_dev *dev); ...@@ -1823,9 +1823,12 @@ int aac_send_shutdown(struct aac_dev *dev);
int aac_probe_container(struct aac_dev *dev, int cid); int aac_probe_container(struct aac_dev *dev, int cid);
int _aac_rx_init(struct aac_dev *dev); int _aac_rx_init(struct aac_dev *dev);
int aac_rx_select_comm(struct aac_dev *dev, int comm); int aac_rx_select_comm(struct aac_dev *dev, int comm);
int aac_rx_deliver_producer(struct fib * fib);
extern int numacb; extern int numacb;
extern int acbsize; extern int acbsize;
extern char aac_driver_version[]; extern char aac_driver_version[];
extern int startup_timeout; extern int startup_timeout;
extern int aif_timeout; extern int aif_timeout;
extern int expose_physicals; extern int expose_physicals;
extern int aac_reset_devices;
extern int aac_commit;
...@@ -378,7 +378,7 @@ static int aac_rx_check_health(struct aac_dev *dev) ...@@ -378,7 +378,7 @@ static int aac_rx_check_health(struct aac_dev *dev)
* *
* Will send a fib, returning 0 if successful. * Will send a fib, returning 0 if successful.
*/ */
static int aac_rx_deliver_producer(struct fib * fib) int aac_rx_deliver_producer(struct fib * fib)
{ {
struct aac_dev *dev = fib->dev; struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
...@@ -488,6 +488,8 @@ static int aac_rx_restart_adapter(struct aac_dev *dev, int bled) ...@@ -488,6 +488,8 @@ static int aac_rx_restart_adapter(struct aac_dev *dev, int bled)
return -EINVAL; return -EINVAL;
if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
return -ENODEV; return -ENODEV;
if (startup_timeout < 300)
startup_timeout = 300;
return 0; return 0;
} }
...@@ -542,7 +544,7 @@ int _aac_rx_init(struct aac_dev *dev) ...@@ -542,7 +544,7 @@ int _aac_rx_init(struct aac_dev *dev)
dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt; dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;
dev->OIMR = status = rx_readb (dev, MUnit.OIMR); dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
if ((((status & 0x0c) != 0x0c) || reset_devices) && if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) &&
!aac_rx_restart_adapter(dev, 0)) !aac_rx_restart_adapter(dev, 0))
++restart; ++restart;
/* /*
...@@ -594,6 +596,8 @@ int _aac_rx_init(struct aac_dev *dev) ...@@ -594,6 +596,8 @@ int _aac_rx_init(struct aac_dev *dev)
} }
msleep(1); msleep(1);
} }
if (restart)
aac_commit = 1;
/* /*
* Fill in the common function dispatch table. * Fill in the common function dispatch table.
*/ */
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* based on the old aacraid driver that is.. * based on the old aacraid driver that is..
* Adaptec aacraid device driver for Linux. * Adaptec aacraid device driver for Linux.
* *
* Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -257,6 +257,11 @@ static void aac_sa_start_adapter(struct aac_dev *dev) ...@@ -257,6 +257,11 @@ static void aac_sa_start_adapter(struct aac_dev *dev)
NULL, NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL, NULL);
} }
static int aac_sa_restart_adapter(struct aac_dev *dev, int bled)
{
return -EINVAL;
}
/** /**
* aac_sa_check_health * aac_sa_check_health
* @dev: device to check if healthy * @dev: device to check if healthy
...@@ -366,7 +371,9 @@ int aac_sa_init(struct aac_dev *dev) ...@@ -366,7 +371,9 @@ int aac_sa_init(struct aac_dev *dev)
dev->a_ops.adapter_notify = aac_sa_notify_adapter; dev->a_ops.adapter_notify = aac_sa_notify_adapter;
dev->a_ops.adapter_sync_cmd = sa_sync_cmd; dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
dev->a_ops.adapter_check_health = aac_sa_check_health; dev->a_ops.adapter_check_health = aac_sa_check_health;
dev->a_ops.adapter_restart = aac_sa_restart_adapter;
dev->a_ops.adapter_intr = aac_sa_intr; dev->a_ops.adapter_intr = aac_sa_intr;
dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
dev->a_ops.adapter_ioremap = aac_sa_ioremap; dev->a_ops.adapter_ioremap = aac_sa_ioremap;
/* /*
......
...@@ -106,6 +106,7 @@ static void make_expression(expression_t *immed, int value); ...@@ -106,6 +106,7 @@ static void make_expression(expression_t *immed, int value);
static void add_conditional(symbol_t *symbol); static void add_conditional(symbol_t *symbol);
static void add_version(const char *verstring); static void add_version(const char *verstring);
static int is_download_const(expression_t *immed); static int is_download_const(expression_t *immed);
void yyerror(const char *string);
#define SRAM_SYMNAME "SRAM_BASE" #define SRAM_SYMNAME "SRAM_BASE"
#define SCB_SYMNAME "SCB_BASE" #define SCB_SYMNAME "SCB_BASE"
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
static symbol_t *macro_symbol; static symbol_t *macro_symbol;
static void add_macro_arg(const char *argtext, int position); static void add_macro_arg(const char *argtext, int position);
void mmerror(const char *string);
%} %}
......
...@@ -290,6 +290,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb, ...@@ -290,6 +290,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
static inline int asd_clear_nexus(struct sas_task *task) static inline int asd_clear_nexus(struct sas_task *task)
{ {
int res = TMF_RESP_FUNC_FAILED; int res = TMF_RESP_FUNC_FAILED;
int leftover;
struct asd_ascb *tascb = task->lldd_task; struct asd_ascb *tascb = task->lldd_task;
unsigned long flags; unsigned long flags;
...@@ -298,10 +299,12 @@ static inline int asd_clear_nexus(struct sas_task *task) ...@@ -298,10 +299,12 @@ static inline int asd_clear_nexus(struct sas_task *task)
res = asd_clear_nexus_tag(task); res = asd_clear_nexus_tag(task);
else else
res = asd_clear_nexus_index(task); res = asd_clear_nexus_index(task);
wait_for_completion_timeout(&tascb->completion, leftover = wait_for_completion_timeout(&tascb->completion,
AIC94XX_SCB_TIMEOUT); AIC94XX_SCB_TIMEOUT);
ASD_DPRINTK("came back from clear nexus\n"); ASD_DPRINTK("came back from clear nexus\n");
spin_lock_irqsave(&task->task_state_lock, flags); spin_lock_irqsave(&task->task_state_lock, flags);
if (leftover < 1)
res = TMF_RESP_FUNC_FAILED;
if (task->task_state_flags & SAS_TASK_STATE_DONE) if (task->task_state_flags & SAS_TASK_STATE_DONE)
res = TMF_RESP_FUNC_COMPLETE; res = TMF_RESP_FUNC_COMPLETE;
spin_unlock_irqrestore(&task->task_state_lock, flags); spin_unlock_irqrestore(&task->task_state_lock, flags);
...@@ -350,6 +353,7 @@ int asd_abort_task(struct sas_task *task) ...@@ -350,6 +353,7 @@ int asd_abort_task(struct sas_task *task)
unsigned long flags; unsigned long flags;
struct asd_ascb *ascb = NULL; struct asd_ascb *ascb = NULL;
struct scb *scb; struct scb *scb;
int leftover;
spin_lock_irqsave(&task->task_state_lock, flags); spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_DONE) { if (task->task_state_flags & SAS_TASK_STATE_DONE) {
...@@ -455,9 +459,11 @@ int asd_abort_task(struct sas_task *task) ...@@ -455,9 +459,11 @@ int asd_abort_task(struct sas_task *task)
break; break;
case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */ case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */
res = TMF_RESP_FUNC_FAILED; res = TMF_RESP_FUNC_FAILED;
wait_for_completion_timeout(&tascb->completion, leftover = wait_for_completion_timeout(&tascb->completion,
AIC94XX_SCB_TIMEOUT); AIC94XX_SCB_TIMEOUT);
spin_lock_irqsave(&task->task_state_lock, flags); spin_lock_irqsave(&task->task_state_lock, flags);
if (leftover < 1)
res = TMF_RESP_FUNC_FAILED;
if (task->task_state_flags & SAS_TASK_STATE_DONE) if (task->task_state_flags & SAS_TASK_STATE_DONE)
res = TMF_RESP_FUNC_COMPLETE; res = TMF_RESP_FUNC_COMPLETE;
spin_unlock_irqrestore(&task->task_state_lock, flags); spin_unlock_irqrestore(&task->task_state_lock, flags);
......
...@@ -3954,6 +3954,13 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) ...@@ -3954,6 +3954,13 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
spin_unlock_irq(scsi_cmd->device->host->host_lock); spin_unlock_irq(scsi_cmd->device->host->host_lock);
ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL); ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);
spin_lock_irq(scsi_cmd->device->host->host_lock); spin_lock_irq(scsi_cmd->device->host->host_lock);
list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
rc = -EIO;
break;
}
}
} else } else
rc = ipr_device_reset(ioa_cfg, res); rc = ipr_device_reset(ioa_cfg, res);
res->resetting_device = 0; res->resetting_device = 0;
......
...@@ -254,6 +254,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, ...@@ -254,6 +254,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
sg_init_one(&dummy, md, id->table_desc.len); sg_init_one(&dummy, md, id->table_desc.len);
sg_dma_address(&dummy) = token; sg_dma_address(&dummy) = token;
sg_dma_len(&dummy) = id->table_desc.len;
err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE, err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE,
id->table_desc.len); id->table_desc.len);
if (err) { if (err) {
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
* *
* FILE : megaraid_sas.c * FILE : megaraid_sas.c
* Version : v00.00.03.10-rc1 * Version : v00.00.03.10-rc5
* *
* Authors: * Authors:
* (email-id : megaraidlinux@lsi.com) * (email-id : megaraidlinux@lsi.com)
...@@ -886,6 +886,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) ...@@ -886,6 +886,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
goto out_return_cmd; goto out_return_cmd;
cmd->scmd = scmd; cmd->scmd = scmd;
scmd->SCp.ptr = (char *)cmd;
/* /*
* Issue the command to the FW * Issue the command to the FW
...@@ -919,7 +920,7 @@ static int megasas_slave_configure(struct scsi_device *sdev) ...@@ -919,7 +920,7 @@ static int megasas_slave_configure(struct scsi_device *sdev)
* The RAID firmware may require extended timeouts. * The RAID firmware may require extended timeouts.
*/ */
if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
sdev->timeout = 90 * HZ; sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ;
return 0; return 0;
} }
...@@ -981,8 +982,8 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) ...@@ -981,8 +982,8 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
instance = (struct megasas_instance *)scmd->device->host->hostdata; instance = (struct megasas_instance *)scmd->device->host->hostdata;
scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x\n", scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",
scmd->serial_number, scmd->cmnd[0]); scmd->serial_number, scmd->cmnd[0], scmd->retries);
if (instance->hw_crit_error) { if (instance->hw_crit_error) {
printk(KERN_ERR "megasas: cannot recover from previous reset " printk(KERN_ERR "megasas: cannot recover from previous reset "
...@@ -999,6 +1000,39 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) ...@@ -999,6 +1000,39 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
return ret_val; return ret_val;
} }
/**
* megasas_reset_timer - quiesce the adapter if required
* @scmd: scsi cmnd
*
* Sets the FW busy flag and reduces the host->can_queue if the
* cmd has not been completed within the timeout period.
*/
static enum
scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
{
struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
struct megasas_instance *instance;
unsigned long flags;
if (time_after(jiffies, scmd->jiffies_at_alloc +
(MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
return EH_NOT_HANDLED;
}
instance = cmd->instance;
if (!(instance->flag & MEGASAS_FW_BUSY)) {
/* FW is busy, throttle IO */
spin_lock_irqsave(instance->host->host_lock, flags);
instance->host->can_queue = 16;
instance->last_time = jiffies;
instance->flag |= MEGASAS_FW_BUSY;
spin_unlock_irqrestore(instance->host->host_lock, flags);
}
return EH_RESET_TIMER;
}
/** /**
* megasas_reset_device - Device reset handler entry point * megasas_reset_device - Device reset handler entry point
*/ */
...@@ -1112,6 +1146,7 @@ static struct scsi_host_template megasas_template = { ...@@ -1112,6 +1146,7 @@ static struct scsi_host_template megasas_template = {
.eh_device_reset_handler = megasas_reset_device, .eh_device_reset_handler = megasas_reset_device,
.eh_bus_reset_handler = megasas_reset_bus_host, .eh_bus_reset_handler = megasas_reset_bus_host,
.eh_host_reset_handler = megasas_reset_bus_host, .eh_host_reset_handler = megasas_reset_bus_host,
.eh_timed_out = megasas_reset_timer,
.bios_param = megasas_bios_param, .bios_param = megasas_bios_param,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
}; };
...@@ -1215,9 +1250,8 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, ...@@ -1215,9 +1250,8 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
int exception = 0; int exception = 0;
struct megasas_header *hdr = &cmd->frame->hdr; struct megasas_header *hdr = &cmd->frame->hdr;
if (cmd->scmd) { if (cmd->scmd)
cmd->scmd->SCp.ptr = (char *)0; cmd->scmd->SCp.ptr = NULL;
}
switch (hdr->cmd) { switch (hdr->cmd) {
...@@ -1806,6 +1840,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr) ...@@ -1806,6 +1840,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
u32 context; u32 context;
struct megasas_cmd *cmd; struct megasas_cmd *cmd;
struct megasas_instance *instance = (struct megasas_instance *)instance_addr; struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
unsigned long flags;
/* If we have already declared adapter dead, donot complete cmds */ /* If we have already declared adapter dead, donot complete cmds */
if (instance->hw_crit_error) if (instance->hw_crit_error)
...@@ -1828,6 +1863,22 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr) ...@@ -1828,6 +1863,22 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
} }
*instance->consumer = producer; *instance->consumer = producer;
/*
* Check if we can restore can_queue
*/
if (instance->flag & MEGASAS_FW_BUSY
&& time_after(jiffies, instance->last_time + 5 * HZ)
&& atomic_read(&instance->fw_outstanding) < 17) {
spin_lock_irqsave(instance->host->host_lock, flags);
instance->flag &= ~MEGASAS_FW_BUSY;
instance->host->can_queue =
instance->max_fw_cmds - MEGASAS_INT_CMDS;
spin_unlock_irqrestore(instance->host->host_lock, flags);
}
} }
/** /**
...@@ -2398,6 +2449,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2398,6 +2449,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
instance->init_id = MEGASAS_DEFAULT_INIT_ID; instance->init_id = MEGASAS_DEFAULT_INIT_ID;
megasas_dbg_lvl = 0; megasas_dbg_lvl = 0;
instance->flag = 0;
instance->last_time = 0;
/* /*
* Initialize MFI Firmware * Initialize MFI Firmware
......
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
/* /*
* MegaRAID SAS Driver meta data * MegaRAID SAS Driver meta data
*/ */
#define MEGASAS_VERSION "00.00.03.10-rc1" #define MEGASAS_VERSION "00.00.03.10-rc5"
#define MEGASAS_RELDATE "Feb 14, 2007" #define MEGASAS_RELDATE "May 17, 2007"
#define MEGASAS_EXT_VERSION "Wed Feb 14 10:14:25 PST 2007" #define MEGASAS_EXT_VERSION "Thu May 17 10:09:32 PDT 2007"
/* /*
* Device IDs * Device IDs
...@@ -539,6 +539,8 @@ struct megasas_ctrl_info { ...@@ -539,6 +539,8 @@ struct megasas_ctrl_info {
#define MEGASAS_DBG_LVL 1 #define MEGASAS_DBG_LVL 1
#define MEGASAS_FW_BUSY 1
/* /*
* When SCSI mid-layer calls driver's reset routine, driver waits for * When SCSI mid-layer calls driver's reset routine, driver waits for
* MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
...@@ -549,8 +551,8 @@ struct megasas_ctrl_info { ...@@ -549,8 +551,8 @@ struct megasas_ctrl_info {
#define MEGASAS_RESET_WAIT_TIME 180 #define MEGASAS_RESET_WAIT_TIME 180
#define MEGASAS_INTERNAL_CMD_WAIT_TIME 180 #define MEGASAS_INTERNAL_CMD_WAIT_TIME 180
#define MEGASAS_RESET_NOTICE_INTERVAL 5 #define MEGASAS_RESET_NOTICE_INTERVAL 5
#define MEGASAS_IOCTL_CMD 0 #define MEGASAS_IOCTL_CMD 0
#define MEGASAS_DEFAULT_CMD_TIMEOUT 90
/* /*
* FW reports the maximum of number of commands that it can accept (maximum * FW reports the maximum of number of commands that it can accept (maximum
...@@ -1073,7 +1075,6 @@ struct megasas_instance { ...@@ -1073,7 +1075,6 @@ struct megasas_instance {
struct megasas_register_set __iomem *reg_set; struct megasas_register_set __iomem *reg_set;
s8 init_id; s8 init_id;
u8 reserved[3];
u16 max_num_sge; u16 max_num_sge;
u16 max_fw_cmds; u16 max_fw_cmds;
...@@ -1104,6 +1105,9 @@ struct megasas_instance { ...@@ -1104,6 +1105,9 @@ struct megasas_instance {
struct megasas_instance_template *instancet; struct megasas_instance_template *instancet;
struct tasklet_struct isr_tasklet; struct tasklet_struct isr_tasklet;
u8 flag;
unsigned long last_time;
}; };
#define MEGASAS_IS_LOGICAL(scp) \ #define MEGASAS_IS_LOGICAL(scp) \
......
...@@ -209,6 +209,7 @@ static struct { ...@@ -209,6 +209,7 @@ static struct {
{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"Promise", "", NULL, BLIST_SPARSELUN},
{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
{"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */ {"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */
......
...@@ -1789,7 +1789,7 @@ static void sd_shutdown(struct device *dev) ...@@ -1789,7 +1789,7 @@ static void sd_shutdown(struct device *dev)
static int sd_suspend(struct device *dev, pm_message_t mesg) static int sd_suspend(struct device *dev, pm_message_t mesg)
{ {
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
int ret; int ret = 0;
if (!sdkp) if (!sdkp)
return 0; /* this can happen */ return 0; /* this can happen */
...@@ -1798,30 +1798,34 @@ static int sd_suspend(struct device *dev, pm_message_t mesg) ...@@ -1798,30 +1798,34 @@ static int sd_suspend(struct device *dev, pm_message_t mesg)
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
ret = sd_sync_cache(sdkp); ret = sd_sync_cache(sdkp);
if (ret) if (ret)
return ret; goto done;
} }
if (mesg.event == PM_EVENT_SUSPEND && if (mesg.event == PM_EVENT_SUSPEND &&
sdkp->device->manage_start_stop) { sdkp->device->manage_start_stop) {
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
ret = sd_start_stop_device(sdkp, 0); ret = sd_start_stop_device(sdkp, 0);
if (ret)
return ret;
} }
return 0; done:
scsi_disk_put(sdkp);
return ret;
} }
static int sd_resume(struct device *dev) static int sd_resume(struct device *dev)
{ {
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
int ret = 0;
if (!sdkp->device->manage_start_stop) if (!sdkp->device->manage_start_stop)
return 0; goto done;
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
ret = sd_start_stop_device(sdkp, 1);
return sd_start_stop_device(sdkp, 1); done:
scsi_disk_put(sdkp);
return ret;
} }
/** /**
......
...@@ -32,11 +32,12 @@ ...@@ -32,11 +32,12 @@
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h> #include <scsi/scsi_tcq.h>
#include <scsi/scsi_dbg.h>
#define DRV_NAME "stex" #define DRV_NAME "stex"
#define ST_DRIVER_VERSION "3.1.0.1" #define ST_DRIVER_VERSION "3.6.0000.1"
#define ST_VER_MAJOR 3 #define ST_VER_MAJOR 3
#define ST_VER_MINOR 1 #define ST_VER_MINOR 6
#define ST_OEM 0 #define ST_OEM 0
#define ST_BUILD_VER 1 #define ST_BUILD_VER 1
...@@ -113,10 +114,6 @@ enum { ...@@ -113,10 +114,6 @@ enum {
SG_CF_64B = 0x40, /* 64 bit item */ SG_CF_64B = 0x40, /* 64 bit item */
SG_CF_HOST = 0x20, /* sg in host memory */ SG_CF_HOST = 0x20, /* sg in host memory */
ST_MAX_ARRAY_SUPPORTED = 16,
ST_MAX_TARGET_NUM = (ST_MAX_ARRAY_SUPPORTED+1),
ST_MAX_LUN_PER_TARGET = 16,
st_shasta = 0, st_shasta = 0,
st_vsc = 1, st_vsc = 1,
st_vsc1 = 2, st_vsc1 = 2,
...@@ -586,7 +583,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) ...@@ -586,7 +583,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
u16 tag; u16 tag;
host = cmd->device->host; host = cmd->device->host;
id = cmd->device->id; id = cmd->device->id;
lun = cmd->device->channel; /* firmware lun issue work around */ lun = cmd->device->lun;
hba = (struct st_hba *) &host->hostdata[0]; hba = (struct st_hba *) &host->hostdata[0];
switch (cmd->cmnd[0]) { switch (cmd->cmnd[0]) {
...@@ -605,8 +602,26 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) ...@@ -605,8 +602,26 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
stex_invalid_field(cmd, done); stex_invalid_field(cmd, done);
return 0; return 0;
} }
case REPORT_LUNS:
/*
* The shasta firmware does not report actual luns in the
* target, so fail the command to force sequential lun scan.
* Also, the console device does not support this command.
*/
if (hba->cardtype == st_shasta || id == host->max_id - 1) {
stex_invalid_field(cmd, done);
return 0;
}
break;
case TEST_UNIT_READY:
if (id == host->max_id - 1) {
cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
done(cmd);
return 0;
}
break;
case INQUIRY: case INQUIRY:
if (id != ST_MAX_ARRAY_SUPPORTED) if (id != host->max_id - 1)
break; break;
if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
stex_direct_copy(cmd, console_inq_page, stex_direct_copy(cmd, console_inq_page,
...@@ -624,7 +639,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) ...@@ -624,7 +639,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
ver.oem = ST_OEM; ver.oem = ST_OEM;
ver.build = ST_BUILD_VER; ver.build = ST_BUILD_VER;
ver.signature[0] = PASSTHRU_SIGNATURE; ver.signature[0] = PASSTHRU_SIGNATURE;
ver.console_id = ST_MAX_ARRAY_SUPPORTED; ver.console_id = host->max_id - 1;
ver.host_no = hba->host->host_no; ver.host_no = hba->host->host_no;
cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ? cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ?
DID_OK << 16 | COMMAND_COMPLETE << 8 : DID_OK << 16 | COMMAND_COMPLETE << 8 :
...@@ -645,13 +660,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) ...@@ -645,13 +660,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
req = stex_alloc_req(hba); req = stex_alloc_req(hba);
if (hba->cardtype == st_yosemite) {
req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id;
req->target = 0;
} else {
req->lun = lun; req->lun = lun;
req->target = id; req->target = id;
}
/* cdb */ /* cdb */
memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
...@@ -767,18 +777,6 @@ static void stex_ys_commands(struct st_hba *hba, ...@@ -767,18 +777,6 @@ static void stex_ys_commands(struct st_hba *hba,
ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
else else
ccb->srb_status = SRB_STATUS_SUCCESS; ccb->srb_status = SRB_STATUS_SUCCESS;
} else if (ccb->cmd->cmnd[0] == REPORT_LUNS) {
u8 *report_lun_data = (u8 *)hba->copy_buffer;
count = STEX_EXTRA_SIZE;
stex_internal_copy(ccb->cmd, report_lun_data,
&count, ccb->sg_count, ST_FROM_CMD);
if (report_lun_data[2] || report_lun_data[3]) {
report_lun_data[2] = 0x00;
report_lun_data[3] = 0x08;
stex_internal_copy(ccb->cmd, report_lun_data,
&count, ccb->sg_count, ST_TO_CMD);
}
} }
} }
...@@ -995,6 +993,11 @@ static int stex_abort(struct scsi_cmnd *cmd) ...@@ -995,6 +993,11 @@ static int stex_abort(struct scsi_cmnd *cmd)
u32 data; u32 data;
int result = SUCCESS; int result = SUCCESS;
unsigned long flags; unsigned long flags;
printk(KERN_INFO DRV_NAME
"(%s): aborting command\n", pci_name(hba->pdev));
scsi_print_command(cmd);
base = hba->mmio_base; base = hba->mmio_base;
spin_lock_irqsave(host->host_lock, flags); spin_lock_irqsave(host->host_lock, flags);
if (tag < host->can_queue && hba->ccb[tag].cmd == cmd) if (tag < host->can_queue && hba->ccb[tag].cmd == cmd)
...@@ -1051,7 +1054,12 @@ static void stex_hard_reset(struct st_hba *hba) ...@@ -1051,7 +1054,12 @@ static void stex_hard_reset(struct st_hba *hba)
pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl); pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl);
pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET; pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
msleep(1);
/*
* 1 ms may be enough for 8-port controllers. But 16-port controllers
* require more time to finish bus reset. Use 100 ms here for safety
*/
msleep(100);
pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET; pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
...@@ -1075,6 +1083,10 @@ static int stex_reset(struct scsi_cmnd *cmd) ...@@ -1075,6 +1083,10 @@ static int stex_reset(struct scsi_cmnd *cmd)
unsigned long before; unsigned long before;
hba = (struct st_hba *) &cmd->device->host->hostdata[0]; hba = (struct st_hba *) &cmd->device->host->hostdata[0];
printk(KERN_INFO DRV_NAME
"(%s): resetting host\n", pci_name(hba->pdev));
scsi_print_command(cmd);
hba->mu_status = MU_STATE_RESETTING; hba->mu_status = MU_STATE_RESETTING;
if (hba->cardtype == st_shasta) if (hba->cardtype == st_shasta)
...@@ -1194,7 +1206,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1194,7 +1206,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_scsi_host_put; goto out_scsi_host_put;
} }
hba->mmio_base = ioremap(pci_resource_start(pdev, 0), hba->mmio_base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0)); pci_resource_len(pdev, 0));
if ( !hba->mmio_base) { if ( !hba->mmio_base) {
printk(KERN_ERR DRV_NAME "(%s): memory map failed\n", printk(KERN_ERR DRV_NAME "(%s): memory map failed\n",
...@@ -1229,12 +1241,18 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1229,12 +1241,18 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE;
hba->mu_status = MU_STATE_STARTING; hba->mu_status = MU_STATE_STARTING;
/* firmware uses id/lun pair for a logical drive, but lun would be if (hba->cardtype == st_shasta) {
always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use host->max_lun = 8;
channel to map lun here */ host->max_id = 16 + 1;
host->max_channel = ST_MAX_LUN_PER_TARGET - 1; } else if (hba->cardtype == st_yosemite) {
host->max_id = ST_MAX_TARGET_NUM; host->max_lun = 128;
host->max_id = 1 + 1;
} else {
/* st_vsc and st_vsc1 */
host->max_lun = 1; host->max_lun = 1;
host->max_id = 128 + 1;
}
host->max_channel = 0;
host->unique_id = host->host_no; host->unique_id = host->host_no;
host->max_cmd_len = STEX_CDB_LENGTH; host->max_cmd_len = STEX_CDB_LENGTH;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment