diff options
Diffstat (limited to 'drivers/scsi/arcmsr/arcmsr_hba.c')
| -rw-r--r-- | drivers/scsi/arcmsr/arcmsr_hba.c | 286 | 
1 files changed, 114 insertions, 172 deletions
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 05a78e515a2..652b41b4ddb 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -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  ******************************************************************************* @@ -61,7 +61,6 @@  #include <linux/aer.h>  #include <asm/dma.h>  #include <asm/io.h> -#include <asm/system.h>  #include <asm/uaccess.h>  #include <scsi/scsi_host.h>  #include <scsi/scsi.h> @@ -75,8 +74,10 @@ MODULE_AUTHOR("Nick Cheng <support@areca.com.tw>");  MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus Adapter");  MODULE_LICENSE("Dual BSD/GPL");  MODULE_VERSION(ARCMSR_DRIVER_VERSION); -static int sleeptime = 10; -static int retrycount = 30; + +#define	ARCMSR_SLEEPTIME	10 +#define	ARCMSR_RETRYCOUNT	12 +  wait_queue_head_t wait_q;  static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,  					struct scsi_cmnd *cmd); @@ -85,8 +86,7 @@ static int arcmsr_abort(struct scsi_cmnd *);  static int arcmsr_bus_reset(struct scsi_cmnd *);  static int arcmsr_bios_param(struct scsi_device *sdev,  		struct block_device *bdev, sector_t capacity, int *info); -static int arcmsr_queue_command(struct scsi_cmnd *cmd, -					void (*done) (struct scsi_cmnd *)); +static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);  static int arcmsr_probe(struct pci_dev *pdev,  				const struct pci_device_id *id);  static void arcmsr_remove(struct pci_dev *pdev); @@ -137,6 +137,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = {  	.cmd_per_lun		= ARCMSR_MAX_CMD_PERLUN,  	.use_clustering		= ENABLE_CLUSTERING,  	.shost_attrs		= arcmsr_host_attrs, +	.no_write_same		= 1,  };  static struct pci_device_id arcmsr_device_id_table[] = {  	{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, @@ -172,25 +173,6 @@ static struct pci_driver arcmsr_pci_driver = {  ****************************************************************************  ****************************************************************************  */ -int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd) -{ -		struct Scsi_Host *shost = NULL; -		int i, isleep; -		shost = cmd->device->host; -		isleep = sleeptime / 10; -		if (isleep > 0) { -			for (i = 0; i < isleep; i++) { -				msleep(10000); -			} -		} - -		isleep = sleeptime % 10; -		if (isleep > 0) { -			msleep(isleep*1000); -		} -		printk(KERN_NOTICE "wake-up\n"); -		return 0; -}  static void arcmsr_free_hbb_mu(struct AdapterControlBlock *acb)  { @@ -325,66 +307,64 @@ static void arcmsr_define_adapter_type(struct AdapterControlBlock *acb)  	default: acb->adapter_type = ACB_ADAPTER_TYPE_A;  	} -}	 +}  static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)  {  	struct MessageUnit_A __iomem *reg = acb->pmuA; -	uint32_t Index; -	uint8_t Retries = 0x00; -	do { -		for (Index = 0; Index < 100; Index++) { -			if (readl(®->outbound_intstatus) & -					ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { -				writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, -					®->outbound_intstatus); -				return true; -			} -			msleep(10); -		}/*max 1 seconds*/ +	int i; + +	for (i = 0; i < 2000; i++) { +		if (readl(®->outbound_intstatus) & +				ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { +			writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, +				®->outbound_intstatus); +			return true; +		} +		msleep(10); +	} /* max 20 seconds */ -	} while (Retries++ < 20);/*max 20 sec*/  	return false;  }  static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)  {  	struct MessageUnit_B *reg = acb->pmuB; -	uint32_t Index; -	uint8_t Retries = 0x00; -	do { -		for (Index = 0; Index < 100; Index++) { -			if (readl(reg->iop2drv_doorbell) -				& ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { -				writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN -					, reg->iop2drv_doorbell); -				writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); -				return true; -			} -			msleep(10); -		}/*max 1 seconds*/ +	int i; + +	for (i = 0; i < 2000; i++) { +		if (readl(reg->iop2drv_doorbell) +			& ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { +			writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, +					reg->iop2drv_doorbell); +			writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, +					reg->drv2iop_doorbell); +			return true; +		} +		msleep(10); +	} /* max 20 seconds */ -	} while (Retries++ < 20);/*max 20 sec*/  	return false;  }  static uint8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *pACB)  {  	struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC; -	unsigned char Retries = 0x00; -	uint32_t Index; -	do { -		for (Index = 0; Index < 100; Index++) { -			if (readl(&phbcmu->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { -				writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &phbcmu->outbound_doorbell_clear);/*clear interrupt*/ -				return true; -			} -			/* one us delay	*/ -			msleep(10); -		} /*max 1 seconds*/ -	} while (Retries++ < 20); /*max 20 sec*/ +	int i; + +	for (i = 0; i < 2000; i++) { +		if (readl(&phbcmu->outbound_doorbell) +				& ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { +			writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, +				&phbcmu->outbound_doorbell_clear); /*clear interrupt*/ +			return true; +		} +		msleep(10); +	} /* max 20 seconds */ +  	return false;  } +  static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)  {  	struct MessageUnit_A __iomem *reg = acb->pmuA; @@ -461,10 +441,11 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)  	struct CommandControlBlock *ccb_tmp;  	int i = 0, j = 0;  	dma_addr_t cdb_phyaddr; -	unsigned long roundup_ccbsize = 0, offset; +	unsigned long roundup_ccbsize;  	unsigned long max_xfer_len;  	unsigned long max_sg_entrys;  	uint32_t  firm_config_version; +  	for (i = 0; i < ARCMSR_MAX_TARGETID; i++)  		for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++)  			acb->devstate[i][j] = ARECA_RAID_GONE; @@ -474,23 +455,20 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)  	firm_config_version = acb->firm_cfg_version;  	if((firm_config_version & 0xFF) >= 3){  		max_xfer_len = (ARCMSR_CDB_SG_PAGE_LENGTH << ((firm_config_version >> 8) & 0xFF)) * 1024;/* max 4M byte */ -		max_sg_entrys = (max_xfer_len/4096);	 +		max_sg_entrys = (max_xfer_len/4096);  	}  	acb->host->max_sectors = max_xfer_len/512;  	acb->host->sg_tablesize = max_sg_entrys;  	roundup_ccbsize = roundup(sizeof(struct CommandControlBlock) + (max_sg_entrys - 1) * sizeof(struct SG64ENTRY), 32); -	acb->uncache_size = roundup_ccbsize * ARCMSR_MAX_FREECCB_NUM + 32; +	acb->uncache_size = roundup_ccbsize * ARCMSR_MAX_FREECCB_NUM;  	dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, &dma_coherent_handle, GFP_KERNEL);  	if(!dma_coherent){ -		printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error \n", acb->host->host_no); +		printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error\n", acb->host->host_no);  		return -ENOMEM;  	}  	acb->dma_coherent = dma_coherent;  	acb->dma_coherent_handle = dma_coherent_handle;  	memset(dma_coherent, 0, acb->uncache_size); -	offset = roundup((unsigned long)dma_coherent, 32) - (unsigned long)dma_coherent; -	dma_coherent_handle = dma_coherent_handle + offset; -	dma_coherent = (struct CommandControlBlock *)dma_coherent + offset;  	ccb_tmp = dma_coherent;  	acb->vir2phy_offset = (unsigned long)dma_coherent - (unsigned long)dma_coherent_handle;  	for(i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++){ @@ -922,7 +900,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)) { @@ -949,7 +926,7 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct Comma  				, pCCB->startdone  				, atomic_read(&acb->ccboutstandingcount));  		  return; -		} +	}  	arcmsr_report_ccb_state(acb, pCCB, error);  } @@ -982,7 +959,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, ®->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(®->done_qbuffer[i])) != 0) {  				writel(0, ®->done_qbuffer[i]); @@ -1023,7 +1000,7 @@ static void arcmsr_remove(struct pci_dev *pdev)  	int poll_count = 0;  	arcmsr_free_sysfs_attr(acb);  	scsi_remove_host(host); -	flush_scheduled_work(); +	flush_work(&acb->arcmsr_do_message_isr_bh);  	del_timer_sync(&acb->eternal_timer);  	arcmsr_disable_outbound_ints(acb);  	arcmsr_stop_adapter_bgrb(acb); @@ -1059,7 +1036,6 @@ static void arcmsr_remove(struct pci_dev *pdev)  	pci_release_regions(pdev);  	scsi_host_put(host);  	pci_disable_device(pdev); -	pci_set_drvdata(pdev, NULL);  }  static void arcmsr_shutdown(struct pci_dev *pdev) @@ -1069,7 +1045,7 @@ static void arcmsr_shutdown(struct pci_dev *pdev)  		(struct AdapterControlBlock *)host->hostdata;  	del_timer_sync(&acb->eternal_timer);  	arcmsr_disable_outbound_ints(acb); -	flush_scheduled_work(); +	flush_work(&acb->arcmsr_do_message_isr_bh);  	arcmsr_stop_adapter_bgrb(acb);  	arcmsr_flush_adapter_cache(acb);  } @@ -1172,9 +1148,8 @@ static int arcmsr_build_ccb(struct AdapterControlBlock *acb,  	arcmsr_cdb->msgPages = arccdbsize/0x100 + (arccdbsize % 0x100 ? 1 : 0);  	if ( arccdbsize > 256)  		arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE; -	if (pcmd->cmnd[0]|WRITE_6 || pcmd->cmnd[0]|WRITE_10 || pcmd->cmnd[0]|WRITE_12 ){ +	if (pcmd->sc_data_direction == DMA_TO_DEVICE)  		arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE; -	}  	ccb->arc_cdb_size = arccdbsize;  	return SUCCESS;  } @@ -1513,7 +1488,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; @@ -1761,7 +1735,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,  						(uint32_t ) cmd->cmnd[8];  						/* 4 bytes: Areca io control code */  	sg = scsi_sglist(cmd); -	buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; +	buffer = kmap_atomic(sg_page(sg)) + sg->offset;  	if (scsi_sg_count(cmd) > 1) {  		retvalue = ARCMSR_MESSAGE_FAIL;  		goto message_out; @@ -2010,7 +1984,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,  	}  	message_out:  	sg = scsi_sglist(cmd); -	kunmap_atomic(buffer - sg->offset, KM_IRQ0); +	kunmap_atomic(buffer - sg->offset);  	return retvalue;  } @@ -2060,11 +2034,11 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,  		strncpy(&inqdata[32], "R001", 4); /* Product Revision */  		sg = scsi_sglist(cmd); -		buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; +		buffer = kmap_atomic(sg_page(sg)) + sg->offset;  		memcpy(buffer, inqdata, sizeof(inqdata));  		sg = scsi_sglist(cmd); -		kunmap_atomic(buffer - sg->offset, KM_IRQ0); +		kunmap_atomic(buffer - sg->offset);  		cmd->scsi_done(cmd);  	} @@ -2081,7 +2055,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,  	}  } -static int arcmsr_queue_command(struct scsi_cmnd *cmd, +static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,  	void (* done)(struct scsi_cmnd *))  {  	struct Scsi_Host *host = cmd->device->host; @@ -2108,10 +2082,6 @@ static int arcmsr_queue_command(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; @@ -2124,6 +2094,8 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,  	return 0;  } +static DEF_SCSI_QCMD(arcmsr_queue_command) +  static bool arcmsr_get_hba_config(struct AdapterControlBlock *acb)  {  	struct MessageUnit_A __iomem *reg = acb->pmuA; @@ -2393,6 +2365,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); @@ -2527,16 +2500,15 @@ static int arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,  static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)  {  	uint32_t cdb_phyaddr, cdb_phyaddr_hi32; -	dma_addr_t dma_coherent_handle; +  	/*  	********************************************************************  	** here we need to tell iop 331 our freeccb.HighPart  	** if freeccb.HighPart is not zero  	********************************************************************  	*/ -	dma_coherent_handle = acb->dma_coherent_handle; -	cdb_phyaddr = (uint32_t)(dma_coherent_handle); -	cdb_phyaddr_hi32 = (uint32_t)((cdb_phyaddr >> 16) >> 16); +	cdb_phyaddr = lower_32_bits(acb->dma_coherent_handle); +	cdb_phyaddr_hi32 = upper_32_bits(acb->dma_coherent_handle);  	acb->cdb_phyaddr_hi32 = cdb_phyaddr_hi32;  	/*  	*********************************************************************** @@ -2608,12 +2580,8 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)  		if (cdb_phyaddr_hi32 != 0) {  			struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC; -			if (cdb_phyaddr_hi32 != 0) { -				unsigned char Retries = 0x00; -				do { -					printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x \n", acb->adapter_index, cdb_phyaddr_hi32); -				} while (Retries++ < 100); -			} +			printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x\n", +					acb->adapter_index, cdb_phyaddr_hi32);  			writel(ARCMSR_SIGNATURE_SET_CONFIG, ®->msgcode_rwbuffer[0]);  			writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[1]);  			writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); @@ -2663,6 +2631,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 +2639,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, ®->inbound_msgaddr0);  		mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));  	} @@ -2682,15 +2653,18 @@ 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;  		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)); -		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 +2675,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 +2683,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, ®->inbound_msgaddr0);  		writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell);  		mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); @@ -2843,7 +2820,7 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb)  	int i, count = 0;  	struct MessageUnit_A __iomem *pmuA = acb->pmuA;  	struct MessageUnit_C __iomem *pmuC = acb->pmuC; -	u32 temp = 0; +  	/* backup pci config data */  	printk(KERN_NOTICE "arcmsr%d: executing hw bus reset .....\n", acb->host->host_no);  	for (i = 0; i < 64; i++) { @@ -2861,7 +2838,7 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb)  			writel(0x2, &pmuC->write_sequence);  			writel(0x7, &pmuC->write_sequence);  			writel(0xD, &pmuC->write_sequence); -		} while ((((temp = readl(&pmuC->host_diagnostic)) | ARCMSR_ARC1880_DiagWrite_ENABLE) == 0) && (count < 5)); +		} while (((readl(&pmuC->host_diagnostic) & ARCMSR_ARC1880_DiagWrite_ENABLE) == 0) && (count < 5));  		writel(ARCMSR_ARC1880_RESET_ADAPTER, &pmuC->host_diagnostic);  	} else {  		pci_write_config_byte(acb->pdev, 0x84, 0x20); @@ -2897,6 +2874,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 +2886,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 +2904,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; @@ -2946,12 +2929,12 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd)  				arcmsr_hardware_reset(acb);  				acb->acb_flags &= ~ACB_F_IOP_INITED;  sleep_again: -				arcmsr_sleep_for_bus_reset(cmd); +				ssleep(ARCMSR_SLEEPTIME);  				if ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { -					printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count); -					if (retry_count > retrycount) { +					printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); +					if (retry_count > ARCMSR_RETRYCOUNT) {  						acb->fw_flag = FW_DEADLOCK; -						printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no); +						printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no);  						return FAILED;  					}  					retry_count++; @@ -2971,31 +2954,16 @@ sleep_again:  				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)); -				} +				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 +2975,10 @@ sleep_again:  				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)); -				} +				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; @@ -3042,12 +2999,12 @@ sleep_again:  				arcmsr_hardware_reset(acb);  				acb->acb_flags &= ~ACB_F_IOP_INITED;  sleep: -				arcmsr_sleep_for_bus_reset(cmd); +				ssleep(ARCMSR_SLEEPTIME);  				if ((readl(®->host_diagnostic) & 0x04) != 0) { -					printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count); -					if (retry_count > retrycount) { +					printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); +					if (retry_count > ARCMSR_RETRYCOUNT) {  						acb->fw_flag = FW_DEADLOCK; -						printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no); +						printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no);  						return FAILED;  					}  					retry_count++; @@ -3067,31 +3024,16 @@ sleep:  				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)); -				} +				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;  | 
