diff options
author | Nick Cheng <nick.cheng@areca.com.tw> | 2010-07-13 08:03:04 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-27 13:03:49 -0400 |
commit | cdd3cb156f190edb37d7066ddbf879354da2b634 (patch) | |
tree | 8633100619eb382a49f79c7003d59ae048368abe /drivers/scsi | |
parent | a91c1be21704113b023919826c6d531da46656ef (diff) |
[SCSI] SCSI: Support Type C RAID controller
1. To support Type C RAID controller, ACB_ADAPTER_TYPE_C, i.e. PCI device
ID: 0x1880.
Signed-off-by: Nick Cheng< nick.cheng@areca.com.tw >
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/arcmsr/arcmsr.h | 208 | ||||
-rw-r--r-- | drivers/scsi/arcmsr/arcmsr_attr.c | 9 | ||||
-rw-r--r-- | drivers/scsi/arcmsr/arcmsr_hba.c | 1538 |
3 files changed, 1182 insertions, 573 deletions
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index c0861c05cd49..475c31ae985c 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h | |||
@@ -43,12 +43,11 @@ | |||
43 | ******************************************************************************* | 43 | ******************************************************************************* |
44 | */ | 44 | */ |
45 | #include <linux/interrupt.h> | 45 | #include <linux/interrupt.h> |
46 | |||
47 | struct device_attribute; | 46 | struct device_attribute; |
48 | /*The limit of outstanding scsi command that firmware can handle*/ | 47 | /*The limit of outstanding scsi command that firmware can handle*/ |
49 | #define ARCMSR_MAX_OUTSTANDING_CMD 256 | 48 | #define ARCMSR_MAX_OUTSTANDING_CMD 256 |
50 | #define ARCMSR_MAX_FREECCB_NUM 320 | 49 | #define ARCMSR_MAX_FREECCB_NUM 320 |
51 | #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2009/12/09" | 50 | #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2010/02/02" |
52 | #define ARCMSR_SCSI_INITIATOR_ID 255 | 51 | #define ARCMSR_SCSI_INITIATOR_ID 255 |
53 | #define ARCMSR_MAX_XFER_SECTORS 512 | 52 | #define ARCMSR_MAX_XFER_SECTORS 512 |
54 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 | 53 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 |
@@ -60,7 +59,8 @@ struct device_attribute; | |||
60 | #define ARCMSR_DEFAULT_SG_ENTRIES 38 | 59 | #define ARCMSR_DEFAULT_SG_ENTRIES 38 |
61 | #define ARCMSR_MAX_HBB_POSTQUEUE 264 | 60 | #define ARCMSR_MAX_HBB_POSTQUEUE 264 |
62 | #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ | 61 | #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ |
63 | #define ARCMSR_CDB_SG_PAGE_LENGTH 256 | 62 | #define ARCMSR_CDB_SG_PAGE_LENGTH 256 |
63 | #define SCSI_CMD_ARECA_SPECIFIC 0xE1 | ||
64 | #ifndef PCI_DEVICE_ID_ARECA_1880 | 64 | #ifndef PCI_DEVICE_ID_ARECA_1880 |
65 | #define PCI_DEVICE_ID_ARECA_1880 0x1880 | 65 | #define PCI_DEVICE_ID_ARECA_1880 0x1880 |
66 | #endif | 66 | #endif |
@@ -138,9 +138,9 @@ struct CMD_MESSAGE_FIELD | |||
138 | #define ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE \ | 138 | #define ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE \ |
139 | ARECA_SATA_RAID | FUNCTION_FLUSH_ADAPTER_CACHE | 139 | ARECA_SATA_RAID | FUNCTION_FLUSH_ADAPTER_CACHE |
140 | /* ARECA IOCTL ReturnCode */ | 140 | /* ARECA IOCTL ReturnCode */ |
141 | #define ARCMSR_MESSAGE_RETURNCODE_OK 0x00000001 | 141 | #define ARCMSR_MESSAGE_RETURNCODE_OK 0x00000001 |
142 | #define ARCMSR_MESSAGE_RETURNCODE_ERROR 0x00000006 | 142 | #define ARCMSR_MESSAGE_RETURNCODE_ERROR 0x00000006 |
143 | #define ARCMSR_MESSAGE_RETURNCODE_3F 0x0000003F | 143 | #define ARCMSR_MESSAGE_RETURNCODE_3F 0x0000003F |
144 | #define ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON 0x00000088 | 144 | #define ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON 0x00000088 |
145 | /* | 145 | /* |
146 | ************************************************************* | 146 | ************************************************************* |
@@ -153,13 +153,13 @@ struct SG32ENTRY | |||
153 | { | 153 | { |
154 | __le32 length; | 154 | __le32 length; |
155 | __le32 address; | 155 | __le32 address; |
156 | } __attribute__ ((packed)); | 156 | }__attribute__ ((packed)); |
157 | struct SG64ENTRY | 157 | struct SG64ENTRY |
158 | { | 158 | { |
159 | __le32 length; | 159 | __le32 length; |
160 | __le32 address; | 160 | __le32 address; |
161 | __le32 addresshigh; | 161 | __le32 addresshigh; |
162 | } __attribute__ ((packed)); | 162 | }__attribute__ ((packed)); |
163 | /* | 163 | /* |
164 | ******************************************************************** | 164 | ******************************************************************** |
165 | ** Q Buffer of IOP Message Transfer | 165 | ** Q Buffer of IOP Message Transfer |
@@ -186,9 +186,9 @@ struct FIRMWARE_INFO | |||
186 | char model[8]; /*15, 60-67*/ | 186 | char model[8]; /*15, 60-67*/ |
187 | char firmware_ver[16]; /*17, 68-83*/ | 187 | char firmware_ver[16]; /*17, 68-83*/ |
188 | char device_map[16]; /*21, 84-99*/ | 188 | char device_map[16]; /*21, 84-99*/ |
189 | uint32_t cfgVersion; /*25,100-103 Added for checking of new firmware capability*/ | 189 | uint32_t cfgVersion; /*25,100-103 Added for checking of new firmware capability*/ |
190 | uint8_t cfgSerial[16]; /*26,104-119*/ | 190 | uint8_t cfgSerial[16]; /*26,104-119*/ |
191 | uint32_t cfgPicStatus; /*30,120-123*/ | 191 | uint32_t cfgPicStatus; /*30,120-123*/ |
192 | }; | 192 | }; |
193 | /* signature of set and get firmware config */ | 193 | /* signature of set and get firmware config */ |
194 | #define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 | 194 | #define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 |
@@ -212,11 +212,15 @@ struct FIRMWARE_INFO | |||
212 | #define ARCMSR_CCBPOST_FLAG_SGL_BSIZE 0x80000000 | 212 | #define ARCMSR_CCBPOST_FLAG_SGL_BSIZE 0x80000000 |
213 | #define ARCMSR_CCBPOST_FLAG_IAM_BIOS 0x40000000 | 213 | #define ARCMSR_CCBPOST_FLAG_IAM_BIOS 0x40000000 |
214 | #define ARCMSR_CCBREPLY_FLAG_IAM_BIOS 0x40000000 | 214 | #define ARCMSR_CCBREPLY_FLAG_IAM_BIOS 0x40000000 |
215 | #define ARCMSR_CCBREPLY_FLAG_ERROR 0x10000000 | 215 | #define ARCMSR_CCBREPLY_FLAG_ERROR_MODE0 0x10000000 |
216 | #define ARCMSR_CCBREPLY_FLAG_ERROR_MODE1 0x00000001 | ||
216 | /* outbound firmware ok */ | 217 | /* outbound firmware ok */ |
217 | #define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 | 218 | #define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 |
218 | /* ARC-1680 Bus Reset*/ | 219 | /* ARC-1680 Bus Reset*/ |
219 | #define ARCMSR_ARC1680_BUS_RESET 0x00000003 | 220 | #define ARCMSR_ARC1680_BUS_RESET 0x00000003 |
221 | /* ARC-1880 Bus Reset*/ | ||
222 | #define ARCMSR_ARC1880_RESET_ADAPTER 0x00000024 | ||
223 | #define ARCMSR_ARC1880_DiagWrite_ENABLE 0x00000080 | ||
220 | 224 | ||
221 | /* | 225 | /* |
222 | ************************************************************************ | 226 | ************************************************************************ |
@@ -273,6 +277,61 @@ struct FIRMWARE_INFO | |||
273 | #define ARCMSR_MESSAGE_RBUFFER 0x0000ff00 | 277 | #define ARCMSR_MESSAGE_RBUFFER 0x0000ff00 |
274 | /* iop message_rwbuffer for message command */ | 278 | /* iop message_rwbuffer for message command */ |
275 | #define ARCMSR_MESSAGE_RWBUFFER 0x0000fa00 | 279 | #define ARCMSR_MESSAGE_RWBUFFER 0x0000fa00 |
280 | /* | ||
281 | ************************************************************************ | ||
282 | ** SPEC. for Areca HBC adapter | ||
283 | ************************************************************************ | ||
284 | */ | ||
285 | #define ARCMSR_HBC_ISR_THROTTLING_LEVEL 12 | ||
286 | #define ARCMSR_HBC_ISR_MAX_DONE_QUEUE 20 | ||
287 | /* Host Interrupt Mask */ | ||
288 | #define ARCMSR_HBCMU_UTILITY_A_ISR_MASK 0x00000001 /* When clear, the Utility_A interrupt routes to the host.*/ | ||
289 | #define ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK 0x00000004 /* When clear, the General Outbound Doorbell interrupt routes to the host.*/ | ||
290 | #define ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK 0x00000008 /* When clear, the Outbound Post List FIFO Not Empty interrupt routes to the host.*/ | ||
291 | #define ARCMSR_HBCMU_ALL_INTMASKENABLE 0x0000000D /* disable all ISR */ | ||
292 | /* Host Interrupt Status */ | ||
293 | #define ARCMSR_HBCMU_UTILITY_A_ISR 0x00000001 | ||
294 | /* | ||
295 | ** Set when the Utility_A Interrupt bit is set in the Outbound Doorbell Register. | ||
296 | ** It clears by writing a 1 to the Utility_A bit in the Outbound Doorbell Clear Register or through automatic clearing (if enabled). | ||
297 | */ | ||
298 | #define ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR 0x00000004 | ||
299 | /* | ||
300 | ** Set if Outbound Doorbell register bits 30:1 have a non-zero | ||
301 | ** value. This bit clears only when Outbound Doorbell bits | ||
302 | ** 30:1 are ALL clear. Only a write to the Outbound Doorbell | ||
303 | ** Clear register clears bits in the Outbound Doorbell register. | ||
304 | */ | ||
305 | #define ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR 0x00000008 | ||
306 | /* | ||
307 | ** Set whenever the Outbound Post List Producer/Consumer | ||
308 | ** Register (FIFO) is not empty. It clears when the Outbound | ||
309 | ** Post List FIFO is empty. | ||
310 | */ | ||
311 | #define ARCMSR_HBCMU_SAS_ALL_INT 0x00000010 | ||
312 | /* | ||
313 | ** This bit indicates a SAS interrupt from a source external to | ||
314 | ** the PCIe core. This bit is not maskable. | ||
315 | */ | ||
316 | /* DoorBell*/ | ||
317 | #define ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK 0x00000002 | ||
318 | #define ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK 0x00000004 | ||
319 | /*inbound message 0 ready*/ | ||
320 | #define ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE 0x00000008 | ||
321 | /*more than 12 request completed in a time*/ | ||
322 | #define ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING 0x00000010 | ||
323 | #define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK 0x00000002 | ||
324 | /*outbound DATA WRITE isr door bell clear*/ | ||
325 | #define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_DOORBELL_CLEAR 0x00000002 | ||
326 | #define ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK 0x00000004 | ||
327 | /*outbound DATA READ isr door bell clear*/ | ||
328 | #define ARCMSR_HBCMU_IOP2DRV_DATA_READ_DOORBELL_CLEAR 0x00000004 | ||
329 | /*outbound message 0 ready*/ | ||
330 | #define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE 0x00000008 | ||
331 | /*outbound message cmd isr door bell clear*/ | ||
332 | #define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR 0x00000008 | ||
333 | /*ARCMSR_HBAMU_MESSAGE_FIRMWARE_OK*/ | ||
334 | #define ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK 0x80000000 | ||
276 | /* | 335 | /* |
277 | ******************************************************************************* | 336 | ******************************************************************************* |
278 | ** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) | 337 | ** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) |
@@ -310,7 +369,7 @@ struct ARCMSR_CDB | |||
310 | struct SG32ENTRY sg32entry[1]; | 369 | struct SG32ENTRY sg32entry[1]; |
311 | struct SG64ENTRY sg64entry[1]; | 370 | struct SG64ENTRY sg64entry[1]; |
312 | } u; | 371 | } u; |
313 | } __attribute__ ((packed)); | 372 | }; |
314 | /* | 373 | /* |
315 | ******************************************************************************* | 374 | ******************************************************************************* |
316 | ** Messaging Unit (MU) of the Intel R 80331 I/O processor(Type A) and Type B processor | 375 | ** Messaging Unit (MU) of the Intel R 80331 I/O processor(Type A) and Type B processor |
@@ -356,7 +415,81 @@ struct MessageUnit_B | |||
356 | uint32_t __iomem *message_wbuffer; | 415 | uint32_t __iomem *message_wbuffer; |
357 | uint32_t __iomem *message_rbuffer; | 416 | uint32_t __iomem *message_rbuffer; |
358 | }; | 417 | }; |
359 | 418 | /* | |
419 | ********************************************************************* | ||
420 | ** LSI | ||
421 | ********************************************************************* | ||
422 | */ | ||
423 | struct MessageUnit_C{ | ||
424 | uint32_t message_unit_status; /*0000 0003*/ | ||
425 | uint32_t slave_error_attribute; /*0004 0007*/ | ||
426 | uint32_t slave_error_address; /*0008 000B*/ | ||
427 | uint32_t posted_outbound_doorbell; /*000C 000F*/ | ||
428 | uint32_t master_error_attribute; /*0010 0013*/ | ||
429 | uint32_t master_error_address_low; /*0014 0017*/ | ||
430 | uint32_t master_error_address_high; /*0018 001B*/ | ||
431 | uint32_t hcb_size; /*001C 001F*/ | ||
432 | uint32_t inbound_doorbell; /*0020 0023*/ | ||
433 | uint32_t diagnostic_rw_data; /*0024 0027*/ | ||
434 | uint32_t diagnostic_rw_address_low; /*0028 002B*/ | ||
435 | uint32_t diagnostic_rw_address_high; /*002C 002F*/ | ||
436 | uint32_t host_int_status; /*0030 0033*/ | ||
437 | uint32_t host_int_mask; /*0034 0037*/ | ||
438 | uint32_t dcr_data; /*0038 003B*/ | ||
439 | uint32_t dcr_address; /*003C 003F*/ | ||
440 | uint32_t inbound_queueport; /*0040 0043*/ | ||
441 | uint32_t outbound_queueport; /*0044 0047*/ | ||
442 | uint32_t hcb_pci_address_low; /*0048 004B*/ | ||
443 | uint32_t hcb_pci_address_high; /*004C 004F*/ | ||
444 | uint32_t iop_int_status; /*0050 0053*/ | ||
445 | uint32_t iop_int_mask; /*0054 0057*/ | ||
446 | uint32_t iop_inbound_queue_port; /*0058 005B*/ | ||
447 | uint32_t iop_outbound_queue_port; /*005C 005F*/ | ||
448 | uint32_t inbound_free_list_index; /*0060 0063*/ | ||
449 | uint32_t inbound_post_list_index; /*0064 0067*/ | ||
450 | uint32_t outbound_free_list_index; /*0068 006B*/ | ||
451 | uint32_t outbound_post_list_index; /*006C 006F*/ | ||
452 | uint32_t inbound_doorbell_clear; /*0070 0073*/ | ||
453 | uint32_t i2o_message_unit_control; /*0074 0077*/ | ||
454 | uint32_t last_used_message_source_address_low; /*0078 007B*/ | ||
455 | uint32_t last_used_message_source_address_high; /*007C 007F*/ | ||
456 | uint32_t pull_mode_data_byte_count[4]; /*0080 008F*/ | ||
457 | uint32_t message_dest_address_index; /*0090 0093*/ | ||
458 | uint32_t done_queue_not_empty_int_counter_timer; /*0094 0097*/ | ||
459 | uint32_t utility_A_int_counter_timer; /*0098 009B*/ | ||
460 | uint32_t outbound_doorbell; /*009C 009F*/ | ||
461 | uint32_t outbound_doorbell_clear; /*00A0 00A3*/ | ||
462 | uint32_t message_source_address_index; /*00A4 00A7*/ | ||
463 | uint32_t message_done_queue_index; /*00A8 00AB*/ | ||
464 | uint32_t reserved0; /*00AC 00AF*/ | ||
465 | uint32_t inbound_msgaddr0; /*00B0 00B3*/ | ||
466 | uint32_t inbound_msgaddr1; /*00B4 00B7*/ | ||
467 | uint32_t outbound_msgaddr0; /*00B8 00BB*/ | ||
468 | uint32_t outbound_msgaddr1; /*00BC 00BF*/ | ||
469 | uint32_t inbound_queueport_low; /*00C0 00C3*/ | ||
470 | uint32_t inbound_queueport_high; /*00C4 00C7*/ | ||
471 | uint32_t outbound_queueport_low; /*00C8 00CB*/ | ||
472 | uint32_t outbound_queueport_high; /*00CC 00CF*/ | ||
473 | uint32_t iop_inbound_queue_port_low; /*00D0 00D3*/ | ||
474 | uint32_t iop_inbound_queue_port_high; /*00D4 00D7*/ | ||
475 | uint32_t iop_outbound_queue_port_low; /*00D8 00DB*/ | ||
476 | uint32_t iop_outbound_queue_port_high; /*00DC 00DF*/ | ||
477 | uint32_t message_dest_queue_port_low; /*00E0 00E3*/ | ||
478 | uint32_t message_dest_queue_port_high; /*00E4 00E7*/ | ||
479 | uint32_t last_used_message_dest_address_low; /*00E8 00EB*/ | ||
480 | uint32_t last_used_message_dest_address_high; /*00EC 00EF*/ | ||
481 | uint32_t message_done_queue_base_address_low; /*00F0 00F3*/ | ||
482 | uint32_t message_done_queue_base_address_high; /*00F4 00F7*/ | ||
483 | uint32_t host_diagnostic; /*00F8 00FB*/ | ||
484 | uint32_t write_sequence; /*00FC 00FF*/ | ||
485 | uint32_t reserved1[34]; /*0100 0187*/ | ||
486 | uint32_t reserved2[1950]; /*0188 1FFF*/ | ||
487 | uint32_t message_wbuffer[32]; /*2000 207F*/ | ||
488 | uint32_t reserved3[32]; /*2080 20FF*/ | ||
489 | uint32_t message_rbuffer[32]; /*2100 217F*/ | ||
490 | uint32_t reserved4[32]; /*2180 21FF*/ | ||
491 | uint32_t msgcode_rwbuffer[256]; /*2200 23FF*/ | ||
492 | }; | ||
360 | /* | 493 | /* |
361 | ******************************************************************************* | 494 | ******************************************************************************* |
362 | ** Adapter Control Block | 495 | ** Adapter Control Block |
@@ -374,11 +507,14 @@ struct AdapterControlBlock | |||
374 | unsigned long vir2phy_offset; | 507 | unsigned long vir2phy_offset; |
375 | /* Offset is used in making arc cdb physical to virtual calculations */ | 508 | /* Offset is used in making arc cdb physical to virtual calculations */ |
376 | uint32_t outbound_int_enable; | 509 | uint32_t outbound_int_enable; |
510 | uint32_t cdb_phyaddr_hi32; | ||
511 | uint32_t reg_mu_acc_handle0; | ||
377 | spinlock_t eh_lock; | 512 | spinlock_t eh_lock; |
378 | spinlock_t ccblist_lock; | 513 | spinlock_t ccblist_lock; |
379 | union { | 514 | union { |
380 | struct MessageUnit_A __iomem * pmuA; | 515 | struct MessageUnit_A __iomem *pmuA; |
381 | struct MessageUnit_B * pmuB; | 516 | struct MessageUnit_B *pmuB; |
517 | struct MessageUnit_C __iomem *pmuC; | ||
382 | }; | 518 | }; |
383 | /* message unit ATU inbound base address0 */ | 519 | /* message unit ATU inbound base address0 */ |
384 | void __iomem *mem_base0; | 520 | void __iomem *mem_base0; |
@@ -399,6 +535,8 @@ struct AdapterControlBlock | |||
399 | /* message clear rqbuffer */ | 535 | /* message clear rqbuffer */ |
400 | #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 | 536 | #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 |
401 | #define ACB_F_BUS_RESET 0x0080 | 537 | #define ACB_F_BUS_RESET 0x0080 |
538 | #define ACB_F_BUS_HANG_ON 0x0800/* need hardware reset bus */ | ||
539 | |||
402 | #define ACB_F_IOP_INITED 0x0100 | 540 | #define ACB_F_IOP_INITED 0x0100 |
403 | /* iop init */ | 541 | /* iop init */ |
404 | #define ACB_F_ABORT 0x0200 | 542 | #define ACB_F_ABORT 0x0200 |
@@ -441,9 +579,9 @@ struct AdapterControlBlock | |||
441 | uint32_t firm_numbers_queue; | 579 | uint32_t firm_numbers_queue; |
442 | uint32_t firm_sdram_size; | 580 | uint32_t firm_sdram_size; |
443 | uint32_t firm_hd_channels; | 581 | uint32_t firm_hd_channels; |
444 | uint32_t firm_cfg_version; | 582 | uint32_t firm_cfg_version; |
445 | char firm_model[12]; | 583 | char firm_model[12]; |
446 | char firm_version[20]; | 584 | char firm_version[20]; |
447 | char device_map[20]; /*21,84-99*/ | 585 | char device_map[20]; /*21,84-99*/ |
448 | struct work_struct arcmsr_do_message_isr_bh; | 586 | struct work_struct arcmsr_do_message_isr_bh; |
449 | struct timer_list eternal_timer; | 587 | struct timer_list eternal_timer; |
@@ -460,31 +598,31 @@ struct AdapterControlBlock | |||
460 | ** this CCB length must be 32 bytes boundary | 598 | ** this CCB length must be 32 bytes boundary |
461 | ******************************************************************************* | 599 | ******************************************************************************* |
462 | */ | 600 | */ |
463 | struct CommandControlBlock | 601 | struct CommandControlBlock{ |
464 | { | ||
465 | /*x32:sizeof struct_CCB=(32+60)byte, x64:sizeof struct_CCB=(64+60)byte*/ | 602 | /*x32:sizeof struct_CCB=(32+60)byte, x64:sizeof struct_CCB=(64+60)byte*/ |
466 | struct list_head list; /*x32: 8byte, x64: 16byte*/ | 603 | struct list_head list; /*x32: 8byte, x64: 16byte*/ |
467 | struct scsi_cmnd *pcmd; /*8 bytes pointer of linux scsi command */ | 604 | struct scsi_cmnd *pcmd; /*8 bytes pointer of linux scsi command */ |
468 | struct AdapterControlBlock *acb; /*x32: 4byte, x64: 8byte*/ | 605 | struct AdapterControlBlock *acb; /*x32: 4byte, x64: 8byte*/ |
469 | uint32_t shifted_cdb_phyaddr; /*x32: 4byte, x64: 4byte*/ | 606 | uint32_t cdb_phyaddr_pattern; /*x32: 4byte, x64: 4byte*/ |
607 | uint32_t arc_cdb_size; /*x32:4byte,x64:4byte*/ | ||
470 | uint16_t ccb_flags; /*x32: 2byte, x64: 2byte*/ | 608 | uint16_t ccb_flags; /*x32: 2byte, x64: 2byte*/ |
471 | #define CCB_FLAG_READ 0x0000 | 609 | #define CCB_FLAG_READ 0x0000 |
472 | #define CCB_FLAG_WRITE 0x0001 | 610 | #define CCB_FLAG_WRITE 0x0001 |
473 | #define CCB_FLAG_ERROR 0x0002 | 611 | #define CCB_FLAG_ERROR 0x0002 |
474 | #define CCB_FLAG_FLUSHCACHE 0x0004 | 612 | #define CCB_FLAG_FLUSHCACHE 0x0004 |
475 | #define CCB_FLAG_MASTER_ABORTED 0x0008 | 613 | #define CCB_FLAG_MASTER_ABORTED 0x0008 |
476 | uint16_t startdone; /*x32:2byte,x32:2byte*/ | 614 | uint16_t startdone; /*x32:2byte,x32:2byte*/ |
477 | #define ARCMSR_CCB_DONE 0x0000 | 615 | #define ARCMSR_CCB_DONE 0x0000 |
478 | #define ARCMSR_CCB_START 0x55AA | 616 | #define ARCMSR_CCB_START 0x55AA |
479 | #define ARCMSR_CCB_ABORTED 0xAA55 | 617 | #define ARCMSR_CCB_ABORTED 0xAA55 |
480 | #define ARCMSR_CCB_ILLEGAL 0xFFFF | 618 | #define ARCMSR_CCB_ILLEGAL 0xFFFF |
481 | #if BITS_PER_LONG == 64 | 619 | #if BITS_PER_LONG == 64 |
482 | /* ======================512+64 bytes======================== */ | 620 | /* ======================512+64 bytes======================== */ |
483 | uint32_t reserved[6]; /*24 byte*/ | 621 | uint32_t reserved[5]; /*24 byte*/ |
484 | #else | 622 | #else |
485 | /* ======================512+32 bytes======================== */ | 623 | /* ======================512+32 bytes======================== */ |
486 | uint32_t reserved[2]; /*8 byte*/ | 624 | uint32_t reserved; /*8 byte*/ |
487 | #endif | 625 | #endif |
488 | /* ======================================================= */ | 626 | /* ======================================================= */ |
489 | struct ARCMSR_CDB arcmsr_cdb; | 627 | struct ARCMSR_CDB arcmsr_cdb; |
490 | }; | 628 | }; |
diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 07fdfe57e38e..69f8346aa288 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c | |||
@@ -59,8 +59,7 @@ | |||
59 | 59 | ||
60 | struct device_attribute *arcmsr_host_attrs[]; | 60 | struct device_attribute *arcmsr_host_attrs[]; |
61 | 61 | ||
62 | static ssize_t arcmsr_sysfs_iop_message_read(struct file *filp, | 62 | static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, |
63 | struct kobject *kobj, | ||
64 | struct bin_attribute *bin, | 63 | struct bin_attribute *bin, |
65 | char *buf, loff_t off, | 64 | char *buf, loff_t off, |
66 | size_t count) | 65 | size_t count) |
@@ -106,8 +105,7 @@ static ssize_t arcmsr_sysfs_iop_message_read(struct file *filp, | |||
106 | return (allxfer_len); | 105 | return (allxfer_len); |
107 | } | 106 | } |
108 | 107 | ||
109 | static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp, | 108 | static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, |
110 | struct kobject *kobj, | ||
111 | struct bin_attribute *bin, | 109 | struct bin_attribute *bin, |
112 | char *buf, loff_t off, | 110 | char *buf, loff_t off, |
113 | size_t count) | 111 | size_t count) |
@@ -155,8 +153,7 @@ static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp, | |||
155 | } | 153 | } |
156 | } | 154 | } |
157 | 155 | ||
158 | static ssize_t arcmsr_sysfs_iop_message_clear(struct file *filp, | 156 | static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj, |
159 | struct kobject *kobj, | ||
160 | struct bin_attribute *bin, | 157 | struct bin_attribute *bin, |
161 | char *buf, loff_t off, | 158 | char *buf, loff_t off, |
162 | size_t count) | 159 | size_t count) |
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index ba33473b27a1..95a895dd4f13 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c | |||
@@ -71,11 +71,11 @@ | |||
71 | #include <scsi/scsicam.h> | 71 | #include <scsi/scsicam.h> |
72 | #include "arcmsr.h" | 72 | #include "arcmsr.h" |
73 | MODULE_AUTHOR("Nick Cheng <support@areca.com.tw>"); | 73 | MODULE_AUTHOR("Nick Cheng <support@areca.com.tw>"); |
74 | MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx) SATA/SAS RAID Host Bus Adapter"); | 74 | MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus Adapter"); |
75 | MODULE_LICENSE("Dual BSD/GPL"); | 75 | MODULE_LICENSE("Dual BSD/GPL"); |
76 | MODULE_VERSION(ARCMSR_DRIVER_VERSION); | 76 | MODULE_VERSION(ARCMSR_DRIVER_VERSION); |
77 | static int sleeptime = 20; | 77 | static int sleeptime = 10; |
78 | static int retrycount = 12; | 78 | static int retrycount = 30; |
79 | wait_queue_head_t wait_q; | 79 | wait_queue_head_t wait_q; |
80 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | 80 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, |
81 | struct scsi_cmnd *cmd); | 81 | struct scsi_cmnd *cmd); |
@@ -99,10 +99,12 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb); | |||
99 | static void arcmsr_request_device_map(unsigned long pacb); | 99 | static void arcmsr_request_device_map(unsigned long pacb); |
100 | static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb); | 100 | static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb); |
101 | static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb); | 101 | static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb); |
102 | static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb); | ||
102 | static void arcmsr_message_isr_bh_fn(struct work_struct *work); | 103 | static void arcmsr_message_isr_bh_fn(struct work_struct *work); |
103 | static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb); | 104 | static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb); |
104 | static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb); | 105 | static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb); |
105 | 106 | static void arcmsr_hbc_message_isr(struct AdapterControlBlock *pACB); | |
107 | static void arcmsr_hardware_reset(struct AdapterControlBlock *acb); | ||
106 | static const char *arcmsr_info(struct Scsi_Host *); | 108 | static const char *arcmsr_info(struct Scsi_Host *); |
107 | static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); | 109 | static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); |
108 | static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, | 110 | static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, |
@@ -119,18 +121,18 @@ static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, | |||
119 | 121 | ||
120 | static struct scsi_host_template arcmsr_scsi_host_template = { | 122 | static struct scsi_host_template arcmsr_scsi_host_template = { |
121 | .module = THIS_MODULE, | 123 | .module = THIS_MODULE, |
122 | .name = "ARCMSR ARECA SATA/SAS RAID Host Bus Adapter" | 124 | .name = "ARCMSR ARECA SATA/SAS RAID Controller" |
123 | ARCMSR_DRIVER_VERSION, | 125 | ARCMSR_DRIVER_VERSION, |
124 | .info = arcmsr_info, | 126 | .info = arcmsr_info, |
125 | .queuecommand = arcmsr_queue_command, | 127 | .queuecommand = arcmsr_queue_command, |
126 | .eh_abort_handler = arcmsr_abort, | 128 | .eh_abort_handler = arcmsr_abort, |
127 | .eh_bus_reset_handler = arcmsr_bus_reset, | 129 | .eh_bus_reset_handler = arcmsr_bus_reset, |
128 | .bios_param = arcmsr_bios_param, | 130 | .bios_param = arcmsr_bios_param, |
129 | .change_queue_depth = arcmsr_adjust_disk_queue_depth, | 131 | .change_queue_depth = arcmsr_adjust_disk_queue_depth, |
130 | .can_queue = ARCMSR_MAX_FREECCB_NUM, | 132 | .can_queue = ARCMSR_MAX_FREECCB_NUM, |
131 | .this_id = ARCMSR_SCSI_INITIATOR_ID, | 133 | .this_id = ARCMSR_SCSI_INITIATOR_ID, |
132 | .sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES, | 134 | .sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES, |
133 | .max_sectors = ARCMSR_MAX_XFER_SECTORS_C, | 135 | .max_sectors = ARCMSR_MAX_XFER_SECTORS_C, |
134 | .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, | 136 | .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, |
135 | .use_clustering = ENABLE_CLUSTERING, | 137 | .use_clustering = ENABLE_CLUSTERING, |
136 | .shost_attrs = arcmsr_host_attrs, | 138 | .shost_attrs = arcmsr_host_attrs, |
@@ -160,22 +162,45 @@ static struct pci_device_id arcmsr_device_id_table[] = { | |||
160 | MODULE_DEVICE_TABLE(pci, arcmsr_device_id_table); | 162 | MODULE_DEVICE_TABLE(pci, arcmsr_device_id_table); |
161 | static struct pci_driver arcmsr_pci_driver = { | 163 | static struct pci_driver arcmsr_pci_driver = { |
162 | .name = "arcmsr", | 164 | .name = "arcmsr", |
163 | .id_table = arcmsr_device_id_table, | 165 | .id_table = arcmsr_device_id_table, |
164 | .probe = arcmsr_probe, | 166 | .probe = arcmsr_probe, |
165 | .remove = arcmsr_remove, | 167 | .remove = arcmsr_remove, |
166 | .shutdown = arcmsr_shutdown, | 168 | .shutdown = arcmsr_shutdown, |
167 | }; | 169 | }; |
170 | /* | ||
171 | **************************************************************************** | ||
172 | **************************************************************************** | ||
173 | */ | ||
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 | } | ||
168 | 185 | ||
169 | static void arcmsr_free_mu(struct AdapterControlBlock *acb) | 186 | isleep = sleeptime % 10; |
187 | if (isleep > 0) { | ||
188 | msleep(isleep*1000); | ||
189 | } | ||
190 | printk(KERN_NOTICE "wake-up\n"); | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static void arcmsr_free_hbb_mu(struct AdapterControlBlock *acb) | ||
170 | { | 195 | { |
171 | switch (acb->adapter_type) { | 196 | switch (acb->adapter_type) { |
172 | case ACB_ADAPTER_TYPE_A: | 197 | case ACB_ADAPTER_TYPE_A: |
198 | case ACB_ADAPTER_TYPE_C: | ||
173 | break; | 199 | break; |
174 | case ACB_ADAPTER_TYPE_B:{ | 200 | case ACB_ADAPTER_TYPE_B:{ |
175 | struct MessageUnit_B *reg = acb->pmuB; | 201 | dma_free_coherent(&acb->pdev->dev, |
176 | dma_free_coherent(&acb->pdev->dev, | 202 | sizeof(struct MessageUnit_B), |
177 | sizeof(struct MessageUnit_B), | 203 | acb->pmuB, acb->dma_coherent_handle_hbb_mu); |
178 | reg, acb->dma_coherent_handle_hbb_mu); | ||
179 | } | 204 | } |
180 | } | 205 | } |
181 | } | 206 | } |
@@ -183,10 +208,9 @@ static void arcmsr_free_mu(struct AdapterControlBlock *acb) | |||
183 | static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb) | 208 | static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb) |
184 | { | 209 | { |
185 | struct pci_dev *pdev = acb->pdev; | 210 | struct pci_dev *pdev = acb->pdev; |
186 | 211 | switch (acb->adapter_type){ | |
187 | switch (acb->adapter_type) { | ||
188 | case ACB_ADAPTER_TYPE_A:{ | 212 | case ACB_ADAPTER_TYPE_A:{ |
189 | acb->pmuA = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); | 213 | acb->pmuA = ioremap(pci_resource_start(pdev,0), pci_resource_len(pdev,0)); |
190 | if (!acb->pmuA) { | 214 | if (!acb->pmuA) { |
191 | printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no); | 215 | printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no); |
192 | return false; | 216 | return false; |
@@ -208,6 +232,19 @@ static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb) | |||
208 | } | 232 | } |
209 | acb->mem_base0 = mem_base0; | 233 | acb->mem_base0 = mem_base0; |
210 | acb->mem_base1 = mem_base1; | 234 | acb->mem_base1 = mem_base1; |
235 | break; | ||
236 | } | ||
237 | case ACB_ADAPTER_TYPE_C:{ | ||
238 | acb->pmuC = ioremap_nocache(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); | ||
239 | if (!acb->pmuC) { | ||
240 | printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no); | ||
241 | return false; | ||
242 | } | ||
243 | if (readl(&acb->pmuC->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { | ||
244 | writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &acb->pmuC->outbound_doorbell_clear);/*clear interrupt*/ | ||
245 | return true; | ||
246 | } | ||
247 | break; | ||
211 | } | 248 | } |
212 | } | 249 | } |
213 | return true; | 250 | return true; |
@@ -216,13 +253,19 @@ static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb) | |||
216 | static void arcmsr_unmap_pciregion(struct AdapterControlBlock *acb) | 253 | static void arcmsr_unmap_pciregion(struct AdapterControlBlock *acb) |
217 | { | 254 | { |
218 | switch (acb->adapter_type) { | 255 | switch (acb->adapter_type) { |
219 | case ACB_ADAPTER_TYPE_A:{ | 256 | case ACB_ADAPTER_TYPE_A:{ |
220 | iounmap(acb->pmuA); | 257 | iounmap(acb->pmuA); |
221 | } | 258 | } |
222 | case ACB_ADAPTER_TYPE_B:{ | 259 | break; |
223 | iounmap(acb->mem_base0); | 260 | case ACB_ADAPTER_TYPE_B:{ |
224 | iounmap(acb->mem_base1); | 261 | iounmap(acb->mem_base0); |
225 | } | 262 | iounmap(acb->mem_base1); |
263 | } | ||
264 | |||
265 | break; | ||
266 | case ACB_ADAPTER_TYPE_C:{ | ||
267 | iounmap(acb->pmuC); | ||
268 | } | ||
226 | } | 269 | } |
227 | } | 270 | } |
228 | 271 | ||
@@ -270,34 +313,37 @@ static void arcmsr_define_adapter_type(struct AdapterControlBlock *acb) | |||
270 | pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id); | 313 | pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id); |
271 | acb->dev_id = dev_id; | 314 | acb->dev_id = dev_id; |
272 | switch (dev_id) { | 315 | switch (dev_id) { |
273 | case 0x1201 : { | 316 | case 0x1880: { |
317 | acb->adapter_type = ACB_ADAPTER_TYPE_C; | ||
318 | } | ||
319 | break; | ||
320 | case 0x1201: { | ||
274 | acb->adapter_type = ACB_ADAPTER_TYPE_B; | 321 | acb->adapter_type = ACB_ADAPTER_TYPE_B; |
275 | } | 322 | } |
276 | break; | 323 | break; |
277 | 324 | ||
278 | default : acb->adapter_type = ACB_ADAPTER_TYPE_A; | 325 | default: acb->adapter_type = ACB_ADAPTER_TYPE_A; |
279 | } | 326 | } |
280 | } | 327 | } |
281 | 328 | ||
282 | static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb) | 329 | static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb) |
283 | { | 330 | { |
284 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 331 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
285 | uint32_t Index; | 332 | uint32_t Index; |
286 | uint8_t Retries = 0x00; | 333 | uint8_t Retries = 0x00; |
287 | |||
288 | do { | 334 | do { |
289 | for (Index = 0; Index < 100; Index++) { | 335 | for (Index = 0; Index < 100; Index++) { |
290 | if (readl(®->outbound_intstatus) & | 336 | if (readl(®->outbound_intstatus) & |
291 | ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { | 337 | ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { |
292 | writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, | 338 | writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, |
293 | ®->outbound_intstatus); | 339 | ®->outbound_intstatus); |
294 | return 0x00; | 340 | return true; |
295 | } | 341 | } |
296 | msleep(10); | 342 | msleep(10); |
297 | } /*max 1 seconds*/ | 343 | }/*max 1 seconds*/ |
298 | 344 | ||
299 | } while (Retries++ < 20);/*max 20 sec*/ | 345 | } while (Retries++ < 20);/*max 20 sec*/ |
300 | return 0xff; | 346 | return false; |
301 | } | 347 | } |
302 | 348 | ||
303 | static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) | 349 | static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) |
@@ -305,7 +351,6 @@ static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) | |||
305 | struct MessageUnit_B *reg = acb->pmuB; | 351 | struct MessageUnit_B *reg = acb->pmuB; |
306 | uint32_t Index; | 352 | uint32_t Index; |
307 | uint8_t Retries = 0x00; | 353 | uint8_t Retries = 0x00; |
308 | |||
309 | do { | 354 | do { |
310 | for (Index = 0; Index < 100; Index++) { | 355 | for (Index = 0; Index < 100; Index++) { |
311 | if (readl(reg->iop2drv_doorbell) | 356 | if (readl(reg->iop2drv_doorbell) |
@@ -313,23 +358,39 @@ static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) | |||
313 | writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN | 358 | writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN |
314 | , reg->iop2drv_doorbell); | 359 | , reg->iop2drv_doorbell); |
315 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); | 360 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); |
316 | return 0x00; | 361 | return true; |
317 | } | 362 | } |
318 | msleep(10); | 363 | msleep(10); |
319 | } /*max 1 seconds*/ | 364 | }/*max 1 seconds*/ |
320 | 365 | ||
321 | } while (Retries++ < 20);/*max 20 sec*/ | 366 | } while (Retries++ < 20);/*max 20 sec*/ |
322 | return 0xff; | 367 | return false; |
323 | } | 368 | } |
324 | 369 | ||
370 | static uint8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *pACB) | ||
371 | { | ||
372 | struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC; | ||
373 | unsigned char Retries = 0x00; | ||
374 | uint32_t Index; | ||
375 | do { | ||
376 | for (Index = 0; Index < 100; Index++) { | ||
377 | if (readl(&phbcmu->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { | ||
378 | writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &phbcmu->outbound_doorbell_clear);/*clear interrupt*/ | ||
379 | return true; | ||
380 | } | ||
381 | /* one us delay */ | ||
382 | msleep(10); | ||
383 | } /*max 1 seconds*/ | ||
384 | } while (Retries++ < 20); /*max 20 sec*/ | ||
385 | return false; | ||
386 | } | ||
325 | static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb) | 387 | static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb) |
326 | { | 388 | { |
327 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 389 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
328 | int retry_count = 30; | 390 | int retry_count = 30; |
329 | |||
330 | writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0); | 391 | writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0); |
331 | do { | 392 | do { |
332 | if (!arcmsr_hba_wait_msgint_ready(acb)) | 393 | if (arcmsr_hba_wait_msgint_ready(acb)) |
333 | break; | 394 | break; |
334 | else { | 395 | else { |
335 | retry_count--; | 396 | retry_count--; |
@@ -343,10 +404,9 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb) | |||
343 | { | 404 | { |
344 | struct MessageUnit_B *reg = acb->pmuB; | 405 | struct MessageUnit_B *reg = acb->pmuB; |
345 | int retry_count = 30; | 406 | int retry_count = 30; |
346 | |||
347 | writel(ARCMSR_MESSAGE_FLUSH_CACHE, reg->drv2iop_doorbell); | 407 | writel(ARCMSR_MESSAGE_FLUSH_CACHE, reg->drv2iop_doorbell); |
348 | do { | 408 | do { |
349 | if (!arcmsr_hbb_wait_msgint_ready(acb)) | 409 | if (arcmsr_hbb_wait_msgint_ready(acb)) |
350 | break; | 410 | break; |
351 | else { | 411 | else { |
352 | retry_count--; | 412 | retry_count--; |
@@ -356,6 +416,23 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb) | |||
356 | } while (retry_count != 0); | 416 | } while (retry_count != 0); |
357 | } | 417 | } |
358 | 418 | ||
419 | static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *pACB) | ||
420 | { | ||
421 | struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC; | ||
422 | int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */ | ||
423 | writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0); | ||
424 | writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); | ||
425 | do { | ||
426 | if (arcmsr_hbc_wait_msgint_ready(pACB)) { | ||
427 | break; | ||
428 | } else { | ||
429 | retry_count--; | ||
430 | printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \ | ||
431 | timeout,retry count down = %d \n", pACB->host->host_no, retry_count); | ||
432 | } | ||
433 | } while (retry_count != 0); | ||
434 | return; | ||
435 | } | ||
359 | static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) | 436 | static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) |
360 | { | 437 | { |
361 | switch (acb->adapter_type) { | 438 | switch (acb->adapter_type) { |
@@ -368,151 +445,94 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) | |||
368 | case ACB_ADAPTER_TYPE_B: { | 445 | case ACB_ADAPTER_TYPE_B: { |
369 | arcmsr_flush_hbb_cache(acb); | 446 | arcmsr_flush_hbb_cache(acb); |
370 | } | 447 | } |
448 | break; | ||
449 | case ACB_ADAPTER_TYPE_C: { | ||
450 | arcmsr_flush_hbc_cache(acb); | ||
451 | } | ||
371 | } | 452 | } |
372 | } | 453 | } |
373 | 454 | ||
374 | static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) | 455 | static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) |
375 | { | 456 | { |
376 | struct pci_dev *pdev = acb->pdev; | 457 | struct pci_dev *pdev = acb->pdev; |
377 | switch (acb->adapter_type) { | 458 | void *dma_coherent; |
378 | case ACB_ADAPTER_TYPE_A: { | 459 | dma_addr_t dma_coherent_handle; |
379 | 460 | struct CommandControlBlock *ccb_tmp; | |
380 | void *dma_coherent; | 461 | int i = 0, j = 0; |
381 | dma_addr_t dma_coherent_handle; | 462 | dma_addr_t cdb_phyaddr; |
382 | struct CommandControlBlock *ccb_tmp; | 463 | unsigned long roundup_ccbsize = 0, offset; |
383 | int i = 0, j = 0; | 464 | unsigned long max_xfer_len; |
384 | dma_addr_t cdb_phyaddr; | 465 | unsigned long max_sg_entrys; |
385 | unsigned long roundup_ccbsize = 0; | 466 | uint32_t firm_config_version; |
386 | unsigned long max_xfer_len; | 467 | for (i = 0; i < ARCMSR_MAX_TARGETID; i++) |
387 | unsigned long max_sg_entrys; | 468 | for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) |
388 | uint32_t firm_config_version; | 469 | acb->devstate[i][j] = ARECA_RAID_GONE; |
389 | 470 | ||
390 | for (i = 0; i < ARCMSR_MAX_TARGETID; i++) | 471 | max_xfer_len = ARCMSR_MAX_XFER_LEN; |
391 | for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) | 472 | max_sg_entrys = ARCMSR_DEFAULT_SG_ENTRIES; |
392 | acb->devstate[i][j] = ARECA_RAID_GONE; | 473 | firm_config_version = acb->firm_cfg_version; |
393 | 474 | if((firm_config_version & 0xFF) >= 3){ | |
394 | max_xfer_len = ARCMSR_MAX_XFER_LEN; | 475 | max_xfer_len = (ARCMSR_CDB_SG_PAGE_LENGTH << ((firm_config_version >> 8) & 0xFF)) * 1024;/* max 4M byte */ |
395 | max_sg_entrys = ARCMSR_DEFAULT_SG_ENTRIES; | 476 | max_sg_entrys = (max_xfer_len/4096); |
396 | firm_config_version = acb->firm_cfg_version; | 477 | } |
397 | if ((firm_config_version & 0xFF) >= 3) { | 478 | acb->host->max_sectors = max_xfer_len/512; |
398 | max_xfer_len = (ARCMSR_CDB_SG_PAGE_LENGTH << ((firm_config_version >> 8) & 0xFF)) * 1024;/* max 16M byte */ | 479 | acb->host->sg_tablesize = max_sg_entrys; |
399 | max_sg_entrys = (max_xfer_len/4096); | 480 | roundup_ccbsize = roundup(sizeof(struct CommandControlBlock) + (max_sg_entrys - 1) * sizeof(struct SG64ENTRY), 32); |
400 | } | 481 | acb->uncache_size = roundup_ccbsize * ARCMSR_MAX_FREECCB_NUM + 32; |
401 | acb->host->max_sectors = max_xfer_len/512; | 482 | dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, &dma_coherent_handle, GFP_KERNEL); |
402 | acb->host->sg_tablesize = max_sg_entrys; | 483 | if(!dma_coherent){ |
403 | roundup_ccbsize = roundup(sizeof(struct CommandControlBlock) + max_sg_entrys * sizeof(struct SG64ENTRY), 32); | 484 | printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error \n", acb->host->host_no); |
404 | acb->uncache_size = roundup_ccbsize * ARCMSR_MAX_FREECCB_NUM; | 485 | return -ENOMEM; |
405 | dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, &dma_coherent_handle, GFP_KERNEL); | 486 | } |
406 | if (!dma_coherent) { | 487 | acb->dma_coherent = dma_coherent; |
407 | printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error \n", acb->host->host_no); | 488 | acb->dma_coherent_handle = dma_coherent_handle; |
408 | return -ENOMEM; | 489 | memset(dma_coherent, 0, acb->uncache_size); |
409 | } | 490 | offset = roundup((unsigned long)dma_coherent, 32) - (unsigned long)dma_coherent; |
410 | memset(dma_coherent, 0, acb->uncache_size); | 491 | dma_coherent_handle = dma_coherent_handle + offset; |
411 | acb->dma_coherent = dma_coherent; | 492 | dma_coherent = (struct CommandControlBlock *)dma_coherent + offset; |
412 | acb->dma_coherent_handle = dma_coherent_handle; | 493 | ccb_tmp = dma_coherent; |
413 | ccb_tmp = (struct CommandControlBlock *)dma_coherent; | 494 | acb->vir2phy_offset = (unsigned long)dma_coherent - (unsigned long)dma_coherent_handle; |
414 | acb->vir2phy_offset = (unsigned long)dma_coherent - (unsigned long)dma_coherent_handle; | 495 | for(i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++){ |
415 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { | 496 | cdb_phyaddr = dma_coherent_handle + offsetof(struct CommandControlBlock, arcmsr_cdb); |
416 | cdb_phyaddr = dma_coherent_handle + offsetof(struct CommandControlBlock, arcmsr_cdb); | 497 | ccb_tmp->cdb_phyaddr_pattern = ((acb->adapter_type == ACB_ADAPTER_TYPE_C) ? cdb_phyaddr : (cdb_phyaddr >> 5)); |
417 | ccb_tmp->shifted_cdb_phyaddr = cdb_phyaddr >> 5; | 498 | acb->pccb_pool[i] = ccb_tmp; |
418 | acb->pccb_pool[i] = ccb_tmp; | 499 | ccb_tmp->acb = acb; |
419 | ccb_tmp->acb = acb; | 500 | INIT_LIST_HEAD(&ccb_tmp->list); |
420 | INIT_LIST_HEAD(&ccb_tmp->list); | 501 | list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); |
421 | list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); | 502 | ccb_tmp = (struct CommandControlBlock *)((unsigned long)ccb_tmp + roundup_ccbsize); |
422 | ccb_tmp = (struct CommandControlBlock *)((unsigned long)ccb_tmp + roundup_ccbsize); | 503 | dma_coherent_handle = dma_coherent_handle + roundup_ccbsize; |
423 | dma_coherent_handle = dma_coherent_handle + roundup_ccbsize; | ||
424 | } | ||
425 | break; | ||
426 | } | ||
427 | case ACB_ADAPTER_TYPE_B: { | ||
428 | |||
429 | void *dma_coherent; | ||
430 | dma_addr_t dma_coherent_handle; | ||
431 | struct CommandControlBlock *ccb_tmp; | ||
432 | uint32_t cdb_phyaddr; | ||
433 | unsigned int roundup_ccbsize = 0; | ||
434 | unsigned long max_xfer_len; | ||
435 | unsigned long max_sg_entrys; | ||
436 | unsigned long firm_config_version; | ||
437 | unsigned long max_freeccb_num = 0; | ||
438 | int i = 0, j = 0; | ||
439 | |||
440 | max_freeccb_num = ARCMSR_MAX_FREECCB_NUM; | ||
441 | max_xfer_len = ARCMSR_MAX_XFER_LEN; | ||
442 | max_sg_entrys = ARCMSR_DEFAULT_SG_ENTRIES; | ||
443 | firm_config_version = acb->firm_cfg_version; | ||
444 | if ((firm_config_version & 0xFF) >= 3) { | ||
445 | max_xfer_len = (ARCMSR_CDB_SG_PAGE_LENGTH << | ||
446 | ((firm_config_version >> 8) & 0xFF)) * 1024;/* max 16M byte */ | ||
447 | max_sg_entrys = (max_xfer_len/4096);/* max 4097 sg entry*/ | ||
448 | } | ||
449 | acb->host->max_sectors = max_xfer_len / 512; | ||
450 | acb->host->sg_tablesize = max_sg_entrys; | ||
451 | roundup_ccbsize = roundup(sizeof(struct CommandControlBlock)+ | ||
452 | (max_sg_entrys - 1) * sizeof(struct SG64ENTRY), 32); | ||
453 | acb->uncache_size = roundup_ccbsize * ARCMSR_MAX_FREECCB_NUM; | ||
454 | dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, | ||
455 | &dma_coherent_handle, GFP_KERNEL); | ||
456 | |||
457 | if (!dma_coherent) { | ||
458 | printk(KERN_NOTICE "DMA allocation failed...........................\n"); | ||
459 | return -ENOMEM; | ||
460 | } | ||
461 | memset(dma_coherent, 0, acb->uncache_size); | ||
462 | acb->dma_coherent = dma_coherent; | ||
463 | acb->dma_coherent_handle = dma_coherent_handle; | ||
464 | ccb_tmp = (struct CommandControlBlock *)dma_coherent; | ||
465 | acb->vir2phy_offset = (unsigned long)dma_coherent - | ||
466 | (unsigned long)dma_coherent_handle; | ||
467 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { | ||
468 | cdb_phyaddr = dma_coherent_handle + | ||
469 | offsetof(struct CommandControlBlock, arcmsr_cdb); | ||
470 | ccb_tmp->shifted_cdb_phyaddr = cdb_phyaddr >> 5; | ||
471 | acb->pccb_pool[i] = ccb_tmp; | ||
472 | ccb_tmp->acb = acb; | ||
473 | INIT_LIST_HEAD(&ccb_tmp->list); | ||
474 | list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); | ||
475 | ccb_tmp = (struct CommandControlBlock *)((unsigned long)ccb_tmp + | ||
476 | roundup_ccbsize); | ||
477 | dma_coherent_handle = dma_coherent_handle + roundup_ccbsize; | ||
478 | } | ||
479 | for (i = 0; i < ARCMSR_MAX_TARGETID; i++) | ||
480 | for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) | ||
481 | acb->devstate[i][j] = ARECA_RAID_GONE; | ||
482 | } | ||
483 | break; | ||
484 | } | 504 | } |
485 | return 0; | 505 | return 0; |
486 | } | 506 | } |
487 | static void arcmsr_message_isr_bh_fn(struct work_struct *work) | ||
488 | { | ||
489 | struct AdapterControlBlock *acb = container_of(work, struct AdapterControlBlock, arcmsr_do_message_isr_bh); | ||
490 | 507 | ||
508 | static void arcmsr_message_isr_bh_fn(struct work_struct *work) | ||
509 | { | ||
510 | struct AdapterControlBlock *acb = container_of(work,struct AdapterControlBlock, arcmsr_do_message_isr_bh); | ||
491 | switch (acb->adapter_type) { | 511 | switch (acb->adapter_type) { |
492 | case ACB_ADAPTER_TYPE_A: { | 512 | case ACB_ADAPTER_TYPE_A: { |
493 | 513 | ||
494 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 514 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
495 | char *acb_dev_map = (char *)acb->device_map; | 515 | char *acb_dev_map = (char *)acb->device_map; |
496 | uint32_t __iomem *signature = (uint32_t __iomem *) (®->message_rwbuffer[0]); | 516 | uint32_t __iomem *signature = (uint32_t __iomem*) (®->message_rwbuffer[0]); |
497 | char __iomem *devicemap = (char __iomem *) (®->message_rwbuffer[21]); | 517 | char __iomem *devicemap = (char __iomem*) (®->message_rwbuffer[21]); |
498 | int target, lun; | 518 | int target, lun; |
499 | struct scsi_device *psdev; | 519 | struct scsi_device *psdev; |
500 | char diff; | 520 | char diff; |
501 | 521 | ||
502 | atomic_inc(&acb->rq_map_token); | 522 | atomic_inc(&acb->rq_map_token); |
503 | if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) { | 523 | if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) { |
504 | for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) { | 524 | for(target = 0; target < ARCMSR_MAX_TARGETID -1; target++) { |
505 | diff = (*acb_dev_map)^readb(devicemap); | 525 | diff = (*acb_dev_map)^readb(devicemap); |
506 | if (diff != 0) { | 526 | if (diff != 0) { |
507 | char temp; | 527 | char temp; |
508 | *acb_dev_map = readb(devicemap); | 528 | *acb_dev_map = readb(devicemap); |
509 | temp = *acb_dev_map; | 529 | temp =*acb_dev_map; |
510 | for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) { | 530 | for(lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) { |
511 | if ((temp & 0x01) == 1 && (diff & 0x01) == 1) { | 531 | if((temp & 0x01)==1 && (diff & 0x01) == 1) { |
512 | scsi_add_device(acb->host, 0, target, lun); | 532 | scsi_add_device(acb->host, 0, target, lun); |
513 | } else if ((temp & 0x01) == 0 && (diff & 0x01) == 1) { | 533 | }else if((temp & 0x01) == 0 && (diff & 0x01) == 1) { |
514 | psdev = scsi_device_lookup(acb->host, 0, target, lun); | 534 | psdev = scsi_device_lookup(acb->host, 0, target, lun); |
515 | if (psdev != NULL) { | 535 | if (psdev != NULL ) { |
516 | scsi_remove_device(psdev); | 536 | scsi_remove_device(psdev); |
517 | scsi_device_put(psdev); | 537 | scsi_device_put(psdev); |
518 | } | 538 | } |
@@ -531,8 +551,45 @@ static void arcmsr_message_isr_bh_fn(struct work_struct *work) | |||
531 | case ACB_ADAPTER_TYPE_B: { | 551 | case ACB_ADAPTER_TYPE_B: { |
532 | struct MessageUnit_B *reg = acb->pmuB; | 552 | struct MessageUnit_B *reg = acb->pmuB; |
533 | char *acb_dev_map = (char *)acb->device_map; | 553 | char *acb_dev_map = (char *)acb->device_map; |
534 | uint32_t __iomem *signature = (uint32_t __iomem *)(®->message_rwbuffer[0]); | 554 | uint32_t __iomem *signature = (uint32_t __iomem*)(®->message_rwbuffer[0]); |
535 | char __iomem *devicemap = (char __iomem *)(®->message_rwbuffer[21]); | 555 | char __iomem *devicemap = (char __iomem*)(®->message_rwbuffer[21]); |
556 | int target, lun; | ||
557 | struct scsi_device *psdev; | ||
558 | char diff; | ||
559 | |||
560 | atomic_inc(&acb->rq_map_token); | ||
561 | if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) { | ||
562 | for(target = 0; target < ARCMSR_MAX_TARGETID -1; target++) { | ||
563 | diff = (*acb_dev_map)^readb(devicemap); | ||
564 | if (diff != 0) { | ||
565 | char temp; | ||
566 | *acb_dev_map = readb(devicemap); | ||
567 | temp =*acb_dev_map; | ||
568 | for(lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) { | ||
569 | if((temp & 0x01)==1 && (diff & 0x01) == 1) { | ||
570 | scsi_add_device(acb->host, 0, target, lun); | ||
571 | }else if((temp & 0x01) == 0 && (diff & 0x01) == 1) { | ||
572 | psdev = scsi_device_lookup(acb->host, 0, target, lun); | ||
573 | if (psdev != NULL ) { | ||
574 | scsi_remove_device(psdev); | ||
575 | scsi_device_put(psdev); | ||
576 | } | ||
577 | } | ||
578 | temp >>= 1; | ||
579 | diff >>= 1; | ||
580 | } | ||
581 | } | ||
582 | devicemap++; | ||
583 | acb_dev_map++; | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | break; | ||
588 | case ACB_ADAPTER_TYPE_C: { | ||
589 | struct MessageUnit_C *reg = acb->pmuC; | ||
590 | char *acb_dev_map = (char *)acb->device_map; | ||
591 | uint32_t __iomem *signature = (uint32_t __iomem *)(®->msgcode_rwbuffer[0]); | ||
592 | char __iomem *devicemap = (char __iomem *)(®->msgcode_rwbuffer[21]); | ||
536 | int target, lun; | 593 | int target, lun; |
537 | struct scsi_device *psdev; | 594 | struct scsi_device *psdev; |
538 | char diff; | 595 | char diff; |
@@ -571,21 +628,20 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
571 | { | 628 | { |
572 | struct Scsi_Host *host; | 629 | struct Scsi_Host *host; |
573 | struct AdapterControlBlock *acb; | 630 | struct AdapterControlBlock *acb; |
574 | uint8_t bus, dev_fun; | 631 | uint8_t bus,dev_fun; |
575 | int error; | 632 | int error; |
576 | |||
577 | error = pci_enable_device(pdev); | 633 | error = pci_enable_device(pdev); |
578 | if (error) { | 634 | if(error){ |
579 | return -ENODEV; | 635 | return -ENODEV; |
580 | } | 636 | } |
581 | host = scsi_host_alloc(&arcmsr_scsi_host_template, sizeof(struct AdapterControlBlock)); | 637 | host = scsi_host_alloc(&arcmsr_scsi_host_template, sizeof(struct AdapterControlBlock)); |
582 | if (!host) { | 638 | if(!host){ |
583 | goto pci_disable_dev; | 639 | goto pci_disable_dev; |
584 | } | 640 | } |
585 | error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); | 641 | error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); |
586 | if (error) { | 642 | if(error){ |
587 | error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 643 | error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
588 | if (error) { | 644 | if(error){ |
589 | printk(KERN_WARNING | 645 | printk(KERN_WARNING |
590 | "scsi%d: No suitable DMA mask available\n", | 646 | "scsi%d: No suitable DMA mask available\n", |
591 | host->host_no); | 647 | host->host_no); |
@@ -596,53 +652,53 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
596 | bus = pdev->bus->number; | 652 | bus = pdev->bus->number; |
597 | dev_fun = pdev->devfn; | 653 | dev_fun = pdev->devfn; |
598 | acb = (struct AdapterControlBlock *) host->hostdata; | 654 | acb = (struct AdapterControlBlock *) host->hostdata; |
599 | memset(acb, 0, sizeof(struct AdapterControlBlock)); | 655 | memset(acb,0,sizeof(struct AdapterControlBlock)); |
600 | acb->pdev = pdev; | 656 | acb->pdev = pdev; |
601 | acb->host = host; | 657 | acb->host = host; |
602 | host->max_lun = ARCMSR_MAX_TARGETLUN; | 658 | host->max_lun = ARCMSR_MAX_TARGETLUN; |
603 | host->max_id = ARCMSR_MAX_TARGETID;/*16:8*/ | 659 | host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/ |
604 | host->max_cmd_len = 16; /*this is issue of 64bit LBA, over 2T byte*/ | 660 | host->max_cmd_len = 16; /*this is issue of 64bit LBA ,over 2T byte*/ |
605 | host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */ | 661 | host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */ |
606 | host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; | 662 | host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; |
607 | host->this_id = ARCMSR_SCSI_INITIATOR_ID; | 663 | host->this_id = ARCMSR_SCSI_INITIATOR_ID; |
608 | host->unique_id = (bus << 8) | dev_fun; | 664 | host->unique_id = (bus << 8) | dev_fun; |
609 | pci_set_drvdata(pdev, host); | 665 | pci_set_drvdata(pdev, host); |
610 | pci_set_master(pdev); | 666 | pci_set_master(pdev); |
611 | error = pci_request_regions(pdev, "arcmsr"); | 667 | error = pci_request_regions(pdev, "arcmsr"); |
612 | if (error) { | 668 | if(error){ |
613 | goto scsi_host_release; | 669 | goto scsi_host_release; |
614 | } | 670 | } |
615 | spin_lock_init(&acb->eh_lock); | 671 | spin_lock_init(&acb->eh_lock); |
616 | spin_lock_init(&acb->ccblist_lock); | 672 | spin_lock_init(&acb->ccblist_lock); |
617 | acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | | 673 | acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | |
618 | ACB_F_MESSAGE_RQBUFFER_CLEARED | | 674 | ACB_F_MESSAGE_RQBUFFER_CLEARED | |
619 | ACB_F_MESSAGE_WQBUFFER_READED); | 675 | ACB_F_MESSAGE_WQBUFFER_READED); |
620 | acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER; | 676 | acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER; |
621 | INIT_LIST_HEAD(&acb->ccb_free_list); | 677 | INIT_LIST_HEAD(&acb->ccb_free_list); |
622 | arcmsr_define_adapter_type(acb); | 678 | arcmsr_define_adapter_type(acb); |
623 | error = arcmsr_remap_pciregion(acb); | 679 | error = arcmsr_remap_pciregion(acb); |
624 | if (!error) { | 680 | if(!error){ |
625 | goto pci_release_regs; | 681 | goto pci_release_regs; |
626 | } | 682 | } |
627 | error = arcmsr_get_firmware_spec(acb); | 683 | error = arcmsr_get_firmware_spec(acb); |
628 | if (!error) { | 684 | if(!error){ |
629 | goto unmap_pci_region; | 685 | goto unmap_pci_region; |
630 | } | 686 | } |
631 | error = arcmsr_alloc_ccb_pool(acb); | 687 | error = arcmsr_alloc_ccb_pool(acb); |
632 | if (error) { | 688 | if(error){ |
633 | goto free_hbb_mu; | 689 | goto free_hbb_mu; |
634 | } | 690 | } |
635 | arcmsr_iop_init(acb); | 691 | arcmsr_iop_init(acb); |
636 | error = scsi_add_host(host, &pdev->dev); | 692 | error = scsi_add_host(host, &pdev->dev); |
637 | if (error) { | 693 | if(error){ |
638 | goto RAID_controller_stop; | 694 | goto RAID_controller_stop; |
639 | } | 695 | } |
640 | error = request_irq(pdev->irq, arcmsr_do_interrupt, IRQF_SHARED, "arcmsr", acb); | 696 | error = request_irq(pdev->irq, arcmsr_do_interrupt, IRQF_SHARED, "arcmsr", acb); |
641 | if (error) { | 697 | if(error){ |
642 | goto scsi_host_remove; | 698 | goto scsi_host_remove; |
643 | } | 699 | } |
644 | host->irq = pdev->irq; | 700 | host->irq = pdev->irq; |
645 | scsi_scan_host(host); | 701 | scsi_scan_host(host); |
646 | INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn); | 702 | INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn); |
647 | atomic_set(&acb->rq_map_token, 16); | 703 | atomic_set(&acb->rq_map_token, 16); |
648 | atomic_set(&acb->ante_token_value, 16); | 704 | atomic_set(&acb->ante_token_value, 16); |
@@ -652,10 +708,10 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
652 | acb->eternal_timer.data = (unsigned long) acb; | 708 | acb->eternal_timer.data = (unsigned long) acb; |
653 | acb->eternal_timer.function = &arcmsr_request_device_map; | 709 | acb->eternal_timer.function = &arcmsr_request_device_map; |
654 | add_timer(&acb->eternal_timer); | 710 | add_timer(&acb->eternal_timer); |
655 | if (arcmsr_alloc_sysfs_attr(acb)) | 711 | if(arcmsr_alloc_sysfs_attr(acb)) |
656 | goto out_free_sysfs; | 712 | goto out_free_sysfs; |
657 | return 0; | 713 | return 0; |
658 | out_free_sysfs: | 714 | out_free_sysfs: |
659 | scsi_host_remove: | 715 | scsi_host_remove: |
660 | scsi_remove_host(host); | 716 | scsi_remove_host(host); |
661 | RAID_controller_stop: | 717 | RAID_controller_stop: |
@@ -663,7 +719,7 @@ RAID_controller_stop: | |||
663 | arcmsr_flush_adapter_cache(acb); | 719 | arcmsr_flush_adapter_cache(acb); |
664 | arcmsr_free_ccb_pool(acb); | 720 | arcmsr_free_ccb_pool(acb); |
665 | free_hbb_mu: | 721 | free_hbb_mu: |
666 | arcmsr_free_mu(acb); | 722 | arcmsr_free_hbb_mu(acb); |
667 | unmap_pci_region: | 723 | unmap_pci_region: |
668 | arcmsr_unmap_pciregion(acb); | 724 | arcmsr_unmap_pciregion(acb); |
669 | pci_release_regs: | 725 | pci_release_regs: |
@@ -678,15 +734,14 @@ pci_disable_dev: | |||
678 | static uint8_t arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb) | 734 | static uint8_t arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb) |
679 | { | 735 | { |
680 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 736 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
681 | |||
682 | writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0); | 737 | writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0); |
683 | if (arcmsr_hba_wait_msgint_ready(acb)) { | 738 | if (!arcmsr_hba_wait_msgint_ready(acb)) { |
684 | printk(KERN_NOTICE | 739 | printk(KERN_NOTICE |
685 | "arcmsr%d: wait 'abort all outstanding command' timeout \n" | 740 | "arcmsr%d: wait 'abort all outstanding command' timeout \n" |
686 | , acb->host->host_no); | 741 | , acb->host->host_no); |
687 | return 0xff; | 742 | return false; |
688 | } | 743 | } |
689 | return 0x00; | 744 | return true; |
690 | } | 745 | } |
691 | 746 | ||
692 | static uint8_t arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb) | 747 | static uint8_t arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb) |
@@ -694,15 +749,27 @@ static uint8_t arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb) | |||
694 | struct MessageUnit_B *reg = acb->pmuB; | 749 | struct MessageUnit_B *reg = acb->pmuB; |
695 | 750 | ||
696 | writel(ARCMSR_MESSAGE_ABORT_CMD, reg->drv2iop_doorbell); | 751 | writel(ARCMSR_MESSAGE_ABORT_CMD, reg->drv2iop_doorbell); |
697 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | 752 | if (!arcmsr_hbb_wait_msgint_ready(acb)) { |
698 | printk(KERN_NOTICE | 753 | printk(KERN_NOTICE |
699 | "arcmsr%d: wait 'abort all outstanding command' timeout \n" | 754 | "arcmsr%d: wait 'abort all outstanding command' timeout \n" |
700 | , acb->host->host_no); | 755 | , acb->host->host_no); |
701 | return 0xff; | 756 | return false; |
702 | } | 757 | } |
703 | return 0x00; | 758 | return true; |
759 | } | ||
760 | static uint8_t arcmsr_abort_hbc_allcmd(struct AdapterControlBlock *pACB) | ||
761 | { | ||
762 | struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC; | ||
763 | writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0); | ||
764 | writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); | ||
765 | if (!arcmsr_hbc_wait_msgint_ready(pACB)) { | ||
766 | printk(KERN_NOTICE | ||
767 | "arcmsr%d: wait 'abort all outstanding command' timeout \n" | ||
768 | , pACB->host->host_no); | ||
769 | return false; | ||
770 | } | ||
771 | return true; | ||
704 | } | 772 | } |
705 | |||
706 | static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb) | 773 | static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb) |
707 | { | 774 | { |
708 | uint8_t rtnval = 0; | 775 | uint8_t rtnval = 0; |
@@ -715,6 +782,11 @@ static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb) | |||
715 | case ACB_ADAPTER_TYPE_B: { | 782 | case ACB_ADAPTER_TYPE_B: { |
716 | rtnval = arcmsr_abort_hbb_allcmd(acb); | 783 | rtnval = arcmsr_abort_hbb_allcmd(acb); |
717 | } | 784 | } |
785 | break; | ||
786 | |||
787 | case ACB_ADAPTER_TYPE_C: { | ||
788 | rtnval = arcmsr_abort_hbc_allcmd(acb); | ||
789 | } | ||
718 | } | 790 | } |
719 | return rtnval; | 791 | return rtnval; |
720 | } | 792 | } |
@@ -722,13 +794,12 @@ static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb) | |||
722 | static bool arcmsr_hbb_enable_driver_mode(struct AdapterControlBlock *pacb) | 794 | static bool arcmsr_hbb_enable_driver_mode(struct AdapterControlBlock *pacb) |
723 | { | 795 | { |
724 | struct MessageUnit_B *reg = pacb->pmuB; | 796 | struct MessageUnit_B *reg = pacb->pmuB; |
725 | |||
726 | writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell); | 797 | writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell); |
727 | if (arcmsr_hbb_wait_msgint_ready(pacb)) { | 798 | if (!arcmsr_hbb_wait_msgint_ready(pacb)) { |
728 | printk(KERN_ERR "arcmsr%d: can't set driver mode. \n", pacb->host->host_no); | 799 | printk(KERN_ERR "arcmsr%d: can't set driver mode. \n", pacb->host->host_no); |
729 | return false; | 800 | return false; |
730 | } | 801 | } |
731 | return true; | 802 | return true; |
732 | } | 803 | } |
733 | 804 | ||
734 | static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) | 805 | static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) |
@@ -736,18 +807,16 @@ static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) | |||
736 | struct scsi_cmnd *pcmd = ccb->pcmd; | 807 | struct scsi_cmnd *pcmd = ccb->pcmd; |
737 | 808 | ||
738 | scsi_dma_unmap(pcmd); | 809 | scsi_dma_unmap(pcmd); |
739 | } | 810 | } |
740 | 811 | ||
741 | static void arcmsr_ccb_complete(struct CommandControlBlock *ccb) | 812 | static void arcmsr_ccb_complete(struct CommandControlBlock *ccb) |
742 | { | 813 | { |
743 | struct AdapterControlBlock *acb = ccb->acb; | 814 | struct AdapterControlBlock *acb = ccb->acb; |
744 | struct scsi_cmnd *pcmd = ccb->pcmd; | 815 | struct scsi_cmnd *pcmd = ccb->pcmd; |
745 | unsigned long flags; | 816 | unsigned long flags; |
746 | |||
747 | atomic_dec(&acb->ccboutstandingcount); | 817 | atomic_dec(&acb->ccboutstandingcount); |
748 | arcmsr_pci_unmap_dma(ccb); | 818 | arcmsr_pci_unmap_dma(ccb); |
749 | ccb->startdone = ARCMSR_CCB_DONE; | 819 | ccb->startdone = ARCMSR_CCB_DONE; |
750 | ccb->ccb_flags = 0; | ||
751 | spin_lock_irqsave(&acb->ccblist_lock, flags); | 820 | spin_lock_irqsave(&acb->ccblist_lock, flags); |
752 | list_add_tail(&ccb->list, &acb->ccb_free_list); | 821 | list_add_tail(&ccb->list, &acb->ccb_free_list); |
753 | spin_unlock_irqrestore(&acb->ccblist_lock, flags); | 822 | spin_unlock_irqrestore(&acb->ccblist_lock, flags); |
@@ -759,7 +828,6 @@ static void arcmsr_report_sense_info(struct CommandControlBlock *ccb) | |||
759 | 828 | ||
760 | struct scsi_cmnd *pcmd = ccb->pcmd; | 829 | struct scsi_cmnd *pcmd = ccb->pcmd; |
761 | struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; | 830 | struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; |
762 | |||
763 | pcmd->result = DID_OK << 16; | 831 | pcmd->result = DID_OK << 16; |
764 | if (sensebuffer) { | 832 | if (sensebuffer) { |
765 | int sense_data_length = | 833 | int sense_data_length = |
@@ -775,8 +843,7 @@ static void arcmsr_report_sense_info(struct CommandControlBlock *ccb) | |||
775 | static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) | 843 | static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) |
776 | { | 844 | { |
777 | u32 orig_mask = 0; | 845 | u32 orig_mask = 0; |
778 | switch (acb->adapter_type) { | 846 | switch (acb->adapter_type) { |
779 | |||
780 | case ACB_ADAPTER_TYPE_A : { | 847 | case ACB_ADAPTER_TYPE_A : { |
781 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 848 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
782 | orig_mask = readl(®->outbound_intmask); | 849 | orig_mask = readl(®->outbound_intmask); |
@@ -784,30 +851,35 @@ static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) | |||
784 | ®->outbound_intmask); | 851 | ®->outbound_intmask); |
785 | } | 852 | } |
786 | break; | 853 | break; |
787 | |||
788 | case ACB_ADAPTER_TYPE_B : { | 854 | case ACB_ADAPTER_TYPE_B : { |
789 | struct MessageUnit_B *reg = acb->pmuB; | 855 | struct MessageUnit_B *reg = acb->pmuB; |
790 | orig_mask = readl(reg->iop2drv_doorbell_mask); | 856 | orig_mask = readl(reg->iop2drv_doorbell_mask); |
791 | writel(0, reg->iop2drv_doorbell_mask); | 857 | writel(0, reg->iop2drv_doorbell_mask); |
792 | } | 858 | } |
793 | break; | 859 | break; |
860 | case ACB_ADAPTER_TYPE_C:{ | ||
861 | struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC; | ||
862 | /* disable all outbound interrupt */ | ||
863 | orig_mask = readl(®->host_int_mask); /* disable outbound message0 int */ | ||
864 | writel(orig_mask|ARCMSR_HBCMU_ALL_INTMASKENABLE, ®->host_int_mask); | ||
865 | } | ||
866 | break; | ||
794 | } | 867 | } |
795 | return orig_mask; | 868 | return orig_mask; |
796 | } | 869 | } |
797 | 870 | ||
798 | static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb, | 871 | static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb, |
799 | struct CommandControlBlock *ccb, uint32_t flag_ccb) | 872 | struct CommandControlBlock *ccb, bool error) |
800 | { | 873 | { |
801 | |||
802 | uint8_t id, lun; | 874 | uint8_t id, lun; |
803 | id = ccb->pcmd->device->id; | 875 | id = ccb->pcmd->device->id; |
804 | lun = ccb->pcmd->device->lun; | 876 | lun = ccb->pcmd->device->lun; |
805 | if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { | 877 | if (!error) { |
806 | if (acb->devstate[id][lun] == ARECA_RAID_GONE) | 878 | if (acb->devstate[id][lun] == ARECA_RAID_GONE) |
807 | acb->devstate[id][lun] = ARECA_RAID_GOOD; | 879 | acb->devstate[id][lun] = ARECA_RAID_GOOD; |
808 | ccb->pcmd->result = DID_OK << 16; | 880 | ccb->pcmd->result = DID_OK << 16; |
809 | arcmsr_ccb_complete(ccb); | 881 | arcmsr_ccb_complete(ccb); |
810 | } else { | 882 | }else{ |
811 | switch (ccb->arcmsr_cdb.DeviceStatus) { | 883 | switch (ccb->arcmsr_cdb.DeviceStatus) { |
812 | case ARCMSR_DEV_SELECT_TIMEOUT: { | 884 | case ARCMSR_DEV_SELECT_TIMEOUT: { |
813 | acb->devstate[id][lun] = ARECA_RAID_GONE; | 885 | acb->devstate[id][lun] = ARECA_RAID_GONE; |
@@ -833,42 +905,37 @@ static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb, | |||
833 | break; | 905 | break; |
834 | 906 | ||
835 | default: | 907 | default: |
836 | printk(KERN_NOTICE | 908 | printk(KERN_NOTICE |
837 | "arcmsr%d: scsi id = %d lun = %d" | 909 | "arcmsr%d: scsi id = %d lun = %d isr get command error done, \ |
838 | " isr get command error done, " | 910 | but got unknown DeviceStatus = 0x%x \n" |
839 | "but got unknown DeviceStatus = 0x%x \n" | 911 | , acb->host->host_no |
840 | , acb->host->host_no | 912 | , id |
841 | , id | 913 | , lun |
842 | , lun | 914 | , ccb->arcmsr_cdb.DeviceStatus); |
843 | , ccb->arcmsr_cdb.DeviceStatus); | 915 | acb->devstate[id][lun] = ARECA_RAID_GONE; |
844 | acb->devstate[id][lun] = ARECA_RAID_GONE; | 916 | ccb->pcmd->result = DID_NO_CONNECT << 16; |
845 | ccb->pcmd->result = DID_NO_CONNECT << 16; | 917 | arcmsr_ccb_complete(ccb); |
846 | arcmsr_ccb_complete(ccb); | ||
847 | break; | 918 | break; |
848 | } | 919 | } |
849 | } | 920 | } |
850 | } | 921 | } |
851 | 922 | ||
852 | static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, uint32_t flag_ccb) | 923 | static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct CommandControlBlock *pCCB, bool error) |
853 | 924 | ||
854 | { | 925 | { |
855 | struct CommandControlBlock *ccb; | ||
856 | struct ARCMSR_CDB *arcmsr_cdb; | ||
857 | int id, lun; | 926 | int id, lun; |
858 | 927 | if ((pCCB->acb != acb) || (pCCB->startdone != ARCMSR_CCB_START)) { | |
859 | arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5)); | 928 | if (pCCB->startdone == ARCMSR_CCB_ABORTED) { |
860 | ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb); | 929 | struct scsi_cmnd *abortcmd = pCCB->pcmd; |
861 | if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { | ||
862 | if (ccb->startdone == ARCMSR_CCB_ABORTED) { | ||
863 | struct scsi_cmnd *abortcmd = ccb->pcmd; | ||
864 | if (abortcmd) { | 930 | if (abortcmd) { |
865 | id = abortcmd->device->id; | 931 | id = abortcmd->device->id; |
866 | lun = abortcmd->device->lun; | 932 | lun = abortcmd->device->lun; |
867 | abortcmd->result |= DID_ABORT << 16; | 933 | abortcmd->result |= DID_ABORT << 16; |
868 | arcmsr_ccb_complete(ccb); | 934 | arcmsr_ccb_complete(pCCB); |
869 | printk(KERN_NOTICE "arcmsr%d: ccb ='0x%p' \ | 935 | printk(KERN_NOTICE "arcmsr%d: pCCB ='0x%p' isr got aborted command \n", |
870 | isr got aborted command \n", acb->host->host_no, ccb); | 936 | acb->host->host_no, pCCB); |
871 | } | 937 | } |
938 | return; | ||
872 | } | 939 | } |
873 | printk(KERN_NOTICE "arcmsr%d: isr get an illegal ccb command \ | 940 | printk(KERN_NOTICE "arcmsr%d: isr get an illegal ccb command \ |
874 | done acb = '0x%p'" | 941 | done acb = '0x%p'" |
@@ -876,20 +943,22 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, uint32_t fla | |||
876 | " ccboutstandingcount = %d \n" | 943 | " ccboutstandingcount = %d \n" |
877 | , acb->host->host_no | 944 | , acb->host->host_no |
878 | , acb | 945 | , acb |
879 | , ccb | 946 | , pCCB |
880 | , ccb->acb | 947 | , pCCB->acb |
881 | , ccb->startdone | 948 | , pCCB->startdone |
882 | , atomic_read(&acb->ccboutstandingcount)); | 949 | , atomic_read(&acb->ccboutstandingcount)); |
950 | return; | ||
883 | } | 951 | } |
884 | else | 952 | arcmsr_report_ccb_state(acb, pCCB, error); |
885 | arcmsr_report_ccb_state(acb, ccb, flag_ccb); | ||
886 | } | 953 | } |
887 | 954 | ||
888 | static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) | 955 | static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) |
889 | { | 956 | { |
890 | int i = 0; | 957 | int i = 0; |
891 | uint32_t flag_ccb; | 958 | uint32_t flag_ccb; |
892 | 959 | struct ARCMSR_CDB *pARCMSR_CDB; | |
960 | bool error; | ||
961 | struct CommandControlBlock *pCCB; | ||
893 | switch (acb->adapter_type) { | 962 | switch (acb->adapter_type) { |
894 | 963 | ||
895 | case ACB_ADAPTER_TYPE_A: { | 964 | case ACB_ADAPTER_TYPE_A: { |
@@ -899,9 +968,12 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) | |||
899 | acb->outbound_int_enable; | 968 | acb->outbound_int_enable; |
900 | /*clear and abort all outbound posted Q*/ | 969 | /*clear and abort all outbound posted Q*/ |
901 | writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ | 970 | writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ |
902 | while (((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) | 971 | while(((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) |
903 | && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { | 972 | && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { |
904 | arcmsr_drain_donequeue(acb, flag_ccb); | 973 | pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/ |
974 | pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb); | ||
975 | error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false; | ||
976 | arcmsr_drain_donequeue(acb, pCCB, error); | ||
905 | } | 977 | } |
906 | } | 978 | } |
907 | break; | 979 | break; |
@@ -909,17 +981,37 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) | |||
909 | case ACB_ADAPTER_TYPE_B: { | 981 | case ACB_ADAPTER_TYPE_B: { |
910 | struct MessageUnit_B *reg = acb->pmuB; | 982 | struct MessageUnit_B *reg = acb->pmuB; |
911 | /*clear all outbound posted Q*/ | 983 | /*clear all outbound posted Q*/ |
984 | writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, ®->iop2drv_doorbell); /* clear doorbell interrupt */ | ||
912 | for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { | 985 | for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { |
913 | if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) { | 986 | if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) { |
914 | writel(0, ®->done_qbuffer[i]); | 987 | writel(0, ®->done_qbuffer[i]); |
915 | arcmsr_drain_donequeue(acb, flag_ccb); | 988 | pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/ |
989 | pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb); | ||
990 | error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false; | ||
991 | arcmsr_drain_donequeue(acb, pCCB, error); | ||
916 | } | 992 | } |
917 | writel(0, ®->post_qbuffer[i]); | 993 | reg->post_qbuffer[i] = 0; |
918 | } | 994 | } |
919 | reg->doneq_index = 0; | 995 | reg->doneq_index = 0; |
920 | reg->postq_index = 0; | 996 | reg->postq_index = 0; |
921 | } | 997 | } |
922 | break; | 998 | break; |
999 | case ACB_ADAPTER_TYPE_C: { | ||
1000 | struct MessageUnit_C *reg = acb->pmuC; | ||
1001 | struct ARCMSR_CDB *pARCMSR_CDB; | ||
1002 | uint32_t flag_ccb, ccb_cdb_phy; | ||
1003 | bool error; | ||
1004 | struct CommandControlBlock *pCCB; | ||
1005 | while ((readl(®->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { | ||
1006 | /*need to do*/ | ||
1007 | flag_ccb = readl(®->outbound_queueport_low); | ||
1008 | ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0); | ||
1009 | pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset+ccb_cdb_phy);/*frame must be 32 bytes aligned*/ | ||
1010 | pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb); | ||
1011 | error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false; | ||
1012 | arcmsr_drain_donequeue(acb, pCCB, error); | ||
1013 | } | ||
1014 | } | ||
923 | } | 1015 | } |
924 | } | 1016 | } |
925 | static void arcmsr_remove(struct pci_dev *pdev) | 1017 | static void arcmsr_remove(struct pci_dev *pdev) |
@@ -930,16 +1022,15 @@ static void arcmsr_remove(struct pci_dev *pdev) | |||
930 | int poll_count = 0; | 1022 | int poll_count = 0; |
931 | arcmsr_free_sysfs_attr(acb); | 1023 | arcmsr_free_sysfs_attr(acb); |
932 | scsi_remove_host(host); | 1024 | scsi_remove_host(host); |
933 | scsi_host_put(host); | ||
934 | flush_scheduled_work(); | 1025 | flush_scheduled_work(); |
935 | del_timer_sync(&acb->eternal_timer); | 1026 | del_timer_sync(&acb->eternal_timer); |
936 | arcmsr_disable_outbound_ints(acb); | 1027 | arcmsr_disable_outbound_ints(acb); |
937 | arcmsr_stop_adapter_bgrb(acb); | 1028 | arcmsr_stop_adapter_bgrb(acb); |
938 | arcmsr_flush_adapter_cache(acb); | 1029 | arcmsr_flush_adapter_cache(acb); |
939 | acb->acb_flags |= ACB_F_SCSISTOPADAPTER; | 1030 | acb->acb_flags |= ACB_F_SCSISTOPADAPTER; |
940 | acb->acb_flags &= ~ACB_F_IOP_INITED; | 1031 | acb->acb_flags &= ~ACB_F_IOP_INITED; |
941 | 1032 | ||
942 | for (poll_count = 0; poll_count < ARCMSR_MAX_OUTSTANDING_CMD; poll_count++) { | 1033 | for (poll_count = 0; poll_count < ARCMSR_MAX_OUTSTANDING_CMD; poll_count++){ |
943 | if (!atomic_read(&acb->ccboutstandingcount)) | 1034 | if (!atomic_read(&acb->ccboutstandingcount)) |
944 | break; | 1035 | break; |
945 | arcmsr_interrupt(acb);/* FIXME: need spinlock */ | 1036 | arcmsr_interrupt(acb);/* FIXME: need spinlock */ |
@@ -962,8 +1053,10 @@ static void arcmsr_remove(struct pci_dev *pdev) | |||
962 | } | 1053 | } |
963 | free_irq(pdev->irq, acb); | 1054 | free_irq(pdev->irq, acb); |
964 | arcmsr_free_ccb_pool(acb); | 1055 | arcmsr_free_ccb_pool(acb); |
965 | arcmsr_free_mu(acb); | 1056 | arcmsr_free_hbb_mu(acb); |
1057 | arcmsr_unmap_pciregion(acb); | ||
966 | pci_release_regions(pdev); | 1058 | pci_release_regions(pdev); |
1059 | scsi_host_put(host); | ||
967 | pci_disable_device(pdev); | 1060 | pci_disable_device(pdev); |
968 | pci_set_drvdata(pdev, NULL); | 1061 | pci_set_drvdata(pdev, NULL); |
969 | } | 1062 | } |
@@ -983,7 +1076,6 @@ static void arcmsr_shutdown(struct pci_dev *pdev) | |||
983 | static int arcmsr_module_init(void) | 1076 | static int arcmsr_module_init(void) |
984 | { | 1077 | { |
985 | int error = 0; | 1078 | int error = 0; |
986 | |||
987 | error = pci_register_driver(&arcmsr_pci_driver); | 1079 | error = pci_register_driver(&arcmsr_pci_driver); |
988 | return error; | 1080 | return error; |
989 | } | 1081 | } |
@@ -999,10 +1091,9 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, | |||
999 | u32 intmask_org) | 1091 | u32 intmask_org) |
1000 | { | 1092 | { |
1001 | u32 mask; | 1093 | u32 mask; |
1002 | |||
1003 | switch (acb->adapter_type) { | 1094 | switch (acb->adapter_type) { |
1004 | 1095 | ||
1005 | case ACB_ADAPTER_TYPE_A : { | 1096 | case ACB_ADAPTER_TYPE_A: { |
1006 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 1097 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
1007 | mask = intmask_org & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | | 1098 | mask = intmask_org & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | |
1008 | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE| | 1099 | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE| |
@@ -1012,7 +1103,7 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, | |||
1012 | } | 1103 | } |
1013 | break; | 1104 | break; |
1014 | 1105 | ||
1015 | case ACB_ADAPTER_TYPE_B : { | 1106 | case ACB_ADAPTER_TYPE_B: { |
1016 | struct MessageUnit_B *reg = acb->pmuB; | 1107 | struct MessageUnit_B *reg = acb->pmuB; |
1017 | mask = intmask_org | (ARCMSR_IOP2DRV_DATA_WRITE_OK | | 1108 | mask = intmask_org | (ARCMSR_IOP2DRV_DATA_WRITE_OK | |
1018 | ARCMSR_IOP2DRV_DATA_READ_OK | | 1109 | ARCMSR_IOP2DRV_DATA_READ_OK | |
@@ -1021,6 +1112,13 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, | |||
1021 | writel(mask, reg->iop2drv_doorbell_mask); | 1112 | writel(mask, reg->iop2drv_doorbell_mask); |
1022 | acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f; | 1113 | acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f; |
1023 | } | 1114 | } |
1115 | break; | ||
1116 | case ACB_ADAPTER_TYPE_C: { | ||
1117 | struct MessageUnit_C *reg = acb->pmuC; | ||
1118 | mask = ~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK|ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK); | ||
1119 | writel(intmask_org & mask, ®->host_int_mask); | ||
1120 | acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f; | ||
1121 | } | ||
1024 | } | 1122 | } |
1025 | } | 1123 | } |
1026 | 1124 | ||
@@ -1032,75 +1130,69 @@ static int arcmsr_build_ccb(struct AdapterControlBlock *acb, | |||
1032 | __le32 address_lo, address_hi; | 1130 | __le32 address_lo, address_hi; |
1033 | int arccdbsize = 0x30; | 1131 | int arccdbsize = 0x30; |
1034 | __le32 length = 0; | 1132 | __le32 length = 0; |
1035 | int i, cdb_sgcount = 0; | 1133 | int i; |
1036 | struct scatterlist *sg; | 1134 | struct scatterlist *sg; |
1037 | int nseg; | 1135 | int nseg; |
1038 | |||
1039 | ccb->pcmd = pcmd; | 1136 | ccb->pcmd = pcmd; |
1040 | memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB)); | 1137 | memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB)); |
1041 | arcmsr_cdb->Bus = 0; | ||
1042 | arcmsr_cdb->TargetID = pcmd->device->id; | 1138 | arcmsr_cdb->TargetID = pcmd->device->id; |
1043 | arcmsr_cdb->LUN = pcmd->device->lun; | 1139 | arcmsr_cdb->LUN = pcmd->device->lun; |
1044 | arcmsr_cdb->Function = 1; | 1140 | arcmsr_cdb->Function = 1; |
1045 | arcmsr_cdb->CdbLength = (uint8_t)pcmd->cmd_len; | ||
1046 | arcmsr_cdb->Context = 0; | 1141 | arcmsr_cdb->Context = 0; |
1047 | memcpy(arcmsr_cdb->Cdb, pcmd->cmnd, pcmd->cmd_len); | 1142 | memcpy(arcmsr_cdb->Cdb, pcmd->cmnd, pcmd->cmd_len); |
1048 | 1143 | ||
1049 | nseg = scsi_dma_map(pcmd); | 1144 | nseg = scsi_dma_map(pcmd); |
1050 | if (nseg > acb->host->sg_tablesize || nseg < 0) | 1145 | if (unlikely(nseg > acb->host->sg_tablesize || nseg < 0)) |
1051 | return FAILED; | 1146 | return FAILED; |
1052 | /* map stor port SG list to our iop SG List. */ | 1147 | scsi_for_each_sg(pcmd, sg, nseg, i) { |
1053 | scsi_for_each_sg(pcmd, sg, nseg, i) { | 1148 | /* Get the physical address of the current data pointer */ |
1054 | /* Get the physical address of the current data pointer */ | 1149 | length = cpu_to_le32(sg_dma_len(sg)); |
1055 | length = cpu_to_le32(sg_dma_len(sg)); | 1150 | address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sg))); |
1056 | address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sg))); | 1151 | address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sg))); |
1057 | address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sg))); | 1152 | if (address_hi == 0) { |
1058 | if (address_hi == 0) { | 1153 | struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge; |
1059 | struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge; | 1154 | |
1060 | 1155 | pdma_sg->address = address_lo; | |
1061 | pdma_sg->address = address_lo; | 1156 | pdma_sg->length = length; |
1062 | pdma_sg->length = length; | 1157 | psge += sizeof (struct SG32ENTRY); |
1063 | psge += sizeof (struct SG32ENTRY); | 1158 | arccdbsize += sizeof (struct SG32ENTRY); |
1064 | arccdbsize += sizeof (struct SG32ENTRY); | 1159 | } else { |
1065 | } else { | 1160 | struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge; |
1066 | struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge; | ||
1067 | 1161 | ||
1068 | pdma_sg->addresshigh = address_hi; | 1162 | pdma_sg->addresshigh = address_hi; |
1069 | pdma_sg->address = address_lo; | 1163 | pdma_sg->address = address_lo; |
1070 | pdma_sg->length = length|cpu_to_le32(IS_SG64_ADDR); | 1164 | pdma_sg->length = length|cpu_to_le32(IS_SG64_ADDR); |
1071 | psge += sizeof (struct SG64ENTRY); | 1165 | psge += sizeof (struct SG64ENTRY); |
1072 | arccdbsize += sizeof (struct SG64ENTRY); | 1166 | arccdbsize += sizeof (struct SG64ENTRY); |
1073 | } | ||
1074 | cdb_sgcount++; | ||
1075 | } | 1167 | } |
1076 | arcmsr_cdb->sgcount = (uint8_t)cdb_sgcount; | 1168 | } |
1077 | arcmsr_cdb->DataLength = scsi_bufflen(pcmd); | 1169 | arcmsr_cdb->sgcount = (uint8_t)nseg; |
1170 | arcmsr_cdb->DataLength = scsi_bufflen(pcmd); | ||
1078 | arcmsr_cdb->msgPages = arccdbsize/0x100 + (arccdbsize % 0x100 ? 1 : 0); | 1171 | arcmsr_cdb->msgPages = arccdbsize/0x100 + (arccdbsize % 0x100 ? 1 : 0); |
1079 | if ( arccdbsize > 256) | 1172 | if ( arccdbsize > 256) |
1080 | arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE; | 1173 | arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE; |
1081 | if (pcmd->cmnd[0]|WRITE_6 || pcmd->cmnd[0] | WRITE_10 || pcmd->cmnd[0]|WRITE_12) { | 1174 | if (pcmd->cmnd[0]|WRITE_6 || pcmd->cmnd[0]|WRITE_10 || pcmd->cmnd[0]|WRITE_12 ){ |
1082 | arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE; | 1175 | arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE; |
1083 | ccb->ccb_flags |= CCB_FLAG_WRITE; | ||
1084 | } | 1176 | } |
1177 | ccb->arc_cdb_size = arccdbsize; | ||
1085 | return SUCCESS; | 1178 | return SUCCESS; |
1086 | } | 1179 | } |
1087 | 1180 | ||
1088 | static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb) | 1181 | static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb) |
1089 | { | 1182 | { |
1090 | uint32_t shifted_cdb_phyaddr = ccb->shifted_cdb_phyaddr; | 1183 | uint32_t cdb_phyaddr_pattern = ccb->cdb_phyaddr_pattern; |
1091 | struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; | 1184 | struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; |
1092 | atomic_inc(&acb->ccboutstandingcount); | 1185 | atomic_inc(&acb->ccboutstandingcount); |
1093 | ccb->startdone = ARCMSR_CCB_START; | 1186 | ccb->startdone = ARCMSR_CCB_START; |
1094 | |||
1095 | switch (acb->adapter_type) { | 1187 | switch (acb->adapter_type) { |
1096 | case ACB_ADAPTER_TYPE_A: { | 1188 | case ACB_ADAPTER_TYPE_A: { |
1097 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 1189 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
1098 | 1190 | ||
1099 | if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) | 1191 | if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) |
1100 | writel(shifted_cdb_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE, | 1192 | writel(cdb_phyaddr_pattern | ARCMSR_CCBPOST_FLAG_SGL_BSIZE, |
1101 | ®->inbound_queueport); | 1193 | ®->inbound_queueport); |
1102 | else { | 1194 | else { |
1103 | writel(shifted_cdb_phyaddr, ®->inbound_queueport); | 1195 | writel(cdb_phyaddr_pattern, ®->inbound_queueport); |
1104 | } | 1196 | } |
1105 | } | 1197 | } |
1106 | break; | 1198 | break; |
@@ -1112,11 +1204,10 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr | |||
1112 | ending_index = ((index + 1) % ARCMSR_MAX_HBB_POSTQUEUE); | 1204 | ending_index = ((index + 1) % ARCMSR_MAX_HBB_POSTQUEUE); |
1113 | writel(0, ®->post_qbuffer[ending_index]); | 1205 | writel(0, ®->post_qbuffer[ending_index]); |
1114 | if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) { | 1206 | if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) { |
1115 | writel(shifted_cdb_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,\ | 1207 | writel(cdb_phyaddr_pattern | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,\ |
1116 | ®->post_qbuffer[index]); | 1208 | ®->post_qbuffer[index]); |
1117 | } | 1209 | } else { |
1118 | else { | 1210 | writel(cdb_phyaddr_pattern, ®->post_qbuffer[index]); |
1119 | writel(shifted_cdb_phyaddr, ®->post_qbuffer[index]); | ||
1120 | } | 1211 | } |
1121 | index++; | 1212 | index++; |
1122 | index %= ARCMSR_MAX_HBB_POSTQUEUE;/*if last index number set it to 0 */ | 1213 | index %= ARCMSR_MAX_HBB_POSTQUEUE;/*if last index number set it to 0 */ |
@@ -1124,6 +1215,19 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr | |||
1124 | writel(ARCMSR_DRV2IOP_CDB_POSTED, reg->drv2iop_doorbell); | 1215 | writel(ARCMSR_DRV2IOP_CDB_POSTED, reg->drv2iop_doorbell); |
1125 | } | 1216 | } |
1126 | break; | 1217 | break; |
1218 | case ACB_ADAPTER_TYPE_C: { | ||
1219 | struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)acb->pmuC; | ||
1220 | uint32_t ccb_post_stamp, arc_cdb_size; | ||
1221 | |||
1222 | arc_cdb_size = (ccb->arc_cdb_size > 0x300) ? 0x300 : ccb->arc_cdb_size; | ||
1223 | ccb_post_stamp = (cdb_phyaddr_pattern | ((arc_cdb_size - 1) >> 6) | 1); | ||
1224 | if (acb->cdb_phyaddr_hi32) { | ||
1225 | writel(acb->cdb_phyaddr_hi32, &phbcmu->inbound_queueport_high); | ||
1226 | writel(ccb_post_stamp, &phbcmu->inbound_queueport_low); | ||
1227 | } else { | ||
1228 | writel(ccb_post_stamp, &phbcmu->inbound_queueport_low); | ||
1229 | } | ||
1230 | } | ||
1127 | } | 1231 | } |
1128 | } | 1232 | } |
1129 | 1233 | ||
@@ -1132,8 +1236,7 @@ static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb) | |||
1132 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 1236 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
1133 | acb->acb_flags &= ~ACB_F_MSG_START_BGRB; | 1237 | acb->acb_flags &= ~ACB_F_MSG_START_BGRB; |
1134 | writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, ®->inbound_msgaddr0); | 1238 | writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, ®->inbound_msgaddr0); |
1135 | 1239 | if (!arcmsr_hba_wait_msgint_ready(acb)) { | |
1136 | if (arcmsr_hba_wait_msgint_ready(acb)) { | ||
1137 | printk(KERN_NOTICE | 1240 | printk(KERN_NOTICE |
1138 | "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" | 1241 | "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" |
1139 | , acb->host->host_no); | 1242 | , acb->host->host_no); |
@@ -1146,13 +1249,26 @@ static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb) | |||
1146 | acb->acb_flags &= ~ACB_F_MSG_START_BGRB; | 1249 | acb->acb_flags &= ~ACB_F_MSG_START_BGRB; |
1147 | writel(ARCMSR_MESSAGE_STOP_BGRB, reg->drv2iop_doorbell); | 1250 | writel(ARCMSR_MESSAGE_STOP_BGRB, reg->drv2iop_doorbell); |
1148 | 1251 | ||
1149 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | 1252 | if (!arcmsr_hbb_wait_msgint_ready(acb)) { |
1150 | printk(KERN_NOTICE | 1253 | printk(KERN_NOTICE |
1151 | "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" | 1254 | "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" |
1152 | , acb->host->host_no); | 1255 | , acb->host->host_no); |
1153 | } | 1256 | } |
1154 | } | 1257 | } |
1155 | 1258 | ||
1259 | static void arcmsr_stop_hbc_bgrb(struct AdapterControlBlock *pACB) | ||
1260 | { | ||
1261 | struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC; | ||
1262 | pACB->acb_flags &= ~ACB_F_MSG_START_BGRB; | ||
1263 | writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, ®->inbound_msgaddr0); | ||
1264 | writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); | ||
1265 | if (!arcmsr_hbc_wait_msgint_ready(pACB)) { | ||
1266 | printk(KERN_NOTICE | ||
1267 | "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" | ||
1268 | , pACB->host->host_no); | ||
1269 | } | ||
1270 | return; | ||
1271 | } | ||
1156 | static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) | 1272 | static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) |
1157 | { | 1273 | { |
1158 | switch (acb->adapter_type) { | 1274 | switch (acb->adapter_type) { |
@@ -1165,21 +1281,15 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) | |||
1165 | arcmsr_stop_hbb_bgrb(acb); | 1281 | arcmsr_stop_hbb_bgrb(acb); |
1166 | } | 1282 | } |
1167 | break; | 1283 | break; |
1284 | case ACB_ADAPTER_TYPE_C: { | ||
1285 | arcmsr_stop_hbc_bgrb(acb); | ||
1286 | } | ||
1168 | } | 1287 | } |
1169 | } | 1288 | } |
1170 | 1289 | ||
1171 | static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) | 1290 | static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) |
1172 | { | 1291 | { |
1173 | switch (acb->adapter_type) { | 1292 | dma_free_coherent(&acb->pdev->dev, acb->uncache_size, acb->dma_coherent, acb->dma_coherent_handle); |
1174 | case ACB_ADAPTER_TYPE_A: { | ||
1175 | dma_free_coherent(&acb->pdev->dev, acb->uncache_size, acb->dma_coherent, acb->dma_coherent_handle); | ||
1176 | iounmap(acb->pmuA); | ||
1177 | } | ||
1178 | break; | ||
1179 | case ACB_ADAPTER_TYPE_B: { | ||
1180 | dma_free_coherent(&acb->pdev->dev, acb->uncache_size, acb->dma_coherent, acb->dma_coherent_handle); | ||
1181 | } | ||
1182 | } | ||
1183 | } | 1293 | } |
1184 | 1294 | ||
1185 | void arcmsr_iop_message_read(struct AdapterControlBlock *acb) | 1295 | void arcmsr_iop_message_read(struct AdapterControlBlock *acb) |
@@ -1196,6 +1306,10 @@ void arcmsr_iop_message_read(struct AdapterControlBlock *acb) | |||
1196 | writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell); | 1306 | writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell); |
1197 | } | 1307 | } |
1198 | break; | 1308 | break; |
1309 | case ACB_ADAPTER_TYPE_C: { | ||
1310 | struct MessageUnit_C __iomem *reg = acb->pmuC; | ||
1311 | writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, ®->inbound_doorbell); | ||
1312 | } | ||
1199 | } | 1313 | } |
1200 | } | 1314 | } |
1201 | 1315 | ||
@@ -1221,13 +1335,21 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb) | |||
1221 | writel(ARCMSR_DRV2IOP_DATA_WRITE_OK, reg->drv2iop_doorbell); | 1335 | writel(ARCMSR_DRV2IOP_DATA_WRITE_OK, reg->drv2iop_doorbell); |
1222 | } | 1336 | } |
1223 | break; | 1337 | break; |
1338 | case ACB_ADAPTER_TYPE_C: { | ||
1339 | struct MessageUnit_C __iomem *reg = acb->pmuC; | ||
1340 | /* | ||
1341 | ** push inbound doorbell tell iop, driver data write ok | ||
1342 | ** and wait reply on next hwinterrupt for next Qbuffer post | ||
1343 | */ | ||
1344 | writel(ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK, ®->inbound_doorbell); | ||
1345 | } | ||
1346 | break; | ||
1224 | } | 1347 | } |
1225 | } | 1348 | } |
1226 | 1349 | ||
1227 | struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb) | 1350 | struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb) |
1228 | { | 1351 | { |
1229 | struct QBUFFER __iomem *qbuffer = NULL; | 1352 | struct QBUFFER __iomem *qbuffer = NULL; |
1230 | |||
1231 | switch (acb->adapter_type) { | 1353 | switch (acb->adapter_type) { |
1232 | 1354 | ||
1233 | case ACB_ADAPTER_TYPE_A: { | 1355 | case ACB_ADAPTER_TYPE_A: { |
@@ -1241,6 +1363,10 @@ struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb) | |||
1241 | qbuffer = (struct QBUFFER __iomem *)reg->message_rbuffer; | 1363 | qbuffer = (struct QBUFFER __iomem *)reg->message_rbuffer; |
1242 | } | 1364 | } |
1243 | break; | 1365 | break; |
1366 | case ACB_ADAPTER_TYPE_C: { | ||
1367 | struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)acb->pmuC; | ||
1368 | qbuffer = (struct QBUFFER __iomem *)&phbcmu->message_rbuffer; | ||
1369 | } | ||
1244 | } | 1370 | } |
1245 | return qbuffer; | 1371 | return qbuffer; |
1246 | } | 1372 | } |
@@ -1248,7 +1374,6 @@ struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb) | |||
1248 | static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBlock *acb) | 1374 | static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBlock *acb) |
1249 | { | 1375 | { |
1250 | struct QBUFFER __iomem *pqbuffer = NULL; | 1376 | struct QBUFFER __iomem *pqbuffer = NULL; |
1251 | |||
1252 | switch (acb->adapter_type) { | 1377 | switch (acb->adapter_type) { |
1253 | 1378 | ||
1254 | case ACB_ADAPTER_TYPE_A: { | 1379 | case ACB_ADAPTER_TYPE_A: { |
@@ -1262,6 +1387,11 @@ static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBloc | |||
1262 | pqbuffer = (struct QBUFFER __iomem *)reg->message_wbuffer; | 1387 | pqbuffer = (struct QBUFFER __iomem *)reg->message_wbuffer; |
1263 | } | 1388 | } |
1264 | break; | 1389 | break; |
1390 | case ACB_ADAPTER_TYPE_C: { | ||
1391 | struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC; | ||
1392 | pqbuffer = (struct QBUFFER __iomem *)®->message_wbuffer; | ||
1393 | } | ||
1394 | |||
1265 | } | 1395 | } |
1266 | return pqbuffer; | 1396 | return pqbuffer; |
1267 | } | 1397 | } |
@@ -1272,19 +1402,18 @@ static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb) | |||
1272 | struct QBUFFER *pQbuffer; | 1402 | struct QBUFFER *pQbuffer; |
1273 | uint8_t __iomem *iop_data; | 1403 | uint8_t __iomem *iop_data; |
1274 | int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; | 1404 | int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; |
1275 | |||
1276 | rqbuf_lastindex = acb->rqbuf_lastindex; | 1405 | rqbuf_lastindex = acb->rqbuf_lastindex; |
1277 | rqbuf_firstindex = acb->rqbuf_firstindex; | 1406 | rqbuf_firstindex = acb->rqbuf_firstindex; |
1278 | prbuffer = arcmsr_get_iop_rqbuffer(acb); | 1407 | prbuffer = arcmsr_get_iop_rqbuffer(acb); |
1279 | iop_data = (uint8_t __iomem *)prbuffer->data; | 1408 | iop_data = (uint8_t __iomem *)prbuffer->data; |
1280 | iop_len = prbuffer->data_len; | 1409 | iop_len = prbuffer->data_len; |
1281 | my_empty_len = (rqbuf_firstindex - rqbuf_lastindex -1)&(ARCMSR_MAX_QBUFFER -1); | 1410 | my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) & (ARCMSR_MAX_QBUFFER - 1); |
1282 | 1411 | ||
1283 | if (my_empty_len >= iop_len) | 1412 | if (my_empty_len >= iop_len) |
1284 | { | 1413 | { |
1285 | while (iop_len > 0) { | 1414 | while (iop_len > 0) { |
1286 | pQbuffer = (struct QBUFFER *)&acb->rqbuffer[rqbuf_lastindex]; | 1415 | pQbuffer = (struct QBUFFER *)&acb->rqbuffer[rqbuf_lastindex]; |
1287 | memcpy(pQbuffer, iop_data,1); | 1416 | memcpy(pQbuffer, iop_data, 1); |
1288 | rqbuf_lastindex++; | 1417 | rqbuf_lastindex++; |
1289 | rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; | 1418 | rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; |
1290 | iop_data++; | 1419 | iop_data++; |
@@ -1335,25 +1464,52 @@ static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb) | |||
1335 | { | 1464 | { |
1336 | uint32_t outbound_doorbell; | 1465 | uint32_t outbound_doorbell; |
1337 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 1466 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
1338 | |||
1339 | outbound_doorbell = readl(®->outbound_doorbell); | 1467 | outbound_doorbell = readl(®->outbound_doorbell); |
1340 | writel(outbound_doorbell, ®->outbound_doorbell); | 1468 | writel(outbound_doorbell, ®->outbound_doorbell); |
1341 | if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { | 1469 | if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { |
1342 | arcmsr_iop2drv_data_wrote_handle(acb); | 1470 | arcmsr_iop2drv_data_wrote_handle(acb); |
1343 | } | 1471 | } |
1344 | 1472 | ||
1345 | if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) { | 1473 | if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) { |
1346 | arcmsr_iop2drv_data_read_handle(acb); | 1474 | arcmsr_iop2drv_data_read_handle(acb); |
1347 | } | 1475 | } |
1348 | } | 1476 | } |
1349 | 1477 | static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *pACB) | |
1478 | { | ||
1479 | uint32_t outbound_doorbell; | ||
1480 | struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC; | ||
1481 | /* | ||
1482 | ******************************************************************* | ||
1483 | ** Maybe here we need to check wrqbuffer_lock is lock or not | ||
1484 | ** DOORBELL: din! don! | ||
1485 | ** check if there are any mail need to pack from firmware | ||
1486 | ******************************************************************* | ||
1487 | */ | ||
1488 | outbound_doorbell = readl(®->outbound_doorbell); | ||
1489 | writel(outbound_doorbell, ®->outbound_doorbell_clear);/*clear interrupt*/ | ||
1490 | if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) { | ||
1491 | arcmsr_iop2drv_data_wrote_handle(pACB); | ||
1492 | } | ||
1493 | if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK) { | ||
1494 | arcmsr_iop2drv_data_read_handle(pACB); | ||
1495 | } | ||
1496 | if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { | ||
1497 | arcmsr_hbc_message_isr(pACB); /* messenger of "driver to iop commands" */ | ||
1498 | } | ||
1499 | return; | ||
1500 | } | ||
1350 | static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb) | 1501 | static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb) |
1351 | { | 1502 | { |
1352 | uint32_t flag_ccb; | 1503 | uint32_t flag_ccb; |
1353 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 1504 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
1354 | 1505 | struct ARCMSR_CDB *pARCMSR_CDB; | |
1506 | struct CommandControlBlock *pCCB; | ||
1507 | bool error; | ||
1355 | while ((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) { | 1508 | while ((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) { |
1356 | arcmsr_drain_donequeue(acb, flag_ccb); | 1509 | pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/ |
1510 | pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb); | ||
1511 | error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false; | ||
1512 | arcmsr_drain_donequeue(acb, pCCB, error); | ||
1357 | } | 1513 | } |
1358 | } | 1514 | } |
1359 | 1515 | ||
@@ -1362,29 +1518,62 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb) | |||
1362 | uint32_t index; | 1518 | uint32_t index; |
1363 | uint32_t flag_ccb; | 1519 | uint32_t flag_ccb; |
1364 | struct MessageUnit_B *reg = acb->pmuB; | 1520 | struct MessageUnit_B *reg = acb->pmuB; |
1365 | 1521 | struct ARCMSR_CDB *pARCMSR_CDB; | |
1522 | struct CommandControlBlock *pCCB; | ||
1523 | bool error; | ||
1366 | index = reg->doneq_index; | 1524 | index = reg->doneq_index; |
1367 | |||
1368 | while ((flag_ccb = readl(®->done_qbuffer[index])) != 0) { | 1525 | while ((flag_ccb = readl(®->done_qbuffer[index])) != 0) { |
1369 | writel(0, ®->done_qbuffer[index]); | 1526 | writel(0, ®->done_qbuffer[index]); |
1370 | arcmsr_drain_donequeue(acb, flag_ccb); | 1527 | pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/ |
1528 | pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb); | ||
1529 | error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false; | ||
1530 | arcmsr_drain_donequeue(acb, pCCB, error); | ||
1371 | index++; | 1531 | index++; |
1372 | index %= ARCMSR_MAX_HBB_POSTQUEUE; | 1532 | index %= ARCMSR_MAX_HBB_POSTQUEUE; |
1373 | reg->doneq_index = index; | 1533 | reg->doneq_index = index; |
1374 | } | 1534 | } |
1375 | } | 1535 | } |
1536 | |||
1537 | static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb) | ||
1538 | { | ||
1539 | struct MessageUnit_C *phbcmu; | ||
1540 | struct ARCMSR_CDB *arcmsr_cdb; | ||
1541 | struct CommandControlBlock *ccb; | ||
1542 | uint32_t flag_ccb, ccb_cdb_phy, throttling = 0; | ||
1543 | int error; | ||
1544 | |||
1545 | phbcmu = (struct MessageUnit_C *)acb->pmuC; | ||
1546 | /* areca cdb command done */ | ||
1547 | /* Use correct offset and size for syncing */ | ||
1548 | |||
1549 | while (readl(&phbcmu->host_int_status) & | ||
1550 | ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR){ | ||
1551 | /* check if command done with no error*/ | ||
1552 | flag_ccb = readl(&phbcmu->outbound_queueport_low); | ||
1553 | ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);/*frame must be 32 bytes aligned*/ | ||
1554 | arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy); | ||
1555 | ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb); | ||
1556 | error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false; | ||
1557 | /* check if command done with no error */ | ||
1558 | arcmsr_drain_donequeue(acb, ccb, error); | ||
1559 | if (throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) { | ||
1560 | writel(ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING, &phbcmu->inbound_doorbell); | ||
1561 | break; | ||
1562 | } | ||
1563 | throttling++; | ||
1564 | } | ||
1565 | } | ||
1376 | /* | 1566 | /* |
1377 | ********************************************************************************** | 1567 | ********************************************************************************** |
1378 | ** Handle a message interrupt | 1568 | ** Handle a message interrupt |
1379 | ** | 1569 | ** |
1380 | ** The only message interrupt we expect is in response to a query for the current adapter config. | 1570 | ** The only message interrupt we expect is in response to a query for the current adapter config. |
1381 | ** We want this in order to compare the drivemap so that we can detect newly-attached drives. | 1571 | ** We want this in order to compare the drivemap so that we can detect newly-attached drives. |
1382 | ********************************************************************************** | 1572 | ********************************************************************************** |
1383 | */ | 1573 | */ |
1384 | static void arcmsr_hba_message_isr(struct AdapterControlBlock *acb) | 1574 | static void arcmsr_hba_message_isr(struct AdapterControlBlock *acb) |
1385 | { | 1575 | { |
1386 | struct MessageUnit_A *reg = acb->pmuA; | 1576 | struct MessageUnit_A *reg = acb->pmuA; |
1387 | |||
1388 | /*clear interrupt and message state*/ | 1577 | /*clear interrupt and message state*/ |
1389 | writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, ®->outbound_intstatus); | 1578 | writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, ®->outbound_intstatus); |
1390 | schedule_work(&acb->arcmsr_do_message_isr_bh); | 1579 | schedule_work(&acb->arcmsr_do_message_isr_bh); |
@@ -1397,13 +1586,29 @@ static void arcmsr_hbb_message_isr(struct AdapterControlBlock *acb) | |||
1397 | writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); | 1586 | writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); |
1398 | schedule_work(&acb->arcmsr_do_message_isr_bh); | 1587 | schedule_work(&acb->arcmsr_do_message_isr_bh); |
1399 | } | 1588 | } |
1589 | /* | ||
1590 | ********************************************************************************** | ||
1591 | ** Handle a message interrupt | ||
1592 | ** | ||
1593 | ** The only message interrupt we expect is in response to a query for the | ||
1594 | ** current adapter config. | ||
1595 | ** We want this in order to compare the drivemap so that we can detect newly-attached drives. | ||
1596 | ********************************************************************************** | ||
1597 | */ | ||
1598 | static void arcmsr_hbc_message_isr(struct AdapterControlBlock *acb) | ||
1599 | { | ||
1600 | struct MessageUnit_C *reg = acb->pmuC; | ||
1601 | /*clear interrupt and message state*/ | ||
1602 | writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, ®->outbound_doorbell_clear); | ||
1603 | schedule_work(&acb->arcmsr_do_message_isr_bh); | ||
1604 | } | ||
1605 | |||
1400 | static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb) | 1606 | static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb) |
1401 | { | 1607 | { |
1402 | uint32_t outbound_intstatus; | 1608 | uint32_t outbound_intstatus; |
1403 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 1609 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
1404 | |||
1405 | outbound_intstatus = readl(®->outbound_intstatus) & | 1610 | outbound_intstatus = readl(®->outbound_intstatus) & |
1406 | acb->outbound_int_enable; | 1611 | acb->outbound_int_enable; |
1407 | if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) { | 1612 | if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) { |
1408 | return 1; | 1613 | return 1; |
1409 | } | 1614 | } |
@@ -1414,7 +1619,7 @@ static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb) | |||
1414 | if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { | 1619 | if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { |
1415 | arcmsr_hba_postqueue_isr(acb); | 1620 | arcmsr_hba_postqueue_isr(acb); |
1416 | } | 1621 | } |
1417 | if (outbound_intstatus & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { | 1622 | if(outbound_intstatus & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { |
1418 | /* messenger of "driver to iop commands" */ | 1623 | /* messenger of "driver to iop commands" */ |
1419 | arcmsr_hba_message_isr(acb); | 1624 | arcmsr_hba_message_isr(acb); |
1420 | } | 1625 | } |
@@ -1425,9 +1630,8 @@ static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb) | |||
1425 | { | 1630 | { |
1426 | uint32_t outbound_doorbell; | 1631 | uint32_t outbound_doorbell; |
1427 | struct MessageUnit_B *reg = acb->pmuB; | 1632 | struct MessageUnit_B *reg = acb->pmuB; |
1428 | |||
1429 | outbound_doorbell = readl(reg->iop2drv_doorbell) & | 1633 | outbound_doorbell = readl(reg->iop2drv_doorbell) & |
1430 | acb->outbound_int_enable; | 1634 | acb->outbound_int_enable; |
1431 | if (!outbound_doorbell) | 1635 | if (!outbound_doorbell) |
1432 | return 1; | 1636 | return 1; |
1433 | 1637 | ||
@@ -1436,7 +1640,7 @@ static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb) | |||
1436 | this action can push HW to write down the clear bit*/ | 1640 | this action can push HW to write down the clear bit*/ |
1437 | readl(reg->iop2drv_doorbell); | 1641 | readl(reg->iop2drv_doorbell); |
1438 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); | 1642 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); |
1439 | if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) { | 1643 | if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) { |
1440 | arcmsr_iop2drv_data_wrote_handle(acb); | 1644 | arcmsr_iop2drv_data_wrote_handle(acb); |
1441 | } | 1645 | } |
1442 | if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_READ_OK) { | 1646 | if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_READ_OK) { |
@@ -1445,14 +1649,37 @@ static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb) | |||
1445 | if (outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE) { | 1649 | if (outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE) { |
1446 | arcmsr_hbb_postqueue_isr(acb); | 1650 | arcmsr_hbb_postqueue_isr(acb); |
1447 | } | 1651 | } |
1448 | if (outbound_doorbell & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { | 1652 | if(outbound_doorbell & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { |
1449 | /* messenger of "driver to iop commands" */ | 1653 | /* messenger of "driver to iop commands" */ |
1450 | arcmsr_hbb_message_isr(acb); | 1654 | arcmsr_hbb_message_isr(acb); |
1451 | } | 1655 | } |
1452 | |||
1453 | return 0; | 1656 | return 0; |
1454 | } | 1657 | } |
1455 | 1658 | ||
1659 | static int arcmsr_handle_hbc_isr(struct AdapterControlBlock *pACB) | ||
1660 | { | ||
1661 | uint32_t host_interrupt_status; | ||
1662 | struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC; | ||
1663 | /* | ||
1664 | ********************************************* | ||
1665 | ** check outbound intstatus | ||
1666 | ********************************************* | ||
1667 | */ | ||
1668 | host_interrupt_status = readl(&phbcmu->host_int_status); | ||
1669 | if (!host_interrupt_status) { | ||
1670 | /*it must be share irq*/ | ||
1671 | return 1; | ||
1672 | } | ||
1673 | /* MU ioctl transfer doorbell interrupts*/ | ||
1674 | if (host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR) { | ||
1675 | arcmsr_hbc_doorbell_isr(pACB); /* messenger of "ioctl message read write" */ | ||
1676 | } | ||
1677 | /* MU post queue interrupts*/ | ||
1678 | if (host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) { | ||
1679 | arcmsr_hbc_postqueue_isr(pACB); /* messenger of "scsi commands" */ | ||
1680 | } | ||
1681 | return 0; | ||
1682 | } | ||
1456 | static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) | 1683 | static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) |
1457 | { | 1684 | { |
1458 | switch (acb->adapter_type) { | 1685 | switch (acb->adapter_type) { |
@@ -1469,6 +1696,11 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) | |||
1469 | } | 1696 | } |
1470 | } | 1697 | } |
1471 | break; | 1698 | break; |
1699 | case ACB_ADAPTER_TYPE_C: { | ||
1700 | if (arcmsr_handle_hbc_isr(acb)) { | ||
1701 | return IRQ_NONE; | ||
1702 | } | ||
1703 | } | ||
1472 | } | 1704 | } |
1473 | return IRQ_HANDLED; | 1705 | return IRQ_HANDLED; |
1474 | } | 1706 | } |
@@ -1495,7 +1727,6 @@ void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb) | |||
1495 | struct QBUFFER __iomem *pwbuffer; | 1727 | struct QBUFFER __iomem *pwbuffer; |
1496 | uint8_t __iomem *iop_data; | 1728 | uint8_t __iomem *iop_data; |
1497 | int32_t allxfer_len = 0; | 1729 | int32_t allxfer_len = 0; |
1498 | |||
1499 | pwbuffer = arcmsr_get_iop_wqbuffer(acb); | 1730 | pwbuffer = arcmsr_get_iop_wqbuffer(acb); |
1500 | iop_data = (uint8_t __iomem *)pwbuffer->data; | 1731 | iop_data = (uint8_t __iomem *)pwbuffer->data; |
1501 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) { | 1732 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) { |
@@ -1528,7 +1759,6 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1528 | (uint32_t ) cmd->cmnd[7] << 8 | | 1759 | (uint32_t ) cmd->cmnd[7] << 8 | |
1529 | (uint32_t ) cmd->cmnd[8]; | 1760 | (uint32_t ) cmd->cmnd[8]; |
1530 | /* 4 bytes: Areca io control code */ | 1761 | /* 4 bytes: Areca io control code */ |
1531 | |||
1532 | sg = scsi_sglist(cmd); | 1762 | sg = scsi_sglist(cmd); |
1533 | buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | 1763 | buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; |
1534 | if (scsi_sg_count(cmd) > 1) { | 1764 | if (scsi_sg_count(cmd) > 1) { |
@@ -1554,7 +1784,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1554 | retvalue = ARCMSR_MESSAGE_FAIL; | 1784 | retvalue = ARCMSR_MESSAGE_FAIL; |
1555 | goto message_out; | 1785 | goto message_out; |
1556 | } | 1786 | } |
1557 | 1787 | ||
1558 | ptmpQbuffer = ver_addr; | 1788 | ptmpQbuffer = ver_addr; |
1559 | while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) | 1789 | while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) |
1560 | && (allxfer_len < 1031)) { | 1790 | && (allxfer_len < 1031)) { |
@@ -1586,10 +1816,10 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1586 | } | 1816 | } |
1587 | memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len); | 1817 | memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len); |
1588 | pcmdmessagefld->cmdmessage.Length = allxfer_len; | 1818 | pcmdmessagefld->cmdmessage.Length = allxfer_len; |
1589 | if (acb->fw_flag == FW_DEADLOCK) { | 1819 | if(acb->fw_flag == FW_DEADLOCK) { |
1590 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; | 1820 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; |
1591 | } else { | 1821 | }else{ |
1592 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; | 1822 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; |
1593 | } | 1823 | } |
1594 | kfree(ver_addr); | 1824 | kfree(ver_addr); |
1595 | } | 1825 | } |
@@ -1605,11 +1835,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1605 | retvalue = ARCMSR_MESSAGE_FAIL; | 1835 | retvalue = ARCMSR_MESSAGE_FAIL; |
1606 | goto message_out; | 1836 | goto message_out; |
1607 | } | 1837 | } |
1608 | if (acb->fw_flag == FW_DEADLOCK) { | 1838 | if(acb->fw_flag == FW_DEADLOCK) { |
1609 | pcmdmessagefld->cmdmessage.ReturnCode = | 1839 | pcmdmessagefld->cmdmessage.ReturnCode = |
1610 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; | 1840 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; |
1611 | } else { | 1841 | }else{ |
1612 | pcmdmessagefld->cmdmessage.ReturnCode = | 1842 | pcmdmessagefld->cmdmessage.ReturnCode = |
1613 | ARCMSR_MESSAGE_RETURNCODE_OK; | 1843 | ARCMSR_MESSAGE_RETURNCODE_OK; |
1614 | } | 1844 | } |
1615 | ptmpuserbuffer = ver_addr; | 1845 | ptmpuserbuffer = ver_addr; |
@@ -1672,10 +1902,10 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1672 | acb->rqbuf_firstindex = 0; | 1902 | acb->rqbuf_firstindex = 0; |
1673 | acb->rqbuf_lastindex = 0; | 1903 | acb->rqbuf_lastindex = 0; |
1674 | memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); | 1904 | memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); |
1675 | if (acb->fw_flag == FW_DEADLOCK) { | 1905 | if(acb->fw_flag == FW_DEADLOCK) { |
1676 | pcmdmessagefld->cmdmessage.ReturnCode = | 1906 | pcmdmessagefld->cmdmessage.ReturnCode = |
1677 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; | 1907 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; |
1678 | } else { | 1908 | }else{ |
1679 | pcmdmessagefld->cmdmessage.ReturnCode = | 1909 | pcmdmessagefld->cmdmessage.ReturnCode = |
1680 | ARCMSR_MESSAGE_RETURNCODE_OK; | 1910 | ARCMSR_MESSAGE_RETURNCODE_OK; |
1681 | } | 1911 | } |
@@ -1684,10 +1914,10 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1684 | 1914 | ||
1685 | case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { | 1915 | case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { |
1686 | uint8_t *pQbuffer = acb->wqbuffer; | 1916 | uint8_t *pQbuffer = acb->wqbuffer; |
1687 | if (acb->fw_flag == FW_DEADLOCK) { | 1917 | if(acb->fw_flag == FW_DEADLOCK) { |
1688 | pcmdmessagefld->cmdmessage.ReturnCode = | 1918 | pcmdmessagefld->cmdmessage.ReturnCode = |
1689 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; | 1919 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; |
1690 | } else { | 1920 | }else{ |
1691 | pcmdmessagefld->cmdmessage.ReturnCode = | 1921 | pcmdmessagefld->cmdmessage.ReturnCode = |
1692 | ARCMSR_MESSAGE_RETURNCODE_OK; | 1922 | ARCMSR_MESSAGE_RETURNCODE_OK; |
1693 | } | 1923 | } |
@@ -1724,10 +1954,10 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1724 | memset(pQbuffer, 0, sizeof(struct QBUFFER)); | 1954 | memset(pQbuffer, 0, sizeof(struct QBUFFER)); |
1725 | pQbuffer = acb->wqbuffer; | 1955 | pQbuffer = acb->wqbuffer; |
1726 | memset(pQbuffer, 0, sizeof(struct QBUFFER)); | 1956 | memset(pQbuffer, 0, sizeof(struct QBUFFER)); |
1727 | if (acb->fw_flag == FW_DEADLOCK) { | 1957 | if(acb->fw_flag == FW_DEADLOCK) { |
1728 | pcmdmessagefld->cmdmessage.ReturnCode = | 1958 | pcmdmessagefld->cmdmessage.ReturnCode = |
1729 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; | 1959 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; |
1730 | } else { | 1960 | }else{ |
1731 | pcmdmessagefld->cmdmessage.ReturnCode = | 1961 | pcmdmessagefld->cmdmessage.ReturnCode = |
1732 | ARCMSR_MESSAGE_RETURNCODE_OK; | 1962 | ARCMSR_MESSAGE_RETURNCODE_OK; |
1733 | } | 1963 | } |
@@ -1735,10 +1965,10 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1735 | break; | 1965 | break; |
1736 | 1966 | ||
1737 | case ARCMSR_MESSAGE_RETURN_CODE_3F: { | 1967 | case ARCMSR_MESSAGE_RETURN_CODE_3F: { |
1738 | if (acb->fw_flag == FW_DEADLOCK) { | 1968 | if(acb->fw_flag == FW_DEADLOCK) { |
1739 | pcmdmessagefld->cmdmessage.ReturnCode = | 1969 | pcmdmessagefld->cmdmessage.ReturnCode = |
1740 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; | 1970 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; |
1741 | } else { | 1971 | }else{ |
1742 | pcmdmessagefld->cmdmessage.ReturnCode = | 1972 | pcmdmessagefld->cmdmessage.ReturnCode = |
1743 | ARCMSR_MESSAGE_RETURNCODE_3F; | 1973 | ARCMSR_MESSAGE_RETURNCODE_3F; |
1744 | } | 1974 | } |
@@ -1746,10 +1976,10 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1746 | } | 1976 | } |
1747 | case ARCMSR_MESSAGE_SAY_HELLO: { | 1977 | case ARCMSR_MESSAGE_SAY_HELLO: { |
1748 | int8_t *hello_string = "Hello! I am ARCMSR"; | 1978 | int8_t *hello_string = "Hello! I am ARCMSR"; |
1749 | if (acb->fw_flag == FW_DEADLOCK) { | 1979 | if(acb->fw_flag == FW_DEADLOCK) { |
1750 | pcmdmessagefld->cmdmessage.ReturnCode = | 1980 | pcmdmessagefld->cmdmessage.ReturnCode = |
1751 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; | 1981 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; |
1752 | } else { | 1982 | }else{ |
1753 | pcmdmessagefld->cmdmessage.ReturnCode = | 1983 | pcmdmessagefld->cmdmessage.ReturnCode = |
1754 | ARCMSR_MESSAGE_RETURNCODE_OK; | 1984 | ARCMSR_MESSAGE_RETURNCODE_OK; |
1755 | } | 1985 | } |
@@ -1759,7 +1989,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1759 | break; | 1989 | break; |
1760 | 1990 | ||
1761 | case ARCMSR_MESSAGE_SAY_GOODBYE: | 1991 | case ARCMSR_MESSAGE_SAY_GOODBYE: |
1762 | if (acb->fw_flag == FW_DEADLOCK) { | 1992 | if(acb->fw_flag == FW_DEADLOCK) { |
1763 | pcmdmessagefld->cmdmessage.ReturnCode = | 1993 | pcmdmessagefld->cmdmessage.ReturnCode = |
1764 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; | 1994 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; |
1765 | } | 1995 | } |
@@ -1767,7 +1997,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | |||
1767 | break; | 1997 | break; |
1768 | 1998 | ||
1769 | case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: | 1999 | case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: |
1770 | if (acb->fw_flag == FW_DEADLOCK) { | 2000 | if(acb->fw_flag == FW_DEADLOCK) { |
1771 | pcmdmessagefld->cmdmessage.ReturnCode = | 2001 | pcmdmessagefld->cmdmessage.ReturnCode = |
1772 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; | 2002 | ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; |
1773 | } | 2003 | } |
@@ -1792,7 +2022,7 @@ static struct CommandControlBlock *arcmsr_get_freeccb(struct AdapterControlBlock | |||
1792 | if (!list_empty(head)) { | 2022 | if (!list_empty(head)) { |
1793 | ccb = list_entry(head->next, struct CommandControlBlock, list); | 2023 | ccb = list_entry(head->next, struct CommandControlBlock, list); |
1794 | list_del_init(&ccb->list); | 2024 | list_del_init(&ccb->list); |
1795 | } else { | 2025 | }else{ |
1796 | spin_unlock_irqrestore(&acb->ccblist_lock, flags); | 2026 | spin_unlock_irqrestore(&acb->ccblist_lock, flags); |
1797 | return 0; | 2027 | return 0; |
1798 | } | 2028 | } |
@@ -1862,29 +2092,29 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd, | |||
1862 | cmd->scsi_done = done; | 2092 | cmd->scsi_done = done; |
1863 | cmd->host_scribble = NULL; | 2093 | cmd->host_scribble = NULL; |
1864 | cmd->result = 0; | 2094 | cmd->result = 0; |
1865 | 2095 | if ((scsicmd == SYNCHRONIZE_CACHE) ||(scsicmd == SEND_DIAGNOSTIC)){ | |
1866 | if ((scsicmd == SYNCHRONIZE_CACHE) || (scsicmd == SEND_DIAGNOSTIC)) { | 2096 | if(acb->devstate[target][lun] == ARECA_RAID_GONE) { |
1867 | if (acb->devstate[target][lun] == ARECA_RAID_GONE) { | 2097 | cmd->result = (DID_NO_CONNECT << 16); |
1868 | cmd->result = (DID_NO_CONNECT << 16); | ||
1869 | } | 2098 | } |
1870 | cmd->scsi_done(cmd); | 2099 | cmd->scsi_done(cmd); |
1871 | return 0; | 2100 | return 0; |
1872 | } | 2101 | } |
1873 | |||
1874 | if (target == 16) { | 2102 | if (target == 16) { |
1875 | /* virtual device for iop message transfer */ | 2103 | /* virtual device for iop message transfer */ |
1876 | arcmsr_handle_virtual_command(acb, cmd); | 2104 | arcmsr_handle_virtual_command(acb, cmd); |
1877 | return 0; | 2105 | return 0; |
1878 | } | 2106 | } |
1879 | |||
1880 | if (atomic_read(&acb->ccboutstandingcount) >= | 2107 | if (atomic_read(&acb->ccboutstandingcount) >= |
1881 | ARCMSR_MAX_OUTSTANDING_CMD) | 2108 | ARCMSR_MAX_OUTSTANDING_CMD) |
1882 | return SCSI_MLQUEUE_HOST_BUSY; | 2109 | return SCSI_MLQUEUE_HOST_BUSY; |
1883 | 2110 | if ((scsicmd == SCSI_CMD_ARECA_SPECIFIC)) { | |
2111 | printk(KERN_NOTICE "Receiveing SCSI_CMD_ARECA_SPECIFIC command..\n"); | ||
2112 | return 0; | ||
2113 | } | ||
1884 | ccb = arcmsr_get_freeccb(acb); | 2114 | ccb = arcmsr_get_freeccb(acb); |
1885 | if (!ccb) | 2115 | if (!ccb) |
1886 | return SCSI_MLQUEUE_HOST_BUSY; | 2116 | return SCSI_MLQUEUE_HOST_BUSY; |
1887 | if ( arcmsr_build_ccb( acb, ccb, cmd ) == FAILED ) { | 2117 | if (arcmsr_build_ccb( acb, ccb, cmd ) == FAILED) { |
1888 | cmd->result = (DID_ERROR << 16) | (RESERVATION_CONFLICT << 1); | 2118 | cmd->result = (DID_ERROR << 16) | (RESERVATION_CONFLICT << 1); |
1889 | cmd->scsi_done(cmd); | 2119 | cmd->scsi_done(cmd); |
1890 | return 0; | 2120 | return 0; |
@@ -1901,17 +2131,16 @@ static bool arcmsr_get_hba_config(struct AdapterControlBlock *acb) | |||
1901 | char *acb_device_map = acb->device_map; | 2131 | char *acb_device_map = acb->device_map; |
1902 | char __iomem *iop_firm_model = (char __iomem *)(®->message_rwbuffer[15]); | 2132 | char __iomem *iop_firm_model = (char __iomem *)(®->message_rwbuffer[15]); |
1903 | char __iomem *iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); | 2133 | char __iomem *iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); |
1904 | char __iomem *iop_device_map = (char __iomem *) (®->message_rwbuffer[21]); | 2134 | char __iomem *iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); |
1905 | int count; | 2135 | int count; |
1906 | |||
1907 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); | 2136 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); |
1908 | if (arcmsr_hba_wait_msgint_ready(acb)) { | 2137 | if (!arcmsr_hba_wait_msgint_ready(acb)) { |
1909 | printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ | 2138 | printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ |
1910 | miscellaneous data' timeout \n", acb->host->host_no); | 2139 | miscellaneous data' timeout \n", acb->host->host_no); |
1911 | return false; | 2140 | return false; |
1912 | } | 2141 | } |
1913 | count = 8; | 2142 | count = 8; |
1914 | while (count) { | 2143 | while (count){ |
1915 | *acb_firm_model = readb(iop_firm_model); | 2144 | *acb_firm_model = readb(iop_firm_model); |
1916 | acb_firm_model++; | 2145 | acb_firm_model++; |
1917 | iop_firm_model++; | 2146 | iop_firm_model++; |
@@ -1919,25 +2148,25 @@ static bool arcmsr_get_hba_config(struct AdapterControlBlock *acb) | |||
1919 | } | 2148 | } |
1920 | 2149 | ||
1921 | count = 16; | 2150 | count = 16; |
1922 | while (count) { | 2151 | while (count){ |
1923 | *acb_firm_version = readb(iop_firm_version); | 2152 | *acb_firm_version = readb(iop_firm_version); |
1924 | acb_firm_version++; | 2153 | acb_firm_version++; |
1925 | iop_firm_version++; | 2154 | iop_firm_version++; |
1926 | count--; | 2155 | count--; |
1927 | } | 2156 | } |
1928 | 2157 | ||
1929 | count = 16; | 2158 | count=16; |
1930 | while (count) { | 2159 | while(count){ |
1931 | *acb_device_map = readb(iop_device_map); | 2160 | *acb_device_map = readb(iop_device_map); |
1932 | acb_device_map++; | 2161 | acb_device_map++; |
1933 | iop_device_map++; | 2162 | iop_device_map++; |
1934 | count--; | 2163 | count--; |
1935 | } | 2164 | } |
1936 | printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n", | 2165 | printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n", |
1937 | acb->host->host_no, | 2166 | acb->host->host_no, |
1938 | acb->firm_version, | 2167 | acb->firm_version, |
1939 | acb->firm_model); | 2168 | acb->firm_model); |
1940 | acb->signature = readl(®->message_rwbuffer[0]); | 2169 | acb->signature = readl(®->message_rwbuffer[0]); |
1941 | acb->firm_request_len = readl(®->message_rwbuffer[1]); | 2170 | acb->firm_request_len = readl(®->message_rwbuffer[1]); |
1942 | acb->firm_numbers_queue = readl(®->message_rwbuffer[2]); | 2171 | acb->firm_numbers_queue = readl(®->message_rwbuffer[2]); |
1943 | acb->firm_sdram_size = readl(®->message_rwbuffer[3]); | 2172 | acb->firm_sdram_size = readl(®->message_rwbuffer[3]); |
@@ -1962,14 +2191,14 @@ static bool arcmsr_get_hbb_config(struct AdapterControlBlock *acb) | |||
1962 | /*firm_version,21,84-99*/ | 2191 | /*firm_version,21,84-99*/ |
1963 | int count; | 2192 | int count; |
1964 | dma_coherent = dma_alloc_coherent(&pdev->dev, sizeof(struct MessageUnit_B), &dma_coherent_handle, GFP_KERNEL); | 2193 | dma_coherent = dma_alloc_coherent(&pdev->dev, sizeof(struct MessageUnit_B), &dma_coherent_handle, GFP_KERNEL); |
1965 | if (!dma_coherent) { | 2194 | if (!dma_coherent){ |
1966 | printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error for hbb mu\n", acb->host->host_no); | 2195 | printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error for hbb mu\n", acb->host->host_no); |
1967 | return false; | 2196 | return false; |
1968 | } | 2197 | } |
1969 | acb->dma_coherent_handle_hbb_mu = dma_coherent_handle; | 2198 | acb->dma_coherent_handle_hbb_mu = dma_coherent_handle; |
1970 | reg = (struct MessageUnit_B *)dma_coherent; | 2199 | reg = (struct MessageUnit_B *)dma_coherent; |
1971 | acb->pmuB = reg; | 2200 | acb->pmuB = reg; |
1972 | reg->drv2iop_doorbell = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL); | 2201 | reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL); |
1973 | reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK); | 2202 | reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK); |
1974 | reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL); | 2203 | reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL); |
1975 | reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK); | 2204 | reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK); |
@@ -1981,41 +2210,41 @@ static bool arcmsr_get_hbb_config(struct AdapterControlBlock *acb) | |||
1981 | iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); /*firm_version,21,84-99*/ | 2210 | iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); /*firm_version,21,84-99*/ |
1982 | 2211 | ||
1983 | writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); | 2212 | writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); |
1984 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | 2213 | if (!arcmsr_hbb_wait_msgint_ready(acb)) { |
1985 | printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ | 2214 | printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ |
1986 | miscellaneous data' timeout \n", acb->host->host_no); | 2215 | miscellaneous data' timeout \n", acb->host->host_no); |
1987 | return false; | 2216 | return false; |
1988 | } | 2217 | } |
1989 | count = 8; | 2218 | count = 8; |
1990 | while (count) { | 2219 | while (count){ |
1991 | *acb_firm_model = readb(iop_firm_model); | 2220 | *acb_firm_model = readb(iop_firm_model); |
1992 | acb_firm_model++; | 2221 | acb_firm_model++; |
1993 | iop_firm_model++; | 2222 | iop_firm_model++; |
1994 | count--; | 2223 | count--; |
1995 | } | 2224 | } |
1996 | count = 16; | 2225 | count = 16; |
1997 | while (count) { | 2226 | while (count){ |
1998 | *acb_firm_version = readb(iop_firm_version); | 2227 | *acb_firm_version = readb(iop_firm_version); |
1999 | acb_firm_version++; | 2228 | acb_firm_version++; |
2000 | iop_firm_version++; | 2229 | iop_firm_version++; |
2001 | count--; | 2230 | count--; |
2002 | } | 2231 | } |
2003 | 2232 | ||
2004 | count = 16; | 2233 | count = 16; |
2005 | while (count) { | 2234 | while(count){ |
2006 | *acb_device_map = readb(iop_device_map); | 2235 | *acb_device_map = readb(iop_device_map); |
2007 | acb_device_map++; | 2236 | acb_device_map++; |
2008 | iop_device_map++; | 2237 | iop_device_map++; |
2009 | count--; | 2238 | count--; |
2010 | } | 2239 | } |
2011 | 2240 | ||
2012 | printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n", | 2241 | printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n", |
2013 | acb->host->host_no, | 2242 | acb->host->host_no, |
2014 | acb->firm_version, | 2243 | acb->firm_version, |
2015 | acb->firm_model); | 2244 | acb->firm_model); |
2016 | 2245 | ||
2017 | acb->signature = readl(®->message_rwbuffer[1]); | 2246 | acb->signature = readl(®->message_rwbuffer[1]); |
2018 | /*firm_signature,1,00-03*/ | 2247 | /*firm_signature,1,00-03*/ |
2019 | acb->firm_request_len = readl(®->message_rwbuffer[2]); | 2248 | acb->firm_request_len = readl(®->message_rwbuffer[2]); |
2020 | /*firm_request_len,1,04-07*/ | 2249 | /*firm_request_len,1,04-07*/ |
2021 | acb->firm_numbers_queue = readl(®->message_rwbuffer[3]); | 2250 | acb->firm_numbers_queue = readl(®->message_rwbuffer[3]); |
@@ -2028,12 +2257,73 @@ static bool arcmsr_get_hbb_config(struct AdapterControlBlock *acb) | |||
2028 | /*firm_ide_channels,4,16-19*/ | 2257 | /*firm_ide_channels,4,16-19*/ |
2029 | return true; | 2258 | return true; |
2030 | } | 2259 | } |
2260 | |||
2261 | static bool arcmsr_get_hbc_config(struct AdapterControlBlock *pACB) | ||
2262 | { | ||
2263 | uint32_t intmask_org, Index, firmware_state = 0; | ||
2264 | struct MessageUnit_C *reg = pACB->pmuC; | ||
2265 | char *acb_firm_model = pACB->firm_model; | ||
2266 | char *acb_firm_version = pACB->firm_version; | ||
2267 | char *iop_firm_model = (char *)(®->msgcode_rwbuffer[15]); /*firm_model,15,60-67*/ | ||
2268 | char *iop_firm_version = (char *)(®->msgcode_rwbuffer[17]); /*firm_version,17,68-83*/ | ||
2269 | int count; | ||
2270 | /* disable all outbound interrupt */ | ||
2271 | intmask_org = readl(®->host_int_mask); /* disable outbound message0 int */ | ||
2272 | writel(intmask_org|ARCMSR_HBCMU_ALL_INTMASKENABLE, ®->host_int_mask); | ||
2273 | /* wait firmware ready */ | ||
2274 | do { | ||
2275 | firmware_state = readl(®->outbound_msgaddr1); | ||
2276 | } while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0); | ||
2277 | /* post "get config" instruction */ | ||
2278 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); | ||
2279 | writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); | ||
2280 | /* wait message ready */ | ||
2281 | for (Index = 0; Index < 2000; Index++) { | ||
2282 | if (readl(®->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { | ||
2283 | writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, ®->outbound_doorbell_clear);/*clear interrupt*/ | ||
2284 | break; | ||
2285 | } | ||
2286 | udelay(10); | ||
2287 | } /*max 1 seconds*/ | ||
2288 | if (Index >= 2000) { | ||
2289 | printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ | ||
2290 | miscellaneous data' timeout \n", pACB->host->host_no); | ||
2291 | return false; | ||
2292 | } | ||
2293 | count = 8; | ||
2294 | while (count) { | ||
2295 | *acb_firm_model = readb(iop_firm_model); | ||
2296 | acb_firm_model++; | ||
2297 | iop_firm_model++; | ||
2298 | count--; | ||
2299 | } | ||
2300 | count = 16; | ||
2301 | while (count) { | ||
2302 | *acb_firm_version = readb(iop_firm_version); | ||
2303 | acb_firm_version++; | ||
2304 | iop_firm_version++; | ||
2305 | count--; | ||
2306 | } | ||
2307 | printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n", | ||
2308 | pACB->host->host_no, | ||
2309 | pACB->firm_version, | ||
2310 | pACB->firm_model); | ||
2311 | pACB->firm_request_len = readl(®->msgcode_rwbuffer[1]); /*firm_request_len,1,04-07*/ | ||
2312 | pACB->firm_numbers_queue = readl(®->msgcode_rwbuffer[2]); /*firm_numbers_queue,2,08-11*/ | ||
2313 | pACB->firm_sdram_size = readl(®->msgcode_rwbuffer[3]); /*firm_sdram_size,3,12-15*/ | ||
2314 | pACB->firm_hd_channels = readl(®->msgcode_rwbuffer[4]); /*firm_ide_channels,4,16-19*/ | ||
2315 | pACB->firm_cfg_version = readl(®->msgcode_rwbuffer[25]); /*firm_cfg_version,25,100-103*/ | ||
2316 | /*all interrupt service will be enable at arcmsr_iop_init*/ | ||
2317 | return true; | ||
2318 | } | ||
2031 | static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) | 2319 | static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) |
2032 | { | 2320 | { |
2033 | if (acb->adapter_type == ACB_ADAPTER_TYPE_A) | 2321 | if (acb->adapter_type == ACB_ADAPTER_TYPE_A) |
2034 | return arcmsr_get_hba_config(acb); | 2322 | return arcmsr_get_hba_config(acb); |
2035 | else | 2323 | else if (acb->adapter_type == ACB_ADAPTER_TYPE_B) |
2036 | return arcmsr_get_hbb_config(acb); | 2324 | return arcmsr_get_hbb_config(acb); |
2325 | else | ||
2326 | return arcmsr_get_hbc_config(acb); | ||
2037 | } | 2327 | } |
2038 | 2328 | ||
2039 | static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb, | 2329 | static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb, |
@@ -2044,18 +2334,19 @@ static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb, | |||
2044 | struct ARCMSR_CDB *arcmsr_cdb; | 2334 | struct ARCMSR_CDB *arcmsr_cdb; |
2045 | uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0; | 2335 | uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0; |
2046 | int rtn; | 2336 | int rtn; |
2047 | 2337 | bool error; | |
2048 | polling_hba_ccb_retry: | 2338 | polling_hba_ccb_retry: |
2049 | poll_count++; | 2339 | poll_count++; |
2050 | outbound_intstatus = readl(®->outbound_intstatus) & acb->outbound_int_enable; | 2340 | outbound_intstatus = readl(®->outbound_intstatus) & acb->outbound_int_enable; |
2051 | writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ | 2341 | writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ |
2052 | while (1) { | 2342 | while (1) { |
2053 | if ((flag_ccb = readl(®->outbound_queueport)) == 0xFFFFFFFF) { | 2343 | if ((flag_ccb = readl(®->outbound_queueport)) == 0xFFFFFFFF) { |
2054 | if (poll_ccb_done) { | 2344 | if (poll_ccb_done){ |
2055 | rtn = SUCCESS; | 2345 | rtn = SUCCESS; |
2056 | break; | 2346 | break; |
2057 | } else { | 2347 | }else { |
2058 | if (poll_count > 100) { | 2348 | msleep(25); |
2349 | if (poll_count > 100){ | ||
2059 | rtn = FAILED; | 2350 | rtn = FAILED; |
2060 | break; | 2351 | break; |
2061 | } | 2352 | } |
@@ -2084,76 +2375,132 @@ static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb, | |||
2084 | , ccb | 2375 | , ccb |
2085 | , atomic_read(&acb->ccboutstandingcount)); | 2376 | , atomic_read(&acb->ccboutstandingcount)); |
2086 | continue; | 2377 | continue; |
2087 | } else { | 2378 | } |
2088 | arcmsr_report_ccb_state(acb, ccb, flag_ccb); | 2379 | error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false; |
2380 | arcmsr_report_ccb_state(acb, ccb, error); | ||
2089 | } | 2381 | } |
2090 | } | ||
2091 | return rtn; | 2382 | return rtn; |
2092 | } | 2383 | } |
2093 | 2384 | ||
2094 | static int arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, | 2385 | static int arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, |
2095 | struct CommandControlBlock *poll_ccb) | 2386 | struct CommandControlBlock *poll_ccb) |
2096 | { | 2387 | { |
2097 | struct MessageUnit_B *reg = acb->pmuB; | 2388 | struct MessageUnit_B *reg = acb->pmuB; |
2098 | struct ARCMSR_CDB *arcmsr_cdb; | 2389 | struct ARCMSR_CDB *arcmsr_cdb; |
2099 | struct CommandControlBlock *ccb; | 2390 | struct CommandControlBlock *ccb; |
2100 | uint32_t flag_ccb, poll_ccb_done = 0, poll_count = 0; | 2391 | uint32_t flag_ccb, poll_ccb_done = 0, poll_count = 0; |
2101 | int index, rtn; | 2392 | int index, rtn; |
2102 | 2393 | bool error; | |
2103 | polling_hbb_ccb_retry: | 2394 | polling_hbb_ccb_retry: |
2104 | poll_count++; | 2395 | poll_count++; |
2105 | /* clear doorbell interrupt */ | 2396 | /* clear doorbell interrupt */ |
2106 | writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); | 2397 | writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); |
2107 | while (1) { | 2398 | while(1){ |
2108 | index = reg->doneq_index; | 2399 | index = reg->doneq_index; |
2109 | if ((flag_ccb = readl(®->done_qbuffer[index])) == 0) { | 2400 | if ((flag_ccb = readl(®->done_qbuffer[index])) == 0) { |
2110 | if (poll_ccb_done) { | 2401 | if (poll_ccb_done){ |
2111 | rtn = SUCCESS; | 2402 | rtn = SUCCESS; |
2112 | break; | 2403 | break; |
2113 | } else { | 2404 | }else { |
2114 | msleep(25); | 2405 | msleep(25); |
2115 | if (poll_count > 100) { | 2406 | if (poll_count > 100){ |
2116 | rtn = FAILED; | 2407 | rtn = FAILED; |
2117 | break; | 2408 | break; |
2118 | } | ||
2119 | goto polling_hbb_ccb_retry; | ||
2120 | } | 2409 | } |
2410 | goto polling_hbb_ccb_retry; | ||
2121 | } | 2411 | } |
2122 | writel(0, ®->done_qbuffer[index]); | 2412 | } |
2123 | index++; | 2413 | writel(0, ®->done_qbuffer[index]); |
2124 | /*if last index number set it to 0 */ | 2414 | index++; |
2125 | index %= ARCMSR_MAX_HBB_POSTQUEUE; | 2415 | /*if last index number set it to 0 */ |
2126 | reg->doneq_index = index; | 2416 | index %= ARCMSR_MAX_HBB_POSTQUEUE; |
2127 | /* check ifcommand done with no error*/ | 2417 | reg->doneq_index = index; |
2418 | /* check if command done with no error*/ | ||
2128 | arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5)); | 2419 | arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5)); |
2129 | ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb); | 2420 | ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb); |
2130 | poll_ccb_done = (ccb == poll_ccb) ? 1:0; | 2421 | poll_ccb_done = (ccb == poll_ccb) ? 1:0; |
2131 | if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { | 2422 | if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { |
2132 | if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == poll_ccb)) { | 2423 | if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == poll_ccb)) { |
2133 | printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'" | 2424 | printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'" |
2134 | " poll command abort successfully \n" | 2425 | " poll command abort successfully \n" |
2135 | ,acb->host->host_no | 2426 | ,acb->host->host_no |
2136 | ,ccb->pcmd->device->id | 2427 | ,ccb->pcmd->device->id |
2137 | ,ccb->pcmd->device->lun | 2428 | ,ccb->pcmd->device->lun |
2138 | ,ccb); | 2429 | ,ccb); |
2139 | ccb->pcmd->result = DID_ABORT << 16; | 2430 | ccb->pcmd->result = DID_ABORT << 16; |
2140 | arcmsr_ccb_complete(ccb); | 2431 | arcmsr_ccb_complete(ccb); |
2141 | continue; | 2432 | continue; |
2433 | } | ||
2434 | printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb" | ||
2435 | " command done ccb = '0x%p'" | ||
2436 | "ccboutstandingcount = %d \n" | ||
2437 | , acb->host->host_no | ||
2438 | , ccb | ||
2439 | , atomic_read(&acb->ccboutstandingcount)); | ||
2440 | continue; | ||
2441 | } | ||
2442 | error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false; | ||
2443 | arcmsr_report_ccb_state(acb, ccb, error); | ||
2444 | } | ||
2445 | return rtn; | ||
2446 | } | ||
2447 | |||
2448 | static int arcmsr_polling_hbc_ccbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_ccb) | ||
2449 | { | ||
2450 | struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC; | ||
2451 | uint32_t flag_ccb, ccb_cdb_phy; | ||
2452 | struct ARCMSR_CDB *arcmsr_cdb; | ||
2453 | bool error; | ||
2454 | struct CommandControlBlock *pCCB; | ||
2455 | uint32_t poll_ccb_done = 0, poll_count = 0; | ||
2456 | int rtn; | ||
2457 | polling_hbc_ccb_retry: | ||
2458 | poll_count++; | ||
2459 | while (1) { | ||
2460 | if ((readl(®->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) == 0) { | ||
2461 | if (poll_ccb_done) { | ||
2462 | rtn = SUCCESS; | ||
2463 | break; | ||
2464 | } else { | ||
2465 | msleep(25); | ||
2466 | if (poll_count > 100) { | ||
2467 | rtn = FAILED; | ||
2468 | break; | ||
2142 | } | 2469 | } |
2143 | printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb" | 2470 | goto polling_hbc_ccb_retry; |
2144 | " command done ccb = '0x%p'" | 2471 | } |
2145 | "ccboutstandingcount = %d \n" | 2472 | } |
2473 | flag_ccb = readl(®->outbound_queueport_low); | ||
2474 | ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0); | ||
2475 | arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);/*frame must be 32 bytes aligned*/ | ||
2476 | pCCB = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb); | ||
2477 | poll_ccb_done = (pCCB == poll_ccb) ? 1 : 0; | ||
2478 | /* check ifcommand done with no error*/ | ||
2479 | if ((pCCB->acb != acb) || (pCCB->startdone != ARCMSR_CCB_START)) { | ||
2480 | if (pCCB->startdone == ARCMSR_CCB_ABORTED) { | ||
2481 | printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'" | ||
2482 | " poll command abort successfully \n" | ||
2146 | , acb->host->host_no | 2483 | , acb->host->host_no |
2147 | , ccb | 2484 | , pCCB->pcmd->device->id |
2148 | , atomic_read(&acb->ccboutstandingcount)); | 2485 | , pCCB->pcmd->device->lun |
2486 | , pCCB); | ||
2487 | pCCB->pcmd->result = DID_ABORT << 16; | ||
2488 | arcmsr_ccb_complete(pCCB); | ||
2149 | continue; | 2489 | continue; |
2150 | } else { | 2490 | } |
2151 | arcmsr_report_ccb_state(acb, ccb, flag_ccb); | 2491 | printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb" |
2492 | " command done ccb = '0x%p'" | ||
2493 | "ccboutstandingcount = %d \n" | ||
2494 | , acb->host->host_no | ||
2495 | , pCCB | ||
2496 | , atomic_read(&acb->ccboutstandingcount)); | ||
2497 | continue; | ||
2152 | } | 2498 | } |
2153 | } /*drain reply FIFO*/ | 2499 | error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false; |
2500 | arcmsr_report_ccb_state(acb, pCCB, error); | ||
2501 | } | ||
2154 | return rtn; | 2502 | return rtn; |
2155 | } | 2503 | } |
2156 | |||
2157 | static int arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, | 2504 | static int arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, |
2158 | struct CommandControlBlock *poll_ccb) | 2505 | struct CommandControlBlock *poll_ccb) |
2159 | { | 2506 | { |
@@ -2168,6 +2515,10 @@ static int arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, | |||
2168 | case ACB_ADAPTER_TYPE_B: { | 2515 | case ACB_ADAPTER_TYPE_B: { |
2169 | rtn = arcmsr_polling_hbb_ccbdone(acb, poll_ccb); | 2516 | rtn = arcmsr_polling_hbb_ccbdone(acb, poll_ccb); |
2170 | } | 2517 | } |
2518 | break; | ||
2519 | case ACB_ADAPTER_TYPE_C: { | ||
2520 | rtn = arcmsr_polling_hbc_ccbdone(acb, poll_ccb); | ||
2521 | } | ||
2171 | } | 2522 | } |
2172 | return rtn; | 2523 | return rtn; |
2173 | } | 2524 | } |
@@ -2185,6 +2536,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) | |||
2185 | dma_coherent_handle = acb->dma_coherent_handle; | 2536 | dma_coherent_handle = acb->dma_coherent_handle; |
2186 | cdb_phyaddr = (uint32_t)(dma_coherent_handle); | 2537 | cdb_phyaddr = (uint32_t)(dma_coherent_handle); |
2187 | cdb_phyaddr_hi32 = (uint32_t)((cdb_phyaddr >> 16) >> 16); | 2538 | cdb_phyaddr_hi32 = (uint32_t)((cdb_phyaddr >> 16) >> 16); |
2539 | acb->cdb_phyaddr_hi32 = cdb_phyaddr_hi32; | ||
2188 | /* | 2540 | /* |
2189 | *********************************************************************** | 2541 | *********************************************************************** |
2190 | ** if adapter type B, set window of "post command Q" | 2542 | ** if adapter type B, set window of "post command Q" |
@@ -2202,7 +2554,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) | |||
2202 | writel(cdb_phyaddr_hi32, ®->message_rwbuffer[1]); | 2554 | writel(cdb_phyaddr_hi32, ®->message_rwbuffer[1]); |
2203 | writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, \ | 2555 | writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, \ |
2204 | ®->inbound_msgaddr0); | 2556 | ®->inbound_msgaddr0); |
2205 | if (arcmsr_hba_wait_msgint_ready(acb)) { | 2557 | if (!arcmsr_hba_wait_msgint_ready(acb)) { |
2206 | printk(KERN_NOTICE "arcmsr%d: ""set ccb high \ | 2558 | printk(KERN_NOTICE "arcmsr%d: ""set ccb high \ |
2207 | part physical address timeout\n", | 2559 | part physical address timeout\n", |
2208 | acb->host->host_no); | 2560 | acb->host->host_no); |
@@ -2223,7 +2575,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) | |||
2223 | reg->postq_index = 0; | 2575 | reg->postq_index = 0; |
2224 | reg->doneq_index = 0; | 2576 | reg->doneq_index = 0; |
2225 | writel(ARCMSR_MESSAGE_SET_POST_WINDOW, reg->drv2iop_doorbell); | 2577 | writel(ARCMSR_MESSAGE_SET_POST_WINDOW, reg->drv2iop_doorbell); |
2226 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | 2578 | if (!arcmsr_hbb_wait_msgint_ready(acb)) { |
2227 | printk(KERN_NOTICE "arcmsr%d:can not set diver mode\n", \ | 2579 | printk(KERN_NOTICE "arcmsr%d:can not set diver mode\n", \ |
2228 | acb->host->host_no); | 2580 | acb->host->host_no); |
2229 | return 1; | 2581 | return 1; |
@@ -2242,7 +2594,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) | |||
2242 | writel(1056, rwbuffer); | 2594 | writel(1056, rwbuffer); |
2243 | 2595 | ||
2244 | writel(ARCMSR_MESSAGE_SET_CONFIG, reg->drv2iop_doorbell); | 2596 | writel(ARCMSR_MESSAGE_SET_CONFIG, reg->drv2iop_doorbell); |
2245 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | 2597 | if (!arcmsr_hbb_wait_msgint_ready(acb)) { |
2246 | printk(KERN_NOTICE "arcmsr%d: 'set command Q window' \ | 2598 | printk(KERN_NOTICE "arcmsr%d: 'set command Q window' \ |
2247 | timeout \n",acb->host->host_no); | 2599 | timeout \n",acb->host->host_no); |
2248 | return 1; | 2600 | return 1; |
@@ -2251,6 +2603,27 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) | |||
2251 | arcmsr_enable_outbound_ints(acb, intmask_org); | 2603 | arcmsr_enable_outbound_ints(acb, intmask_org); |
2252 | } | 2604 | } |
2253 | break; | 2605 | break; |
2606 | case ACB_ADAPTER_TYPE_C: { | ||
2607 | if (cdb_phyaddr_hi32 != 0) { | ||
2608 | struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC; | ||
2609 | |||
2610 | if (cdb_phyaddr_hi32 != 0) { | ||
2611 | unsigned char Retries = 0x00; | ||
2612 | do { | ||
2613 | printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x \n", acb->adapter_index, cdb_phyaddr_hi32); | ||
2614 | } while (Retries++ < 100); | ||
2615 | } | ||
2616 | writel(ARCMSR_SIGNATURE_SET_CONFIG, ®->msgcode_rwbuffer[0]); | ||
2617 | writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[1]); | ||
2618 | writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); | ||
2619 | writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); | ||
2620 | if (!arcmsr_hbc_wait_msgint_ready(acb)) { | ||
2621 | printk(KERN_NOTICE "arcmsr%d: 'set command Q window' \ | ||
2622 | timeout \n", acb->host->host_no); | ||
2623 | return 1; | ||
2624 | } | ||
2625 | } | ||
2626 | } | ||
2254 | } | 2627 | } |
2255 | return 0; | 2628 | return 0; |
2256 | } | 2629 | } |
@@ -2258,7 +2631,6 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) | |||
2258 | static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) | 2631 | static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) |
2259 | { | 2632 | { |
2260 | uint32_t firmware_state = 0; | 2633 | uint32_t firmware_state = 0; |
2261 | |||
2262 | switch (acb->adapter_type) { | 2634 | switch (acb->adapter_type) { |
2263 | 2635 | ||
2264 | case ACB_ADAPTER_TYPE_A: { | 2636 | case ACB_ADAPTER_TYPE_A: { |
@@ -2277,24 +2649,30 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) | |||
2277 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); | 2649 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); |
2278 | } | 2650 | } |
2279 | break; | 2651 | break; |
2652 | case ACB_ADAPTER_TYPE_C: { | ||
2653 | struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC; | ||
2654 | do { | ||
2655 | firmware_state = readl(®->outbound_msgaddr1); | ||
2656 | } while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0); | ||
2657 | } | ||
2280 | } | 2658 | } |
2281 | } | 2659 | } |
2282 | 2660 | ||
2283 | static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb) | 2661 | static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb) |
2284 | { | 2662 | { |
2285 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 2663 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
2286 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0) || ((acb->acb_flags & ACB_F_ABORT) != 0)) { | 2664 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){ |
2287 | return; | 2665 | return; |
2288 | } else { | 2666 | } else { |
2289 | acb->fw_flag = FW_NORMAL; | 2667 | acb->fw_flag = FW_NORMAL; |
2290 | if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) { | 2668 | if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)){ |
2291 | atomic_set(&acb->rq_map_token, 16); | 2669 | atomic_set(&acb->rq_map_token, 16); |
2292 | } | 2670 | } |
2293 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); | 2671 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); |
2294 | if (atomic_dec_and_test(&acb->rq_map_token)) | 2672 | if (atomic_dec_and_test(&acb->rq_map_token)) |
2295 | return; | 2673 | return; |
2296 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); | 2674 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); |
2297 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); | 2675 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); |
2298 | } | 2676 | } |
2299 | return; | 2677 | return; |
2300 | } | 2678 | } |
@@ -2302,7 +2680,25 @@ static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb) | |||
2302 | static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb) | 2680 | static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb) |
2303 | { | 2681 | { |
2304 | struct MessageUnit_B __iomem *reg = acb->pmuB; | 2682 | struct MessageUnit_B __iomem *reg = acb->pmuB; |
2683 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){ | ||
2684 | return; | ||
2685 | } else { | ||
2686 | acb->fw_flag = FW_NORMAL; | ||
2687 | if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) { | ||
2688 | atomic_set(&acb->rq_map_token,16); | ||
2689 | } | ||
2690 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); | ||
2691 | if(atomic_dec_and_test(&acb->rq_map_token)) | ||
2692 | return; | ||
2693 | writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); | ||
2694 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | ||
2695 | } | ||
2696 | return; | ||
2697 | } | ||
2305 | 2698 | ||
2699 | static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb) | ||
2700 | { | ||
2701 | struct MessageUnit_C __iomem *reg = acb->pmuC; | ||
2306 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0) || ((acb->acb_flags & ACB_F_ABORT) != 0)) { | 2702 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0) || ((acb->acb_flags & ACB_F_ABORT) != 0)) { |
2307 | return; | 2703 | return; |
2308 | } else { | 2704 | } else { |
@@ -2313,8 +2709,9 @@ static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb) | |||
2313 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); | 2709 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); |
2314 | if (atomic_dec_and_test(&acb->rq_map_token)) | 2710 | if (atomic_dec_and_test(&acb->rq_map_token)) |
2315 | return; | 2711 | return; |
2316 | writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); | 2712 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); |
2317 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); | 2713 | writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); |
2714 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | ||
2318 | } | 2715 | } |
2319 | return; | 2716 | return; |
2320 | } | 2717 | } |
@@ -2322,7 +2719,6 @@ static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb) | |||
2322 | static void arcmsr_request_device_map(unsigned long pacb) | 2719 | static void arcmsr_request_device_map(unsigned long pacb) |
2323 | { | 2720 | { |
2324 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *)pacb; | 2721 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *)pacb; |
2325 | |||
2326 | switch (acb->adapter_type) { | 2722 | switch (acb->adapter_type) { |
2327 | case ACB_ADAPTER_TYPE_A: { | 2723 | case ACB_ADAPTER_TYPE_A: { |
2328 | arcmsr_request_hba_device_map(acb); | 2724 | arcmsr_request_hba_device_map(acb); |
@@ -2332,6 +2728,9 @@ static void arcmsr_request_device_map(unsigned long pacb) | |||
2332 | arcmsr_request_hbb_device_map(acb); | 2728 | arcmsr_request_hbb_device_map(acb); |
2333 | } | 2729 | } |
2334 | break; | 2730 | break; |
2731 | case ACB_ADAPTER_TYPE_C: { | ||
2732 | arcmsr_request_hbc_device_map(acb); | ||
2733 | } | ||
2335 | } | 2734 | } |
2336 | } | 2735 | } |
2337 | 2736 | ||
@@ -2340,7 +2739,7 @@ static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb) | |||
2340 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 2739 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
2341 | acb->acb_flags |= ACB_F_MSG_START_BGRB; | 2740 | acb->acb_flags |= ACB_F_MSG_START_BGRB; |
2342 | writel(ARCMSR_INBOUND_MESG0_START_BGRB, ®->inbound_msgaddr0); | 2741 | writel(ARCMSR_INBOUND_MESG0_START_BGRB, ®->inbound_msgaddr0); |
2343 | if (arcmsr_hba_wait_msgint_ready(acb)) { | 2742 | if (!arcmsr_hba_wait_msgint_ready(acb)) { |
2344 | printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \ | 2743 | printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \ |
2345 | rebulid' timeout \n", acb->host->host_no); | 2744 | rebulid' timeout \n", acb->host->host_no); |
2346 | } | 2745 | } |
@@ -2351,12 +2750,24 @@ static void arcmsr_start_hbb_bgrb(struct AdapterControlBlock *acb) | |||
2351 | struct MessageUnit_B *reg = acb->pmuB; | 2750 | struct MessageUnit_B *reg = acb->pmuB; |
2352 | acb->acb_flags |= ACB_F_MSG_START_BGRB; | 2751 | acb->acb_flags |= ACB_F_MSG_START_BGRB; |
2353 | writel(ARCMSR_MESSAGE_START_BGRB, reg->drv2iop_doorbell); | 2752 | writel(ARCMSR_MESSAGE_START_BGRB, reg->drv2iop_doorbell); |
2354 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | 2753 | if (!arcmsr_hbb_wait_msgint_ready(acb)) { |
2355 | printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \ | 2754 | printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \ |
2356 | rebulid' timeout \n",acb->host->host_no); | 2755 | rebulid' timeout \n",acb->host->host_no); |
2357 | } | 2756 | } |
2358 | } | 2757 | } |
2359 | 2758 | ||
2759 | static void arcmsr_start_hbc_bgrb(struct AdapterControlBlock *pACB) | ||
2760 | { | ||
2761 | struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC; | ||
2762 | pACB->acb_flags |= ACB_F_MSG_START_BGRB; | ||
2763 | writel(ARCMSR_INBOUND_MESG0_START_BGRB, &phbcmu->inbound_msgaddr0); | ||
2764 | writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, &phbcmu->inbound_doorbell); | ||
2765 | if (!arcmsr_hbc_wait_msgint_ready(pACB)) { | ||
2766 | printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \ | ||
2767 | rebulid' timeout \n", pACB->host->host_no); | ||
2768 | } | ||
2769 | return; | ||
2770 | } | ||
2360 | static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb) | 2771 | static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb) |
2361 | { | 2772 | { |
2362 | switch (acb->adapter_type) { | 2773 | switch (acb->adapter_type) { |
@@ -2366,6 +2777,8 @@ static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb) | |||
2366 | case ACB_ADAPTER_TYPE_B: | 2777 | case ACB_ADAPTER_TYPE_B: |
2367 | arcmsr_start_hbb_bgrb(acb); | 2778 | arcmsr_start_hbb_bgrb(acb); |
2368 | break; | 2779 | break; |
2780 | case ACB_ADAPTER_TYPE_C: | ||
2781 | arcmsr_start_hbc_bgrb(acb); | ||
2369 | } | 2782 | } |
2370 | } | 2783 | } |
2371 | 2784 | ||
@@ -2391,6 +2804,14 @@ static void arcmsr_clear_doorbell_queue_buffer(struct AdapterControlBlock *acb) | |||
2391 | /* let IOP know data has been read */ | 2804 | /* let IOP know data has been read */ |
2392 | } | 2805 | } |
2393 | break; | 2806 | break; |
2807 | case ACB_ADAPTER_TYPE_C: { | ||
2808 | struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC; | ||
2809 | uint32_t outbound_doorbell; | ||
2810 | /* empty doorbell Qbuffer if door bell ringed */ | ||
2811 | outbound_doorbell = readl(®->outbound_doorbell); | ||
2812 | writel(outbound_doorbell, ®->outbound_doorbell_clear); | ||
2813 | writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, ®->inbound_doorbell); | ||
2814 | } | ||
2394 | } | 2815 | } |
2395 | } | 2816 | } |
2396 | 2817 | ||
@@ -2403,12 +2824,14 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb) | |||
2403 | { | 2824 | { |
2404 | struct MessageUnit_B *reg = acb->pmuB; | 2825 | struct MessageUnit_B *reg = acb->pmuB; |
2405 | writel(ARCMSR_MESSAGE_ACTIVE_EOI_MODE, reg->drv2iop_doorbell); | 2826 | writel(ARCMSR_MESSAGE_ACTIVE_EOI_MODE, reg->drv2iop_doorbell); |
2406 | if(arcmsr_hbb_wait_msgint_ready(acb)) { | 2827 | if (!arcmsr_hbb_wait_msgint_ready(acb)) { |
2407 | printk(KERN_NOTICE "ARCMSR IOP enables EOI_MODE TIMEOUT"); | 2828 | printk(KERN_NOTICE "ARCMSR IOP enables EOI_MODE TIMEOUT"); |
2408 | return; | 2829 | return; |
2409 | } | 2830 | } |
2410 | } | 2831 | } |
2411 | break; | 2832 | break; |
2833 | case ACB_ADAPTER_TYPE_C: | ||
2834 | return; | ||
2412 | } | 2835 | } |
2413 | return; | 2836 | return; |
2414 | } | 2837 | } |
@@ -2416,21 +2839,33 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb) | |||
2416 | static void arcmsr_hardware_reset(struct AdapterControlBlock *acb) | 2839 | static void arcmsr_hardware_reset(struct AdapterControlBlock *acb) |
2417 | { | 2840 | { |
2418 | uint8_t value[64]; | 2841 | uint8_t value[64]; |
2419 | int i; | 2842 | int i, count = 0; |
2420 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 2843 | struct MessageUnit_A __iomem *pmuA = acb->pmuA; |
2421 | 2844 | struct MessageUnit_C __iomem *pmuC = acb->pmuC; | |
2845 | u32 temp = 0; | ||
2422 | /* backup pci config data */ | 2846 | /* backup pci config data */ |
2423 | printk(KERN_ERR "arcmsr%d: executing hw bus reset .....\n", acb->host->host_no); | 2847 | printk(KERN_NOTICE "arcmsr%d: executing hw bus reset .....\n", acb->host->host_no); |
2424 | for (i = 0; i < 64; i++) { | 2848 | for (i = 0; i < 64; i++) { |
2425 | pci_read_config_byte(acb->pdev, i, &value[i]); | 2849 | pci_read_config_byte(acb->pdev, i, &value[i]); |
2426 | } | 2850 | } |
2427 | /* hardware reset signal */ | 2851 | /* hardware reset signal */ |
2428 | if ((acb->dev_id == 0x1680)) { | 2852 | if ((acb->dev_id == 0x1680)) { |
2429 | writel(ARCMSR_ARC1680_BUS_RESET, ®->reserved1[0]); | 2853 | writel(ARCMSR_ARC1680_BUS_RESET, &pmuA->reserved1[0]); |
2854 | } else if ((acb->dev_id == 0x1880)) { | ||
2855 | do { | ||
2856 | count++; | ||
2857 | writel(0xF, &pmuC->write_sequence); | ||
2858 | writel(0x4, &pmuC->write_sequence); | ||
2859 | writel(0xB, &pmuC->write_sequence); | ||
2860 | writel(0x2, &pmuC->write_sequence); | ||
2861 | writel(0x7, &pmuC->write_sequence); | ||
2862 | writel(0xD, &pmuC->write_sequence); | ||
2863 | } while ((((temp = readl(&pmuC->host_diagnostic)) | ARCMSR_ARC1880_DiagWrite_ENABLE) == 0) && (count < 5)); | ||
2864 | writel(ARCMSR_ARC1880_RESET_ADAPTER, &pmuC->host_diagnostic); | ||
2430 | } else { | 2865 | } else { |
2431 | pci_write_config_byte(acb->pdev, 0x84, 0x20); | 2866 | pci_write_config_byte(acb->pdev, 0x84, 0x20); |
2432 | } | 2867 | } |
2433 | msleep(1000); | 2868 | msleep(2000); |
2434 | /* write back pci config data */ | 2869 | /* write back pci config data */ |
2435 | for (i = 0; i < 64; i++) { | 2870 | for (i = 0; i < 64; i++) { |
2436 | pci_write_config_byte(acb->pdev, i, value[i]); | 2871 | pci_write_config_byte(acb->pdev, i, value[i]); |
@@ -2438,35 +2873,11 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb) | |||
2438 | msleep(1000); | 2873 | msleep(1000); |
2439 | return; | 2874 | return; |
2440 | } | 2875 | } |
2441 | /* | ||
2442 | **************************************************************************** | ||
2443 | **************************************************************************** | ||
2444 | */ | ||
2445 | int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd) | ||
2446 | { | ||
2447 | struct Scsi_Host *shost = NULL; | ||
2448 | int i, isleep; | ||
2449 | |||
2450 | shost = cmd->device->host; | ||
2451 | isleep = sleeptime / 10; | ||
2452 | if (isleep > 0) { | ||
2453 | for (i = 0; i < isleep; i++) { | ||
2454 | msleep(10000); | ||
2455 | } | ||
2456 | } | ||
2457 | |||
2458 | isleep = sleeptime % 10; | ||
2459 | if (isleep > 0) { | ||
2460 | msleep(isleep * 1000); | ||
2461 | } | ||
2462 | return 0; | ||
2463 | } | ||
2464 | static void arcmsr_iop_init(struct AdapterControlBlock *acb) | 2876 | static void arcmsr_iop_init(struct AdapterControlBlock *acb) |
2465 | { | 2877 | { |
2466 | uint32_t intmask_org; | 2878 | uint32_t intmask_org; |
2467 | 2879 | /* disable all outbound interrupt */ | |
2468 | /* disable all outbound interrupt */ | 2880 | intmask_org = arcmsr_disable_outbound_ints(acb); |
2469 | intmask_org = arcmsr_disable_outbound_ints(acb); | ||
2470 | arcmsr_wait_firmware_ready(acb); | 2881 | arcmsr_wait_firmware_ready(acb); |
2471 | arcmsr_iop_confirm(acb); | 2882 | arcmsr_iop_confirm(acb); |
2472 | /*start background rebuild*/ | 2883 | /*start background rebuild*/ |
@@ -2485,7 +2896,6 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb) | |||
2485 | uint32_t intmask_org; | 2896 | uint32_t intmask_org; |
2486 | uint8_t rtnval = 0x00; | 2897 | uint8_t rtnval = 0x00; |
2487 | int i = 0; | 2898 | int i = 0; |
2488 | |||
2489 | if (atomic_read(&acb->ccboutstandingcount) != 0) { | 2899 | if (atomic_read(&acb->ccboutstandingcount) != 0) { |
2490 | /* disable all outbound interrupt */ | 2900 | /* disable all outbound interrupt */ |
2491 | intmask_org = arcmsr_disable_outbound_ints(acb); | 2901 | intmask_org = arcmsr_disable_outbound_ints(acb); |
@@ -2514,54 +2924,50 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) | |||
2514 | uint32_t intmask_org, outbound_doorbell; | 2924 | uint32_t intmask_org, outbound_doorbell; |
2515 | int retry_count = 0; | 2925 | int retry_count = 0; |
2516 | int rtn = FAILED; | 2926 | int rtn = FAILED; |
2517 | |||
2518 | acb = (struct AdapterControlBlock *) cmd->device->host->hostdata; | 2927 | acb = (struct AdapterControlBlock *) cmd->device->host->hostdata; |
2519 | printk(KERN_ERR "arcmsr: executing eh bus reset .....num_resets = %d, \ | 2928 | printk(KERN_ERR "arcmsr: executing bus reset eh.....num_resets = %d, num_aborts = %d \n", acb->num_resets, acb->num_aborts); |
2520 | num_aborts = %d \n", acb->num_resets, acb->num_aborts); | ||
2521 | acb->num_resets++; | 2929 | acb->num_resets++; |
2522 | 2930 | ||
2523 | switch (acb->adapter_type) { | 2931 | switch(acb->adapter_type){ |
2524 | case ACB_ADAPTER_TYPE_A: { | 2932 | case ACB_ADAPTER_TYPE_A:{ |
2525 | if (acb->acb_flags & ACB_F_BUS_RESET) { | 2933 | if (acb->acb_flags & ACB_F_BUS_RESET){ |
2526 | long timeout; | 2934 | long timeout; |
2527 | timeout = wait_event_timeout(wait_q, | 2935 | printk(KERN_ERR "arcmsr: there is an bus reset eh proceeding.......\n"); |
2528 | (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ); | 2936 | timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ); |
2529 | if (timeout) { | 2937 | if (timeout) { |
2530 | return SUCCESS; | 2938 | return SUCCESS; |
2531 | } | 2939 | } |
2532 | } | 2940 | } |
2533 | acb->acb_flags |= ACB_F_BUS_RESET; | 2941 | acb->acb_flags |= ACB_F_BUS_RESET; |
2534 | if (arcmsr_iop_reset(acb)) { | 2942 | if (!arcmsr_iop_reset(acb)) { |
2535 | struct MessageUnit_A __iomem *reg; | 2943 | struct MessageUnit_A __iomem *reg; |
2536 | reg = acb->pmuA; | 2944 | reg = acb->pmuA; |
2537 | arcmsr_hardware_reset(acb); | 2945 | arcmsr_hardware_reset(acb); |
2538 | acb->acb_flags &= ~ACB_F_IOP_INITED; | 2946 | acb->acb_flags &= ~ACB_F_IOP_INITED; |
2539 | sleep_again: | 2947 | sleep_again: |
2540 | arcmsr_sleep_for_bus_reset(cmd); | 2948 | arcmsr_sleep_for_bus_reset(cmd); |
2541 | if ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { | 2949 | if ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { |
2542 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, \ | 2950 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count); |
2543 | retry=%d \n", acb->host->host_no, retry_count); | 2951 | if (retry_count > retrycount) { |
2544 | if (retry_count > retrycount) { | ||
2545 | acb->fw_flag = FW_DEADLOCK; | 2952 | acb->fw_flag = FW_DEADLOCK; |
2546 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, \ | 2953 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no); |
2547 | RETRY TERMINATED!! \n", acb->host->host_no); | ||
2548 | return FAILED; | 2954 | return FAILED; |
2549 | } | 2955 | } |
2550 | retry_count++; | 2956 | retry_count++; |
2551 | goto sleep_again; | 2957 | goto sleep_again; |
2552 | } | 2958 | } |
2553 | acb->acb_flags |= ACB_F_IOP_INITED; | 2959 | acb->acb_flags |= ACB_F_IOP_INITED; |
2554 | /* disable all outbound interrupt */ | 2960 | /* disable all outbound interrupt */ |
2555 | intmask_org = arcmsr_disable_outbound_ints(acb); | 2961 | intmask_org = arcmsr_disable_outbound_ints(acb); |
2556 | arcmsr_get_firmware_spec(acb); | 2962 | arcmsr_get_firmware_spec(acb); |
2557 | arcmsr_start_adapter_bgrb(acb); | 2963 | arcmsr_start_adapter_bgrb(acb); |
2558 | /* clear Qbuffer if door bell ringed */ | 2964 | /* clear Qbuffer if door bell ringed */ |
2559 | outbound_doorbell = readl(®->outbound_doorbell); | 2965 | outbound_doorbell = readl(®->outbound_doorbell); |
2560 | writel(outbound_doorbell, ®->outbound_doorbell); /*clear interrupt */ | 2966 | writel(outbound_doorbell, ®->outbound_doorbell); /*clear interrupt */ |
2561 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); | 2967 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); |
2562 | /* enable outbound Post Queue,outbound doorbell Interrupt */ | 2968 | /* enable outbound Post Queue,outbound doorbell Interrupt */ |
2563 | arcmsr_enable_outbound_ints(acb, intmask_org); | 2969 | arcmsr_enable_outbound_ints(acb, intmask_org); |
2564 | atomic_set(&acb->rq_map_token, 16); | 2970 | atomic_set(&acb->rq_map_token, 16); |
2565 | atomic_set(&acb->ante_token_value, 16); | 2971 | atomic_set(&acb->ante_token_value, 16); |
2566 | acb->fw_flag = FW_NORMAL; | 2972 | acb->fw_flag = FW_NORMAL; |
2567 | init_timer(&acb->eternal_timer); | 2973 | init_timer(&acb->eternal_timer); |
@@ -2571,35 +2977,35 @@ sleep_again: | |||
2571 | add_timer(&acb->eternal_timer); | 2977 | add_timer(&acb->eternal_timer); |
2572 | acb->acb_flags &= ~ACB_F_BUS_RESET; | 2978 | acb->acb_flags &= ~ACB_F_BUS_RESET; |
2573 | rtn = SUCCESS; | 2979 | rtn = SUCCESS; |
2574 | printk(KERN_ERR "arcmsr: scsi eh bus reset succeeds\n"); | 2980 | printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); |
2575 | } else { | 2981 | } else { |
2576 | acb->acb_flags &= ~ACB_F_BUS_RESET; | 2982 | acb->acb_flags &= ~ACB_F_BUS_RESET; |
2577 | if (atomic_read(&acb->rq_map_token) == 0) { | 2983 | if (atomic_read(&acb->rq_map_token) == 0) { |
2578 | atomic_set(&acb->rq_map_token, 16); | 2984 | atomic_set(&acb->rq_map_token, 16); |
2579 | atomic_set(&acb->ante_token_value, 16); | 2985 | atomic_set(&acb->ante_token_value, 16); |
2580 | acb->fw_flag = FW_NORMAL; | 2986 | acb->fw_flag = FW_NORMAL; |
2581 | init_timer(&acb->eternal_timer); | 2987 | init_timer(&acb->eternal_timer); |
2582 | acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ); | 2988 | acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ); |
2583 | acb->eternal_timer.data = (unsigned long) acb; | 2989 | acb->eternal_timer.data = (unsigned long) acb; |
2584 | acb->eternal_timer.function = &arcmsr_request_device_map; | 2990 | acb->eternal_timer.function = &arcmsr_request_device_map; |
2585 | add_timer(&acb->eternal_timer); | 2991 | add_timer(&acb->eternal_timer); |
2586 | } else { | 2992 | } else { |
2587 | atomic_set(&acb->rq_map_token, 16); | 2993 | atomic_set(&acb->rq_map_token, 16); |
2588 | atomic_set(&acb->ante_token_value, 16); | 2994 | atomic_set(&acb->ante_token_value, 16); |
2589 | acb->fw_flag = FW_NORMAL; | 2995 | acb->fw_flag = FW_NORMAL; |
2590 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); | 2996 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); |
2591 | } | 2997 | } |
2592 | rtn = SUCCESS; | 2998 | rtn = SUCCESS; |
2593 | } | 2999 | } |
2594 | break; | 3000 | break; |
2595 | } | 3001 | } |
2596 | case ACB_ADAPTER_TYPE_B:{ | 3002 | case ACB_ADAPTER_TYPE_B:{ |
2597 | acb->acb_flags |= ACB_F_BUS_RESET; | 3003 | acb->acb_flags |= ACB_F_BUS_RESET; |
2598 | if (arcmsr_iop_reset(acb)) { | 3004 | if (!arcmsr_iop_reset(acb)) { |
2599 | acb->acb_flags &= ~ACB_F_BUS_RESET; | 3005 | acb->acb_flags &= ~ACB_F_BUS_RESET; |
2600 | rtn = FAILED; | 3006 | rtn = FAILED; |
2601 | } else { | 3007 | } else { |
2602 | acb->acb_flags &= ~ACB_F_BUS_RESET; | 3008 | acb->acb_flags &= ~ACB_F_BUS_RESET; |
2603 | if (atomic_read(&acb->rq_map_token) == 0) { | 3009 | if (atomic_read(&acb->rq_map_token) == 0) { |
2604 | atomic_set(&acb->rq_map_token, 16); | 3010 | atomic_set(&acb->rq_map_token, 16); |
2605 | atomic_set(&acb->ante_token_value, 16); | 3011 | atomic_set(&acb->ante_token_value, 16); |
@@ -2616,7 +3022,78 @@ sleep_again: | |||
2616 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); | 3022 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); |
2617 | } | 3023 | } |
2618 | rtn = SUCCESS; | 3024 | rtn = SUCCESS; |
2619 | } | 3025 | } |
3026 | break; | ||
3027 | } | ||
3028 | case ACB_ADAPTER_TYPE_C:{ | ||
3029 | if (acb->acb_flags & ACB_F_BUS_RESET) { | ||
3030 | long timeout; | ||
3031 | printk(KERN_ERR "arcmsr: there is an bus reset eh proceeding.......\n"); | ||
3032 | timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ); | ||
3033 | if (timeout) { | ||
3034 | return SUCCESS; | ||
3035 | } | ||
3036 | } | ||
3037 | acb->acb_flags |= ACB_F_BUS_RESET; | ||
3038 | if (!arcmsr_iop_reset(acb)) { | ||
3039 | struct MessageUnit_C __iomem *reg; | ||
3040 | reg = acb->pmuC; | ||
3041 | arcmsr_hardware_reset(acb); | ||
3042 | acb->acb_flags &= ~ACB_F_IOP_INITED; | ||
3043 | sleep: | ||
3044 | arcmsr_sleep_for_bus_reset(cmd); | ||
3045 | if ((readl(®->host_diagnostic) & 0x04) != 0) { | ||
3046 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count); | ||
3047 | if (retry_count > retrycount) { | ||
3048 | acb->fw_flag = FW_DEADLOCK; | ||
3049 | printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no); | ||
3050 | return FAILED; | ||
3051 | } | ||
3052 | retry_count++; | ||
3053 | goto sleep; | ||
3054 | } | ||
3055 | acb->acb_flags |= ACB_F_IOP_INITED; | ||
3056 | /* disable all outbound interrupt */ | ||
3057 | intmask_org = arcmsr_disable_outbound_ints(acb); | ||
3058 | arcmsr_get_firmware_spec(acb); | ||
3059 | arcmsr_start_adapter_bgrb(acb); | ||
3060 | /* clear Qbuffer if door bell ringed */ | ||
3061 | outbound_doorbell = readl(®->outbound_doorbell); | ||
3062 | writel(outbound_doorbell, ®->outbound_doorbell_clear); /*clear interrupt */ | ||
3063 | writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, ®->inbound_doorbell); | ||
3064 | /* enable outbound Post Queue,outbound doorbell Interrupt */ | ||
3065 | arcmsr_enable_outbound_ints(acb, intmask_org); | ||
3066 | atomic_set(&acb->rq_map_token, 16); | ||
3067 | atomic_set(&acb->ante_token_value, 16); | ||
3068 | acb->fw_flag = FW_NORMAL; | ||
3069 | init_timer(&acb->eternal_timer); | ||
3070 | acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ); | ||
3071 | acb->eternal_timer.data = (unsigned long) acb; | ||
3072 | acb->eternal_timer.function = &arcmsr_request_device_map; | ||
3073 | add_timer(&acb->eternal_timer); | ||
3074 | acb->acb_flags &= ~ACB_F_BUS_RESET; | ||
3075 | rtn = SUCCESS; | ||
3076 | printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); | ||
3077 | } else { | ||
3078 | acb->acb_flags &= ~ACB_F_BUS_RESET; | ||
3079 | if (atomic_read(&acb->rq_map_token) == 0) { | ||
3080 | atomic_set(&acb->rq_map_token, 16); | ||
3081 | atomic_set(&acb->ante_token_value, 16); | ||
3082 | acb->fw_flag = FW_NORMAL; | ||
3083 | init_timer(&acb->eternal_timer); | ||
3084 | acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ); | ||
3085 | acb->eternal_timer.data = (unsigned long) acb; | ||
3086 | acb->eternal_timer.function = &arcmsr_request_device_map; | ||
3087 | add_timer(&acb->eternal_timer); | ||
3088 | } else { | ||
3089 | atomic_set(&acb->rq_map_token, 16); | ||
3090 | atomic_set(&acb->ante_token_value, 16); | ||
3091 | acb->fw_flag = FW_NORMAL; | ||
3092 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); | ||
3093 | } | ||
3094 | rtn = SUCCESS; | ||
3095 | } | ||
3096 | break; | ||
2620 | } | 3097 | } |
2621 | } | 3098 | } |
2622 | return rtn; | 3099 | return rtn; |
@@ -2626,9 +3103,7 @@ static int arcmsr_abort_one_cmd(struct AdapterControlBlock *acb, | |||
2626 | struct CommandControlBlock *ccb) | 3103 | struct CommandControlBlock *ccb) |
2627 | { | 3104 | { |
2628 | int rtn; | 3105 | int rtn; |
2629 | spin_lock_irq(&acb->eh_lock); | ||
2630 | rtn = arcmsr_polling_ccbdone(acb, ccb); | 3106 | rtn = arcmsr_polling_ccbdone(acb, ccb); |
2631 | spin_unlock_irq(&acb->eh_lock); | ||
2632 | return rtn; | 3107 | return rtn; |
2633 | } | 3108 | } |
2634 | 3109 | ||
@@ -2638,7 +3113,6 @@ static int arcmsr_abort(struct scsi_cmnd *cmd) | |||
2638 | (struct AdapterControlBlock *)cmd->device->host->hostdata; | 3113 | (struct AdapterControlBlock *)cmd->device->host->hostdata; |
2639 | int i = 0; | 3114 | int i = 0; |
2640 | int rtn = FAILED; | 3115 | int rtn = FAILED; |
2641 | |||
2642 | printk(KERN_NOTICE | 3116 | printk(KERN_NOTICE |
2643 | "arcmsr%d: abort device command of scsi id = %d lun = %d \n", | 3117 | "arcmsr%d: abort device command of scsi id = %d lun = %d \n", |
2644 | acb->host->host_no, cmd->device->id, cmd->device->lun); | 3118 | acb->host->host_no, cmd->device->id, cmd->device->lun); |
@@ -2672,7 +3146,6 @@ static const char *arcmsr_info(struct Scsi_Host *host) | |||
2672 | static char buf[256]; | 3146 | static char buf[256]; |
2673 | char *type; | 3147 | char *type; |
2674 | int raid6 = 1; | 3148 | int raid6 = 1; |
2675 | |||
2676 | switch (acb->pdev->device) { | 3149 | switch (acb->pdev->device) { |
2677 | case PCI_DEVICE_ID_ARECA_1110: | 3150 | case PCI_DEVICE_ID_ARECA_1110: |
2678 | case PCI_DEVICE_ID_ARECA_1200: | 3151 | case PCI_DEVICE_ID_ARECA_1200: |
@@ -2696,6 +3169,7 @@ static const char *arcmsr_info(struct Scsi_Host *host) | |||
2696 | case PCI_DEVICE_ID_ARECA_1381: | 3169 | case PCI_DEVICE_ID_ARECA_1381: |
2697 | case PCI_DEVICE_ID_ARECA_1680: | 3170 | case PCI_DEVICE_ID_ARECA_1680: |
2698 | case PCI_DEVICE_ID_ARECA_1681: | 3171 | case PCI_DEVICE_ID_ARECA_1681: |
3172 | case PCI_DEVICE_ID_ARECA_1880: | ||
2699 | type = "SAS"; | 3173 | type = "SAS"; |
2700 | break; | 3174 | break; |
2701 | default: | 3175 | default: |