diff options
Diffstat (limited to 'drivers/scsi/arcmsr')
-rw-r--r-- | drivers/scsi/arcmsr/arcmsr_hba.c | 126 |
1 files changed, 52 insertions, 74 deletions
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index da7b9887ec48..a47327fe162c 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c | |||
@@ -75,8 +75,10 @@ MODULE_AUTHOR("Nick Cheng <support@areca.com.tw>"); | |||
75 | MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus Adapter"); | 75 | MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus Adapter"); |
76 | MODULE_LICENSE("Dual BSD/GPL"); | 76 | MODULE_LICENSE("Dual BSD/GPL"); |
77 | MODULE_VERSION(ARCMSR_DRIVER_VERSION); | 77 | MODULE_VERSION(ARCMSR_DRIVER_VERSION); |
78 | static int sleeptime = 10; | 78 | |
79 | static int retrycount = 12; | 79 | #define ARCMSR_SLEEPTIME 10 |
80 | #define ARCMSR_RETRYCOUNT 12 | ||
81 | |||
80 | wait_queue_head_t wait_q; | 82 | wait_queue_head_t wait_q; |
81 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | 83 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, |
82 | struct scsi_cmnd *cmd); | 84 | struct scsi_cmnd *cmd); |
@@ -171,24 +173,6 @@ static struct pci_driver arcmsr_pci_driver = { | |||
171 | **************************************************************************** | 173 | **************************************************************************** |
172 | **************************************************************************** | 174 | **************************************************************************** |
173 | */ | 175 | */ |
174 | int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd) | ||
175 | { | ||
176 | struct Scsi_Host *shost = NULL; | ||
177 | int i, isleep; | ||
178 | shost = cmd->device->host; | ||
179 | isleep = sleeptime / 10; | ||
180 | if (isleep > 0) { | ||
181 | for (i = 0; i < isleep; i++) { | ||
182 | msleep(10000); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | isleep = sleeptime % 10; | ||
187 | if (isleep > 0) { | ||
188 | msleep(isleep*1000); | ||
189 | } | ||
190 | return 0; | ||
191 | } | ||
192 | 176 | ||
193 | static void arcmsr_free_hbb_mu(struct AdapterControlBlock *acb) | 177 | static void arcmsr_free_hbb_mu(struct AdapterControlBlock *acb) |
194 | { | 178 | { |
@@ -323,66 +307,64 @@ static void arcmsr_define_adapter_type(struct AdapterControlBlock *acb) | |||
323 | 307 | ||
324 | default: acb->adapter_type = ACB_ADAPTER_TYPE_A; | 308 | default: acb->adapter_type = ACB_ADAPTER_TYPE_A; |
325 | } | 309 | } |
326 | } | 310 | } |
327 | 311 | ||
328 | static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb) | 312 | static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb) |
329 | { | 313 | { |
330 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 314 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
331 | uint32_t Index; | 315 | int i; |
332 | uint8_t Retries = 0x00; | 316 | |
333 | do { | 317 | for (i = 0; i < 2000; i++) { |
334 | for (Index = 0; Index < 100; Index++) { | 318 | if (readl(®->outbound_intstatus) & |
335 | if (readl(®->outbound_intstatus) & | 319 | ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { |
336 | ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { | 320 | writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, |
337 | writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, | 321 | ®->outbound_intstatus); |
338 | ®->outbound_intstatus); | 322 | return true; |
339 | return true; | 323 | } |
340 | } | 324 | msleep(10); |
341 | msleep(10); | 325 | } /* max 20 seconds */ |
342 | }/*max 1 seconds*/ | ||
343 | 326 | ||
344 | } while (Retries++ < 20);/*max 20 sec*/ | ||
345 | return false; | 327 | return false; |
346 | } | 328 | } |
347 | 329 | ||
348 | static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) | 330 | static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) |
349 | { | 331 | { |
350 | struct MessageUnit_B *reg = acb->pmuB; | 332 | struct MessageUnit_B *reg = acb->pmuB; |
351 | uint32_t Index; | 333 | int i; |
352 | uint8_t Retries = 0x00; | 334 | |
353 | do { | 335 | for (i = 0; i < 2000; i++) { |
354 | for (Index = 0; Index < 100; Index++) { | 336 | if (readl(reg->iop2drv_doorbell) |
355 | if (readl(reg->iop2drv_doorbell) | 337 | & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { |
356 | & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { | 338 | writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, |
357 | writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN | 339 | reg->iop2drv_doorbell); |
358 | , reg->iop2drv_doorbell); | 340 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, |
359 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); | 341 | reg->drv2iop_doorbell); |
360 | return true; | 342 | return true; |
361 | } | 343 | } |
362 | msleep(10); | 344 | msleep(10); |
363 | }/*max 1 seconds*/ | 345 | } /* max 20 seconds */ |
364 | 346 | ||
365 | } while (Retries++ < 20);/*max 20 sec*/ | ||
366 | return false; | 347 | return false; |
367 | } | 348 | } |
368 | 349 | ||
369 | static uint8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *pACB) | 350 | static uint8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *pACB) |
370 | { | 351 | { |
371 | struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC; | 352 | struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC; |
372 | unsigned char Retries = 0x00; | 353 | int i; |
373 | uint32_t Index; | 354 | |
374 | do { | 355 | for (i = 0; i < 2000; i++) { |
375 | for (Index = 0; Index < 100; Index++) { | 356 | if (readl(&phbcmu->outbound_doorbell) |
376 | if (readl(&phbcmu->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { | 357 | & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { |
377 | writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &phbcmu->outbound_doorbell_clear);/*clear interrupt*/ | 358 | writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, |
378 | return true; | 359 | &phbcmu->outbound_doorbell_clear); /*clear interrupt*/ |
379 | } | 360 | return true; |
380 | /* one us delay */ | 361 | } |
381 | msleep(10); | 362 | msleep(10); |
382 | } /*max 1 seconds*/ | 363 | } /* max 20 seconds */ |
383 | } while (Retries++ < 20); /*max 20 sec*/ | 364 | |
384 | return false; | 365 | return false; |
385 | } | 366 | } |
367 | |||
386 | static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb) | 368 | static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb) |
387 | { | 369 | { |
388 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 370 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
@@ -2602,12 +2584,8 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) | |||
2602 | if (cdb_phyaddr_hi32 != 0) { | 2584 | if (cdb_phyaddr_hi32 != 0) { |
2603 | struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC; | 2585 | struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC; |
2604 | 2586 | ||
2605 | if (cdb_phyaddr_hi32 != 0) { | 2587 | printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x\n", |
2606 | unsigned char Retries = 0x00; | 2588 | acb->adapter_index, cdb_phyaddr_hi32); |
2607 | do { | ||
2608 | printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x \n", acb->adapter_index, cdb_phyaddr_hi32); | ||
2609 | } while (Retries++ < 100); | ||
2610 | } | ||
2611 | writel(ARCMSR_SIGNATURE_SET_CONFIG, ®->msgcode_rwbuffer[0]); | 2589 | writel(ARCMSR_SIGNATURE_SET_CONFIG, ®->msgcode_rwbuffer[0]); |
2612 | writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[1]); | 2590 | writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[1]); |
2613 | writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); | 2591 | writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); |
@@ -2955,12 +2933,12 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) | |||
2955 | arcmsr_hardware_reset(acb); | 2933 | arcmsr_hardware_reset(acb); |
2956 | acb->acb_flags &= ~ACB_F_IOP_INITED; | 2934 | acb->acb_flags &= ~ACB_F_IOP_INITED; |
2957 | sleep_again: | 2935 | sleep_again: |
2958 | arcmsr_sleep_for_bus_reset(cmd); | 2936 | ssleep(ARCMSR_SLEEPTIME); |
2959 | if ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { | 2937 | if ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { |
2960 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count); | 2938 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); |
2961 | if (retry_count > retrycount) { | 2939 | if (retry_count > ARCMSR_RETRYCOUNT) { |
2962 | acb->fw_flag = FW_DEADLOCK; | 2940 | acb->fw_flag = FW_DEADLOCK; |
2963 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no); | 2941 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no); |
2964 | return FAILED; | 2942 | return FAILED; |
2965 | } | 2943 | } |
2966 | retry_count++; | 2944 | retry_count++; |
@@ -3025,12 +3003,12 @@ sleep_again: | |||
3025 | arcmsr_hardware_reset(acb); | 3003 | arcmsr_hardware_reset(acb); |
3026 | acb->acb_flags &= ~ACB_F_IOP_INITED; | 3004 | acb->acb_flags &= ~ACB_F_IOP_INITED; |
3027 | sleep: | 3005 | sleep: |
3028 | arcmsr_sleep_for_bus_reset(cmd); | 3006 | ssleep(ARCMSR_SLEEPTIME); |
3029 | if ((readl(®->host_diagnostic) & 0x04) != 0) { | 3007 | if ((readl(®->host_diagnostic) & 0x04) != 0) { |
3030 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count); | 3008 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); |
3031 | if (retry_count > retrycount) { | 3009 | if (retry_count > ARCMSR_RETRYCOUNT) { |
3032 | acb->fw_flag = FW_DEADLOCK; | 3010 | acb->fw_flag = FW_DEADLOCK; |
3033 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no); | 3011 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no); |
3034 | return FAILED; | 3012 | return FAILED; |
3035 | } | 3013 | } |
3036 | retry_count++; | 3014 | retry_count++; |