Commit 008aef52 authored by Linus Torvalds's avatar Linus Torvalds

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

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] libsas: fix runaway error handler problem
  [SCSI] fix incorrect value of SCSI_MAX_SG_CHAIN_SEGMENTS due to include file ordering
  [SCSI] arcmsr: Fix the issue of system hangup after commands timeout on ARC-1200
  [SCSI] mpt2sas: fix Integrated Raid unsynced on shutdown problem
  [SCSI] mpt2sas: Kernel Panic during Large Topology discovery
  [SCSI] mpt2sas: Fix the race between broadcast asyn event and scsi command completion
  [SCSI] mpt2sas: Correct resizing calculation for max_queue_depth
  [SCSI] mpt2sas: fix internal device reset for older firmware prior to MPI Rev K
  [SCSI] mpt2sas: Fix device removal handshake for zoned devices
parents 831d52bc 9ee91f7f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
******************************************************************************* *******************************************************************************
** O.S : Linux ** O.S : Linux
** FILE NAME : arcmsr.h ** FILE NAME : arcmsr.h
** BY : Erich Chen ** BY : Nick Cheng
** Description: SCSI RAID Device Driver for ** Description: SCSI RAID Device Driver for
** ARECA RAID Host adapter ** ARECA RAID Host adapter
******************************************************************************* *******************************************************************************
...@@ -46,8 +46,12 @@ ...@@ -46,8 +46,12 @@
struct device_attribute; struct device_attribute;
/*The limit of outstanding scsi command that firmware can handle*/ /*The limit of outstanding scsi command that firmware can handle*/
#define ARCMSR_MAX_OUTSTANDING_CMD 256 #define ARCMSR_MAX_OUTSTANDING_CMD 256
#define ARCMSR_MAX_FREECCB_NUM 320 #ifdef CONFIG_XEN
#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2010/02/02" #define ARCMSR_MAX_FREECCB_NUM 160
#else
#define ARCMSR_MAX_FREECCB_NUM 320
#endif
#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2010/08/05"
#define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_SCSI_INITIATOR_ID 255
#define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS 512
#define ARCMSR_MAX_XFER_SECTORS_B 4096 #define ARCMSR_MAX_XFER_SECTORS_B 4096
...@@ -60,7 +64,6 @@ struct device_attribute; ...@@ -60,7 +64,6 @@ struct device_attribute;
#define ARCMSR_MAX_HBB_POSTQUEUE 264 #define ARCMSR_MAX_HBB_POSTQUEUE 264
#define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */
#define ARCMSR_CDB_SG_PAGE_LENGTH 256 #define ARCMSR_CDB_SG_PAGE_LENGTH 256
#define SCSI_CMD_ARECA_SPECIFIC 0xE1
#ifndef PCI_DEVICE_ID_ARECA_1880 #ifndef PCI_DEVICE_ID_ARECA_1880
#define PCI_DEVICE_ID_ARECA_1880 0x1880 #define PCI_DEVICE_ID_ARECA_1880 0x1880
#endif #endif
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
******************************************************************************* *******************************************************************************
** O.S : Linux ** O.S : Linux
** FILE NAME : arcmsr_attr.c ** FILE NAME : arcmsr_attr.c
** BY : Erich Chen ** BY : Nick Cheng
** Description: attributes exported to sysfs and device host ** Description: attributes exported to sysfs and device host
******************************************************************************* *******************************************************************************
** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved
......
This diff is collapsed.
...@@ -646,6 +646,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) ...@@ -646,6 +646,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost)
spin_lock_irqsave(shost->host_lock, flags); spin_lock_irqsave(shost->host_lock, flags);
list_splice_init(&shost->eh_cmd_q, &eh_work_q); list_splice_init(&shost->eh_cmd_q, &eh_work_q);
shost->host_eh_scheduled = 0;
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
SAS_DPRINTK("Enter %s\n", __func__); SAS_DPRINTK("Enter %s\n", __func__);
......
...@@ -2176,9 +2176,9 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -2176,9 +2176,9 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
/* adjust hba_queue_depth, reply_free_queue_depth, /* adjust hba_queue_depth, reply_free_queue_depth,
* and queue_size * and queue_size
*/ */
ioc->hba_queue_depth -= queue_diff; ioc->hba_queue_depth -= (queue_diff / 2);
ioc->reply_free_queue_depth -= queue_diff; ioc->reply_free_queue_depth -= (queue_diff / 2);
queue_size -= queue_diff; queue_size = facts->MaxReplyDescriptorPostQueueDepth;
} }
ioc->reply_post_queue_depth = queue_size; ioc->reply_post_queue_depth = queue_size;
...@@ -3941,6 +3941,8 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) ...@@ -3941,6 +3941,8 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
static void static void
_base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
{ {
mpt2sas_scsih_reset_handler(ioc, reset_phase);
mpt2sas_ctl_reset_handler(ioc, reset_phase);
switch (reset_phase) { switch (reset_phase) {
case MPT2_IOC_PRE_RESET: case MPT2_IOC_PRE_RESET:
dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
...@@ -3971,8 +3973,6 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) ...@@ -3971,8 +3973,6 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
"MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
break; break;
} }
mpt2sas_scsih_reset_handler(ioc, reset_phase);
mpt2sas_ctl_reset_handler(ioc, reset_phase);
} }
/** /**
...@@ -4026,6 +4026,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, ...@@ -4026,6 +4026,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
{ {
int r; int r;
unsigned long flags; unsigned long flags;
u8 pe_complete = ioc->wait_for_port_enable_to_complete;
dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
__func__)); __func__));
...@@ -4068,6 +4069,14 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, ...@@ -4068,6 +4069,14 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
if (r) if (r)
goto out; goto out;
_base_reset_handler(ioc, MPT2_IOC_AFTER_RESET); _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET);
/* If this hard reset is called while port enable is active, then
* there is no reason to call make_ioc_operational
*/
if (pe_complete) {
r = -EFAULT;
goto out;
}
r = _base_make_ioc_operational(ioc, sleep_flag); r = _base_make_ioc_operational(ioc, sleep_flag);
if (!r) if (!r)
_base_reset_handler(ioc, MPT2_IOC_DONE_RESET); _base_reset_handler(ioc, MPT2_IOC_DONE_RESET);
......
...@@ -819,7 +819,7 @@ _scsih_is_end_device(u32 device_info) ...@@ -819,7 +819,7 @@ _scsih_is_end_device(u32 device_info)
} }
/** /**
* mptscsih_get_scsi_lookup - returns scmd entry * _scsih_scsi_lookup_get - returns scmd entry
* @ioc: per adapter object * @ioc: per adapter object
* @smid: system request message index * @smid: system request message index
* *
...@@ -831,6 +831,28 @@ _scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid) ...@@ -831,6 +831,28 @@ _scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
return ioc->scsi_lookup[smid - 1].scmd; return ioc->scsi_lookup[smid - 1].scmd;
} }
/**
* _scsih_scsi_lookup_get_clear - returns scmd entry
* @ioc: per adapter object
* @smid: system request message index
*
* Returns the smid stored scmd pointer.
* Then will derefrence the stored scmd pointer.
*/
static inline struct scsi_cmnd *
_scsih_scsi_lookup_get_clear(struct MPT2SAS_ADAPTER *ioc, u16 smid)
{
unsigned long flags;
struct scsi_cmnd *scmd;
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
scmd = ioc->scsi_lookup[smid - 1].scmd;
ioc->scsi_lookup[smid - 1].scmd = NULL;
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
return scmd;
}
/** /**
* _scsih_scsi_lookup_find_by_scmd - scmd lookup * _scsih_scsi_lookup_find_by_scmd - scmd lookup
* @ioc: per adapter object * @ioc: per adapter object
...@@ -2981,9 +3003,6 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc, ...@@ -2981,9 +3003,6 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
u16 handle; u16 handle;
for (i = 0 ; i < event_data->NumEntries; i++) { for (i = 0 ; i < event_data->NumEntries; i++) {
if (event_data->PHY[i].PhyStatus &
MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT)
continue;
handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
if (!handle) if (!handle)
continue; continue;
...@@ -3210,7 +3229,7 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc) ...@@ -3210,7 +3229,7 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
u16 count = 0; u16 count = 0;
for (smid = 1; smid <= ioc->scsiio_depth; smid++) { for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
scmd = _scsih_scsi_lookup_get(ioc, smid); scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
if (!scmd) if (!scmd)
continue; continue;
count++; count++;
...@@ -3804,7 +3823,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) ...@@ -3804,7 +3823,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
u32 response_code = 0; u32 response_code = 0;
mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
scmd = _scsih_scsi_lookup_get(ioc, smid); scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
if (scmd == NULL) if (scmd == NULL)
return 1; return 1;
...@@ -5005,6 +5024,12 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, ...@@ -5005,6 +5024,12 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
event_data); event_data);
#endif #endif
/* In MPI Revision K (0xC), the internal device reset complete was
* implemented, so avoid setting tm_busy flag for older firmware.
*/
if ((ioc->facts.HeaderVersion >> 8) < 0xC)
return;
if (event_data->ReasonCode != if (event_data->ReasonCode !=
MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
event_data->ReasonCode != event_data->ReasonCode !=
...@@ -5099,6 +5124,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, ...@@ -5099,6 +5124,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
struct fw_event_work *fw_event) struct fw_event_work *fw_event)
{ {
struct scsi_cmnd *scmd; struct scsi_cmnd *scmd;
struct scsi_device *sdev;
u16 smid, handle; u16 smid, handle;
u32 lun; u32 lun;
struct MPT2SAS_DEVICE *sas_device_priv_data; struct MPT2SAS_DEVICE *sas_device_priv_data;
...@@ -5109,12 +5135,17 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, ...@@ -5109,12 +5135,17 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
#endif #endif
u16 ioc_status; u16 ioc_status;
unsigned long flags;
int r;
dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: " dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: "
"phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
event_data->PortWidth)); event_data->PortWidth));
dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
__func__)); __func__));
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
ioc->broadcast_aen_busy = 0;
termination_count = 0; termination_count = 0;
query_count = 0; query_count = 0;
mpi_reply = ioc->tm_cmds.reply; mpi_reply = ioc->tm_cmds.reply;
...@@ -5122,7 +5153,8 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, ...@@ -5122,7 +5153,8 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
scmd = _scsih_scsi_lookup_get(ioc, smid); scmd = _scsih_scsi_lookup_get(ioc, smid);
if (!scmd) if (!scmd)
continue; continue;
sas_device_priv_data = scmd->device->hostdata; sdev = scmd->device;
sas_device_priv_data = sdev->hostdata;
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) if (!sas_device_priv_data || !sas_device_priv_data->sas_target)
continue; continue;
/* skip hidden raid components */ /* skip hidden raid components */
...@@ -5138,6 +5170,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, ...@@ -5138,6 +5170,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
lun = sas_device_priv_data->lun; lun = sas_device_priv_data->lun;
query_count++; query_count++;
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL); MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL);
ioc->tm_cmds.status = MPT2_CMD_NOT_USED; ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
...@@ -5147,14 +5180,20 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, ...@@ -5147,14 +5180,20 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
(mpi_reply->ResponseCode == (mpi_reply->ResponseCode ==
MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
mpi_reply->ResponseCode == mpi_reply->ResponseCode ==
MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) {
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
continue; continue;
}
mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30, NULL); sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
scmd);
if (r == FAILED)
sdev_printk(KERN_WARNING, sdev, "task abort: FAILED "
"scmd(%p)\n", scmd);
termination_count += le32_to_cpu(mpi_reply->TerminationCount); termination_count += le32_to_cpu(mpi_reply->TerminationCount);
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
} }
ioc->broadcast_aen_busy = 0; spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
dtmprintk(ioc, printk(MPT2SAS_INFO_FMT dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
"%s - exit, query_count = %d termination_count = %d\n", "%s - exit, query_count = %d termination_count = %d\n",
...@@ -6626,6 +6665,7 @@ _scsih_remove(struct pci_dev *pdev) ...@@ -6626,6 +6665,7 @@ _scsih_remove(struct pci_dev *pdev)
destroy_workqueue(wq); destroy_workqueue(wq);
/* release all the volumes */ /* release all the volumes */
_scsih_ir_shutdown(ioc);
list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list,
list) { list) {
if (raid_device->starget) { if (raid_device->starget) {
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define _SCSI_SCSI_H #define _SCSI_SCSI_H
#include <linux/types.h> #include <linux/types.h>
#include <linux/scatterlist.h>
struct scsi_cmnd; struct scsi_cmnd;
......
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