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
This commit is contained in:
commit
008aef526e
|
@ -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 @@
|
||||||
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;
|
||||||
#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 @@
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
** 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
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
** O.S : Linux
|
** O.S : Linux
|
||||||
** FILE NAME : arcmsr_hba.c
|
** FILE NAME : arcmsr_hba.c
|
||||||
** 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
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
|
@ -76,7 +76,7 @@ MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus Adapte
|
||||||
MODULE_LICENSE("Dual BSD/GPL");
|
MODULE_LICENSE("Dual BSD/GPL");
|
||||||
MODULE_VERSION(ARCMSR_DRIVER_VERSION);
|
MODULE_VERSION(ARCMSR_DRIVER_VERSION);
|
||||||
static int sleeptime = 10;
|
static int sleeptime = 10;
|
||||||
static int retrycount = 30;
|
static int retrycount = 12;
|
||||||
wait_queue_head_t wait_q;
|
wait_queue_head_t wait_q;
|
||||||
static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
|
static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
|
||||||
struct scsi_cmnd *cmd);
|
struct scsi_cmnd *cmd);
|
||||||
|
@ -187,7 +187,6 @@ int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd)
|
||||||
if (isleep > 0) {
|
if (isleep > 0) {
|
||||||
msleep(isleep*1000);
|
msleep(isleep*1000);
|
||||||
}
|
}
|
||||||
printk(KERN_NOTICE "wake-up\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,7 +920,6 @@ static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct CommandControlBlock *pCCB, bool error)
|
static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct CommandControlBlock *pCCB, bool error)
|
||||||
|
|
||||||
{
|
{
|
||||||
int id, lun;
|
int id, lun;
|
||||||
if ((pCCB->acb != acb) || (pCCB->startdone != ARCMSR_CCB_START)) {
|
if ((pCCB->acb != acb) || (pCCB->startdone != ARCMSR_CCB_START)) {
|
||||||
|
@ -981,7 +979,7 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
|
||||||
case ACB_ADAPTER_TYPE_B: {
|
case ACB_ADAPTER_TYPE_B: {
|
||||||
struct MessageUnit_B *reg = acb->pmuB;
|
struct MessageUnit_B *reg = acb->pmuB;
|
||||||
/*clear all outbound posted Q*/
|
/*clear all outbound posted Q*/
|
||||||
writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, ®->iop2drv_doorbell); /* clear doorbell interrupt */
|
writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); /* clear doorbell interrupt */
|
||||||
for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
|
for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
|
||||||
if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) {
|
if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) {
|
||||||
writel(0, ®->done_qbuffer[i]);
|
writel(0, ®->done_qbuffer[i]);
|
||||||
|
@ -1511,7 +1509,6 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
|
||||||
arcmsr_drain_donequeue(acb, pCCB, error);
|
arcmsr_drain_donequeue(acb, pCCB, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
|
static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
|
||||||
{
|
{
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
|
@ -2106,10 +2103,6 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,
|
||||||
if (atomic_read(&acb->ccboutstandingcount) >=
|
if (atomic_read(&acb->ccboutstandingcount) >=
|
||||||
ARCMSR_MAX_OUTSTANDING_CMD)
|
ARCMSR_MAX_OUTSTANDING_CMD)
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
if ((scsicmd == SCSI_CMD_ARECA_SPECIFIC)) {
|
|
||||||
printk(KERN_NOTICE "Receiveing SCSI_CMD_ARECA_SPECIFIC command..\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ccb = arcmsr_get_freeccb(acb);
|
ccb = arcmsr_get_freeccb(acb);
|
||||||
if (!ccb)
|
if (!ccb)
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
|
@ -2393,6 +2386,7 @@ static int arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb,
|
||||||
int index, rtn;
|
int index, rtn;
|
||||||
bool error;
|
bool error;
|
||||||
polling_hbb_ccb_retry:
|
polling_hbb_ccb_retry:
|
||||||
|
|
||||||
poll_count++;
|
poll_count++;
|
||||||
/* clear doorbell interrupt */
|
/* clear doorbell interrupt */
|
||||||
writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell);
|
writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell);
|
||||||
|
@ -2663,6 +2657,7 @@ static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb)
|
||||||
{
|
{
|
||||||
struct MessageUnit_A __iomem *reg = acb->pmuA;
|
struct MessageUnit_A __iomem *reg = acb->pmuA;
|
||||||
if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){
|
if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){
|
||||||
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
acb->fw_flag = FW_NORMAL;
|
acb->fw_flag = FW_NORMAL;
|
||||||
|
@ -2670,8 +2665,10 @@ static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb)
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
atomic_set(&acb->rq_map_token, 16);
|
||||||
}
|
}
|
||||||
atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token));
|
atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token));
|
||||||
if (atomic_dec_and_test(&acb->rq_map_token))
|
if (atomic_dec_and_test(&acb->rq_map_token)) {
|
||||||
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0);
|
writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0);
|
||||||
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
}
|
}
|
||||||
|
@ -2682,15 +2679,18 @@ static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb)
|
||||||
{
|
{
|
||||||
struct MessageUnit_B __iomem *reg = acb->pmuB;
|
struct MessageUnit_B __iomem *reg = acb->pmuB;
|
||||||
if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){
|
if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){
|
||||||
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
acb->fw_flag = FW_NORMAL;
|
acb->fw_flag = FW_NORMAL;
|
||||||
if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) {
|
if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) {
|
||||||
atomic_set(&acb->rq_map_token,16);
|
atomic_set(&acb->rq_map_token, 16);
|
||||||
}
|
}
|
||||||
atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token));
|
atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token));
|
||||||
if(atomic_dec_and_test(&acb->rq_map_token))
|
if (atomic_dec_and_test(&acb->rq_map_token)) {
|
||||||
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell);
|
writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell);
|
||||||
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
}
|
}
|
||||||
|
@ -2701,6 +2701,7 @@ static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb)
|
||||||
{
|
{
|
||||||
struct MessageUnit_C __iomem *reg = acb->pmuC;
|
struct MessageUnit_C __iomem *reg = acb->pmuC;
|
||||||
if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0) || ((acb->acb_flags & ACB_F_ABORT) != 0)) {
|
if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0) || ((acb->acb_flags & ACB_F_ABORT) != 0)) {
|
||||||
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
acb->fw_flag = FW_NORMAL;
|
acb->fw_flag = FW_NORMAL;
|
||||||
|
@ -2708,8 +2709,10 @@ static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb)
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
atomic_set(&acb->rq_map_token, 16);
|
||||||
}
|
}
|
||||||
atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token));
|
atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token));
|
||||||
if (atomic_dec_and_test(&acb->rq_map_token))
|
if (atomic_dec_and_test(&acb->rq_map_token)) {
|
||||||
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0);
|
writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0);
|
||||||
writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell);
|
writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell);
|
||||||
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
|
@ -2897,6 +2900,8 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb)
|
||||||
uint32_t intmask_org;
|
uint32_t intmask_org;
|
||||||
uint8_t rtnval = 0x00;
|
uint8_t rtnval = 0x00;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (atomic_read(&acb->ccboutstandingcount) != 0) {
|
if (atomic_read(&acb->ccboutstandingcount) != 0) {
|
||||||
/* disable all outbound interrupt */
|
/* disable all outbound interrupt */
|
||||||
intmask_org = arcmsr_disable_outbound_ints(acb);
|
intmask_org = arcmsr_disable_outbound_ints(acb);
|
||||||
|
@ -2907,7 +2912,12 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb)
|
||||||
for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
|
for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
|
||||||
ccb = acb->pccb_pool[i];
|
ccb = acb->pccb_pool[i];
|
||||||
if (ccb->startdone == ARCMSR_CCB_START) {
|
if (ccb->startdone == ARCMSR_CCB_START) {
|
||||||
arcmsr_ccb_complete(ccb);
|
scsi_dma_unmap(ccb->pcmd);
|
||||||
|
ccb->startdone = ARCMSR_CCB_DONE;
|
||||||
|
ccb->ccb_flags = 0;
|
||||||
|
spin_lock_irqsave(&acb->ccblist_lock, flags);
|
||||||
|
list_add_tail(&ccb->list, &acb->ccb_free_list);
|
||||||
|
spin_unlock_irqrestore(&acb->ccblist_lock, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atomic_set(&acb->ccboutstandingcount, 0);
|
atomic_set(&acb->ccboutstandingcount, 0);
|
||||||
|
@ -2920,8 +2930,7 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb)
|
||||||
|
|
||||||
static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
|
static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
struct AdapterControlBlock *acb =
|
struct AdapterControlBlock *acb;
|
||||||
(struct AdapterControlBlock *)cmd->device->host->hostdata;
|
|
||||||
uint32_t intmask_org, outbound_doorbell;
|
uint32_t intmask_org, outbound_doorbell;
|
||||||
int retry_count = 0;
|
int retry_count = 0;
|
||||||
int rtn = FAILED;
|
int rtn = FAILED;
|
||||||
|
@ -2971,31 +2980,16 @@ sleep_again:
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
atomic_set(&acb->rq_map_token, 16);
|
||||||
atomic_set(&acb->ante_token_value, 16);
|
atomic_set(&acb->ante_token_value, 16);
|
||||||
acb->fw_flag = FW_NORMAL;
|
acb->fw_flag = FW_NORMAL;
|
||||||
init_timer(&acb->eternal_timer);
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ);
|
|
||||||
acb->eternal_timer.data = (unsigned long) acb;
|
|
||||||
acb->eternal_timer.function = &arcmsr_request_device_map;
|
|
||||||
add_timer(&acb->eternal_timer);
|
|
||||||
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
||||||
rtn = SUCCESS;
|
rtn = SUCCESS;
|
||||||
printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n");
|
printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n");
|
||||||
} else {
|
} else {
|
||||||
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
||||||
if (atomic_read(&acb->rq_map_token) == 0) {
|
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
|
||||||
atomic_set(&acb->ante_token_value, 16);
|
|
||||||
acb->fw_flag = FW_NORMAL;
|
|
||||||
init_timer(&acb->eternal_timer);
|
|
||||||
acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ);
|
|
||||||
acb->eternal_timer.data = (unsigned long) acb;
|
|
||||||
acb->eternal_timer.function = &arcmsr_request_device_map;
|
|
||||||
add_timer(&acb->eternal_timer);
|
|
||||||
} else {
|
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
atomic_set(&acb->rq_map_token, 16);
|
||||||
atomic_set(&acb->ante_token_value, 16);
|
atomic_set(&acb->ante_token_value, 16);
|
||||||
acb->fw_flag = FW_NORMAL;
|
acb->fw_flag = FW_NORMAL;
|
||||||
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
|
||||||
}
|
|
||||||
rtn = SUCCESS;
|
rtn = SUCCESS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3007,21 +3001,10 @@ sleep_again:
|
||||||
rtn = FAILED;
|
rtn = FAILED;
|
||||||
} else {
|
} else {
|
||||||
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
||||||
if (atomic_read(&acb->rq_map_token) == 0) {
|
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
atomic_set(&acb->rq_map_token, 16);
|
||||||
atomic_set(&acb->ante_token_value, 16);
|
atomic_set(&acb->ante_token_value, 16);
|
||||||
acb->fw_flag = FW_NORMAL;
|
acb->fw_flag = FW_NORMAL;
|
||||||
init_timer(&acb->eternal_timer);
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ);
|
|
||||||
acb->eternal_timer.data = (unsigned long) acb;
|
|
||||||
acb->eternal_timer.function = &arcmsr_request_device_map;
|
|
||||||
add_timer(&acb->eternal_timer);
|
|
||||||
} else {
|
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
|
||||||
atomic_set(&acb->ante_token_value, 16);
|
|
||||||
acb->fw_flag = FW_NORMAL;
|
|
||||||
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
|
|
||||||
}
|
|
||||||
rtn = SUCCESS;
|
rtn = SUCCESS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3067,31 +3050,16 @@ sleep:
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
atomic_set(&acb->rq_map_token, 16);
|
||||||
atomic_set(&acb->ante_token_value, 16);
|
atomic_set(&acb->ante_token_value, 16);
|
||||||
acb->fw_flag = FW_NORMAL;
|
acb->fw_flag = FW_NORMAL;
|
||||||
init_timer(&acb->eternal_timer);
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ);
|
|
||||||
acb->eternal_timer.data = (unsigned long) acb;
|
|
||||||
acb->eternal_timer.function = &arcmsr_request_device_map;
|
|
||||||
add_timer(&acb->eternal_timer);
|
|
||||||
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
||||||
rtn = SUCCESS;
|
rtn = SUCCESS;
|
||||||
printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n");
|
printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n");
|
||||||
} else {
|
} else {
|
||||||
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
acb->acb_flags &= ~ACB_F_BUS_RESET;
|
||||||
if (atomic_read(&acb->rq_map_token) == 0) {
|
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
|
||||||
atomic_set(&acb->ante_token_value, 16);
|
|
||||||
acb->fw_flag = FW_NORMAL;
|
|
||||||
init_timer(&acb->eternal_timer);
|
|
||||||
acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ);
|
|
||||||
acb->eternal_timer.data = (unsigned long) acb;
|
|
||||||
acb->eternal_timer.function = &arcmsr_request_device_map;
|
|
||||||
add_timer(&acb->eternal_timer);
|
|
||||||
} else {
|
|
||||||
atomic_set(&acb->rq_map_token, 16);
|
atomic_set(&acb->rq_map_token, 16);
|
||||||
atomic_set(&acb->ante_token_value, 16);
|
atomic_set(&acb->ante_token_value, 16);
|
||||||
acb->fw_flag = FW_NORMAL;
|
acb->fw_flag = FW_NORMAL;
|
||||||
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
|
||||||
}
|
|
||||||
rtn = SUCCESS;
|
rtn = SUCCESS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -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)
|
||||||
/* 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)
|
||||||
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)
|
||||||
"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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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)
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
(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,
|
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30, NULL);
|
|
||||||
termination_count += le32_to_cpu(mpi_reply->TerminationCount);
|
|
||||||
}
|
}
|
||||||
ioc->broadcast_aen_busy = 0;
|
r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
|
||||||
|
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);
|
||||||
|
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
|
||||||
|
}
|
||||||
|
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)
|
||||||
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 @@
|
||||||
#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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue