Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 008aef52 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 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
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
*******************************************************************************
**        O.S   : Linux
**   FILE NAME  : arcmsr.h
**        BY    : Erich Chen
**        BY    : Nick Cheng
**   Description: SCSI RAID Device Driver for
**                ARECA RAID Host adapter
*******************************************************************************
@@ -46,8 +46,12 @@
struct device_attribute;
/*The limit of outstanding scsi command that firmware can handle*/
#define ARCMSR_MAX_OUTSTANDING_CMD						256
#ifdef CONFIG_XEN
	#define ARCMSR_MAX_FREECCB_NUM	160
#else
	#define ARCMSR_MAX_FREECCB_NUM	320
#define ARCMSR_DRIVER_VERSION		     "Driver Version 1.20.00.15 2010/02/02"
#endif
#define ARCMSR_DRIVER_VERSION		     "Driver Version 1.20.00.15 2010/08/05"
#define ARCMSR_SCSI_INITIATOR_ID						255
#define ARCMSR_MAX_XFER_SECTORS							512
#define ARCMSR_MAX_XFER_SECTORS_B						4096
@@ -60,7 +64,6 @@ struct device_attribute;
#define ARCMSR_MAX_HBB_POSTQUEUE						264
#define ARCMSR_MAX_XFER_LEN							0x26000 /* 152K */
#define ARCMSR_CDB_SG_PAGE_LENGTH						256 
#define SCSI_CMD_ARECA_SPECIFIC						0xE1
#ifndef PCI_DEVICE_ID_ARECA_1880
#define PCI_DEVICE_ID_ARECA_1880 0x1880
 #endif
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
*******************************************************************************
**        O.S   : Linux
**   FILE NAME  : arcmsr_attr.c
**        BY    : Erich Chen
**        BY    : Nick Cheng
**   Description: attributes exported to sysfs and device host
*******************************************************************************
** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved
+41 −73
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
*******************************************************************************
**        O.S   : Linux
**   FILE NAME  : arcmsr_hba.c
**        BY    : Erich Chen
**        BY    : Nick Cheng
**   Description: SCSI RAID Device Driver for
**                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_VERSION(ARCMSR_DRIVER_VERSION);
static int sleeptime = 10;
static int retrycount = 30;
static int retrycount = 12;
wait_queue_head_t wait_q;
static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
					struct scsi_cmnd *cmd);
@@ -187,7 +187,6 @@ int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd)
		if (isleep > 0) {
			msleep(isleep*1000);
		}
		printk(KERN_NOTICE "wake-up\n");
		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)

{
	int id, lun;
	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: {
		struct MessageUnit_B *reg = acb->pmuB;
		/*clear all outbound posted Q*/
		writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, &reg->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++) {
			if ((flag_ccb = readl(&reg->done_qbuffer[i])) != 0) {
				writel(0, &reg->done_qbuffer[i]);
@@ -1511,7 +1509,6 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
		arcmsr_drain_donequeue(acb, pCCB, error);
	}
}

static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
{
	uint32_t index;
@@ -2106,10 +2103,6 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,
	if (atomic_read(&acb->ccboutstandingcount) >=
			ARCMSR_MAX_OUTSTANDING_CMD)
		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);
	if (!ccb)
		return SCSI_MLQUEUE_HOST_BUSY;
@@ -2393,6 +2386,7 @@ static int arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb,
	int index, rtn;
	bool error;
	polling_hbb_ccb_retry:

	poll_count++;
	/* clear doorbell interrupt */
	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;
	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;
	} else {
		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->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;
		}
		writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, &reg->inbound_msgaddr0);
		mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
	}
@@ -2682,6 +2679,7 @@ static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb)
{
	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 )){
		mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
		return;
	} else {
		acb->fw_flag = FW_NORMAL;
@@ -2689,8 +2687,10 @@ static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb)
			atomic_set(&acb->rq_map_token, 16);
		}
		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;
		}
		writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell);
		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;
	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;
	} else {
		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->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;
		}
		writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, &reg->inbound_msgaddr0);
		writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, &reg->inbound_doorbell);
		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;
	uint8_t rtnval = 0x00;
	int i = 0;
	unsigned long flags;

	if (atomic_read(&acb->ccboutstandingcount) != 0) {
		/* disable all outbound interrupt */
		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++) {
			ccb = acb->pccb_pool[i];
			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);
@@ -2920,8 +2930,7 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb)

static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
{
	struct AdapterControlBlock *acb =
		(struct AdapterControlBlock *)cmd->device->host->hostdata;
	struct AdapterControlBlock *acb;
	uint32_t intmask_org, outbound_doorbell;
	int retry_count = 0;
	int rtn = FAILED;
@@ -2971,31 +2980,16 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
				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);
				mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
				acb->acb_flags &= ~ACB_F_BUS_RESET;
				rtn = SUCCESS;
				printk(KERN_ERR "arcmsr: scsi  bus reset eh returns with success\n");
			} else {
				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->ante_token_value, 16);
				acb->fw_flag = FW_NORMAL;
				mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
				}
				rtn = SUCCESS;
			}
			break;
@@ -3007,21 +3001,10 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
				rtn = FAILED;
			} else {
				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->ante_token_value, 16);
				acb->fw_flag = FW_NORMAL;
				mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
				}
				rtn = SUCCESS;
			}
			break;
@@ -3067,31 +3050,16 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
				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);
				mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
				acb->acb_flags &= ~ACB_F_BUS_RESET;
				rtn = SUCCESS;
				printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n");
			} else {
				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->ante_token_value, 16);
				acb->fw_flag = FW_NORMAL;
				mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
				}
				rtn = SUCCESS;
			}
			break;
+1 −0
Original line number Diff line number Diff line
@@ -646,6 +646,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost)

	spin_lock_irqsave(shost->host_lock, flags);
	list_splice_init(&shost->eh_cmd_q, &eh_work_q);
	shost->host_eh_scheduled = 0;
	spin_unlock_irqrestore(shost->host_lock, flags);

	SAS_DPRINTK("Enter %s\n", __func__);
+14 −5
Original line number Diff line number Diff line
@@ -2176,9 +2176,9 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
		/* adjust hba_queue_depth, reply_free_queue_depth,
		 * and queue_size
		 */
		ioc->hba_queue_depth -= queue_diff;
		ioc->reply_free_queue_depth -= queue_diff;
		queue_size -= queue_diff;
		ioc->hba_queue_depth -= (queue_diff / 2);
		ioc->reply_free_queue_depth -= (queue_diff / 2);
		queue_size = facts->MaxReplyDescriptorPostQueueDepth;
	}
	ioc->reply_post_queue_depth = queue_size;

@@ -3941,6 +3941,8 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
static void
_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) {
	case MPT2_IOC_PRE_RESET:
		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__));
		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;
	unsigned long flags;
	u8 pe_complete = ioc->wait_for_port_enable_to_complete;

	dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
	    __func__));
@@ -4068,6 +4069,14 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
	if (r)
		goto out;
	_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);
	if (!r)
		_base_reset_handler(ioc, MPT2_IOC_DONE_RESET);
Loading