diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/Kconfig | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 36 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 124 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 23 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 78 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dfs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 173 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 33 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 192 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_inline.h | 87 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 5 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 223 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 318 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 30 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 443 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_settings.h | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 315 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_version.h | 6 |
19 files changed, 1266 insertions, 857 deletions
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index 8c865b9e02b5..6208d562890d 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig | |||
@@ -16,7 +16,8 @@ config SCSI_QLA_FC | |||
16 | 22xx ql2200_fw.bin | 16 | 22xx ql2200_fw.bin |
17 | 2300, 2312, 6312 ql2300_fw.bin | 17 | 2300, 2312, 6312 ql2300_fw.bin |
18 | 2322, 6322 ql2322_fw.bin | 18 | 2322, 6322 ql2322_fw.bin |
19 | 24xx ql2400_fw.bin | 19 | 24xx, 54xx ql2400_fw.bin |
20 | 25xx ql2500_fw.bin | ||
20 | 21 | ||
21 | Upon request, the driver caches the firmware image until | 22 | Upon request, the driver caches the firmware image until |
22 | the driver is unloaded. | 23 | the driver is unloaded. |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 4894dc886b62..413d8cd6a324 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -849,20 +849,20 @@ static void | |||
849 | qla2x00_get_host_speed(struct Scsi_Host *shost) | 849 | qla2x00_get_host_speed(struct Scsi_Host *shost) |
850 | { | 850 | { |
851 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); | 851 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); |
852 | uint32_t speed = 0; | 852 | u32 speed = FC_PORTSPEED_UNKNOWN; |
853 | 853 | ||
854 | switch (ha->link_data_rate) { | 854 | switch (ha->link_data_rate) { |
855 | case PORT_SPEED_1GB: | 855 | case PORT_SPEED_1GB: |
856 | speed = 1; | 856 | speed = FC_PORTSPEED_1GBIT; |
857 | break; | 857 | break; |
858 | case PORT_SPEED_2GB: | 858 | case PORT_SPEED_2GB: |
859 | speed = 2; | 859 | speed = FC_PORTSPEED_2GBIT; |
860 | break; | 860 | break; |
861 | case PORT_SPEED_4GB: | 861 | case PORT_SPEED_4GB: |
862 | speed = 4; | 862 | speed = FC_PORTSPEED_4GBIT; |
863 | break; | 863 | break; |
864 | case PORT_SPEED_8GB: | 864 | case PORT_SPEED_8GB: |
865 | speed = 8; | 865 | speed = FC_PORTSPEED_8GBIT; |
866 | break; | 866 | break; |
867 | } | 867 | } |
868 | fc_host_speed(shost) = speed; | 868 | fc_host_speed(shost) = speed; |
@@ -900,7 +900,8 @@ qla2x00_get_starget_node_name(struct scsi_target *starget) | |||
900 | u64 node_name = 0; | 900 | u64 node_name = 0; |
901 | 901 | ||
902 | list_for_each_entry(fcport, &ha->fcports, list) { | 902 | list_for_each_entry(fcport, &ha->fcports, list) { |
903 | if (starget->id == fcport->os_target_id) { | 903 | if (fcport->rport && |
904 | starget->id == fcport->rport->scsi_target_id) { | ||
904 | node_name = wwn_to_u64(fcport->node_name); | 905 | node_name = wwn_to_u64(fcport->node_name); |
905 | break; | 906 | break; |
906 | } | 907 | } |
@@ -918,7 +919,8 @@ qla2x00_get_starget_port_name(struct scsi_target *starget) | |||
918 | u64 port_name = 0; | 919 | u64 port_name = 0; |
919 | 920 | ||
920 | list_for_each_entry(fcport, &ha->fcports, list) { | 921 | list_for_each_entry(fcport, &ha->fcports, list) { |
921 | if (starget->id == fcport->os_target_id) { | 922 | if (fcport->rport && |
923 | starget->id == fcport->rport->scsi_target_id) { | ||
922 | port_name = wwn_to_u64(fcport->port_name); | 924 | port_name = wwn_to_u64(fcport->port_name); |
923 | break; | 925 | break; |
924 | } | 926 | } |
@@ -936,7 +938,8 @@ qla2x00_get_starget_port_id(struct scsi_target *starget) | |||
936 | uint32_t port_id = ~0U; | 938 | uint32_t port_id = ~0U; |
937 | 939 | ||
938 | list_for_each_entry(fcport, &ha->fcports, list) { | 940 | list_for_each_entry(fcport, &ha->fcports, list) { |
939 | if (starget->id == fcport->os_target_id) { | 941 | if (fcport->rport && |
942 | starget->id == fcport->rport->scsi_target_id) { | ||
940 | port_id = fcport->d_id.b.domain << 16 | | 943 | port_id = fcport->d_id.b.domain << 16 | |
941 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; | 944 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; |
942 | break; | 945 | break; |
@@ -1196,6 +1199,7 @@ struct fc_function_template qla2xxx_transport_functions = { | |||
1196 | .show_host_node_name = 1, | 1199 | .show_host_node_name = 1, |
1197 | .show_host_port_name = 1, | 1200 | .show_host_port_name = 1, |
1198 | .show_host_supported_classes = 1, | 1201 | .show_host_supported_classes = 1, |
1202 | .show_host_supported_speeds = 1, | ||
1199 | 1203 | ||
1200 | .get_host_port_id = qla2x00_get_host_port_id, | 1204 | .get_host_port_id = qla2x00_get_host_port_id, |
1201 | .show_host_port_id = 1, | 1205 | .show_host_port_id = 1, |
@@ -1276,9 +1280,23 @@ struct fc_function_template qla2xxx_transport_vport_functions = { | |||
1276 | void | 1280 | void |
1277 | qla2x00_init_host_attr(scsi_qla_host_t *ha) | 1281 | qla2x00_init_host_attr(scsi_qla_host_t *ha) |
1278 | { | 1282 | { |
1283 | u32 speed = FC_PORTSPEED_UNKNOWN; | ||
1284 | |||
1279 | fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); | 1285 | fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); |
1280 | fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); | 1286 | fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); |
1281 | fc_host_supported_classes(ha->host) = FC_COS_CLASS3; | 1287 | fc_host_supported_classes(ha->host) = FC_COS_CLASS3; |
1282 | fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; | 1288 | fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; |
1283 | fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; | 1289 | fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; |
1290 | |||
1291 | if (IS_QLA25XX(ha)) | ||
1292 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | | ||
1293 | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | ||
1294 | else if (IS_QLA24XX_TYPE(ha)) | ||
1295 | speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | | ||
1296 | FC_PORTSPEED_1GBIT; | ||
1297 | else if (IS_QLA23XX(ha)) | ||
1298 | speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | ||
1299 | else | ||
1300 | speed = FC_PORTSPEED_1GBIT; | ||
1301 | fc_host_supported_speeds(ha->host) = speed; | ||
1284 | } | 1302 | } |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index d88e98c476b0..9d12d9f26209 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -1410,125 +1410,3 @@ qla2x00_dump_buffer(uint8_t * b, uint32_t size) | |||
1410 | if (cnt % 16) | 1410 | if (cnt % 16) |
1411 | printk("\n"); | 1411 | printk("\n"); |
1412 | } | 1412 | } |
1413 | |||
1414 | /************************************************************************** | ||
1415 | * qla2x00_print_scsi_cmd | ||
1416 | * Dumps out info about the scsi cmd and srb. | ||
1417 | * Input | ||
1418 | * cmd : struct scsi_cmnd | ||
1419 | **************************************************************************/ | ||
1420 | void | ||
1421 | qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) | ||
1422 | { | ||
1423 | int i; | ||
1424 | struct scsi_qla_host *ha; | ||
1425 | srb_t *sp; | ||
1426 | |||
1427 | ha = shost_priv(cmd->device->host); | ||
1428 | |||
1429 | sp = (srb_t *) cmd->SCp.ptr; | ||
1430 | printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); | ||
1431 | printk(" chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n", | ||
1432 | cmd->device->channel, cmd->device->id, cmd->device->lun, | ||
1433 | cmd->cmd_len); | ||
1434 | printk(" CDB: "); | ||
1435 | for (i = 0; i < cmd->cmd_len; i++) { | ||
1436 | printk("0x%02x ", cmd->cmnd[i]); | ||
1437 | } | ||
1438 | printk("\n seg_cnt=%d, allowed=%d, retries=%d\n", | ||
1439 | scsi_sg_count(cmd), cmd->allowed, cmd->retries); | ||
1440 | printk(" request buffer=0x%p, request buffer len=0x%x\n", | ||
1441 | scsi_sglist(cmd), scsi_bufflen(cmd)); | ||
1442 | printk(" tag=%d, transfersize=0x%x\n", | ||
1443 | cmd->tag, cmd->transfersize); | ||
1444 | printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp); | ||
1445 | printk(" data direction=%d\n", cmd->sc_data_direction); | ||
1446 | |||
1447 | if (!sp) | ||
1448 | return; | ||
1449 | |||
1450 | printk(" sp flags=0x%x\n", sp->flags); | ||
1451 | } | ||
1452 | |||
1453 | #if defined(QL_DEBUG_ROUTINES) | ||
1454 | /* | ||
1455 | * qla2x00_formatted_dump_buffer | ||
1456 | * Prints string plus buffer. | ||
1457 | * | ||
1458 | * Input: | ||
1459 | * string = Null terminated string (no newline at end). | ||
1460 | * buffer = buffer address. | ||
1461 | * wd_size = word size 8, 16, 32 or 64 bits | ||
1462 | * count = number of words. | ||
1463 | */ | ||
1464 | void | ||
1465 | qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer, | ||
1466 | uint8_t wd_size, uint32_t count) | ||
1467 | { | ||
1468 | uint32_t cnt; | ||
1469 | uint16_t *buf16; | ||
1470 | uint32_t *buf32; | ||
1471 | |||
1472 | if (strcmp(string, "") != 0) | ||
1473 | printk("%s\n",string); | ||
1474 | |||
1475 | switch (wd_size) { | ||
1476 | case 8: | ||
1477 | printk(" 0 1 2 3 4 5 6 7 " | ||
1478 | "8 9 Ah Bh Ch Dh Eh Fh\n"); | ||
1479 | printk("-----------------------------------------" | ||
1480 | "-------------------------------------\n"); | ||
1481 | |||
1482 | for (cnt = 1; cnt <= count; cnt++, buffer++) { | ||
1483 | printk("%02x",*buffer); | ||
1484 | if (cnt % 16 == 0) | ||
1485 | printk("\n"); | ||
1486 | else | ||
1487 | printk(" "); | ||
1488 | } | ||
1489 | if (cnt % 16 != 0) | ||
1490 | printk("\n"); | ||
1491 | break; | ||
1492 | case 16: | ||
1493 | printk(" 0 2 4 6 8 Ah " | ||
1494 | " Ch Eh\n"); | ||
1495 | printk("-----------------------------------------" | ||
1496 | "-------------\n"); | ||
1497 | |||
1498 | buf16 = (uint16_t *) buffer; | ||
1499 | for (cnt = 1; cnt <= count; cnt++, buf16++) { | ||
1500 | printk("%4x",*buf16); | ||
1501 | |||
1502 | if (cnt % 8 == 0) | ||
1503 | printk("\n"); | ||
1504 | else if (*buf16 < 10) | ||
1505 | printk(" "); | ||
1506 | else | ||
1507 | printk(" "); | ||
1508 | } | ||
1509 | if (cnt % 8 != 0) | ||
1510 | printk("\n"); | ||
1511 | break; | ||
1512 | case 32: | ||
1513 | printk(" 0 4 8 Ch\n"); | ||
1514 | printk("------------------------------------------\n"); | ||
1515 | |||
1516 | buf32 = (uint32_t *) buffer; | ||
1517 | for (cnt = 1; cnt <= count; cnt++, buf32++) { | ||
1518 | printk("%8x", *buf32); | ||
1519 | |||
1520 | if (cnt % 4 == 0) | ||
1521 | printk("\n"); | ||
1522 | else if (*buf32 < 10) | ||
1523 | printk(" "); | ||
1524 | else | ||
1525 | printk(" "); | ||
1526 | } | ||
1527 | if (cnt % 4 != 0) | ||
1528 | printk("\n"); | ||
1529 | break; | ||
1530 | default: | ||
1531 | break; | ||
1532 | } | ||
1533 | } | ||
1534 | #endif | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 524598afc81c..2e9c0c097f5e 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -22,19 +22,7 @@ | |||
22 | /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ | 22 | /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ |
23 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ | 23 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ |
24 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ | 24 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ |
25 | /* | 25 | /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ |
26 | * Local Macro Definitions. | ||
27 | */ | ||
28 | #if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \ | ||
29 | defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \ | ||
30 | defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \ | ||
31 | defined(QL_DEBUG_LEVEL_7) || defined(QL_DEBUG_LEVEL_8) || \ | ||
32 | defined(QL_DEBUG_LEVEL_9) || defined(QL_DEBUG_LEVEL_10) || \ | ||
33 | defined(QL_DEBUG_LEVEL_11) || defined(QL_DEBUG_LEVEL_12) || \ | ||
34 | defined(QL_DEBUG_LEVEL_13) || defined(QL_DEBUG_LEVEL_14) || \ | ||
35 | defined(QL_DEBUG_LEVEL_15) | ||
36 | #define QL_DEBUG_ROUTINES | ||
37 | #endif | ||
38 | 26 | ||
39 | /* | 27 | /* |
40 | * Macros use for debugging the driver. | 28 | * Macros use for debugging the driver. |
@@ -54,6 +42,7 @@ | |||
54 | #define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0) | 42 | #define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
55 | #define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) | 43 | #define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
56 | #define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0) | 44 | #define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
45 | #define DEBUG2_16(x) do { if (ql2xextended_error_logging) { x; } } while (0) | ||
57 | 46 | ||
58 | #if defined(QL_DEBUG_LEVEL_3) | 47 | #if defined(QL_DEBUG_LEVEL_3) |
59 | #define DEBUG3(x) do {x;} while (0) | 48 | #define DEBUG3(x) do {x;} while (0) |
@@ -133,6 +122,12 @@ | |||
133 | #define DEBUG15(x) do {} while (0) | 122 | #define DEBUG15(x) do {} while (0) |
134 | #endif | 123 | #endif |
135 | 124 | ||
125 | #if defined(QL_DEBUG_LEVEL_16) | ||
126 | #define DEBUG16(x) do {x;} while (0) | ||
127 | #else | ||
128 | #define DEBUG16(x) do {} while (0) | ||
129 | #endif | ||
130 | |||
136 | /* | 131 | /* |
137 | * Firmware Dump structure definition | 132 | * Firmware Dump structure definition |
138 | */ | 133 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3750319f4968..094d95f0764c 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
25 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
26 | #include <linux/aer.h> | 26 | #include <linux/aer.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <asm/semaphore.h> | 28 | #include <asm/semaphore.h> |
28 | 29 | ||
29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
@@ -192,9 +193,6 @@ typedef struct srb { | |||
192 | 193 | ||
193 | uint16_t flags; | 194 | uint16_t flags; |
194 | 195 | ||
195 | /* Single transfer DMA context */ | ||
196 | dma_addr_t dma_handle; | ||
197 | |||
198 | uint32_t request_sense_length; | 196 | uint32_t request_sense_length; |
199 | uint8_t *request_sense_ptr; | 197 | uint8_t *request_sense_ptr; |
200 | } srb_t; | 198 | } srb_t; |
@@ -1542,8 +1540,6 @@ typedef struct fc_port { | |||
1542 | atomic_t state; | 1540 | atomic_t state; |
1543 | uint32_t flags; | 1541 | uint32_t flags; |
1544 | 1542 | ||
1545 | unsigned int os_target_id; | ||
1546 | |||
1547 | int port_login_retry_count; | 1543 | int port_login_retry_count; |
1548 | int login_retry; | 1544 | int login_retry; |
1549 | atomic_t port_down_timer; | 1545 | atomic_t port_down_timer; |
@@ -1613,6 +1609,7 @@ typedef struct fc_port { | |||
1613 | #define CT_ACCEPT_RESPONSE 0x8002 | 1609 | #define CT_ACCEPT_RESPONSE 0x8002 |
1614 | #define CT_REASON_INVALID_COMMAND_CODE 0x01 | 1610 | #define CT_REASON_INVALID_COMMAND_CODE 0x01 |
1615 | #define CT_REASON_CANNOT_PERFORM 0x09 | 1611 | #define CT_REASON_CANNOT_PERFORM 0x09 |
1612 | #define CT_REASON_COMMAND_UNSUPPORTED 0x0b | ||
1616 | #define CT_EXPL_ALREADY_REGISTERED 0x10 | 1613 | #define CT_EXPL_ALREADY_REGISTERED 0x10 |
1617 | 1614 | ||
1618 | #define NS_N_PORT_TYPE 0x01 | 1615 | #define NS_N_PORT_TYPE 0x01 |
@@ -2063,7 +2060,8 @@ struct isp_operations { | |||
2063 | void (*disable_intrs) (struct scsi_qla_host *); | 2060 | void (*disable_intrs) (struct scsi_qla_host *); |
2064 | 2061 | ||
2065 | int (*abort_command) (struct scsi_qla_host *, srb_t *); | 2062 | int (*abort_command) (struct scsi_qla_host *, srb_t *); |
2066 | int (*abort_target) (struct fc_port *); | 2063 | int (*target_reset) (struct fc_port *, unsigned int); |
2064 | int (*lun_reset) (struct fc_port *, unsigned int); | ||
2067 | int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t, | 2065 | int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t, |
2068 | uint8_t, uint8_t, uint16_t *, uint8_t); | 2066 | uint8_t, uint8_t, uint16_t *, uint8_t); |
2069 | int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t, | 2067 | int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t, |
@@ -2117,6 +2115,46 @@ struct qla_msix_entry { | |||
2117 | 2115 | ||
2118 | #define WATCH_INTERVAL 1 /* number of seconds */ | 2116 | #define WATCH_INTERVAL 1 /* number of seconds */ |
2119 | 2117 | ||
2118 | /* Work events. */ | ||
2119 | enum qla_work_type { | ||
2120 | QLA_EVT_AEN, | ||
2121 | QLA_EVT_HWE_LOG, | ||
2122 | }; | ||
2123 | |||
2124 | |||
2125 | struct qla_work_evt { | ||
2126 | struct list_head list; | ||
2127 | enum qla_work_type type; | ||
2128 | u32 flags; | ||
2129 | #define QLA_EVT_FLAG_FREE 0x1 | ||
2130 | |||
2131 | union { | ||
2132 | struct { | ||
2133 | enum fc_host_event_code code; | ||
2134 | u32 data; | ||
2135 | } aen; | ||
2136 | struct { | ||
2137 | uint16_t code; | ||
2138 | uint16_t d1, d2, d3; | ||
2139 | } hwe; | ||
2140 | } u; | ||
2141 | }; | ||
2142 | |||
2143 | struct qla_chip_state_84xx { | ||
2144 | struct list_head list; | ||
2145 | struct kref kref; | ||
2146 | |||
2147 | void *bus; | ||
2148 | spinlock_t access_lock; | ||
2149 | struct mutex fw_update_mutex; | ||
2150 | uint32_t fw_update; | ||
2151 | uint32_t op_fw_version; | ||
2152 | uint32_t op_fw_size; | ||
2153 | uint32_t op_fw_seq_size; | ||
2154 | uint32_t diag_fw_version; | ||
2155 | uint32_t gold_fw_version; | ||
2156 | }; | ||
2157 | |||
2120 | /* | 2158 | /* |
2121 | * Linux Host Adapter structure | 2159 | * Linux Host Adapter structure |
2122 | */ | 2160 | */ |
@@ -2155,6 +2193,7 @@ typedef struct scsi_qla_host { | |||
2155 | uint32_t vsan_enabled :1; | 2193 | uint32_t vsan_enabled :1; |
2156 | uint32_t npiv_supported :1; | 2194 | uint32_t npiv_supported :1; |
2157 | uint32_t fce_enabled :1; | 2195 | uint32_t fce_enabled :1; |
2196 | uint32_t hw_event_marker_found :1; | ||
2158 | } flags; | 2197 | } flags; |
2159 | 2198 | ||
2160 | atomic_t loop_state; | 2199 | atomic_t loop_state; |
@@ -2204,6 +2243,7 @@ typedef struct scsi_qla_host { | |||
2204 | #define DFLG_NO_CABLE BIT_4 | 2243 | #define DFLG_NO_CABLE BIT_4 |
2205 | 2244 | ||
2206 | #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 | 2245 | #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 |
2246 | #define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432 | ||
2207 | uint32_t device_type; | 2247 | uint32_t device_type; |
2208 | #define DT_ISP2100 BIT_0 | 2248 | #define DT_ISP2100 BIT_0 |
2209 | #define DT_ISP2200 BIT_1 | 2249 | #define DT_ISP2200 BIT_1 |
@@ -2217,7 +2257,8 @@ typedef struct scsi_qla_host { | |||
2217 | #define DT_ISP5422 BIT_9 | 2257 | #define DT_ISP5422 BIT_9 |
2218 | #define DT_ISP5432 BIT_10 | 2258 | #define DT_ISP5432 BIT_10 |
2219 | #define DT_ISP2532 BIT_11 | 2259 | #define DT_ISP2532 BIT_11 |
2220 | #define DT_ISP_LAST (DT_ISP2532 << 1) | 2260 | #define DT_ISP8432 BIT_12 |
2261 | #define DT_ISP_LAST (DT_ISP8432 << 1) | ||
2221 | 2262 | ||
2222 | #define DT_IIDMA BIT_26 | 2263 | #define DT_IIDMA BIT_26 |
2223 | #define DT_FWI2 BIT_27 | 2264 | #define DT_FWI2 BIT_27 |
@@ -2239,12 +2280,16 @@ typedef struct scsi_qla_host { | |||
2239 | #define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422) | 2280 | #define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422) |
2240 | #define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432) | 2281 | #define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432) |
2241 | #define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532) | 2282 | #define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532) |
2283 | #define IS_QLA8432(ha) (DT_MASK(ha) & DT_ISP8432) | ||
2242 | 2284 | ||
2243 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ | 2285 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ |
2244 | IS_QLA6312(ha) || IS_QLA6322(ha)) | 2286 | IS_QLA6312(ha) || IS_QLA6322(ha)) |
2245 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) | 2287 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) |
2246 | #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) | 2288 | #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) |
2247 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) | 2289 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) |
2290 | #define IS_QLA84XX(ha) (IS_QLA8432(ha)) | ||
2291 | #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ | ||
2292 | IS_QLA84XX(ha)) | ||
2248 | 2293 | ||
2249 | #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) | 2294 | #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) |
2250 | #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) | 2295 | #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) |
@@ -2356,6 +2401,8 @@ typedef struct scsi_qla_host { | |||
2356 | uint32_t login_retry_count; | 2401 | uint32_t login_retry_count; |
2357 | int max_q_depth; | 2402 | int max_q_depth; |
2358 | 2403 | ||
2404 | struct list_head work_list; | ||
2405 | |||
2359 | /* Fibre Channel Device List. */ | 2406 | /* Fibre Channel Device List. */ |
2360 | struct list_head fcports; | 2407 | struct list_head fcports; |
2361 | 2408 | ||
@@ -2423,8 +2470,6 @@ typedef struct scsi_qla_host { | |||
2423 | #define MBX_TIMEDOUT BIT_5 | 2470 | #define MBX_TIMEDOUT BIT_5 |
2424 | #define MBX_ACCESS_TIMEDOUT BIT_6 | 2471 | #define MBX_ACCESS_TIMEDOUT BIT_6 |
2425 | 2472 | ||
2426 | mbx_cmd_t mc; | ||
2427 | |||
2428 | /* Basic firmware related information. */ | 2473 | /* Basic firmware related information. */ |
2429 | uint16_t fw_major_version; | 2474 | uint16_t fw_major_version; |
2430 | uint16_t fw_minor_version; | 2475 | uint16_t fw_minor_version; |
@@ -2458,6 +2503,10 @@ typedef struct scsi_qla_host { | |||
2458 | uint64_t fce_wr, fce_rd; | 2503 | uint64_t fce_wr, fce_rd; |
2459 | struct mutex fce_mutex; | 2504 | struct mutex fce_mutex; |
2460 | 2505 | ||
2506 | uint32_t hw_event_start; | ||
2507 | uint32_t hw_event_ptr; | ||
2508 | uint32_t hw_event_pause_errors; | ||
2509 | |||
2461 | uint8_t host_str[16]; | 2510 | uint8_t host_str[16]; |
2462 | uint32_t pci_attr; | 2511 | uint32_t pci_attr; |
2463 | uint16_t chip_revision; | 2512 | uint16_t chip_revision; |
@@ -2493,6 +2542,13 @@ typedef struct scsi_qla_host { | |||
2493 | uint8_t fcode_revision[16]; | 2542 | uint8_t fcode_revision[16]; |
2494 | uint32_t fw_revision[4]; | 2543 | uint32_t fw_revision[4]; |
2495 | 2544 | ||
2545 | uint16_t fdt_odd_index; | ||
2546 | uint32_t fdt_wrt_disable; | ||
2547 | uint32_t fdt_erase_cmd; | ||
2548 | uint32_t fdt_block_size; | ||
2549 | uint32_t fdt_unprotect_sec_cmd; | ||
2550 | uint32_t fdt_protect_sec_cmd; | ||
2551 | |||
2496 | /* Needed for BEACON */ | 2552 | /* Needed for BEACON */ |
2497 | uint16_t beacon_blink_led; | 2553 | uint16_t beacon_blink_led; |
2498 | uint8_t beacon_color_state; | 2554 | uint8_t beacon_color_state; |
@@ -2538,6 +2594,8 @@ typedef struct scsi_qla_host { | |||
2538 | #define VP_ERR_ADAP_NORESOURCES 5 | 2594 | #define VP_ERR_ADAP_NORESOURCES 5 |
2539 | uint16_t max_npiv_vports; /* 63 or 125 per topoloty */ | 2595 | uint16_t max_npiv_vports; /* 63 or 125 per topoloty */ |
2540 | int cur_vport_count; | 2596 | int cur_vport_count; |
2597 | |||
2598 | struct qla_chip_state_84xx *cs84xx; | ||
2541 | } scsi_qla_host_t; | 2599 | } scsi_qla_host_t; |
2542 | 2600 | ||
2543 | 2601 | ||
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 2cd899bfe84b..561a4411719d 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 9337e138ed63..078f2a15f40b 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -719,7 +719,7 @@ struct tsk_mgmt_entry { | |||
719 | 719 | ||
720 | uint16_t timeout; /* Command timeout. */ | 720 | uint16_t timeout; /* Command timeout. */ |
721 | 721 | ||
722 | uint8_t lun[8]; /* FCP LUN (BE). */ | 722 | struct scsi_lun lun; /* FCP LUN (BE). */ |
723 | 723 | ||
724 | uint32_t control_flags; /* Control Flags. */ | 724 | uint32_t control_flags; /* Control Flags. */ |
725 | #define TCF_NOTMCMD_TO_TARGET BIT_31 | 725 | #define TCF_NOTMCMD_TO_TARGET BIT_31 |
@@ -793,7 +793,19 @@ struct device_reg_24xx { | |||
793 | #define FA_VPD_NVRAM_ADDR 0x48000 | 793 | #define FA_VPD_NVRAM_ADDR 0x48000 |
794 | #define FA_FEATURE_ADDR 0x4C000 | 794 | #define FA_FEATURE_ADDR 0x4C000 |
795 | #define FA_FLASH_DESCR_ADDR 0x50000 | 795 | #define FA_FLASH_DESCR_ADDR 0x50000 |
796 | #define FA_HW_EVENT_ADDR 0x54000 | 796 | #define FA_HW_EVENT0_ADDR 0x54000 |
797 | #define FA_HW_EVENT1_ADDR 0x54200 | ||
798 | #define FA_HW_EVENT_SIZE 0x200 | ||
799 | #define FA_HW_EVENT_ENTRY_SIZE 4 | ||
800 | /* | ||
801 | * Flash Error Log Event Codes. | ||
802 | */ | ||
803 | #define HW_EVENT_RESET_ERR 0xF00B | ||
804 | #define HW_EVENT_ISP_ERR 0xF020 | ||
805 | #define HW_EVENT_PARITY_ERR 0xF022 | ||
806 | #define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023 | ||
807 | #define HW_EVENT_FLASH_FW_ERR 0xF024 | ||
808 | |||
797 | #define FA_BOOT_LOG_ADDR 0x58000 | 809 | #define FA_BOOT_LOG_ADDR 0x58000 |
798 | #define FA_FW_DUMP0_ADDR 0x60000 | 810 | #define FA_FW_DUMP0_ADDR 0x60000 |
799 | #define FA_FW_DUMP1_ADDR 0x70000 | 811 | #define FA_FW_DUMP1_ADDR 0x70000 |
@@ -1174,4 +1186,159 @@ struct vf_evfp_entry_24xx { | |||
1174 | }; | 1186 | }; |
1175 | 1187 | ||
1176 | /* END MID Support ***********************************************************/ | 1188 | /* END MID Support ***********************************************************/ |
1189 | |||
1190 | /* Flash Description Table ***************************************************/ | ||
1191 | |||
1192 | struct qla_fdt_layout { | ||
1193 | uint8_t sig[4]; | ||
1194 | uint16_t version; | ||
1195 | uint16_t len; | ||
1196 | uint16_t checksum; | ||
1197 | uint8_t unused1[2]; | ||
1198 | uint8_t model[16]; | ||
1199 | uint16_t man_id; | ||
1200 | uint16_t id; | ||
1201 | uint8_t flags; | ||
1202 | uint8_t erase_cmd; | ||
1203 | uint8_t alt_erase_cmd; | ||
1204 | uint8_t wrt_enable_cmd; | ||
1205 | uint8_t wrt_enable_bits; | ||
1206 | uint8_t wrt_sts_reg_cmd; | ||
1207 | uint8_t unprotect_sec_cmd; | ||
1208 | uint8_t read_man_id_cmd; | ||
1209 | uint32_t block_size; | ||
1210 | uint32_t alt_block_size; | ||
1211 | uint32_t flash_size; | ||
1212 | uint32_t wrt_enable_data; | ||
1213 | uint8_t read_id_addr_len; | ||
1214 | uint8_t wrt_disable_bits; | ||
1215 | uint8_t read_dev_id_len; | ||
1216 | uint8_t chip_erase_cmd; | ||
1217 | uint16_t read_timeout; | ||
1218 | uint8_t protect_sec_cmd; | ||
1219 | uint8_t unused2[65]; | ||
1220 | }; | ||
1221 | |||
1222 | /* 84XX Support **************************************************************/ | ||
1223 | |||
1224 | #define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */ | ||
1225 | #define A84_PANIC_RECOVERY 0x1 | ||
1226 | #define A84_OP_LOGIN_COMPLETE 0x2 | ||
1227 | #define A84_DIAG_LOGIN_COMPLETE 0x3 | ||
1228 | #define A84_GOLD_LOGIN_COMPLETE 0x4 | ||
1229 | |||
1230 | #define MBC_ISP84XX_RESET 0x3a /* Reset. */ | ||
1231 | |||
1232 | #define FSTATE_REMOTE_FC_DOWN BIT_0 | ||
1233 | #define FSTATE_NSL_LINK_DOWN BIT_1 | ||
1234 | #define FSTATE_IS_DIAG_FW BIT_2 | ||
1235 | #define FSTATE_LOGGED_IN BIT_3 | ||
1236 | #define FSTATE_WAITING_FOR_VERIFY BIT_4 | ||
1237 | |||
1238 | #define VERIFY_CHIP_IOCB_TYPE 0x1B | ||
1239 | struct verify_chip_entry_84xx { | ||
1240 | uint8_t entry_type; | ||
1241 | uint8_t entry_count; | ||
1242 | uint8_t sys_defined; | ||
1243 | uint8_t entry_status; | ||
1244 | |||
1245 | uint32_t handle; | ||
1246 | |||
1247 | uint16_t options; | ||
1248 | #define VCO_DONT_UPDATE_FW BIT_0 | ||
1249 | #define VCO_FORCE_UPDATE BIT_1 | ||
1250 | #define VCO_DONT_RESET_UPDATE BIT_2 | ||
1251 | #define VCO_DIAG_FW BIT_3 | ||
1252 | #define VCO_END_OF_DATA BIT_14 | ||
1253 | #define VCO_ENABLE_DSD BIT_15 | ||
1254 | |||
1255 | uint16_t reserved_1; | ||
1256 | |||
1257 | uint16_t data_seg_cnt; | ||
1258 | uint16_t reserved_2[3]; | ||
1259 | |||
1260 | uint32_t fw_ver; | ||
1261 | uint32_t exchange_address; | ||
1262 | |||
1263 | uint32_t reserved_3[3]; | ||
1264 | uint32_t fw_size; | ||
1265 | uint32_t fw_seq_size; | ||
1266 | uint32_t relative_offset; | ||
1267 | |||
1268 | uint32_t dseg_address[2]; | ||
1269 | uint32_t dseg_length; | ||
1270 | }; | ||
1271 | |||
1272 | struct verify_chip_rsp_84xx { | ||
1273 | uint8_t entry_type; | ||
1274 | uint8_t entry_count; | ||
1275 | uint8_t sys_defined; | ||
1276 | uint8_t entry_status; | ||
1277 | |||
1278 | uint32_t handle; | ||
1279 | |||
1280 | uint16_t comp_status; | ||
1281 | #define CS_VCS_CHIP_FAILURE 0x3 | ||
1282 | #define CS_VCS_BAD_EXCHANGE 0x8 | ||
1283 | #define CS_VCS_SEQ_COMPLETEi 0x40 | ||
1284 | |||
1285 | uint16_t failure_code; | ||
1286 | #define VFC_CHECKSUM_ERROR 0x1 | ||
1287 | #define VFC_INVALID_LEN 0x2 | ||
1288 | #define VFC_ALREADY_IN_PROGRESS 0x8 | ||
1289 | |||
1290 | uint16_t reserved_1[4]; | ||
1291 | |||
1292 | uint32_t fw_ver; | ||
1293 | uint32_t exchange_address; | ||
1294 | |||
1295 | uint32_t reserved_2[6]; | ||
1296 | }; | ||
1297 | |||
1298 | #define ACCESS_CHIP_IOCB_TYPE 0x2B | ||
1299 | struct access_chip_84xx { | ||
1300 | uint8_t entry_type; | ||
1301 | uint8_t entry_count; | ||
1302 | uint8_t sys_defined; | ||
1303 | uint8_t entry_status; | ||
1304 | |||
1305 | uint32_t handle; | ||
1306 | |||
1307 | uint16_t options; | ||
1308 | #define ACO_DUMP_MEMORY 0x0 | ||
1309 | #define ACO_LOAD_MEMORY 0x1 | ||
1310 | #define ACO_CHANGE_CONFIG_PARAM 0x2 | ||
1311 | #define ACO_REQUEST_INFO 0x3 | ||
1312 | |||
1313 | uint16_t reserved1; | ||
1314 | |||
1315 | uint16_t dseg_count; | ||
1316 | uint16_t reserved2[3]; | ||
1317 | |||
1318 | uint32_t parameter1; | ||
1319 | uint32_t parameter2; | ||
1320 | uint32_t parameter3; | ||
1321 | |||
1322 | uint32_t reserved3[3]; | ||
1323 | uint32_t total_byte_cnt; | ||
1324 | uint32_t reserved4; | ||
1325 | |||
1326 | uint32_t dseg_address[2]; | ||
1327 | uint32_t dseg_length; | ||
1328 | }; | ||
1329 | |||
1330 | struct access_chip_rsp_84xx { | ||
1331 | uint8_t entry_type; | ||
1332 | uint8_t entry_count; | ||
1333 | uint8_t sys_defined; | ||
1334 | uint8_t entry_status; | ||
1335 | |||
1336 | uint32_t handle; | ||
1337 | |||
1338 | uint16_t comp_status; | ||
1339 | uint16_t failure_code; | ||
1340 | uint32_t residual_count; | ||
1341 | |||
1342 | uint32_t reserved[12]; | ||
1343 | }; | ||
1177 | #endif | 1344 | #endif |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 193f688ec3d7..a9571c214a9e 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -38,9 +38,6 @@ extern int qla2x00_loop_resync(scsi_qla_host_t *); | |||
38 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); | 38 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); |
39 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); | 39 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); |
40 | 40 | ||
41 | extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t); | ||
42 | |||
43 | extern void qla2x00_rescan_fcports(scsi_qla_host_t *); | ||
44 | extern void qla2x00_update_fcports(scsi_qla_host_t *); | 41 | extern void qla2x00_update_fcports(scsi_qla_host_t *); |
45 | 42 | ||
46 | extern int qla2x00_abort_isp(scsi_qla_host_t *); | 43 | extern int qla2x00_abort_isp(scsi_qla_host_t *); |
@@ -50,6 +47,8 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | |||
50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); | 47 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); |
51 | extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); | 48 | extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); |
52 | 49 | ||
50 | extern void qla84xx_put_chip(struct scsi_qla_host *); | ||
51 | |||
53 | /* | 52 | /* |
54 | * Global Data in qla_os.c source file. | 53 | * Global Data in qla_os.c source file. |
55 | */ | 54 | */ |
@@ -67,6 +66,10 @@ extern int num_hosts; | |||
67 | 66 | ||
68 | extern int qla2x00_loop_reset(scsi_qla_host_t *); | 67 | extern int qla2x00_loop_reset(scsi_qla_host_t *); |
69 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); | 68 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); |
69 | extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum | ||
70 | fc_host_event_code, u32); | ||
71 | extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, | ||
72 | uint16_t, uint16_t); | ||
70 | 73 | ||
71 | /* | 74 | /* |
72 | * Global Functions in qla_mid.c source file. | 75 | * Global Functions in qla_mid.c source file. |
@@ -149,12 +152,17 @@ extern int | |||
149 | qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t); | 152 | qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t); |
150 | 153 | ||
151 | extern int | 154 | extern int |
155 | qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t, | ||
156 | uint32_t); | ||
157 | |||
158 | extern int | ||
152 | qla2x00_abort_command(scsi_qla_host_t *, srb_t *); | 159 | qla2x00_abort_command(scsi_qla_host_t *, srb_t *); |
153 | 160 | ||
154 | #if USE_ABORT_TGT | ||
155 | extern int | 161 | extern int |
156 | qla2x00_abort_target(fc_port_t *); | 162 | qla2x00_abort_target(struct fc_port *, unsigned int); |
157 | #endif | 163 | |
164 | extern int | ||
165 | qla2x00_lun_reset(struct fc_port *, unsigned int); | ||
158 | 166 | ||
159 | extern int | 167 | extern int |
160 | qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, | 168 | qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, |
@@ -220,7 +228,8 @@ qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *, | |||
220 | dma_addr_t); | 228 | dma_addr_t); |
221 | 229 | ||
222 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); | 230 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); |
223 | extern int qla24xx_abort_target(fc_port_t *); | 231 | extern int qla24xx_abort_target(struct fc_port *, unsigned int); |
232 | extern int qla24xx_lun_reset(struct fc_port *, unsigned int); | ||
224 | 233 | ||
225 | extern int | 234 | extern int |
226 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | 235 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); |
@@ -246,6 +255,8 @@ qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | |||
246 | extern int | 255 | extern int |
247 | qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); | 256 | qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); |
248 | 257 | ||
258 | extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *); | ||
259 | |||
249 | /* | 260 | /* |
250 | * Global Function Prototypes in qla_isr.c source file. | 261 | * Global Function Prototypes in qla_isr.c source file. |
251 | */ | 262 | */ |
@@ -298,6 +309,11 @@ extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | |||
298 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); | 309 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); |
299 | extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); | 310 | extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); |
300 | 311 | ||
312 | extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t, | ||
313 | uint16_t, uint16_t); | ||
314 | |||
315 | extern void qla2xxx_get_flash_info(scsi_qla_host_t *); | ||
316 | |||
301 | /* | 317 | /* |
302 | * Global Function Prototypes in qla_dbg.c source file. | 318 | * Global Function Prototypes in qla_dbg.c source file. |
303 | */ | 319 | */ |
@@ -307,7 +323,6 @@ extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | |||
307 | extern void qla25xx_fw_dump(scsi_qla_host_t *, int); | 323 | extern void qla25xx_fw_dump(scsi_qla_host_t *, int); |
308 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 324 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
309 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 325 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
310 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); | ||
311 | 326 | ||
312 | /* | 327 | /* |
313 | * Global Function Prototypes in qla_gs.c source file. | 328 | * Global Function Prototypes in qla_gs.c source file. |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index c1808763d40e..750d7ef83aae 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -1,17 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | static inline struct ct_sns_req * | ||
10 | qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t); | ||
11 | |||
12 | static inline struct sns_cmd_pkt * | ||
13 | qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | ||
14 | |||
15 | static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); | 9 | static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); |
16 | static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); | 10 | static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); |
17 | static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); | 11 | static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); |
@@ -1538,7 +1532,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1538 | eiter->a.sup_speed = __constant_cpu_to_be32( | 1532 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1539 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | 1533 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| |
1540 | FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB); | 1534 | FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB); |
1541 | else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 1535 | else if (IS_QLA24XX_TYPE(ha)) |
1542 | eiter->a.sup_speed = __constant_cpu_to_be32( | 1536 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1543 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | 1537 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| |
1544 | FDMI_PORT_SPEED_4GB); | 1538 | FDMI_PORT_SPEED_4GB); |
@@ -1847,8 +1841,10 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) | |||
1847 | "GPSC")) != QLA_SUCCESS) { | 1841 | "GPSC")) != QLA_SUCCESS) { |
1848 | /* FM command unsupported? */ | 1842 | /* FM command unsupported? */ |
1849 | if (rval == QLA_INVALID_COMMAND && | 1843 | if (rval == QLA_INVALID_COMMAND && |
1850 | ct_rsp->header.reason_code == | 1844 | (ct_rsp->header.reason_code == |
1851 | CT_REASON_INVALID_COMMAND_CODE) { | 1845 | CT_REASON_INVALID_COMMAND_CODE || |
1846 | ct_rsp->header.reason_code == | ||
1847 | CT_REASON_COMMAND_UNSUPPORTED)) { | ||
1852 | DEBUG2(printk("scsi(%ld): GPSC command " | 1848 | DEBUG2(printk("scsi(%ld): GPSC command " |
1853 | "unsupported, disabling query...\n", | 1849 | "unsupported, disabling query...\n", |
1854 | ha->host_no)); | 1850 | ha->host_no)); |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 364be7d06875..01e26087c1dd 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -15,14 +15,6 @@ | |||
15 | #include <asm/prom.h> | 15 | #include <asm/prom.h> |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | /* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */ | ||
19 | #ifndef EXT_IS_LUN_BIT_SET | ||
20 | #define EXT_IS_LUN_BIT_SET(P,L) \ | ||
21 | (((P)->mask[L/8] & (0x80 >> (L%8)))?1:0) | ||
22 | #define EXT_SET_LUN_BIT(P,L) \ | ||
23 | ((P)->mask[L/8] |= (0x80 >> (L%8))) | ||
24 | #endif | ||
25 | |||
26 | /* | 18 | /* |
27 | * QLogic ISP2x00 Hardware Support Function Prototypes. | 19 | * QLogic ISP2x00 Hardware Support Function Prototypes. |
28 | */ | 20 | */ |
@@ -45,6 +37,9 @@ static int qla2x00_restart_isp(scsi_qla_host_t *); | |||
45 | 37 | ||
46 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); | 38 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); |
47 | 39 | ||
40 | static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); | ||
41 | static int qla84xx_init_chip(scsi_qla_host_t *); | ||
42 | |||
48 | /****************************************************************************/ | 43 | /****************************************************************************/ |
49 | /* QLogic ISP2x00 Hardware Support Functions. */ | 44 | /* QLogic ISP2x00 Hardware Support Functions. */ |
50 | /****************************************************************************/ | 45 | /****************************************************************************/ |
@@ -114,6 +109,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
114 | rval = qla2x00_setup_chip(ha); | 109 | rval = qla2x00_setup_chip(ha); |
115 | if (rval) | 110 | if (rval) |
116 | return (rval); | 111 | return (rval); |
112 | qla2xxx_get_flash_info(ha); | ||
113 | } | ||
114 | if (IS_QLA84XX(ha)) { | ||
115 | ha->cs84xx = qla84xx_get_chip(ha); | ||
116 | if (!ha->cs84xx) { | ||
117 | qla_printk(KERN_ERR, ha, | ||
118 | "Unable to configure ISP84XX.\n"); | ||
119 | return QLA_FUNCTION_FAILED; | ||
120 | } | ||
117 | } | 121 | } |
118 | rval = qla2x00_init_rings(ha); | 122 | rval = qla2x00_init_rings(ha); |
119 | 123 | ||
@@ -500,6 +504,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) | |||
500 | static inline void | 504 | static inline void |
501 | qla24xx_reset_risc(scsi_qla_host_t *ha) | 505 | qla24xx_reset_risc(scsi_qla_host_t *ha) |
502 | { | 506 | { |
507 | int hw_evt = 0; | ||
503 | unsigned long flags = 0; | 508 | unsigned long flags = 0; |
504 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 509 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
505 | uint32_t cnt, d2; | 510 | uint32_t cnt, d2; |
@@ -528,6 +533,8 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) | |||
528 | d2 = (uint32_t) RD_REG_WORD(®->mailbox0); | 533 | d2 = (uint32_t) RD_REG_WORD(®->mailbox0); |
529 | barrier(); | 534 | barrier(); |
530 | } | 535 | } |
536 | if (cnt == 0) | ||
537 | hw_evt = 1; | ||
531 | 538 | ||
532 | /* Wait for soft-reset to complete. */ | 539 | /* Wait for soft-reset to complete. */ |
533 | d2 = RD_REG_DWORD(®->ctrl_status); | 540 | d2 = RD_REG_DWORD(®->ctrl_status); |
@@ -536,6 +543,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) | |||
536 | d2 = RD_REG_DWORD(®->ctrl_status); | 543 | d2 = RD_REG_DWORD(®->ctrl_status); |
537 | barrier(); | 544 | barrier(); |
538 | } | 545 | } |
546 | if (cnt == 0 || hw_evt) | ||
547 | qla2xxx_hw_event_log(ha, HW_EVENT_RESET_ERR, | ||
548 | RD_REG_WORD(®->mailbox1), RD_REG_WORD(®->mailbox2), | ||
549 | RD_REG_WORD(®->mailbox3)); | ||
539 | 550 | ||
540 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); | 551 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); |
541 | RD_REG_DWORD(®->hccr); | 552 | RD_REG_DWORD(®->hccr); |
@@ -1243,10 +1254,10 @@ static int | |||
1243 | qla2x00_fw_ready(scsi_qla_host_t *ha) | 1254 | qla2x00_fw_ready(scsi_qla_host_t *ha) |
1244 | { | 1255 | { |
1245 | int rval; | 1256 | int rval; |
1246 | unsigned long wtime, mtime; | 1257 | unsigned long wtime, mtime, cs84xx_time; |
1247 | uint16_t min_wait; /* Minimum wait time if loop is down */ | 1258 | uint16_t min_wait; /* Minimum wait time if loop is down */ |
1248 | uint16_t wait_time; /* Wait time if loop is coming ready */ | 1259 | uint16_t wait_time; /* Wait time if loop is coming ready */ |
1249 | uint16_t fw_state; | 1260 | uint16_t state[3]; |
1250 | 1261 | ||
1251 | rval = QLA_SUCCESS; | 1262 | rval = QLA_SUCCESS; |
1252 | 1263 | ||
@@ -1275,12 +1286,34 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1275 | ha->host_no)); | 1286 | ha->host_no)); |
1276 | 1287 | ||
1277 | do { | 1288 | do { |
1278 | rval = qla2x00_get_firmware_state(ha, &fw_state); | 1289 | rval = qla2x00_get_firmware_state(ha, state); |
1279 | if (rval == QLA_SUCCESS) { | 1290 | if (rval == QLA_SUCCESS) { |
1280 | if (fw_state < FSTATE_LOSS_OF_SYNC) { | 1291 | if (state[0] < FSTATE_LOSS_OF_SYNC) { |
1281 | ha->device_flags &= ~DFLG_NO_CABLE; | 1292 | ha->device_flags &= ~DFLG_NO_CABLE; |
1282 | } | 1293 | } |
1283 | if (fw_state == FSTATE_READY) { | 1294 | if (IS_QLA84XX(ha) && state[0] != FSTATE_READY) { |
1295 | DEBUG16(printk("scsi(%ld): fw_state=%x " | ||
1296 | "84xx=%x.\n", ha->host_no, state[0], | ||
1297 | state[2])); | ||
1298 | if ((state[2] & FSTATE_LOGGED_IN) && | ||
1299 | (state[2] & FSTATE_WAITING_FOR_VERIFY)) { | ||
1300 | DEBUG16(printk("scsi(%ld): Sending " | ||
1301 | "verify iocb.\n", ha->host_no)); | ||
1302 | |||
1303 | cs84xx_time = jiffies; | ||
1304 | rval = qla84xx_init_chip(ha); | ||
1305 | if (rval != QLA_SUCCESS) | ||
1306 | break; | ||
1307 | |||
1308 | /* Add time taken to initialize. */ | ||
1309 | cs84xx_time = jiffies - cs84xx_time; | ||
1310 | wtime += cs84xx_time; | ||
1311 | mtime += cs84xx_time; | ||
1312 | DEBUG16(printk("scsi(%ld): Increasing " | ||
1313 | "wait time by %ld. New time %ld\n", | ||
1314 | ha->host_no, cs84xx_time, wtime)); | ||
1315 | } | ||
1316 | } else if (state[0] == FSTATE_READY) { | ||
1284 | DEBUG(printk("scsi(%ld): F/W Ready - OK \n", | 1317 | DEBUG(printk("scsi(%ld): F/W Ready - OK \n", |
1285 | ha->host_no)); | 1318 | ha->host_no)); |
1286 | 1319 | ||
@@ -1294,7 +1327,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1294 | rval = QLA_FUNCTION_FAILED; | 1327 | rval = QLA_FUNCTION_FAILED; |
1295 | 1328 | ||
1296 | if (atomic_read(&ha->loop_down_timer) && | 1329 | if (atomic_read(&ha->loop_down_timer) && |
1297 | fw_state != FSTATE_READY) { | 1330 | state[0] != FSTATE_READY) { |
1298 | /* Loop down. Timeout on min_wait for states | 1331 | /* Loop down. Timeout on min_wait for states |
1299 | * other than Wait for Login. | 1332 | * other than Wait for Login. |
1300 | */ | 1333 | */ |
@@ -1319,11 +1352,11 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1319 | msleep(500); | 1352 | msleep(500); |
1320 | 1353 | ||
1321 | DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", | 1354 | DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", |
1322 | ha->host_no, fw_state, jiffies)); | 1355 | ha->host_no, state[0], jiffies)); |
1323 | } while (1); | 1356 | } while (1); |
1324 | 1357 | ||
1325 | DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", | 1358 | DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", |
1326 | ha->host_no, fw_state, jiffies)); | 1359 | ha->host_no, state[0], jiffies)); |
1327 | 1360 | ||
1328 | if (rval) { | 1361 | if (rval) { |
1329 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", | 1362 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", |
@@ -1555,6 +1588,10 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1555 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " | 1588 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " |
1556 | "invalid -- WWPN) defaults.\n"); | 1589 | "invalid -- WWPN) defaults.\n"); |
1557 | 1590 | ||
1591 | if (chksum) | ||
1592 | qla2xxx_hw_event_log(ha, HW_EVENT_NVRAM_CHKSUM_ERR, 0, | ||
1593 | MSW(chksum), LSW(chksum)); | ||
1594 | |||
1558 | /* | 1595 | /* |
1559 | * Set default initialization control block. | 1596 | * Set default initialization control block. |
1560 | */ | 1597 | */ |
@@ -2165,20 +2202,6 @@ cleanup_allocation: | |||
2165 | } | 2202 | } |
2166 | 2203 | ||
2167 | static void | 2204 | static void |
2168 | qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) | ||
2169 | { | ||
2170 | fc_port_t *fcport; | ||
2171 | |||
2172 | qla2x00_mark_all_devices_lost(ha, 0); | ||
2173 | list_for_each_entry(fcport, &ha->fcports, list) { | ||
2174 | if (fcport->port_type != FCT_TARGET) | ||
2175 | continue; | ||
2176 | |||
2177 | qla2x00_update_fcport(ha, fcport); | ||
2178 | } | ||
2179 | } | ||
2180 | |||
2181 | static void | ||
2182 | qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | 2205 | qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) |
2183 | { | 2206 | { |
2184 | #define LS_UNKNOWN 2 | 2207 | #define LS_UNKNOWN 2 |
@@ -2251,10 +2274,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2251 | if (fcport->port_type == FCT_TARGET) | 2274 | if (fcport->port_type == FCT_TARGET) |
2252 | rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; | 2275 | rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; |
2253 | fc_remote_port_rolechg(rport, rport_ids.roles); | 2276 | fc_remote_port_rolechg(rport, rport_ids.roles); |
2254 | |||
2255 | if (rport->scsi_target_id != -1 && | ||
2256 | rport->scsi_target_id < ha->host->max_id) | ||
2257 | fcport->os_target_id = rport->scsi_target_id; | ||
2258 | } | 2277 | } |
2259 | 2278 | ||
2260 | /* | 2279 | /* |
@@ -2434,7 +2453,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2434 | 2453 | ||
2435 | if (fcport->loop_id == FC_NO_LOOP_ID) { | 2454 | if (fcport->loop_id == FC_NO_LOOP_ID) { |
2436 | fcport->loop_id = next_loopid; | 2455 | fcport->loop_id = next_loopid; |
2437 | rval = qla2x00_find_new_loop_id(ha, fcport); | 2456 | rval = qla2x00_find_new_loop_id( |
2457 | to_qla_parent(ha), fcport); | ||
2438 | if (rval != QLA_SUCCESS) { | 2458 | if (rval != QLA_SUCCESS) { |
2439 | /* Ran out of IDs to use */ | 2459 | /* Ran out of IDs to use */ |
2440 | break; | 2460 | break; |
@@ -2459,7 +2479,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2459 | 2479 | ||
2460 | /* Find a new loop ID to use. */ | 2480 | /* Find a new loop ID to use. */ |
2461 | fcport->loop_id = next_loopid; | 2481 | fcport->loop_id = next_loopid; |
2462 | rval = qla2x00_find_new_loop_id(ha, fcport); | 2482 | rval = qla2x00_find_new_loop_id(to_qla_parent(ha), |
2483 | fcport); | ||
2463 | if (rval != QLA_SUCCESS) { | 2484 | if (rval != QLA_SUCCESS) { |
2464 | /* Ran out of IDs to use */ | 2485 | /* Ran out of IDs to use */ |
2465 | break; | 2486 | break; |
@@ -3193,25 +3214,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha) | |||
3193 | } | 3214 | } |
3194 | 3215 | ||
3195 | void | 3216 | void |
3196 | qla2x00_rescan_fcports(scsi_qla_host_t *ha) | ||
3197 | { | ||
3198 | int rescan_done; | ||
3199 | fc_port_t *fcport; | ||
3200 | |||
3201 | rescan_done = 0; | ||
3202 | list_for_each_entry(fcport, &ha->fcports, list) { | ||
3203 | if ((fcport->flags & FCF_RESCAN_NEEDED) == 0) | ||
3204 | continue; | ||
3205 | |||
3206 | qla2x00_update_fcport(ha, fcport); | ||
3207 | fcport->flags &= ~FCF_RESCAN_NEEDED; | ||
3208 | |||
3209 | rescan_done = 1; | ||
3210 | } | ||
3211 | qla2x00_probe_for_all_luns(ha); | ||
3212 | } | ||
3213 | |||
3214 | void | ||
3215 | qla2x00_update_fcports(scsi_qla_host_t *ha) | 3217 | qla2x00_update_fcports(scsi_qla_host_t *ha) |
3216 | { | 3218 | { |
3217 | fc_port_t *fcport; | 3219 | fc_port_t *fcport; |
@@ -4044,16 +4046,16 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) | |||
4044 | if (!ha->parent) | 4046 | if (!ha->parent) |
4045 | return -EINVAL; | 4047 | return -EINVAL; |
4046 | 4048 | ||
4047 | rval = qla2x00_fw_ready(ha); | 4049 | rval = qla2x00_fw_ready(ha->parent); |
4048 | if (rval == QLA_SUCCESS) { | 4050 | if (rval == QLA_SUCCESS) { |
4049 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 4051 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
4050 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | 4052 | qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL); |
4051 | } | 4053 | } |
4052 | 4054 | ||
4053 | ha->flags.management_server_logged_in = 0; | 4055 | ha->flags.management_server_logged_in = 0; |
4054 | 4056 | ||
4055 | /* Login to SNS first */ | 4057 | /* Login to SNS first */ |
4056 | qla24xx_login_fabric(ha, NPH_SNS, 0xff, 0xff, 0xfc, | 4058 | qla24xx_login_fabric(ha->parent, NPH_SNS, 0xff, 0xff, 0xfc, |
4057 | mb, BIT_1); | 4059 | mb, BIT_1); |
4058 | if (mb[0] != MBS_COMMAND_COMPLETE) { | 4060 | if (mb[0] != MBS_COMMAND_COMPLETE) { |
4059 | DEBUG15(qla_printk(KERN_INFO, ha, | 4061 | DEBUG15(qla_printk(KERN_INFO, ha, |
@@ -4067,7 +4069,77 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) | |||
4067 | atomic_set(&ha->loop_state, LOOP_UP); | 4069 | atomic_set(&ha->loop_state, LOOP_UP); |
4068 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 4070 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
4069 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 4071 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
4070 | rval = qla2x00_loop_resync(ha); | 4072 | rval = qla2x00_loop_resync(ha->parent); |
4071 | 4073 | ||
4072 | return rval; | 4074 | return rval; |
4073 | } | 4075 | } |
4076 | |||
4077 | /* 84XX Support **************************************************************/ | ||
4078 | |||
4079 | static LIST_HEAD(qla_cs84xx_list); | ||
4080 | static DEFINE_MUTEX(qla_cs84xx_mutex); | ||
4081 | |||
4082 | static struct qla_chip_state_84xx * | ||
4083 | qla84xx_get_chip(struct scsi_qla_host *ha) | ||
4084 | { | ||
4085 | struct qla_chip_state_84xx *cs84xx; | ||
4086 | |||
4087 | mutex_lock(&qla_cs84xx_mutex); | ||
4088 | |||
4089 | /* Find any shared 84xx chip. */ | ||
4090 | list_for_each_entry(cs84xx, &qla_cs84xx_list, list) { | ||
4091 | if (cs84xx->bus == ha->pdev->bus) { | ||
4092 | kref_get(&cs84xx->kref); | ||
4093 | goto done; | ||
4094 | } | ||
4095 | } | ||
4096 | |||
4097 | cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL); | ||
4098 | if (!cs84xx) | ||
4099 | goto done; | ||
4100 | |||
4101 | kref_init(&cs84xx->kref); | ||
4102 | spin_lock_init(&cs84xx->access_lock); | ||
4103 | mutex_init(&cs84xx->fw_update_mutex); | ||
4104 | cs84xx->bus = ha->pdev->bus; | ||
4105 | |||
4106 | list_add_tail(&cs84xx->list, &qla_cs84xx_list); | ||
4107 | done: | ||
4108 | mutex_unlock(&qla_cs84xx_mutex); | ||
4109 | return cs84xx; | ||
4110 | } | ||
4111 | |||
4112 | static void | ||
4113 | __qla84xx_chip_release(struct kref *kref) | ||
4114 | { | ||
4115 | struct qla_chip_state_84xx *cs84xx = | ||
4116 | container_of(kref, struct qla_chip_state_84xx, kref); | ||
4117 | |||
4118 | mutex_lock(&qla_cs84xx_mutex); | ||
4119 | list_del(&cs84xx->list); | ||
4120 | mutex_unlock(&qla_cs84xx_mutex); | ||
4121 | kfree(cs84xx); | ||
4122 | } | ||
4123 | |||
4124 | void | ||
4125 | qla84xx_put_chip(struct scsi_qla_host *ha) | ||
4126 | { | ||
4127 | if (ha->cs84xx) | ||
4128 | kref_put(&ha->cs84xx->kref, __qla84xx_chip_release); | ||
4129 | } | ||
4130 | |||
4131 | static int | ||
4132 | qla84xx_init_chip(scsi_qla_host_t *ha) | ||
4133 | { | ||
4134 | int rval; | ||
4135 | uint16_t status[2]; | ||
4136 | |||
4137 | mutex_lock(&ha->cs84xx->fw_update_mutex); | ||
4138 | |||
4139 | rval = qla84xx_verify_chip(ha, status); | ||
4140 | |||
4141 | mutex_unlock(&ha->cs84xx->fw_update_mutex); | ||
4142 | |||
4143 | return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED: | ||
4144 | QLA_SUCCESS; | ||
4145 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 5d1a3f7c408f..e9bae27737d1 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | static __inline__ uint16_t qla2x00_debounce_register(volatile uint16_t __iomem *); | ||
9 | /* | 8 | /* |
10 | * qla2x00_debounce_register | 9 | * qla2x00_debounce_register |
11 | * Debounce register. | 10 | * Debounce register. |
@@ -32,94 +31,12 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr) | |||
32 | return (first); | 31 | return (first); |
33 | } | 32 | } |
34 | 33 | ||
35 | static __inline__ int qla2x00_normalize_dma_addr( | ||
36 | dma_addr_t *e_addr, uint32_t *e_len, | ||
37 | dma_addr_t *ne_addr, uint32_t *ne_len); | ||
38 | |||
39 | /** | ||
40 | * qla2x00_normalize_dma_addr() - Normalize an DMA address. | ||
41 | * @e_addr: Raw DMA address | ||
42 | * @e_len: Raw DMA length | ||
43 | * @ne_addr: Normalized second DMA address | ||
44 | * @ne_len: Normalized second DMA length | ||
45 | * | ||
46 | * If the address does not span a 4GB page boundary, the contents of @ne_addr | ||
47 | * and @ne_len are undefined. @e_len is updated to reflect a normalization. | ||
48 | * | ||
49 | * Example: | ||
50 | * | ||
51 | * ffffabc0ffffeeee (e_addr) start of DMA address | ||
52 | * 0000000020000000 (e_len) length of DMA transfer | ||
53 | * ffffabc11fffeeed end of DMA transfer | ||
54 | * | ||
55 | * Is the 4GB boundary crossed? | ||
56 | * | ||
57 | * ffffabc0ffffeeee (e_addr) | ||
58 | * ffffabc11fffeeed (e_addr + e_len - 1) | ||
59 | * 00000001e0000003 ((e_addr ^ (e_addr + e_len - 1)) | ||
60 | * 0000000100000000 ((e_addr ^ (e_addr + e_len - 1)) & ~(0xffffffff) | ||
61 | * | ||
62 | * Compute start of second DMA segment: | ||
63 | * | ||
64 | * ffffabc0ffffeeee (e_addr) | ||
65 | * ffffabc1ffffeeee (0x100000000 + e_addr) | ||
66 | * ffffabc100000000 (0x100000000 + e_addr) & ~(0xffffffff) | ||
67 | * ffffabc100000000 (ne_addr) | ||
68 | * | ||
69 | * Compute length of second DMA segment: | ||
70 | * | ||
71 | * 00000000ffffeeee (e_addr & 0xffffffff) | ||
72 | * 0000000000001112 (0x100000000 - (e_addr & 0xffffffff)) | ||
73 | * 000000001fffeeee (e_len - (0x100000000 - (e_addr & 0xffffffff)) | ||
74 | * 000000001fffeeee (ne_len) | ||
75 | * | ||
76 | * Adjust length of first DMA segment | ||
77 | * | ||
78 | * 0000000020000000 (e_len) | ||
79 | * 0000000000001112 (e_len - ne_len) | ||
80 | * 0000000000001112 (e_len) | ||
81 | * | ||
82 | * Returns non-zero if the specified address was normalized, else zero. | ||
83 | */ | ||
84 | static __inline__ int | ||
85 | qla2x00_normalize_dma_addr( | ||
86 | dma_addr_t *e_addr, uint32_t *e_len, | ||
87 | dma_addr_t *ne_addr, uint32_t *ne_len) | ||
88 | { | ||
89 | int normalized; | ||
90 | |||
91 | normalized = 0; | ||
92 | if ((*e_addr ^ (*e_addr + *e_len - 1)) & ~(0xFFFFFFFFULL)) { | ||
93 | /* Compute normalized crossed address and len */ | ||
94 | *ne_addr = (0x100000000ULL + *e_addr) & ~(0xFFFFFFFFULL); | ||
95 | *ne_len = *e_len - (0x100000000ULL - (*e_addr & 0xFFFFFFFFULL)); | ||
96 | *e_len -= *ne_len; | ||
97 | |||
98 | normalized++; | ||
99 | } | ||
100 | return (normalized); | ||
101 | } | ||
102 | |||
103 | static __inline__ void qla2x00_poll(scsi_qla_host_t *); | ||
104 | static inline void | 34 | static inline void |
105 | qla2x00_poll(scsi_qla_host_t *ha) | 35 | qla2x00_poll(scsi_qla_host_t *ha) |
106 | { | 36 | { |
107 | ha->isp_ops->intr_handler(0, ha); | 37 | ha->isp_ops->intr_handler(0, ha); |
108 | } | 38 | } |
109 | 39 | ||
110 | static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *); | ||
111 | /* | ||
112 | * This routine will wait for fabric devices for | ||
113 | * the reset delay. | ||
114 | */ | ||
115 | static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *ha) | ||
116 | { | ||
117 | uint16_t fw_state; | ||
118 | |||
119 | qla2x00_get_firmware_state(ha, &fw_state); | ||
120 | } | ||
121 | |||
122 | static __inline__ scsi_qla_host_t * to_qla_parent(scsi_qla_host_t *); | ||
123 | static __inline__ scsi_qla_host_t * | 40 | static __inline__ scsi_qla_host_t * |
124 | to_qla_parent(scsi_qla_host_t *ha) | 41 | to_qla_parent(scsi_qla_host_t *ha) |
125 | { | 42 | { |
@@ -152,7 +69,6 @@ qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked) | |||
152 | return (QLA_SUCCESS); | 69 | return (QLA_SUCCESS); |
153 | } | 70 | } |
154 | 71 | ||
155 | static inline uint8_t *host_to_fcp_swap(uint8_t *, uint32_t); | ||
156 | static inline uint8_t * | 72 | static inline uint8_t * |
157 | host_to_fcp_swap(uint8_t *fcp, uint32_t bsize) | 73 | host_to_fcp_swap(uint8_t *fcp, uint32_t bsize) |
158 | { | 74 | { |
@@ -166,7 +82,6 @@ host_to_fcp_swap(uint8_t *fcp, uint32_t bsize) | |||
166 | return fcp; | 82 | return fcp; |
167 | } | 83 | } |
168 | 84 | ||
169 | static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t); | ||
170 | static inline int | 85 | static inline int |
171 | qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id) | 86 | qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id) |
172 | { | 87 | { |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 024c662ec34d..5489d5024673 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -11,9 +11,6 @@ | |||
11 | 11 | ||
12 | #include <scsi/scsi_tcq.h> | 12 | #include <scsi/scsi_tcq.h> |
13 | 13 | ||
14 | static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd); | ||
15 | static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *); | ||
16 | static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *); | ||
17 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); | 14 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); |
18 | static void qla2x00_isp_cmd(scsi_qla_host_t *ha); | 15 | static void qla2x00_isp_cmd(scsi_qla_host_t *ha); |
19 | 16 | ||
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index f0337036c7bb..285479b62d8f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -14,9 +14,6 @@ static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); | |||
14 | static void qla2x00_status_entry(scsi_qla_host_t *, void *); | 14 | static void qla2x00_status_entry(scsi_qla_host_t *, void *); |
15 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); | 15 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); |
16 | static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); | 16 | static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); |
17 | static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *); | ||
18 | |||
19 | static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *); | ||
20 | 17 | ||
21 | /** | 18 | /** |
22 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. | 19 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. |
@@ -33,7 +30,6 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
33 | scsi_qla_host_t *ha; | 30 | scsi_qla_host_t *ha; |
34 | struct device_reg_2xxx __iomem *reg; | 31 | struct device_reg_2xxx __iomem *reg; |
35 | int status; | 32 | int status; |
36 | unsigned long flags; | ||
37 | unsigned long iter; | 33 | unsigned long iter; |
38 | uint16_t hccr; | 34 | uint16_t hccr; |
39 | uint16_t mb[4]; | 35 | uint16_t mb[4]; |
@@ -48,7 +44,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
48 | reg = &ha->iobase->isp; | 44 | reg = &ha->iobase->isp; |
49 | status = 0; | 45 | status = 0; |
50 | 46 | ||
51 | spin_lock_irqsave(&ha->hardware_lock, flags); | 47 | spin_lock(&ha->hardware_lock); |
52 | for (iter = 50; iter--; ) { | 48 | for (iter = 50; iter--; ) { |
53 | hccr = RD_REG_WORD(®->hccr); | 49 | hccr = RD_REG_WORD(®->hccr); |
54 | if (hccr & HCCR_RISC_PAUSE) { | 50 | if (hccr & HCCR_RISC_PAUSE) { |
@@ -99,7 +95,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
99 | RD_REG_WORD(®->hccr); | 95 | RD_REG_WORD(®->hccr); |
100 | } | 96 | } |
101 | } | 97 | } |
102 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 98 | spin_unlock(&ha->hardware_lock); |
103 | 99 | ||
104 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 100 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
105 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 101 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -125,7 +121,6 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
125 | scsi_qla_host_t *ha; | 121 | scsi_qla_host_t *ha; |
126 | struct device_reg_2xxx __iomem *reg; | 122 | struct device_reg_2xxx __iomem *reg; |
127 | int status; | 123 | int status; |
128 | unsigned long flags; | ||
129 | unsigned long iter; | 124 | unsigned long iter; |
130 | uint32_t stat; | 125 | uint32_t stat; |
131 | uint16_t hccr; | 126 | uint16_t hccr; |
@@ -141,7 +136,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
141 | reg = &ha->iobase->isp; | 136 | reg = &ha->iobase->isp; |
142 | status = 0; | 137 | status = 0; |
143 | 138 | ||
144 | spin_lock_irqsave(&ha->hardware_lock, flags); | 139 | spin_lock(&ha->hardware_lock); |
145 | for (iter = 50; iter--; ) { | 140 | for (iter = 50; iter--; ) { |
146 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 141 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
147 | if (stat & HSR_RISC_PAUSED) { | 142 | if (stat & HSR_RISC_PAUSED) { |
@@ -211,7 +206,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
211 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | 206 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
212 | RD_REG_WORD_RELAXED(®->hccr); | 207 | RD_REG_WORD_RELAXED(®->hccr); |
213 | } | 208 | } |
214 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 209 | spin_unlock(&ha->hardware_lock); |
215 | 210 | ||
216 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 211 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
217 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 212 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -276,6 +271,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
276 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 271 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
277 | uint32_t rscn_entry, host_pid; | 272 | uint32_t rscn_entry, host_pid; |
278 | uint8_t rscn_queue_index; | 273 | uint8_t rscn_queue_index; |
274 | unsigned long flags; | ||
275 | scsi_qla_host_t *vha; | ||
276 | int i; | ||
279 | 277 | ||
280 | /* Setup to process RIO completion. */ | 278 | /* Setup to process RIO completion. */ |
281 | handle_cnt = 0; | 279 | handle_cnt = 0; |
@@ -351,6 +349,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
351 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", | 349 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", |
352 | mb[1], mb[2], mb[3]); | 350 | mb[1], mb[2], mb[3]); |
353 | 351 | ||
352 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
354 | ha->isp_ops->fw_dump(ha, 1); | 353 | ha->isp_ops->fw_dump(ha, 1); |
355 | 354 | ||
356 | if (IS_FWI2_CAPABLE(ha)) { | 355 | if (IS_FWI2_CAPABLE(ha)) { |
@@ -375,6 +374,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
375 | ha->host_no)); | 374 | ha->host_no)); |
376 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); | 375 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); |
377 | 376 | ||
377 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
378 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 378 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
379 | break; | 379 | break; |
380 | 380 | ||
@@ -383,6 +383,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
383 | ha->host_no)); | 383 | ha->host_no)); |
384 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); | 384 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); |
385 | 385 | ||
386 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
386 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 387 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
387 | break; | 388 | break; |
388 | 389 | ||
@@ -410,6 +411,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
410 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | 411 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); |
411 | 412 | ||
412 | ha->flags.management_server_logged_in = 0; | 413 | ha->flags.management_server_logged_in = 0; |
414 | qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]); | ||
413 | break; | 415 | break; |
414 | 416 | ||
415 | case MBA_LOOP_UP: /* Loop Up Event */ | 417 | case MBA_LOOP_UP: /* Loop Up Event */ |
@@ -429,12 +431,14 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
429 | link_speed); | 431 | link_speed); |
430 | 432 | ||
431 | ha->flags.management_server_logged_in = 0; | 433 | ha->flags.management_server_logged_in = 0; |
434 | qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate); | ||
432 | break; | 435 | break; |
433 | 436 | ||
434 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 437 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
435 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n", | 438 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN " |
436 | ha->host_no, mb[1])); | 439 | "(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3])); |
437 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]); | 440 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n", |
441 | mb[1], mb[2], mb[3]); | ||
438 | 442 | ||
439 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 443 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { |
440 | atomic_set(&ha->loop_state, LOOP_DOWN); | 444 | atomic_set(&ha->loop_state, LOOP_DOWN); |
@@ -452,6 +456,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
452 | ha->link_data_rate = PORT_SPEED_UNKNOWN; | 456 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
453 | if (ql2xfdmienable) | 457 | if (ql2xfdmienable) |
454 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 458 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
459 | qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0); | ||
455 | break; | 460 | break; |
456 | 461 | ||
457 | case MBA_LIP_RESET: /* LIP reset occurred */ | 462 | case MBA_LIP_RESET: /* LIP reset occurred */ |
@@ -475,6 +480,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
475 | 480 | ||
476 | ha->operating_mode = LOOP; | 481 | ha->operating_mode = LOOP; |
477 | ha->flags.management_server_logged_in = 0; | 482 | ha->flags.management_server_logged_in = 0; |
483 | qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]); | ||
478 | break; | 484 | break; |
479 | 485 | ||
480 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 486 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
@@ -538,6 +544,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
538 | break; | 544 | break; |
539 | 545 | ||
540 | case MBA_PORT_UPDATE: /* Port database update */ | 546 | case MBA_PORT_UPDATE: /* Port database update */ |
547 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { | ||
548 | for_each_mapped_vp_idx(ha, i) { | ||
549 | list_for_each_entry(vha, &ha->vp_list, | ||
550 | vp_list) { | ||
551 | if ((mb[3] & 0xff) | ||
552 | == vha->vp_idx) { | ||
553 | ha = vha; | ||
554 | break; | ||
555 | } | ||
556 | } | ||
557 | } | ||
558 | } | ||
541 | /* | 559 | /* |
542 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET | 560 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET |
543 | * event etc. earlier indicating loop is down) then process | 561 | * event etc. earlier indicating loop is down) then process |
@@ -572,12 +590,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
572 | break; | 590 | break; |
573 | 591 | ||
574 | case MBA_RSCN_UPDATE: /* State Change Registration */ | 592 | case MBA_RSCN_UPDATE: /* State Change Registration */ |
575 | /* Check if the Vport has issued a SCR */ | 593 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { |
576 | if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) | 594 | for_each_mapped_vp_idx(ha, i) { |
577 | break; | 595 | list_for_each_entry(vha, &ha->vp_list, |
578 | /* Only handle SCNs for our Vport index. */ | 596 | vp_list) { |
579 | if (ha->flags.npiv_supported && ha->vp_idx != mb[3]) | 597 | if ((mb[3] & 0xff) |
580 | break; | 598 | == vha->vp_idx) { |
599 | ha = vha; | ||
600 | break; | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | } | ||
581 | 605 | ||
582 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", | 606 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", |
583 | ha->host_no)); | 607 | ha->host_no)); |
@@ -612,6 +636,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
612 | 636 | ||
613 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 637 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
614 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 638 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
639 | qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry); | ||
615 | break; | 640 | break; |
616 | 641 | ||
617 | /* case MBA_RIO_RESPONSE: */ | 642 | /* case MBA_RIO_RESPONSE: */ |
@@ -637,6 +662,42 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
637 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", | 662 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", |
638 | ha->host_no, mb[1], mb[2])); | 663 | ha->host_no, mb[1], mb[2])); |
639 | break; | 664 | break; |
665 | |||
666 | case MBA_ISP84XX_ALERT: | ||
667 | DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- " | ||
668 | "%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3])); | ||
669 | |||
670 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); | ||
671 | switch (mb[1]) { | ||
672 | case A84_PANIC_RECOVERY: | ||
673 | qla_printk(KERN_INFO, ha, "Alert 84XX: panic recovery " | ||
674 | "%04x %04x\n", mb[2], mb[3]); | ||
675 | break; | ||
676 | case A84_OP_LOGIN_COMPLETE: | ||
677 | ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2]; | ||
678 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" | ||
679 | "firmware version %x\n", ha->cs84xx->op_fw_version)); | ||
680 | break; | ||
681 | case A84_DIAG_LOGIN_COMPLETE: | ||
682 | ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; | ||
683 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" | ||
684 | "diagnostic firmware version %x\n", | ||
685 | ha->cs84xx->diag_fw_version)); | ||
686 | break; | ||
687 | case A84_GOLD_LOGIN_COMPLETE: | ||
688 | ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; | ||
689 | ha->cs84xx->fw_update = 1; | ||
690 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX: gold " | ||
691 | "firmware version %x\n", | ||
692 | ha->cs84xx->gold_fw_version)); | ||
693 | break; | ||
694 | default: | ||
695 | qla_printk(KERN_ERR, ha, | ||
696 | "Alert 84xx: Invalid Alert %04x %04x %04x\n", | ||
697 | mb[1], mb[2], mb[3]); | ||
698 | } | ||
699 | spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags); | ||
700 | break; | ||
640 | } | 701 | } |
641 | 702 | ||
642 | if (!ha->parent && ha->num_vhosts) | 703 | if (!ha->parent && ha->num_vhosts) |
@@ -803,9 +864,6 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha) | |||
803 | case STATUS_CONT_TYPE: | 864 | case STATUS_CONT_TYPE: |
804 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 865 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); |
805 | break; | 866 | break; |
806 | case MS_IOCB_TYPE: | ||
807 | qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt); | ||
808 | break; | ||
809 | default: | 867 | default: |
810 | /* Type Not Supported. */ | 868 | /* Type Not Supported. */ |
811 | DEBUG4(printk(KERN_WARNING | 869 | DEBUG4(printk(KERN_WARNING |
@@ -1340,44 +1398,6 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) | |||
1340 | } | 1398 | } |
1341 | 1399 | ||
1342 | /** | 1400 | /** |
1343 | * qla2x00_ms_entry() - Process a Management Server entry. | ||
1344 | * @ha: SCSI driver HA context | ||
1345 | * @index: Response queue out pointer | ||
1346 | */ | ||
1347 | static void | ||
1348 | qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt) | ||
1349 | { | ||
1350 | srb_t *sp; | ||
1351 | |||
1352 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | ||
1353 | __func__, ha->host_no, pkt, pkt->handle1)); | ||
1354 | |||
1355 | /* Validate handle. */ | ||
1356 | if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS) | ||
1357 | sp = ha->outstanding_cmds[pkt->handle1]; | ||
1358 | else | ||
1359 | sp = NULL; | ||
1360 | |||
1361 | if (sp == NULL) { | ||
1362 | DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1363 | ha->host_no)); | ||
1364 | qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n"); | ||
1365 | |||
1366 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1367 | return; | ||
1368 | } | ||
1369 | |||
1370 | CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status); | ||
1371 | CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; | ||
1372 | |||
1373 | /* Free outstanding command slot. */ | ||
1374 | ha->outstanding_cmds[pkt->handle1] = NULL; | ||
1375 | |||
1376 | qla2x00_sp_compl(ha, sp); | ||
1377 | } | ||
1378 | |||
1379 | |||
1380 | /** | ||
1381 | * qla24xx_mbx_completion() - Process mailbox command completions. | 1401 | * qla24xx_mbx_completion() - Process mailbox command completions. |
1382 | * @ha: SCSI driver HA context | 1402 | * @ha: SCSI driver HA context |
1383 | * @mb0: Mailbox0 register | 1403 | * @mb0: Mailbox0 register |
@@ -1449,9 +1469,6 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) | |||
1449 | case STATUS_CONT_TYPE: | 1469 | case STATUS_CONT_TYPE: |
1450 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 1470 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); |
1451 | break; | 1471 | break; |
1452 | case MS_IOCB_TYPE: | ||
1453 | qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt); | ||
1454 | break; | ||
1455 | case VP_RPT_ID_IOCB_TYPE: | 1472 | case VP_RPT_ID_IOCB_TYPE: |
1456 | qla24xx_report_id_acquisition(ha, | 1473 | qla24xx_report_id_acquisition(ha, |
1457 | (struct vp_rpt_id_entry_24xx *)pkt); | 1474 | (struct vp_rpt_id_entry_24xx *)pkt); |
@@ -1533,7 +1550,6 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1533 | scsi_qla_host_t *ha; | 1550 | scsi_qla_host_t *ha; |
1534 | struct device_reg_24xx __iomem *reg; | 1551 | struct device_reg_24xx __iomem *reg; |
1535 | int status; | 1552 | int status; |
1536 | unsigned long flags; | ||
1537 | unsigned long iter; | 1553 | unsigned long iter; |
1538 | uint32_t stat; | 1554 | uint32_t stat; |
1539 | uint32_t hccr; | 1555 | uint32_t hccr; |
@@ -1549,13 +1565,19 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1549 | reg = &ha->iobase->isp24; | 1565 | reg = &ha->iobase->isp24; |
1550 | status = 0; | 1566 | status = 0; |
1551 | 1567 | ||
1552 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1568 | spin_lock(&ha->hardware_lock); |
1553 | for (iter = 50; iter--; ) { | 1569 | for (iter = 50; iter--; ) { |
1554 | stat = RD_REG_DWORD(®->host_status); | 1570 | stat = RD_REG_DWORD(®->host_status); |
1555 | if (stat & HSRX_RISC_PAUSED) { | 1571 | if (stat & HSRX_RISC_PAUSED) { |
1556 | if (pci_channel_offline(ha->pdev)) | 1572 | if (pci_channel_offline(ha->pdev)) |
1557 | break; | 1573 | break; |
1558 | 1574 | ||
1575 | if (ha->hw_event_pause_errors == 0) | ||
1576 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | ||
1577 | 0, MSW(stat), LSW(stat)); | ||
1578 | else if (ha->hw_event_pause_errors < 0xffffffff) | ||
1579 | ha->hw_event_pause_errors++; | ||
1580 | |||
1559 | hccr = RD_REG_DWORD(®->hccr); | 1581 | hccr = RD_REG_DWORD(®->hccr); |
1560 | 1582 | ||
1561 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1583 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
@@ -1597,7 +1619,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1597 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1619 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1598 | RD_REG_DWORD_RELAXED(®->hccr); | 1620 | RD_REG_DWORD_RELAXED(®->hccr); |
1599 | } | 1621 | } |
1600 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1622 | spin_unlock(&ha->hardware_lock); |
1601 | 1623 | ||
1602 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1624 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1603 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1625 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -1608,66 +1630,21 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1608 | return IRQ_HANDLED; | 1630 | return IRQ_HANDLED; |
1609 | } | 1631 | } |
1610 | 1632 | ||
1611 | /** | ||
1612 | * qla24xx_ms_entry() - Process a Management Server entry. | ||
1613 | * @ha: SCSI driver HA context | ||
1614 | * @index: Response queue out pointer | ||
1615 | */ | ||
1616 | static void | ||
1617 | qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt) | ||
1618 | { | ||
1619 | srb_t *sp; | ||
1620 | |||
1621 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | ||
1622 | __func__, ha->host_no, pkt, pkt->handle)); | ||
1623 | |||
1624 | DEBUG9(printk("%s: ct pkt dump:\n", __func__)); | ||
1625 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx))); | ||
1626 | |||
1627 | /* Validate handle. */ | ||
1628 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) | ||
1629 | sp = ha->outstanding_cmds[pkt->handle]; | ||
1630 | else | ||
1631 | sp = NULL; | ||
1632 | |||
1633 | if (sp == NULL) { | ||
1634 | DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1635 | ha->host_no)); | ||
1636 | DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1637 | ha->host_no)); | ||
1638 | qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n", | ||
1639 | pkt->handle); | ||
1640 | |||
1641 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1642 | return; | ||
1643 | } | ||
1644 | |||
1645 | CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status); | ||
1646 | CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; | ||
1647 | |||
1648 | /* Free outstanding command slot. */ | ||
1649 | ha->outstanding_cmds[pkt->handle] = NULL; | ||
1650 | |||
1651 | qla2x00_sp_compl(ha, sp); | ||
1652 | } | ||
1653 | |||
1654 | static irqreturn_t | 1633 | static irqreturn_t |
1655 | qla24xx_msix_rsp_q(int irq, void *dev_id) | 1634 | qla24xx_msix_rsp_q(int irq, void *dev_id) |
1656 | { | 1635 | { |
1657 | scsi_qla_host_t *ha; | 1636 | scsi_qla_host_t *ha; |
1658 | struct device_reg_24xx __iomem *reg; | 1637 | struct device_reg_24xx __iomem *reg; |
1659 | unsigned long flags; | ||
1660 | 1638 | ||
1661 | ha = dev_id; | 1639 | ha = dev_id; |
1662 | reg = &ha->iobase->isp24; | 1640 | reg = &ha->iobase->isp24; |
1663 | 1641 | ||
1664 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1642 | spin_lock(&ha->hardware_lock); |
1665 | 1643 | ||
1666 | qla24xx_process_response_queue(ha); | 1644 | qla24xx_process_response_queue(ha); |
1667 | |||
1668 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1645 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1669 | 1646 | ||
1670 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1647 | spin_unlock(&ha->hardware_lock); |
1671 | 1648 | ||
1672 | return IRQ_HANDLED; | 1649 | return IRQ_HANDLED; |
1673 | } | 1650 | } |
@@ -1678,7 +1655,6 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1678 | scsi_qla_host_t *ha; | 1655 | scsi_qla_host_t *ha; |
1679 | struct device_reg_24xx __iomem *reg; | 1656 | struct device_reg_24xx __iomem *reg; |
1680 | int status; | 1657 | int status; |
1681 | unsigned long flags; | ||
1682 | uint32_t stat; | 1658 | uint32_t stat; |
1683 | uint32_t hccr; | 1659 | uint32_t hccr; |
1684 | uint16_t mb[4]; | 1660 | uint16_t mb[4]; |
@@ -1687,13 +1663,19 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1687 | reg = &ha->iobase->isp24; | 1663 | reg = &ha->iobase->isp24; |
1688 | status = 0; | 1664 | status = 0; |
1689 | 1665 | ||
1690 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1666 | spin_lock(&ha->hardware_lock); |
1691 | do { | 1667 | do { |
1692 | stat = RD_REG_DWORD(®->host_status); | 1668 | stat = RD_REG_DWORD(®->host_status); |
1693 | if (stat & HSRX_RISC_PAUSED) { | 1669 | if (stat & HSRX_RISC_PAUSED) { |
1694 | if (pci_channel_offline(ha->pdev)) | 1670 | if (pci_channel_offline(ha->pdev)) |
1695 | break; | 1671 | break; |
1696 | 1672 | ||
1673 | if (ha->hw_event_pause_errors == 0) | ||
1674 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | ||
1675 | 0, MSW(stat), LSW(stat)); | ||
1676 | else if (ha->hw_event_pause_errors < 0xffffffff) | ||
1677 | ha->hw_event_pause_errors++; | ||
1678 | |||
1697 | hccr = RD_REG_DWORD(®->hccr); | 1679 | hccr = RD_REG_DWORD(®->hccr); |
1698 | 1680 | ||
1699 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1681 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
@@ -1734,7 +1716,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1734 | } | 1716 | } |
1735 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1717 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1736 | } while (0); | 1718 | } while (0); |
1737 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1719 | spin_unlock(&ha->hardware_lock); |
1738 | 1720 | ||
1739 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1721 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1740 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1722 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -1821,10 +1803,9 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1821 | { | 1803 | { |
1822 | int ret; | 1804 | int ret; |
1823 | device_reg_t __iomem *reg = ha->iobase; | 1805 | device_reg_t __iomem *reg = ha->iobase; |
1824 | unsigned long flags; | ||
1825 | 1806 | ||
1826 | /* If possible, enable MSI-X. */ | 1807 | /* If possible, enable MSI-X. */ |
1827 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha)) | 1808 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) |
1828 | goto skip_msix; | 1809 | goto skip_msix; |
1829 | 1810 | ||
1830 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || | 1811 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || |
@@ -1859,7 +1840,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1859 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); | 1840 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); |
1860 | skip_msix: | 1841 | skip_msix: |
1861 | 1842 | ||
1862 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha)) | 1843 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) |
1863 | goto skip_msi; | 1844 | goto skip_msi; |
1864 | 1845 | ||
1865 | ret = pci_enable_msi(ha->pdev); | 1846 | ret = pci_enable_msi(ha->pdev); |
@@ -1882,7 +1863,7 @@ skip_msi: | |||
1882 | clear_risc_ints: | 1863 | clear_risc_ints: |
1883 | 1864 | ||
1884 | ha->isp_ops->disable_intrs(ha); | 1865 | ha->isp_ops->disable_intrs(ha); |
1885 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1866 | spin_lock_irq(&ha->hardware_lock); |
1886 | if (IS_FWI2_CAPABLE(ha)) { | 1867 | if (IS_FWI2_CAPABLE(ha)) { |
1887 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); | 1868 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); |
1888 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); | 1869 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); |
@@ -1891,7 +1872,7 @@ clear_risc_ints: | |||
1891 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); | 1872 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); |
1892 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); | 1873 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); |
1893 | } | 1874 | } |
1894 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1875 | spin_unlock_irq(&ha->hardware_lock); |
1895 | ha->isp_ops->enable_intrs(ha); | 1876 | ha->isp_ops->enable_intrs(ha); |
1896 | 1877 | ||
1897 | fail: | 1878 | fail: |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index bb103580e1ba..7d0a8a4c7719 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -310,7 +310,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr, | |||
310 | } | 310 | } |
311 | 311 | ||
312 | mcp->in_mb = MBX_0; | 312 | mcp->in_mb = MBX_0; |
313 | mcp->tov = 30; | 313 | mcp->tov = MBX_TOV_SECONDS; |
314 | mcp->flags = 0; | 314 | mcp->flags = 0; |
315 | rval = qla2x00_mailbox_command(ha, mcp); | 315 | rval = qla2x00_mailbox_command(ha, mcp); |
316 | 316 | ||
@@ -367,7 +367,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
367 | } | 367 | } |
368 | } | 368 | } |
369 | 369 | ||
370 | mcp->tov = 30; | 370 | mcp->tov = MBX_TOV_SECONDS; |
371 | mcp->flags = 0; | 371 | mcp->flags = 0; |
372 | rval = qla2x00_mailbox_command(ha, mcp); | 372 | rval = qla2x00_mailbox_command(ha, mcp); |
373 | 373 | ||
@@ -417,7 +417,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor, | |||
417 | mcp->out_mb = MBX_0; | 417 | mcp->out_mb = MBX_0; |
418 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 418 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
419 | mcp->flags = 0; | 419 | mcp->flags = 0; |
420 | mcp->tov = 30; | 420 | mcp->tov = MBX_TOV_SECONDS; |
421 | rval = qla2x00_mailbox_command(ha, mcp); | 421 | rval = qla2x00_mailbox_command(ha, mcp); |
422 | 422 | ||
423 | /* Return mailbox data. */ | 423 | /* Return mailbox data. */ |
@@ -466,7 +466,7 @@ qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) | |||
466 | mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; | 466 | mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; |
467 | mcp->out_mb = MBX_0; | 467 | mcp->out_mb = MBX_0; |
468 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 468 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
469 | mcp->tov = 30; | 469 | mcp->tov = MBX_TOV_SECONDS; |
470 | mcp->flags = 0; | 470 | mcp->flags = 0; |
471 | rval = qla2x00_mailbox_command(ha, mcp); | 471 | rval = qla2x00_mailbox_command(ha, mcp); |
472 | 472 | ||
@@ -524,7 +524,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) | |||
524 | mcp->mb[12] = 0; /* Undocumented, but used */ | 524 | mcp->mb[12] = 0; /* Undocumented, but used */ |
525 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; | 525 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; |
526 | } | 526 | } |
527 | mcp->tov = 30; | 527 | mcp->tov = MBX_TOV_SECONDS; |
528 | mcp->flags = 0; | 528 | mcp->flags = 0; |
529 | rval = qla2x00_mailbox_command(ha, mcp); | 529 | rval = qla2x00_mailbox_command(ha, mcp); |
530 | 530 | ||
@@ -576,7 +576,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
576 | mcp->mb[7] = 0x2525; | 576 | mcp->mb[7] = 0x2525; |
577 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 577 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
578 | mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 578 | mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
579 | mcp->tov = 30; | 579 | mcp->tov = MBX_TOV_SECONDS; |
580 | mcp->flags = 0; | 580 | mcp->flags = 0; |
581 | rval = qla2x00_mailbox_command(ha, mcp); | 581 | rval = qla2x00_mailbox_command(ha, mcp); |
582 | 582 | ||
@@ -587,6 +587,14 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
587 | if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || | 587 | if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || |
588 | mcp->mb[7] != 0x2525) | 588 | mcp->mb[7] != 0x2525) |
589 | rval = QLA_FUNCTION_FAILED; | 589 | rval = QLA_FUNCTION_FAILED; |
590 | if (rval == QLA_FUNCTION_FAILED) { | ||
591 | struct device_reg_24xx __iomem *reg = | ||
592 | &ha->iobase->isp24; | ||
593 | |||
594 | qla2xxx_hw_event_log(ha, HW_EVENT_ISP_ERR, 0, | ||
595 | LSW(RD_REG_DWORD(®->hccr)), | ||
596 | LSW(RD_REG_DWORD(®->istatus))); | ||
597 | } | ||
590 | } | 598 | } |
591 | 599 | ||
592 | if (rval != QLA_SUCCESS) { | 600 | if (rval != QLA_SUCCESS) { |
@@ -640,7 +648,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
640 | mcp->in_mb |= MBX_1; | 648 | mcp->in_mb |= MBX_1; |
641 | } | 649 | } |
642 | 650 | ||
643 | mcp->tov = 30; | 651 | mcp->tov = MBX_TOV_SECONDS; |
644 | mcp->flags = 0; | 652 | mcp->flags = 0; |
645 | rval = qla2x00_mailbox_command(ha, mcp); | 653 | rval = qla2x00_mailbox_command(ha, mcp); |
646 | 654 | ||
@@ -674,8 +682,8 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
674 | * Kernel context. | 682 | * Kernel context. |
675 | */ | 683 | */ |
676 | int | 684 | int |
677 | qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | 685 | qla2x00_issue_iocb_timeout(scsi_qla_host_t *ha, void *buffer, |
678 | size_t size) | 686 | dma_addr_t phys_addr, size_t size, uint32_t tov) |
679 | { | 687 | { |
680 | int rval; | 688 | int rval; |
681 | mbx_cmd_t mc; | 689 | mbx_cmd_t mc; |
@@ -689,7 +697,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
689 | mcp->mb[7] = LSW(MSD(phys_addr)); | 697 | mcp->mb[7] = LSW(MSD(phys_addr)); |
690 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 698 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
691 | mcp->in_mb = MBX_2|MBX_0; | 699 | mcp->in_mb = MBX_2|MBX_0; |
692 | mcp->tov = 30; | 700 | mcp->tov = tov; |
693 | mcp->flags = 0; | 701 | mcp->flags = 0; |
694 | rval = qla2x00_mailbox_command(ha, mcp); | 702 | rval = qla2x00_mailbox_command(ha, mcp); |
695 | 703 | ||
@@ -710,6 +718,14 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
710 | return rval; | 718 | return rval; |
711 | } | 719 | } |
712 | 720 | ||
721 | int | ||
722 | qla2x00_issue_iocb(scsi_qla_host_t *ha, void *buffer, dma_addr_t phys_addr, | ||
723 | size_t size) | ||
724 | { | ||
725 | return qla2x00_issue_iocb_timeout(ha, buffer, phys_addr, size, | ||
726 | MBX_TOV_SECONDS); | ||
727 | } | ||
728 | |||
713 | /* | 729 | /* |
714 | * qla2x00_abort_command | 730 | * qla2x00_abort_command |
715 | * Abort command aborts a specified IOCB. | 731 | * Abort command aborts a specified IOCB. |
@@ -760,7 +776,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
760 | mcp->mb[6] = (uint16_t)sp->cmd->device->lun; | 776 | mcp->mb[6] = (uint16_t)sp->cmd->device->lun; |
761 | mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 777 | mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
762 | mcp->in_mb = MBX_0; | 778 | mcp->in_mb = MBX_0; |
763 | mcp->tov = 30; | 779 | mcp->tov = MBX_TOV_SECONDS; |
764 | mcp->flags = 0; | 780 | mcp->flags = 0; |
765 | rval = qla2x00_mailbox_command(ha, mcp); | 781 | rval = qla2x00_mailbox_command(ha, mcp); |
766 | 782 | ||
@@ -776,36 +792,20 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
776 | return rval; | 792 | return rval; |
777 | } | 793 | } |
778 | 794 | ||
779 | #if USE_ABORT_TGT | ||
780 | /* | ||
781 | * qla2x00_abort_target | ||
782 | * Issue abort target mailbox command. | ||
783 | * | ||
784 | * Input: | ||
785 | * ha = adapter block pointer. | ||
786 | * | ||
787 | * Returns: | ||
788 | * qla2x00 local function return status code. | ||
789 | * | ||
790 | * Context: | ||
791 | * Kernel context. | ||
792 | */ | ||
793 | int | 795 | int |
794 | qla2x00_abort_target(fc_port_t *fcport) | 796 | qla2x00_abort_target(struct fc_port *fcport, unsigned int l) |
795 | { | 797 | { |
796 | int rval; | 798 | int rval, rval2; |
797 | mbx_cmd_t mc; | 799 | mbx_cmd_t mc; |
798 | mbx_cmd_t *mcp = &mc; | 800 | mbx_cmd_t *mcp = &mc; |
799 | scsi_qla_host_t *ha; | 801 | scsi_qla_host_t *ha; |
800 | 802 | ||
801 | if (fcport == NULL) | ||
802 | return 0; | ||
803 | |||
804 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | 803 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
805 | 804 | ||
805 | l = l; | ||
806 | ha = fcport->ha; | 806 | ha = fcport->ha; |
807 | mcp->mb[0] = MBC_ABORT_TARGET; | 807 | mcp->mb[0] = MBC_ABORT_TARGET; |
808 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | 808 | mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; |
809 | if (HAS_EXTENDED_IDS(ha)) { | 809 | if (HAS_EXTENDED_IDS(ha)) { |
810 | mcp->mb[1] = fcport->loop_id; | 810 | mcp->mb[1] = fcport->loop_id; |
811 | mcp->mb[10] = 0; | 811 | mcp->mb[10] = 0; |
@@ -814,27 +814,70 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
814 | mcp->mb[1] = fcport->loop_id << 8; | 814 | mcp->mb[1] = fcport->loop_id << 8; |
815 | } | 815 | } |
816 | mcp->mb[2] = ha->loop_reset_delay; | 816 | mcp->mb[2] = ha->loop_reset_delay; |
817 | mcp->mb[9] = ha->vp_idx; | ||
817 | 818 | ||
818 | mcp->in_mb = MBX_0; | 819 | mcp->in_mb = MBX_0; |
819 | mcp->tov = 30; | 820 | mcp->tov = MBX_TOV_SECONDS; |
820 | mcp->flags = 0; | 821 | mcp->flags = 0; |
821 | rval = qla2x00_mailbox_command(ha, mcp); | 822 | rval = qla2x00_mailbox_command(ha, mcp); |
823 | if (rval != QLA_SUCCESS) { | ||
824 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | ||
825 | ha->host_no, rval)); | ||
826 | } | ||
822 | 827 | ||
823 | /* Issue marker command. */ | 828 | /* Issue marker IOCB. */ |
824 | ha->marker_needed = 1; | 829 | rval2 = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); |
830 | if (rval2 != QLA_SUCCESS) { | ||
831 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | ||
832 | "(%x).\n", __func__, ha->host_no, rval2)); | ||
833 | } else { | ||
834 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
835 | } | ||
836 | |||
837 | return rval; | ||
838 | } | ||
839 | |||
840 | int | ||
841 | qla2x00_lun_reset(struct fc_port *fcport, unsigned int l) | ||
842 | { | ||
843 | int rval, rval2; | ||
844 | mbx_cmd_t mc; | ||
845 | mbx_cmd_t *mcp = &mc; | ||
846 | scsi_qla_host_t *ha; | ||
847 | |||
848 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | ||
849 | |||
850 | ha = fcport->ha; | ||
851 | mcp->mb[0] = MBC_LUN_RESET; | ||
852 | mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; | ||
853 | if (HAS_EXTENDED_IDS(ha)) | ||
854 | mcp->mb[1] = fcport->loop_id; | ||
855 | else | ||
856 | mcp->mb[1] = fcport->loop_id << 8; | ||
857 | mcp->mb[2] = l; | ||
858 | mcp->mb[3] = 0; | ||
859 | mcp->mb[9] = ha->vp_idx; | ||
825 | 860 | ||
861 | mcp->in_mb = MBX_0; | ||
862 | mcp->tov = MBX_TOV_SECONDS; | ||
863 | mcp->flags = 0; | ||
864 | rval = qla2x00_mailbox_command(ha, mcp); | ||
826 | if (rval != QLA_SUCCESS) { | 865 | if (rval != QLA_SUCCESS) { |
827 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", | 866 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, |
828 | ha->host_no, rval)); | 867 | ha->host_no, rval)); |
868 | } | ||
869 | |||
870 | /* Issue marker IOCB. */ | ||
871 | rval2 = qla2x00_marker(ha, fcport->loop_id, l, MK_SYNC_ID_LUN); | ||
872 | if (rval2 != QLA_SUCCESS) { | ||
873 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | ||
874 | "(%x).\n", __func__, ha->host_no, rval2)); | ||
829 | } else { | 875 | } else { |
830 | /*EMPTY*/ | 876 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
831 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", | ||
832 | ha->host_no)); | ||
833 | } | 877 | } |
834 | 878 | ||
835 | return rval; | 879 | return rval; |
836 | } | 880 | } |
837 | #endif | ||
838 | 881 | ||
839 | /* | 882 | /* |
840 | * qla2x00_get_adapter_id | 883 | * qla2x00_get_adapter_id |
@@ -871,7 +914,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
871 | mcp->mb[9] = ha->vp_idx; | 914 | mcp->mb[9] = ha->vp_idx; |
872 | mcp->out_mb = MBX_9|MBX_0; | 915 | mcp->out_mb = MBX_9|MBX_0; |
873 | mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 916 | mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
874 | mcp->tov = 30; | 917 | mcp->tov = MBX_TOV_SECONDS; |
875 | mcp->flags = 0; | 918 | mcp->flags = 0; |
876 | rval = qla2x00_mailbox_command(ha, mcp); | 919 | rval = qla2x00_mailbox_command(ha, mcp); |
877 | if (mcp->mb[0] == MBS_COMMAND_ERROR) | 920 | if (mcp->mb[0] == MBS_COMMAND_ERROR) |
@@ -928,7 +971,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
928 | mcp->mb[0] = MBC_GET_RETRY_COUNT; | 971 | mcp->mb[0] = MBC_GET_RETRY_COUNT; |
929 | mcp->out_mb = MBX_0; | 972 | mcp->out_mb = MBX_0; |
930 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 973 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
931 | mcp->tov = 30; | 974 | mcp->tov = MBX_TOV_SECONDS; |
932 | mcp->flags = 0; | 975 | mcp->flags = 0; |
933 | rval = qla2x00_mailbox_command(ha, mcp); | 976 | rval = qla2x00_mailbox_command(ha, mcp); |
934 | 977 | ||
@@ -995,7 +1038,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) | |||
995 | mcp->in_mb = MBX_5|MBX_4|MBX_0; | 1038 | mcp->in_mb = MBX_5|MBX_4|MBX_0; |
996 | mcp->buf_size = size; | 1039 | mcp->buf_size = size; |
997 | mcp->flags = MBX_DMA_OUT; | 1040 | mcp->flags = MBX_DMA_OUT; |
998 | mcp->tov = 30; | 1041 | mcp->tov = MBX_TOV_SECONDS; |
999 | rval = qla2x00_mailbox_command(ha, mcp); | 1042 | rval = qla2x00_mailbox_command(ha, mcp); |
1000 | 1043 | ||
1001 | if (rval != QLA_SUCCESS) { | 1044 | if (rval != QLA_SUCCESS) { |
@@ -1173,7 +1216,7 @@ gpd_error_out: | |||
1173 | * Kernel context. | 1216 | * Kernel context. |
1174 | */ | 1217 | */ |
1175 | int | 1218 | int |
1176 | qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | 1219 | qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *states) |
1177 | { | 1220 | { |
1178 | int rval; | 1221 | int rval; |
1179 | mbx_cmd_t mc; | 1222 | mbx_cmd_t mc; |
@@ -1184,13 +1227,15 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1184 | 1227 | ||
1185 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; | 1228 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; |
1186 | mcp->out_mb = MBX_0; | 1229 | mcp->out_mb = MBX_0; |
1187 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 1230 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
1188 | mcp->tov = 30; | 1231 | mcp->tov = MBX_TOV_SECONDS; |
1189 | mcp->flags = 0; | 1232 | mcp->flags = 0; |
1190 | rval = qla2x00_mailbox_command(ha, mcp); | 1233 | rval = qla2x00_mailbox_command(ha, mcp); |
1191 | 1234 | ||
1192 | /* Return firmware state. */ | 1235 | /* Return firmware states. */ |
1193 | *dptr = mcp->mb[1]; | 1236 | states[0] = mcp->mb[1]; |
1237 | states[1] = mcp->mb[2]; | ||
1238 | states[2] = mcp->mb[3]; | ||
1194 | 1239 | ||
1195 | if (rval != QLA_SUCCESS) { | 1240 | if (rval != QLA_SUCCESS) { |
1196 | /*EMPTY*/ | 1241 | /*EMPTY*/ |
@@ -1246,7 +1291,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1246 | } | 1291 | } |
1247 | 1292 | ||
1248 | mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 1293 | mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
1249 | mcp->tov = 30; | 1294 | mcp->tov = MBX_TOV_SECONDS; |
1250 | mcp->flags = 0; | 1295 | mcp->flags = 0; |
1251 | rval = qla2x00_mailbox_command(ha, mcp); | 1296 | rval = qla2x00_mailbox_command(ha, mcp); |
1252 | 1297 | ||
@@ -1318,7 +1363,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1318 | mcp->mb[3] = 0; | 1363 | mcp->mb[3] = 0; |
1319 | } | 1364 | } |
1320 | mcp->in_mb = MBX_0; | 1365 | mcp->in_mb = MBX_0; |
1321 | mcp->tov = 30; | 1366 | mcp->tov = MBX_TOV_SECONDS; |
1322 | mcp->flags = 0; | 1367 | mcp->flags = 0; |
1323 | rval = qla2x00_mailbox_command(ha, mcp); | 1368 | rval = qla2x00_mailbox_command(ha, mcp); |
1324 | 1369 | ||
@@ -1743,7 +1788,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1743 | } | 1788 | } |
1744 | 1789 | ||
1745 | mcp->in_mb = MBX_1|MBX_0; | 1790 | mcp->in_mb = MBX_1|MBX_0; |
1746 | mcp->tov = 30; | 1791 | mcp->tov = MBX_TOV_SECONDS; |
1747 | mcp->flags = 0; | 1792 | mcp->flags = 0; |
1748 | rval = qla2x00_mailbox_command(ha, mcp); | 1793 | rval = qla2x00_mailbox_command(ha, mcp); |
1749 | 1794 | ||
@@ -1791,7 +1836,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1791 | mcp->mb[3] = 0; | 1836 | mcp->mb[3] = 0; |
1792 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 1837 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
1793 | mcp->in_mb = MBX_0; | 1838 | mcp->in_mb = MBX_0; |
1794 | mcp->tov = 30; | 1839 | mcp->tov = MBX_TOV_SECONDS; |
1795 | mcp->flags = 0; | 1840 | mcp->flags = 0; |
1796 | rval = qla2x00_mailbox_command(ha, mcp); | 1841 | rval = qla2x00_mailbox_command(ha, mcp); |
1797 | 1842 | ||
@@ -1852,7 +1897,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1852 | mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; | 1897 | mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; |
1853 | } | 1898 | } |
1854 | mcp->in_mb = MBX_1|MBX_0; | 1899 | mcp->in_mb = MBX_1|MBX_0; |
1855 | mcp->tov = 30; | 1900 | mcp->tov = MBX_TOV_SECONDS; |
1856 | mcp->flags = 0; | 1901 | mcp->flags = 0; |
1857 | rval = qla2x00_mailbox_command(ha, mcp); | 1902 | rval = qla2x00_mailbox_command(ha, mcp); |
1858 | 1903 | ||
@@ -1896,7 +1941,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
1896 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; | 1941 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; |
1897 | mcp->out_mb = MBX_0; | 1942 | mcp->out_mb = MBX_0; |
1898 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 1943 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
1899 | mcp->tov = 30; | 1944 | mcp->tov = MBX_TOV_SECONDS; |
1900 | mcp->flags = 0; | 1945 | mcp->flags = 0; |
1901 | rval = qla2x00_mailbox_command(ha, mcp); | 1946 | rval = qla2x00_mailbox_command(ha, mcp); |
1902 | 1947 | ||
@@ -2036,7 +2081,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2036 | mcp->mb[1] = loop_id << 8; | 2081 | mcp->mb[1] = loop_id << 8; |
2037 | mcp->out_mb |= MBX_1; | 2082 | mcp->out_mb |= MBX_1; |
2038 | } | 2083 | } |
2039 | mcp->tov = 30; | 2084 | mcp->tov = MBX_TOV_SECONDS; |
2040 | mcp->flags = IOCTL_CMD; | 2085 | mcp->flags = IOCTL_CMD; |
2041 | rval = qla2x00_mailbox_command(ha, mcp); | 2086 | rval = qla2x00_mailbox_command(ha, mcp); |
2042 | 2087 | ||
@@ -2082,7 +2127,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, struct link_statistics *stats, | |||
2082 | mcp->mb[10] = 0; | 2127 | mcp->mb[10] = 0; |
2083 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; | 2128 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; |
2084 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 2129 | mcp->in_mb = MBX_2|MBX_1|MBX_0; |
2085 | mcp->tov = 30; | 2130 | mcp->tov = MBX_TOV_SECONDS; |
2086 | mcp->flags = IOCTL_CMD; | 2131 | mcp->flags = IOCTL_CMD; |
2087 | rval = qla2x00_mailbox_command(ha, mcp); | 2132 | rval = qla2x00_mailbox_command(ha, mcp); |
2088 | 2133 | ||
@@ -2180,17 +2225,15 @@ struct tsk_mgmt_cmd { | |||
2180 | } p; | 2225 | } p; |
2181 | }; | 2226 | }; |
2182 | 2227 | ||
2183 | int | 2228 | static int |
2184 | qla24xx_abort_target(fc_port_t *fcport) | 2229 | __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, |
2230 | unsigned int l) | ||
2185 | { | 2231 | { |
2186 | int rval; | 2232 | int rval, rval2; |
2187 | struct tsk_mgmt_cmd *tsk; | 2233 | struct tsk_mgmt_cmd *tsk; |
2188 | dma_addr_t tsk_dma; | 2234 | dma_addr_t tsk_dma; |
2189 | scsi_qla_host_t *ha, *pha; | 2235 | scsi_qla_host_t *ha, *pha; |
2190 | 2236 | ||
2191 | if (fcport == NULL) | ||
2192 | return 0; | ||
2193 | |||
2194 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | 2237 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
2195 | 2238 | ||
2196 | ha = fcport->ha; | 2239 | ha = fcport->ha; |
@@ -2207,47 +2250,61 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2207 | tsk->p.tsk.entry_count = 1; | 2250 | tsk->p.tsk.entry_count = 1; |
2208 | tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); | 2251 | tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); |
2209 | tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | 2252 | tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); |
2210 | tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET); | 2253 | tsk->p.tsk.control_flags = cpu_to_le32(type); |
2211 | tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; | 2254 | tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; |
2212 | tsk->p.tsk.port_id[1] = fcport->d_id.b.area; | 2255 | tsk->p.tsk.port_id[1] = fcport->d_id.b.area; |
2213 | tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; | 2256 | tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; |
2214 | tsk->p.tsk.vp_index = fcport->vp_idx; | 2257 | tsk->p.tsk.vp_index = fcport->vp_idx; |
2258 | if (type == TCF_LUN_RESET) { | ||
2259 | int_to_scsilun(l, &tsk->p.tsk.lun); | ||
2260 | host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, | ||
2261 | sizeof(tsk->p.tsk.lun)); | ||
2262 | } | ||
2215 | 2263 | ||
2216 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); | 2264 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); |
2217 | if (rval != QLA_SUCCESS) { | 2265 | if (rval != QLA_SUCCESS) { |
2218 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " | 2266 | DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB " |
2219 | "(%x).\n", __func__, ha->host_no, rval)); | 2267 | "(%x).\n", __func__, ha->host_no, name, rval)); |
2220 | goto atarget_done; | ||
2221 | } else if (tsk->p.sts.entry_status != 0) { | 2268 | } else if (tsk->p.sts.entry_status != 0) { |
2222 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2269 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2223 | "-- error status (%x).\n", __func__, ha->host_no, | 2270 | "-- error status (%x).\n", __func__, ha->host_no, |
2224 | tsk->p.sts.entry_status)); | 2271 | tsk->p.sts.entry_status)); |
2225 | rval = QLA_FUNCTION_FAILED; | 2272 | rval = QLA_FUNCTION_FAILED; |
2226 | goto atarget_done; | ||
2227 | } else if (tsk->p.sts.comp_status != | 2273 | } else if (tsk->p.sts.comp_status != |
2228 | __constant_cpu_to_le16(CS_COMPLETE)) { | 2274 | __constant_cpu_to_le16(CS_COMPLETE)) { |
2229 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2275 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2230 | "-- completion status (%x).\n", __func__, | 2276 | "-- completion status (%x).\n", __func__, |
2231 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); | 2277 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); |
2232 | rval = QLA_FUNCTION_FAILED; | 2278 | rval = QLA_FUNCTION_FAILED; |
2233 | goto atarget_done; | ||
2234 | } | 2279 | } |
2235 | 2280 | ||
2236 | /* Issue marker IOCB. */ | 2281 | /* Issue marker IOCB. */ |
2237 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); | 2282 | rval2 = qla2x00_marker(ha, fcport->loop_id, l, |
2238 | if (rval != QLA_SUCCESS) { | 2283 | type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID); |
2284 | if (rval2 != QLA_SUCCESS) { | ||
2239 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | 2285 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " |
2240 | "(%x).\n", __func__, ha->host_no, rval)); | 2286 | "(%x).\n", __func__, ha->host_no, rval2)); |
2241 | } else { | 2287 | } else { |
2242 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | 2288 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2243 | } | 2289 | } |
2244 | 2290 | ||
2245 | atarget_done: | ||
2246 | dma_pool_free(pha->s_dma_pool, tsk, tsk_dma); | 2291 | dma_pool_free(pha->s_dma_pool, tsk, tsk_dma); |
2247 | 2292 | ||
2248 | return rval; | 2293 | return rval; |
2249 | } | 2294 | } |
2250 | 2295 | ||
2296 | int | ||
2297 | qla24xx_abort_target(struct fc_port *fcport, unsigned int l) | ||
2298 | { | ||
2299 | return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l); | ||
2300 | } | ||
2301 | |||
2302 | int | ||
2303 | qla24xx_lun_reset(struct fc_port *fcport, unsigned int l) | ||
2304 | { | ||
2305 | return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l); | ||
2306 | } | ||
2307 | |||
2251 | #if 0 | 2308 | #if 0 |
2252 | 2309 | ||
2253 | int | 2310 | int |
@@ -2304,7 +2361,7 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g, | |||
2304 | mcp->mb[4] = sw_em_4g | BIT_15; | 2361 | mcp->mb[4] = sw_em_4g | BIT_15; |
2305 | mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2362 | mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2306 | mcp->in_mb = MBX_0; | 2363 | mcp->in_mb = MBX_0; |
2307 | mcp->tov = 30; | 2364 | mcp->tov = MBX_TOV_SECONDS; |
2308 | mcp->flags = 0; | 2365 | mcp->flags = 0; |
2309 | rval = qla2x00_mailbox_command(ha, mcp); | 2366 | rval = qla2x00_mailbox_command(ha, mcp); |
2310 | 2367 | ||
@@ -2372,7 +2429,7 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *ha, dma_addr_t eft_dma, | |||
2372 | mcp->mb[7] = TC_AEN_DISABLE; | 2429 | mcp->mb[7] = TC_AEN_DISABLE; |
2373 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2430 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2374 | mcp->in_mb = MBX_1|MBX_0; | 2431 | mcp->in_mb = MBX_1|MBX_0; |
2375 | mcp->tov = 30; | 2432 | mcp->tov = MBX_TOV_SECONDS; |
2376 | mcp->flags = 0; | 2433 | mcp->flags = 0; |
2377 | rval = qla2x00_mailbox_command(ha, mcp); | 2434 | rval = qla2x00_mailbox_command(ha, mcp); |
2378 | if (rval != QLA_SUCCESS) { | 2435 | if (rval != QLA_SUCCESS) { |
@@ -2401,7 +2458,7 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *ha) | |||
2401 | mcp->mb[1] = TC_EFT_DISABLE; | 2458 | mcp->mb[1] = TC_EFT_DISABLE; |
2402 | mcp->out_mb = MBX_1|MBX_0; | 2459 | mcp->out_mb = MBX_1|MBX_0; |
2403 | mcp->in_mb = MBX_1|MBX_0; | 2460 | mcp->in_mb = MBX_1|MBX_0; |
2404 | mcp->tov = 30; | 2461 | mcp->tov = MBX_TOV_SECONDS; |
2405 | mcp->flags = 0; | 2462 | mcp->flags = 0; |
2406 | rval = qla2x00_mailbox_command(ha, mcp); | 2463 | rval = qla2x00_mailbox_command(ha, mcp); |
2407 | if (rval != QLA_SUCCESS) { | 2464 | if (rval != QLA_SUCCESS) { |
@@ -2441,7 +2498,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma, | |||
2441 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| | 2498 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| |
2442 | MBX_1|MBX_0; | 2499 | MBX_1|MBX_0; |
2443 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2500 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2444 | mcp->tov = 30; | 2501 | mcp->tov = MBX_TOV_SECONDS; |
2445 | mcp->flags = 0; | 2502 | mcp->flags = 0; |
2446 | rval = qla2x00_mailbox_command(ha, mcp); | 2503 | rval = qla2x00_mailbox_command(ha, mcp); |
2447 | if (rval != QLA_SUCCESS) { | 2504 | if (rval != QLA_SUCCESS) { |
@@ -2477,7 +2534,7 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *ha, uint64_t *wr, uint64_t *rd) | |||
2477 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | 2534 | mcp->out_mb = MBX_2|MBX_1|MBX_0; |
2478 | mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| | 2535 | mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| |
2479 | MBX_1|MBX_0; | 2536 | MBX_1|MBX_0; |
2480 | mcp->tov = 30; | 2537 | mcp->tov = MBX_TOV_SECONDS; |
2481 | mcp->flags = 0; | 2538 | mcp->flags = 0; |
2482 | rval = qla2x00_mailbox_command(ha, mcp); | 2539 | rval = qla2x00_mailbox_command(ha, mcp); |
2483 | if (rval != QLA_SUCCESS) { | 2540 | if (rval != QLA_SUCCESS) { |
@@ -2525,7 +2582,7 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | |||
2525 | mcp->mb[10] = 0; | 2582 | mcp->mb[10] = 0; |
2526 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 2583 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
2527 | mcp->in_mb = MBX_0; | 2584 | mcp->in_mb = MBX_0; |
2528 | mcp->tov = 30; | 2585 | mcp->tov = MBX_TOV_SECONDS; |
2529 | mcp->flags = 0; | 2586 | mcp->flags = 0; |
2530 | rval = qla2x00_mailbox_command(ha, mcp); | 2587 | rval = qla2x00_mailbox_command(ha, mcp); |
2531 | 2588 | ||
@@ -2559,7 +2616,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2559 | mcp->mb[4] = mcp->mb[5] = 0; | 2616 | mcp->mb[4] = mcp->mb[5] = 0; |
2560 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2617 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2561 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; | 2618 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; |
2562 | mcp->tov = 30; | 2619 | mcp->tov = MBX_TOV_SECONDS; |
2563 | mcp->flags = 0; | 2620 | mcp->flags = 0; |
2564 | rval = qla2x00_mailbox_command(ha, mcp); | 2621 | rval = qla2x00_mailbox_command(ha, mcp); |
2565 | 2622 | ||
@@ -2877,7 +2934,7 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, | |||
2877 | } | 2934 | } |
2878 | 2935 | ||
2879 | mcp->in_mb = MBX_0; | 2936 | mcp->in_mb = MBX_0; |
2880 | mcp->tov = 30; | 2937 | mcp->tov = MBX_TOV_SECONDS; |
2881 | mcp->flags = 0; | 2938 | mcp->flags = 0; |
2882 | rval = qla2x00_mailbox_command(ha, mcp); | 2939 | rval = qla2x00_mailbox_command(ha, mcp); |
2883 | 2940 | ||
@@ -2890,3 +2947,104 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, | |||
2890 | 2947 | ||
2891 | return rval; | 2948 | return rval; |
2892 | } | 2949 | } |
2950 | |||
2951 | /* 84XX Support **************************************************************/ | ||
2952 | |||
2953 | struct cs84xx_mgmt_cmd { | ||
2954 | union { | ||
2955 | struct verify_chip_entry_84xx req; | ||
2956 | struct verify_chip_rsp_84xx rsp; | ||
2957 | } p; | ||
2958 | }; | ||
2959 | |||
2960 | int | ||
2961 | qla84xx_verify_chip(struct scsi_qla_host *ha, uint16_t *status) | ||
2962 | { | ||
2963 | int rval, retry; | ||
2964 | struct cs84xx_mgmt_cmd *mn; | ||
2965 | dma_addr_t mn_dma; | ||
2966 | uint16_t options; | ||
2967 | unsigned long flags; | ||
2968 | |||
2969 | DEBUG16(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2970 | |||
2971 | mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); | ||
2972 | if (mn == NULL) { | ||
2973 | DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX " | ||
2974 | "IOCB.\n", __func__, ha->host_no)); | ||
2975 | return QLA_MEMORY_ALLOC_FAILED; | ||
2976 | } | ||
2977 | |||
2978 | /* Force Update? */ | ||
2979 | options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0; | ||
2980 | /* Diagnostic firmware? */ | ||
2981 | /* options |= MENLO_DIAG_FW; */ | ||
2982 | /* We update the firmware with only one data sequence. */ | ||
2983 | options |= VCO_END_OF_DATA; | ||
2984 | |||
2985 | retry = 0; | ||
2986 | do { | ||
2987 | memset(mn, 0, sizeof(*mn)); | ||
2988 | mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE; | ||
2989 | mn->p.req.entry_count = 1; | ||
2990 | mn->p.req.options = cpu_to_le16(options); | ||
2991 | |||
2992 | DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__, | ||
2993 | ha->host_no)); | ||
2994 | DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, | ||
2995 | sizeof(*mn))); | ||
2996 | |||
2997 | rval = qla2x00_issue_iocb_timeout(ha, mn, mn_dma, 0, 120); | ||
2998 | if (rval != QLA_SUCCESS) { | ||
2999 | DEBUG2_16(printk("%s(%ld): failed to issue Verify " | ||
3000 | "IOCB (%x).\n", __func__, ha->host_no, rval)); | ||
3001 | goto verify_done; | ||
3002 | } | ||
3003 | |||
3004 | DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__, | ||
3005 | ha->host_no)); | ||
3006 | DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, | ||
3007 | sizeof(*mn))); | ||
3008 | |||
3009 | status[0] = le16_to_cpu(mn->p.rsp.comp_status); | ||
3010 | status[1] = status[0] == CS_VCS_CHIP_FAILURE ? | ||
3011 | le16_to_cpu(mn->p.rsp.failure_code) : 0; | ||
3012 | DEBUG2_16(printk("%s(%ld): cs=%x fc=%x\n", __func__, | ||
3013 | ha->host_no, status[0], status[1])); | ||
3014 | |||
3015 | if (status[0] != CS_COMPLETE) { | ||
3016 | rval = QLA_FUNCTION_FAILED; | ||
3017 | if (!(options & VCO_DONT_UPDATE_FW)) { | ||
3018 | DEBUG2_16(printk("%s(%ld): Firmware update " | ||
3019 | "failed. Retrying without update " | ||
3020 | "firmware.\n", __func__, ha->host_no)); | ||
3021 | options |= VCO_DONT_UPDATE_FW; | ||
3022 | options &= ~VCO_FORCE_UPDATE; | ||
3023 | retry = 1; | ||
3024 | } | ||
3025 | } else { | ||
3026 | DEBUG2_16(printk("%s(%ld): firmware updated to %x.\n", | ||
3027 | __func__, ha->host_no, | ||
3028 | le32_to_cpu(mn->p.rsp.fw_ver))); | ||
3029 | |||
3030 | /* NOTE: we only update OP firmware. */ | ||
3031 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); | ||
3032 | ha->cs84xx->op_fw_version = | ||
3033 | le32_to_cpu(mn->p.rsp.fw_ver); | ||
3034 | spin_unlock_irqrestore(&ha->cs84xx->access_lock, | ||
3035 | flags); | ||
3036 | } | ||
3037 | } while (retry); | ||
3038 | |||
3039 | verify_done: | ||
3040 | dma_pool_free(ha->s_dma_pool, mn, mn_dma); | ||
3041 | |||
3042 | if (rval != QLA_SUCCESS) { | ||
3043 | DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__, | ||
3044 | ha->host_no, rval)); | ||
3045 | } else { | ||
3046 | DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
3047 | } | ||
3048 | |||
3049 | return rval; | ||
3050 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index cf784cdafb01..f2b04979e5f0 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -1,20 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * QLOGIC LINUX SOFTWARE | 2 | * QLogic Fibre Channel HBA Driver |
3 | * | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * QLogic ISP2x00 device driver for Linux 2.6.x | ||
5 | * Copyright (C) 2003-2005 QLogic Corporation | ||
6 | * (www.qlogic.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2, or (at your option) any | ||
11 | * later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | ||
18 | */ | 6 | */ |
19 | #include "qla_def.h" | 7 | #include "qla_def.h" |
20 | 8 | ||
@@ -28,8 +16,6 @@ | |||
28 | #include <scsi/scsicam.h> | 16 | #include <scsi/scsicam.h> |
29 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
30 | 18 | ||
31 | void qla2x00_vp_stop_timer(scsi_qla_host_t *); | ||
32 | |||
33 | void | 19 | void |
34 | qla2x00_vp_stop_timer(scsi_qla_host_t *vha) | 20 | qla2x00_vp_stop_timer(scsi_qla_host_t *vha) |
35 | { | 21 | { |
@@ -268,9 +254,17 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha) | |||
268 | static int | 254 | static int |
269 | qla2x00_do_dpc_vp(scsi_qla_host_t *vha) | 255 | qla2x00_do_dpc_vp(scsi_qla_host_t *vha) |
270 | { | 256 | { |
257 | scsi_qla_host_t *ha = vha->parent; | ||
258 | |||
271 | if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { | 259 | if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { |
272 | /* VP acquired. complete port configuration */ | 260 | /* VP acquired. complete port configuration */ |
273 | qla24xx_configure_vp(vha); | 261 | if (atomic_read(&ha->loop_state) == LOOP_READY) { |
262 | qla24xx_configure_vp(vha); | ||
263 | } else { | ||
264 | set_bit(VP_IDX_ACQUIRED, &vha->vp_flags); | ||
265 | set_bit(VP_DPC_NEEDED, &ha->dpc_flags); | ||
266 | } | ||
267 | |||
274 | return 0; | 268 | return 0; |
275 | } | 269 | } |
276 | 270 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3c1b43356adb..8b33b163b1d4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -26,9 +26,6 @@ char qla2x00_version_str[40]; | |||
26 | */ | 26 | */ |
27 | static struct kmem_cache *srb_cachep; | 27 | static struct kmem_cache *srb_cachep; |
28 | 28 | ||
29 | /* | ||
30 | * Ioctl related information. | ||
31 | */ | ||
32 | int num_hosts; | 29 | int num_hosts; |
33 | int ql2xlogintimeout = 20; | 30 | int ql2xlogintimeout = 20; |
34 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); | 31 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); |
@@ -103,9 +100,9 @@ static int qla24xx_queuecommand(struct scsi_cmnd *cmd, | |||
103 | void (*fn)(struct scsi_cmnd *)); | 100 | void (*fn)(struct scsi_cmnd *)); |
104 | static int qla2xxx_eh_abort(struct scsi_cmnd *); | 101 | static int qla2xxx_eh_abort(struct scsi_cmnd *); |
105 | static int qla2xxx_eh_device_reset(struct scsi_cmnd *); | 102 | static int qla2xxx_eh_device_reset(struct scsi_cmnd *); |
103 | static int qla2xxx_eh_target_reset(struct scsi_cmnd *); | ||
106 | static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); | 104 | static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); |
107 | static int qla2xxx_eh_host_reset(struct scsi_cmnd *); | 105 | static int qla2xxx_eh_host_reset(struct scsi_cmnd *); |
108 | static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *); | ||
109 | 106 | ||
110 | static int qla2x00_change_queue_depth(struct scsi_device *, int); | 107 | static int qla2x00_change_queue_depth(struct scsi_device *, int); |
111 | static int qla2x00_change_queue_type(struct scsi_device *, int); | 108 | static int qla2x00_change_queue_type(struct scsi_device *, int); |
@@ -117,6 +114,7 @@ static struct scsi_host_template qla2x00_driver_template = { | |||
117 | 114 | ||
118 | .eh_abort_handler = qla2xxx_eh_abort, | 115 | .eh_abort_handler = qla2xxx_eh_abort, |
119 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | 116 | .eh_device_reset_handler = qla2xxx_eh_device_reset, |
117 | .eh_target_reset_handler = qla2xxx_eh_target_reset, | ||
120 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, | 118 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, |
121 | .eh_host_reset_handler = qla2xxx_eh_host_reset, | 119 | .eh_host_reset_handler = qla2xxx_eh_host_reset, |
122 | 120 | ||
@@ -148,6 +146,7 @@ struct scsi_host_template qla24xx_driver_template = { | |||
148 | 146 | ||
149 | .eh_abort_handler = qla2xxx_eh_abort, | 147 | .eh_abort_handler = qla2xxx_eh_abort, |
150 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | 148 | .eh_device_reset_handler = qla2xxx_eh_device_reset, |
149 | .eh_target_reset_handler = qla2xxx_eh_target_reset, | ||
151 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, | 150 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, |
152 | .eh_host_reset_handler = qla2xxx_eh_host_reset, | 151 | .eh_host_reset_handler = qla2xxx_eh_host_reset, |
153 | 152 | ||
@@ -253,9 +252,9 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) | |||
253 | 252 | ||
254 | strcpy(str, "PCIe ("); | 253 | strcpy(str, "PCIe ("); |
255 | if (lspeed == 1) | 254 | if (lspeed == 1) |
256 | strcat(str, "2.5Gb/s "); | 255 | strcat(str, "2.5GT/s "); |
257 | else if (lspeed == 2) | 256 | else if (lspeed == 2) |
258 | strcat(str, "5.0Gb/s "); | 257 | strcat(str, "5.0GT/s "); |
259 | else | 258 | else |
260 | strcat(str, "<unknown> "); | 259 | strcat(str, "<unknown> "); |
261 | snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); | 260 | snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); |
@@ -340,6 +339,8 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) | |||
340 | strcat(str, "[T10 CRC] "); | 339 | strcat(str, "[T10 CRC] "); |
341 | if (ha->fw_attributes & BIT_5) | 340 | if (ha->fw_attributes & BIT_5) |
342 | strcat(str, "[VI] "); | 341 | strcat(str, "[VI] "); |
342 | if (ha->fw_attributes & BIT_10) | ||
343 | strcat(str, "[84XX] "); | ||
343 | if (ha->fw_attributes & BIT_13) | 344 | if (ha->fw_attributes & BIT_13) |
344 | strcat(str, "[Experimental]"); | 345 | strcat(str, "[Experimental]"); |
345 | return str; | 346 | return str; |
@@ -570,8 +571,6 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) | |||
570 | else | 571 | else |
571 | return_status = QLA_FUNCTION_FAILED; | 572 | return_status = QLA_FUNCTION_FAILED; |
572 | 573 | ||
573 | DEBUG2(printk("%s return_status=%d\n",__func__,return_status)); | ||
574 | |||
575 | return (return_status); | 574 | return (return_status); |
576 | } | 575 | } |
577 | 576 | ||
@@ -685,7 +684,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
685 | 684 | ||
686 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", | 685 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", |
687 | __func__, ha->host_no, sp, serial)); | 686 | __func__, ha->host_no, sp, serial)); |
688 | DEBUG3(qla2x00_print_scsi_cmd(cmd)); | ||
689 | 687 | ||
690 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 688 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
691 | if (ha->isp_ops->abort_command(ha, sp)) { | 689 | if (ha->isp_ops->abort_command(ha, sp)) { |
@@ -719,190 +717,122 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
719 | return ret; | 717 | return ret; |
720 | } | 718 | } |
721 | 719 | ||
722 | /************************************************************************** | 720 | enum nexus_wait_type { |
723 | * qla2x00_eh_wait_for_pending_target_commands | 721 | WAIT_HOST = 0, |
724 | * | 722 | WAIT_TARGET, |
725 | * Description: | 723 | WAIT_LUN, |
726 | * Waits for all the commands to come back from the specified target. | 724 | }; |
727 | * | 725 | |
728 | * Input: | ||
729 | * ha - pointer to scsi_qla_host structure. | ||
730 | * t - target | ||
731 | * Returns: | ||
732 | * Either SUCCESS or FAILED. | ||
733 | * | ||
734 | * Note: | ||
735 | **************************************************************************/ | ||
736 | static int | 726 | static int |
737 | qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | 727 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t, |
728 | unsigned int l, enum nexus_wait_type type) | ||
738 | { | 729 | { |
739 | int cnt; | 730 | int cnt, match, status; |
740 | int status; | 731 | srb_t *sp; |
741 | srb_t *sp; | ||
742 | struct scsi_cmnd *cmd; | ||
743 | unsigned long flags; | 732 | unsigned long flags; |
744 | scsi_qla_host_t *pha = to_qla_parent(ha); | 733 | scsi_qla_host_t *pha = to_qla_parent(ha); |
745 | 734 | ||
746 | status = 0; | 735 | status = QLA_SUCCESS; |
747 | 736 | spin_lock_irqsave(&pha->hardware_lock, flags); | |
748 | /* | 737 | for (cnt = 1; status == QLA_SUCCESS && cnt < MAX_OUTSTANDING_COMMANDS; |
749 | * Waiting for all commands for the designated target in the active | 738 | cnt++) { |
750 | * array | ||
751 | */ | ||
752 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
753 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
754 | sp = pha->outstanding_cmds[cnt]; | 739 | sp = pha->outstanding_cmds[cnt]; |
755 | if (sp) { | 740 | if (!sp) |
756 | cmd = sp->cmd; | 741 | continue; |
757 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 742 | if (ha->vp_idx != sp->ha->vp_idx) |
758 | if (cmd->device->id == t && | 743 | continue; |
759 | ha->vp_idx == sp->ha->vp_idx) { | 744 | match = 0; |
760 | if (!qla2x00_eh_wait_on_command(ha, cmd)) { | 745 | switch (type) { |
761 | status = 1; | 746 | case WAIT_HOST: |
762 | break; | 747 | match = 1; |
763 | } | 748 | break; |
764 | } | 749 | case WAIT_TARGET: |
765 | } else { | 750 | match = sp->cmd->device->id == t; |
766 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 751 | break; |
752 | case WAIT_LUN: | ||
753 | match = (sp->cmd->device->id == t && | ||
754 | sp->cmd->device->lun == l); | ||
755 | break; | ||
767 | } | 756 | } |
757 | if (!match) | ||
758 | continue; | ||
759 | |||
760 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | ||
761 | status = qla2x00_eh_wait_on_command(ha, sp->cmd); | ||
762 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
768 | } | 763 | } |
769 | return (status); | 764 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
765 | |||
766 | return status; | ||
770 | } | 767 | } |
771 | 768 | ||
769 | static char *reset_errors[] = { | ||
770 | "HBA not online", | ||
771 | "HBA not ready", | ||
772 | "Task management failed", | ||
773 | "Waiting for command completions", | ||
774 | }; | ||
772 | 775 | ||
773 | /************************************************************************** | ||
774 | * qla2xxx_eh_device_reset | ||
775 | * | ||
776 | * Description: | ||
777 | * The device reset function will reset the target and abort any | ||
778 | * executing commands. | ||
779 | * | ||
780 | * NOTE: The use of SP is undefined within this context. Do *NOT* | ||
781 | * attempt to use this value, even if you determine it is | ||
782 | * non-null. | ||
783 | * | ||
784 | * Input: | ||
785 | * cmd = Linux SCSI command packet of the command that cause the | ||
786 | * bus device reset. | ||
787 | * | ||
788 | * Returns: | ||
789 | * SUCCESS/FAILURE (defined as macro in scsi.h). | ||
790 | * | ||
791 | **************************************************************************/ | ||
792 | static int | 776 | static int |
793 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | 777 | __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, |
778 | struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int)) | ||
794 | { | 779 | { |
795 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 780 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
796 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 781 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
797 | int ret = FAILED; | 782 | int err; |
798 | unsigned int id, lun; | ||
799 | unsigned long serial; | ||
800 | 783 | ||
801 | qla2x00_block_error_handler(cmd); | 784 | qla2x00_block_error_handler(cmd); |
802 | 785 | ||
803 | id = cmd->device->id; | ||
804 | lun = cmd->device->lun; | ||
805 | serial = cmd->serial_number; | ||
806 | |||
807 | if (!fcport) | 786 | if (!fcport) |
808 | return ret; | 787 | return FAILED; |
809 | 788 | ||
810 | qla_printk(KERN_INFO, ha, | 789 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET ISSUED.\n", |
811 | "scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun); | 790 | ha->host_no, cmd->device->id, cmd->device->lun, name); |
812 | 791 | ||
792 | err = 0; | ||
813 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) | 793 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) |
814 | goto eh_dev_reset_done; | 794 | goto eh_reset_failed; |
815 | 795 | err = 1; | |
816 | if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { | 796 | if (qla2x00_wait_for_loop_ready(ha) != QLA_SUCCESS) |
817 | if (qla2x00_device_reset(ha, fcport) == 0) | 797 | goto eh_reset_failed; |
818 | ret = SUCCESS; | 798 | err = 2; |
819 | 799 | if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS) | |
820 | #if defined(LOGOUT_AFTER_DEVICE_RESET) | 800 | goto eh_reset_failed; |
821 | if (ret == SUCCESS) { | 801 | err = 3; |
822 | if (fcport->flags & FC_FABRIC_DEVICE) { | 802 | if (qla2x00_eh_wait_for_pending_commands(ha, cmd->device->id, |
823 | ha->isp_ops->fabric_logout(ha, fcport->loop_id); | 803 | cmd->device->lun, type) != QLA_SUCCESS) |
824 | qla2x00_mark_device_lost(ha, fcport, 0, 0); | 804 | goto eh_reset_failed; |
825 | } | 805 | |
826 | } | 806 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n", |
827 | #endif | 807 | ha->host_no, cmd->device->id, cmd->device->lun, name); |
828 | } else { | 808 | |
829 | DEBUG2(printk(KERN_INFO | 809 | return SUCCESS; |
830 | "%s failed: loop not ready\n",__func__)); | 810 | |
831 | } | 811 | eh_reset_failed: |
832 | 812 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n", | |
833 | if (ret == FAILED) { | 813 | ha->host_no, cmd->device->id, cmd->device->lun, name, |
834 | DEBUG3(printk("%s(%ld): device reset failed\n", | 814 | reset_errors[err]); |
835 | __func__, ha->host_no)); | 815 | return FAILED; |
836 | qla_printk(KERN_INFO, ha, "%s: device reset failed\n", | 816 | } |
837 | __func__); | ||
838 | 817 | ||
839 | goto eh_dev_reset_done; | 818 | static int |
840 | } | 819 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) |
820 | { | ||
821 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | ||
841 | 822 | ||
842 | /* Flush outstanding commands. */ | 823 | return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd, |
843 | if (qla2x00_eh_wait_for_pending_target_commands(ha, id)) | 824 | ha->isp_ops->lun_reset); |
844 | ret = FAILED; | ||
845 | if (ret == FAILED) { | ||
846 | DEBUG3(printk("%s(%ld): failed while waiting for commands\n", | ||
847 | __func__, ha->host_no)); | ||
848 | qla_printk(KERN_INFO, ha, | ||
849 | "%s: failed while waiting for commands\n", __func__); | ||
850 | } else | ||
851 | qla_printk(KERN_INFO, ha, | ||
852 | "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, | ||
853 | id, lun); | ||
854 | eh_dev_reset_done: | ||
855 | return ret; | ||
856 | } | 825 | } |
857 | 826 | ||
858 | /************************************************************************** | ||
859 | * qla2x00_eh_wait_for_pending_commands | ||
860 | * | ||
861 | * Description: | ||
862 | * Waits for all the commands to come back from the specified host. | ||
863 | * | ||
864 | * Input: | ||
865 | * ha - pointer to scsi_qla_host structure. | ||
866 | * | ||
867 | * Returns: | ||
868 | * 1 : SUCCESS | ||
869 | * 0 : FAILED | ||
870 | * | ||
871 | * Note: | ||
872 | **************************************************************************/ | ||
873 | static int | 827 | static int |
874 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) | 828 | qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) |
875 | { | 829 | { |
876 | int cnt; | 830 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
877 | int status; | ||
878 | srb_t *sp; | ||
879 | struct scsi_cmnd *cmd; | ||
880 | unsigned long flags; | ||
881 | |||
882 | status = 1; | ||
883 | 831 | ||
884 | /* | 832 | return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd, |
885 | * Waiting for all commands for the designated target in the active | 833 | ha->isp_ops->target_reset); |
886 | * array | ||
887 | */ | ||
888 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
889 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
890 | sp = ha->outstanding_cmds[cnt]; | ||
891 | if (sp) { | ||
892 | cmd = sp->cmd; | ||
893 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
894 | status = qla2x00_eh_wait_on_command(ha, cmd); | ||
895 | if (status == 0) | ||
896 | break; | ||
897 | } | ||
898 | else { | ||
899 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
900 | } | ||
901 | } | ||
902 | return (status); | ||
903 | } | 834 | } |
904 | 835 | ||
905 | |||
906 | /************************************************************************** | 836 | /************************************************************************** |
907 | * qla2xxx_eh_bus_reset | 837 | * qla2xxx_eh_bus_reset |
908 | * | 838 | * |
@@ -953,7 +883,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
953 | goto eh_bus_reset_done; | 883 | goto eh_bus_reset_done; |
954 | 884 | ||
955 | /* Flush outstanding commands. */ | 885 | /* Flush outstanding commands. */ |
956 | if (!qla2x00_eh_wait_for_pending_commands(pha)) | 886 | if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) != |
887 | QLA_SUCCESS) | ||
957 | ret = FAILED; | 888 | ret = FAILED; |
958 | 889 | ||
959 | eh_bus_reset_done: | 890 | eh_bus_reset_done: |
@@ -1024,7 +955,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1024 | clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); | 955 | clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); |
1025 | 956 | ||
1026 | /* Waiting for our command in done_queue to be returned to OS.*/ | 957 | /* Waiting for our command in done_queue to be returned to OS.*/ |
1027 | if (qla2x00_eh_wait_for_pending_commands(pha)) | 958 | if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) == |
959 | QLA_SUCCESS) | ||
1028 | ret = SUCCESS; | 960 | ret = SUCCESS; |
1029 | 961 | ||
1030 | if (ha->parent) | 962 | if (ha->parent) |
@@ -1080,7 +1012,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1080 | if (fcport->port_type != FCT_TARGET) | 1012 | if (fcport->port_type != FCT_TARGET) |
1081 | continue; | 1013 | continue; |
1082 | 1014 | ||
1083 | ret = qla2x00_device_reset(ha, fcport); | 1015 | ret = ha->isp_ops->target_reset(fcport, 0); |
1084 | if (ret != QLA_SUCCESS) { | 1016 | if (ret != QLA_SUCCESS) { |
1085 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " | 1017 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " |
1086 | "target_reset=%d d_id=%x.\n", __func__, | 1018 | "target_reset=%d d_id=%x.\n", __func__, |
@@ -1095,26 +1027,6 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1095 | return QLA_SUCCESS; | 1027 | return QLA_SUCCESS; |
1096 | } | 1028 | } |
1097 | 1029 | ||
1098 | /* | ||
1099 | * qla2x00_device_reset | ||
1100 | * Issue bus device reset message to the target. | ||
1101 | * | ||
1102 | * Input: | ||
1103 | * ha = adapter block pointer. | ||
1104 | * t = SCSI ID. | ||
1105 | * TARGET_QUEUE_LOCK must be released. | ||
1106 | * ADAPTER_STATE_LOCK must be released. | ||
1107 | * | ||
1108 | * Context: | ||
1109 | * Kernel context. | ||
1110 | */ | ||
1111 | static int | ||
1112 | qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport) | ||
1113 | { | ||
1114 | /* Abort Target command will clear Reservation */ | ||
1115 | return ha->isp_ops->abort_target(reset_fcport); | ||
1116 | } | ||
1117 | |||
1118 | void | 1030 | void |
1119 | qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res) | 1031 | qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res) |
1120 | { | 1032 | { |
@@ -1292,7 +1204,8 @@ static struct isp_operations qla2100_isp_ops = { | |||
1292 | .enable_intrs = qla2x00_enable_intrs, | 1204 | .enable_intrs = qla2x00_enable_intrs, |
1293 | .disable_intrs = qla2x00_disable_intrs, | 1205 | .disable_intrs = qla2x00_disable_intrs, |
1294 | .abort_command = qla2x00_abort_command, | 1206 | .abort_command = qla2x00_abort_command, |
1295 | .abort_target = qla2x00_abort_target, | 1207 | .target_reset = qla2x00_abort_target, |
1208 | .lun_reset = qla2x00_lun_reset, | ||
1296 | .fabric_login = qla2x00_login_fabric, | 1209 | .fabric_login = qla2x00_login_fabric, |
1297 | .fabric_logout = qla2x00_fabric_logout, | 1210 | .fabric_logout = qla2x00_fabric_logout, |
1298 | .calc_req_entries = qla2x00_calc_iocbs_32, | 1211 | .calc_req_entries = qla2x00_calc_iocbs_32, |
@@ -1325,7 +1238,8 @@ static struct isp_operations qla2300_isp_ops = { | |||
1325 | .enable_intrs = qla2x00_enable_intrs, | 1238 | .enable_intrs = qla2x00_enable_intrs, |
1326 | .disable_intrs = qla2x00_disable_intrs, | 1239 | .disable_intrs = qla2x00_disable_intrs, |
1327 | .abort_command = qla2x00_abort_command, | 1240 | .abort_command = qla2x00_abort_command, |
1328 | .abort_target = qla2x00_abort_target, | 1241 | .target_reset = qla2x00_abort_target, |
1242 | .lun_reset = qla2x00_lun_reset, | ||
1329 | .fabric_login = qla2x00_login_fabric, | 1243 | .fabric_login = qla2x00_login_fabric, |
1330 | .fabric_logout = qla2x00_fabric_logout, | 1244 | .fabric_logout = qla2x00_fabric_logout, |
1331 | .calc_req_entries = qla2x00_calc_iocbs_32, | 1245 | .calc_req_entries = qla2x00_calc_iocbs_32, |
@@ -1358,7 +1272,8 @@ static struct isp_operations qla24xx_isp_ops = { | |||
1358 | .enable_intrs = qla24xx_enable_intrs, | 1272 | .enable_intrs = qla24xx_enable_intrs, |
1359 | .disable_intrs = qla24xx_disable_intrs, | 1273 | .disable_intrs = qla24xx_disable_intrs, |
1360 | .abort_command = qla24xx_abort_command, | 1274 | .abort_command = qla24xx_abort_command, |
1361 | .abort_target = qla24xx_abort_target, | 1275 | .target_reset = qla24xx_abort_target, |
1276 | .lun_reset = qla24xx_lun_reset, | ||
1362 | .fabric_login = qla24xx_login_fabric, | 1277 | .fabric_login = qla24xx_login_fabric, |
1363 | .fabric_logout = qla24xx_fabric_logout, | 1278 | .fabric_logout = qla24xx_fabric_logout, |
1364 | .calc_req_entries = NULL, | 1279 | .calc_req_entries = NULL, |
@@ -1391,7 +1306,8 @@ static struct isp_operations qla25xx_isp_ops = { | |||
1391 | .enable_intrs = qla24xx_enable_intrs, | 1306 | .enable_intrs = qla24xx_enable_intrs, |
1392 | .disable_intrs = qla24xx_disable_intrs, | 1307 | .disable_intrs = qla24xx_disable_intrs, |
1393 | .abort_command = qla24xx_abort_command, | 1308 | .abort_command = qla24xx_abort_command, |
1394 | .abort_target = qla24xx_abort_target, | 1309 | .target_reset = qla24xx_abort_target, |
1310 | .lun_reset = qla24xx_lun_reset, | ||
1395 | .fabric_login = qla24xx_login_fabric, | 1311 | .fabric_login = qla24xx_login_fabric, |
1396 | .fabric_logout = qla24xx_fabric_logout, | 1312 | .fabric_logout = qla24xx_fabric_logout, |
1397 | .calc_req_entries = NULL, | 1313 | .calc_req_entries = NULL, |
@@ -1464,6 +1380,13 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha) | |||
1464 | ha->device_type |= DT_IIDMA; | 1380 | ha->device_type |= DT_IIDMA; |
1465 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | 1381 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
1466 | break; | 1382 | break; |
1383 | case PCI_DEVICE_ID_QLOGIC_ISP8432: | ||
1384 | ha->device_type |= DT_ISP8432; | ||
1385 | ha->device_type |= DT_ZIO_SUPPORTED; | ||
1386 | ha->device_type |= DT_FWI2; | ||
1387 | ha->device_type |= DT_IIDMA; | ||
1388 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | ||
1389 | break; | ||
1467 | case PCI_DEVICE_ID_QLOGIC_ISP5422: | 1390 | case PCI_DEVICE_ID_QLOGIC_ISP5422: |
1468 | ha->device_type |= DT_ISP5422; | 1391 | ha->device_type |= DT_ISP5422; |
1469 | ha->device_type |= DT_FWI2; | 1392 | ha->device_type |= DT_FWI2; |
@@ -1587,6 +1510,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1587 | sht = &qla2x00_driver_template; | 1510 | sht = &qla2x00_driver_template; |
1588 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || | 1511 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || |
1589 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || | 1512 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || |
1513 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 || | ||
1590 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || | 1514 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || |
1591 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || | 1515 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || |
1592 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { | 1516 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { |
@@ -1677,7 +1601,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1677 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) | 1601 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) |
1678 | ha->optrom_size = OPTROM_SIZE_2322; | 1602 | ha->optrom_size = OPTROM_SIZE_2322; |
1679 | ha->isp_ops = &qla2300_isp_ops; | 1603 | ha->isp_ops = &qla2300_isp_ops; |
1680 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1604 | } else if (IS_QLA24XX_TYPE(ha)) { |
1681 | host->max_id = MAX_TARGETS_2200; | 1605 | host->max_id = MAX_TARGETS_2200; |
1682 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1606 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
1683 | ha->request_q_length = REQUEST_ENTRY_CNT_24XX; | 1607 | ha->request_q_length = REQUEST_ENTRY_CNT_24XX; |
@@ -1699,6 +1623,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1699 | ha->gid_list_info_size = 8; | 1623 | ha->gid_list_info_size = 8; |
1700 | ha->optrom_size = OPTROM_SIZE_25XX; | 1624 | ha->optrom_size = OPTROM_SIZE_25XX; |
1701 | ha->isp_ops = &qla25xx_isp_ops; | 1625 | ha->isp_ops = &qla25xx_isp_ops; |
1626 | ha->hw_event_start = PCI_FUNC(pdev->devfn) ? | ||
1627 | FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR; | ||
1702 | } | 1628 | } |
1703 | host->can_queue = ha->request_q_length + 128; | 1629 | host->can_queue = ha->request_q_length + 128; |
1704 | 1630 | ||
@@ -1713,6 +1639,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1713 | INIT_LIST_HEAD(&ha->list); | 1639 | INIT_LIST_HEAD(&ha->list); |
1714 | INIT_LIST_HEAD(&ha->fcports); | 1640 | INIT_LIST_HEAD(&ha->fcports); |
1715 | INIT_LIST_HEAD(&ha->vp_list); | 1641 | INIT_LIST_HEAD(&ha->vp_list); |
1642 | INIT_LIST_HEAD(&ha->work_list); | ||
1716 | 1643 | ||
1717 | set_bit(0, (unsigned long *) ha->vp_idx_map); | 1644 | set_bit(0, (unsigned long *) ha->vp_idx_map); |
1718 | 1645 | ||
@@ -1819,6 +1746,8 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
1819 | 1746 | ||
1820 | qla2x00_dfs_remove(ha); | 1747 | qla2x00_dfs_remove(ha); |
1821 | 1748 | ||
1749 | qla84xx_put_chip(ha); | ||
1750 | |||
1822 | qla2x00_free_sysfs_attr(ha); | 1751 | qla2x00_free_sysfs_attr(ha); |
1823 | 1752 | ||
1824 | fc_remove_host(ha->host); | 1753 | fc_remove_host(ha->host); |
@@ -2206,6 +2135,97 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2206 | kfree(ha->nvram); | 2135 | kfree(ha->nvram); |
2207 | } | 2136 | } |
2208 | 2137 | ||
2138 | struct qla_work_evt * | ||
2139 | qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type, | ||
2140 | int locked) | ||
2141 | { | ||
2142 | struct qla_work_evt *e; | ||
2143 | |||
2144 | e = kzalloc(sizeof(struct qla_work_evt), locked ? GFP_ATOMIC: | ||
2145 | GFP_KERNEL); | ||
2146 | if (!e) | ||
2147 | return NULL; | ||
2148 | |||
2149 | INIT_LIST_HEAD(&e->list); | ||
2150 | e->type = type; | ||
2151 | e->flags = QLA_EVT_FLAG_FREE; | ||
2152 | return e; | ||
2153 | } | ||
2154 | |||
2155 | int | ||
2156 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) | ||
2157 | { | ||
2158 | unsigned long flags; | ||
2159 | |||
2160 | if (!locked) | ||
2161 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
2162 | list_add_tail(&e->list, &ha->work_list); | ||
2163 | qla2xxx_wake_dpc(ha); | ||
2164 | if (!locked) | ||
2165 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2166 | return QLA_SUCCESS; | ||
2167 | } | ||
2168 | |||
2169 | int | ||
2170 | qla2x00_post_aen_work(struct scsi_qla_host *ha, enum fc_host_event_code code, | ||
2171 | u32 data) | ||
2172 | { | ||
2173 | struct qla_work_evt *e; | ||
2174 | |||
2175 | e = qla2x00_alloc_work(ha, QLA_EVT_AEN, 1); | ||
2176 | if (!e) | ||
2177 | return QLA_FUNCTION_FAILED; | ||
2178 | |||
2179 | e->u.aen.code = code; | ||
2180 | e->u.aen.data = data; | ||
2181 | return qla2x00_post_work(ha, e, 1); | ||
2182 | } | ||
2183 | |||
2184 | int | ||
2185 | qla2x00_post_hwe_work(struct scsi_qla_host *ha, uint16_t code, uint16_t d1, | ||
2186 | uint16_t d2, uint16_t d3) | ||
2187 | { | ||
2188 | struct qla_work_evt *e; | ||
2189 | |||
2190 | e = qla2x00_alloc_work(ha, QLA_EVT_HWE_LOG, 1); | ||
2191 | if (!e) | ||
2192 | return QLA_FUNCTION_FAILED; | ||
2193 | |||
2194 | e->u.hwe.code = code; | ||
2195 | e->u.hwe.d1 = d1; | ||
2196 | e->u.hwe.d2 = d2; | ||
2197 | e->u.hwe.d3 = d3; | ||
2198 | return qla2x00_post_work(ha, e, 1); | ||
2199 | } | ||
2200 | |||
2201 | static void | ||
2202 | qla2x00_do_work(struct scsi_qla_host *ha) | ||
2203 | { | ||
2204 | struct qla_work_evt *e; | ||
2205 | |||
2206 | spin_lock_irq(&ha->hardware_lock); | ||
2207 | while (!list_empty(&ha->work_list)) { | ||
2208 | e = list_entry(ha->work_list.next, struct qla_work_evt, list); | ||
2209 | list_del_init(&e->list); | ||
2210 | spin_unlock_irq(&ha->hardware_lock); | ||
2211 | |||
2212 | switch (e->type) { | ||
2213 | case QLA_EVT_AEN: | ||
2214 | fc_host_post_event(ha->host, fc_get_event_number(), | ||
2215 | e->u.aen.code, e->u.aen.data); | ||
2216 | break; | ||
2217 | case QLA_EVT_HWE_LOG: | ||
2218 | qla2xxx_hw_event_log(ha, e->u.hwe.code, e->u.hwe.d1, | ||
2219 | e->u.hwe.d2, e->u.hwe.d3); | ||
2220 | break; | ||
2221 | } | ||
2222 | if (e->flags & QLA_EVT_FLAG_FREE) | ||
2223 | kfree(e); | ||
2224 | spin_lock_irq(&ha->hardware_lock); | ||
2225 | } | ||
2226 | spin_unlock_irq(&ha->hardware_lock); | ||
2227 | } | ||
2228 | |||
2209 | /************************************************************************** | 2229 | /************************************************************************** |
2210 | * qla2x00_do_dpc | 2230 | * qla2x00_do_dpc |
2211 | * This kernel thread is a task that is schedule by the interrupt handler | 2231 | * This kernel thread is a task that is schedule by the interrupt handler |
@@ -2257,6 +2277,8 @@ qla2x00_do_dpc(void *data) | |||
2257 | continue; | 2277 | continue; |
2258 | } | 2278 | } |
2259 | 2279 | ||
2280 | qla2x00_do_work(ha); | ||
2281 | |||
2260 | if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) { | 2282 | if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) { |
2261 | 2283 | ||
2262 | DEBUG(printk("scsi(%ld): dpc: sched " | 2284 | DEBUG(printk("scsi(%ld): dpc: sched " |
@@ -2291,12 +2313,6 @@ qla2x00_do_dpc(void *data) | |||
2291 | if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) | 2313 | if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) |
2292 | qla2x00_update_fcports(ha); | 2314 | qla2x00_update_fcports(ha); |
2293 | 2315 | ||
2294 | if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) { | ||
2295 | DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n", | ||
2296 | ha->host_no)); | ||
2297 | qla2x00_loop_reset(ha); | ||
2298 | } | ||
2299 | |||
2300 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && | 2316 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && |
2301 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { | 2317 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { |
2302 | 2318 | ||
@@ -2367,19 +2383,6 @@ qla2x00_do_dpc(void *data) | |||
2367 | ha->host_no)); | 2383 | ha->host_no)); |
2368 | } | 2384 | } |
2369 | 2385 | ||
2370 | if ((test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags)) && | ||
2371 | atomic_read(&ha->loop_state) != LOOP_DOWN) { | ||
2372 | |||
2373 | clear_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags); | ||
2374 | DEBUG(printk("scsi(%ld): qla2x00_login_retry()\n", | ||
2375 | ha->host_no)); | ||
2376 | |||
2377 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | ||
2378 | |||
2379 | DEBUG(printk("scsi(%ld): qla2x00_login_retry - end\n", | ||
2380 | ha->host_no)); | ||
2381 | } | ||
2382 | |||
2383 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { | 2386 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { |
2384 | 2387 | ||
2385 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", | 2388 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", |
@@ -2397,18 +2400,6 @@ qla2x00_do_dpc(void *data) | |||
2397 | ha->host_no)); | 2400 | ha->host_no)); |
2398 | } | 2401 | } |
2399 | 2402 | ||
2400 | if (test_and_clear_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags)) { | ||
2401 | |||
2402 | DEBUG(printk("scsi(%ld): Rescan flagged fcports...\n", | ||
2403 | ha->host_no)); | ||
2404 | |||
2405 | qla2x00_rescan_fcports(ha); | ||
2406 | |||
2407 | DEBUG(printk("scsi(%ld): Rescan flagged fcports..." | ||
2408 | "end.\n", | ||
2409 | ha->host_no)); | ||
2410 | } | ||
2411 | |||
2412 | if (!ha->interrupts_on) | 2403 | if (!ha->interrupts_on) |
2413 | ha->isp_ops->enable_intrs(ha); | 2404 | ha->isp_ops->enable_intrs(ha); |
2414 | 2405 | ||
@@ -2586,7 +2577,8 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2586 | set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags); | 2577 | set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags); |
2587 | start_dpc++; | 2578 | start_dpc++; |
2588 | 2579 | ||
2589 | if (!(ha->device_flags & DFLG_NO_CABLE)) { | 2580 | if (!(ha->device_flags & DFLG_NO_CABLE) && |
2581 | !ha->parent) { | ||
2590 | DEBUG(printk("scsi(%ld): Loop down - " | 2582 | DEBUG(printk("scsi(%ld): Loop down - " |
2591 | "aborting ISP.\n", | 2583 | "aborting ISP.\n", |
2592 | ha->host_no)); | 2584 | ha->host_no)); |
@@ -2610,10 +2602,8 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2610 | /* Schedule the DPC routine if needed */ | 2602 | /* Schedule the DPC routine if needed */ |
2611 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || | 2603 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || |
2612 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || | 2604 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || |
2613 | test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || | ||
2614 | test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || | 2605 | test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || |
2615 | start_dpc || | 2606 | start_dpc || |
2616 | test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || | ||
2617 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || | 2607 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || |
2618 | test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || | 2608 | test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || |
2619 | test_bit(VP_DPC_NEEDED, &ha->dpc_flags) || | 2609 | test_bit(VP_DPC_NEEDED, &ha->dpc_flags) || |
@@ -2665,7 +2655,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) | |||
2665 | blob = &qla_fw_blobs[FW_ISP2300]; | 2655 | blob = &qla_fw_blobs[FW_ISP2300]; |
2666 | } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) { | 2656 | } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) { |
2667 | blob = &qla_fw_blobs[FW_ISP2322]; | 2657 | blob = &qla_fw_blobs[FW_ISP2322]; |
2668 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 2658 | } else if (IS_QLA24XX_TYPE(ha)) { |
2669 | blob = &qla_fw_blobs[FW_ISP24XX]; | 2659 | blob = &qla_fw_blobs[FW_ISP24XX]; |
2670 | } else if (IS_QLA25XX(ha)) { | 2660 | } else if (IS_QLA25XX(ha)) { |
2671 | blob = &qla_fw_blobs[FW_ISP25XX]; | 2661 | blob = &qla_fw_blobs[FW_ISP25XX]; |
@@ -2815,6 +2805,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
2815 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) }, | 2805 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) }, |
2816 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) }, | 2806 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) }, |
2817 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, | 2807 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, |
2808 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) }, | ||
2818 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, | 2809 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, |
2819 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, | 2810 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, |
2820 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) }, | 2811 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) }, |
diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h index 249e4d90fdc5..2801c2664b40 100644 --- a/drivers/scsi/qla2xxx/qla_settings.h +++ b/drivers/scsi/qla2xxx/qla_settings.h | |||
@@ -1,26 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | /* | ||
8 | * Compile time Options: | ||
9 | * 0 - Disable and 1 - Enable | ||
10 | */ | ||
11 | #define DEBUG_QLA2100 0 /* For Debug of qla2x00 */ | ||
12 | |||
13 | #define USE_ABORT_TGT 1 /* Use Abort Target mbx cmd */ | ||
14 | |||
15 | #define MAX_RETRIES_OF_ISP_ABORT 5 | 7 | #define MAX_RETRIES_OF_ISP_ABORT 5 |
16 | 8 | ||
17 | /* Max time to wait for the loop to be in LOOP_READY state */ | 9 | /* Max time to wait for the loop to be in LOOP_READY state */ |
18 | #define MAX_LOOP_TIMEOUT (60 * 5) | 10 | #define MAX_LOOP_TIMEOUT (60 * 5) |
19 | 11 | ||
20 | /* | ||
21 | * Some vendor subsystems do not recover properly after a device reset. Define | ||
22 | * the following to force a logout after a successful device reset. | ||
23 | */ | ||
24 | #undef LOGOUT_AFTER_DEVICE_RESET | ||
25 | |||
26 | #include "qla_version.h" | 12 | #include "qla_version.h" |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 26822c8807ee..1728ab3ccb20 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -543,79 +543,174 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, | |||
543 | } | 543 | } |
544 | } | 544 | } |
545 | 545 | ||
546 | static int | 546 | void |
547 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | 547 | qla2xxx_get_flash_info(scsi_qla_host_t *ha) |
548 | uint32_t dwords) | ||
549 | { | 548 | { |
550 | int ret; | 549 | #define FLASH_BLK_SIZE_32K 0x8000 |
551 | uint32_t liter, miter; | 550 | #define FLASH_BLK_SIZE_64K 0x10000 |
552 | uint32_t sec_mask, rest_addr, conf_addr; | 551 | uint16_t cnt, chksum; |
553 | uint32_t fdata, findex, cnt; | 552 | uint16_t *wptr; |
553 | struct qla_fdt_layout *fdt; | ||
554 | uint8_t man_id, flash_id; | 554 | uint8_t man_id, flash_id; |
555 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
556 | dma_addr_t optrom_dma; | ||
557 | void *optrom = NULL; | ||
558 | uint32_t *s, *d; | ||
559 | 555 | ||
560 | ret = QLA_SUCCESS; | 556 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) |
557 | return; | ||
561 | 558 | ||
562 | /* Prepare burst-capable write on supported ISPs. */ | 559 | wptr = (uint16_t *)ha->request_ring; |
563 | if (IS_QLA25XX(ha) && !(faddr & 0xfff) && | 560 | fdt = (struct qla_fdt_layout *)ha->request_ring; |
564 | dwords > OPTROM_BURST_DWORDS) { | 561 | ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring, |
565 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | 562 | FA_FLASH_DESCR_ADDR << 2, OPTROM_BURST_SIZE); |
566 | &optrom_dma, GFP_KERNEL); | 563 | if (*wptr == __constant_cpu_to_le16(0xffff)) |
567 | if (!optrom) { | 564 | goto no_flash_data; |
568 | qla_printk(KERN_DEBUG, ha, | 565 | if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' || |
569 | "Unable to allocate memory for optrom burst write " | 566 | fdt->sig[3] != 'D') |
570 | "(%x KB).\n", OPTROM_BURST_SIZE / 1024); | 567 | goto no_flash_data; |
571 | } | 568 | |
569 | for (cnt = 0, chksum = 0; cnt < sizeof(struct qla_fdt_layout) >> 1; | ||
570 | cnt++) | ||
571 | chksum += le16_to_cpu(*wptr++); | ||
572 | if (chksum) { | ||
573 | DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent FDT detected: " | ||
574 | "checksum=0x%x id=%c version=0x%x.\n", chksum, fdt->sig[0], | ||
575 | le16_to_cpu(fdt->version))); | ||
576 | DEBUG9(qla2x00_dump_buffer((uint8_t *)fdt, sizeof(*fdt))); | ||
577 | goto no_flash_data; | ||
572 | } | 578 | } |
573 | 579 | ||
574 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); | 580 | ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f; |
575 | DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__, | 581 | ha->fdt_wrt_disable = fdt->wrt_disable_bits; |
576 | ha->host_no, man_id, flash_id)); | 582 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd); |
583 | ha->fdt_block_size = le32_to_cpu(fdt->block_size); | ||
584 | if (fdt->unprotect_sec_cmd) { | ||
585 | ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0300 | | ||
586 | fdt->unprotect_sec_cmd); | ||
587 | ha->fdt_protect_sec_cmd = fdt->protect_sec_cmd ? | ||
588 | flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd): | ||
589 | flash_conf_to_access_addr(0x0336); | ||
590 | } | ||
577 | 591 | ||
578 | conf_addr = flash_conf_to_access_addr(0x03d8); | 592 | DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x " |
593 | "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", | ||
594 | le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd, | ||
595 | ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd, | ||
596 | ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size)); | ||
597 | return; | ||
598 | |||
599 | no_flash_data: | ||
600 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); | ||
601 | ha->fdt_wrt_disable = 0x9c; | ||
602 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8); | ||
579 | switch (man_id) { | 603 | switch (man_id) { |
580 | case 0xbf: /* STT flash. */ | 604 | case 0xbf: /* STT flash. */ |
581 | if (flash_id == 0x8e) { | 605 | if (flash_id == 0x8e) |
582 | rest_addr = 0x3fff; | 606 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
583 | sec_mask = 0x7c000; | 607 | else |
584 | } else { | 608 | ha->fdt_block_size = FLASH_BLK_SIZE_32K; |
585 | rest_addr = 0x1fff; | 609 | |
586 | sec_mask = 0x7e000; | ||
587 | } | ||
588 | if (flash_id == 0x80) | 610 | if (flash_id == 0x80) |
589 | conf_addr = flash_conf_to_access_addr(0x0352); | 611 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0352); |
590 | break; | 612 | break; |
591 | case 0x13: /* ST M25P80. */ | 613 | case 0x13: /* ST M25P80. */ |
592 | rest_addr = 0x3fff; | 614 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
593 | sec_mask = 0x7c000; | ||
594 | break; | 615 | break; |
595 | case 0x1f: // Atmel 26DF081A | 616 | case 0x1f: /* Atmel 26DF081A. */ |
596 | rest_addr = 0x3fff; | 617 | ha->fdt_odd_index = 1; |
597 | sec_mask = 0x7c000; | 618 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
598 | conf_addr = flash_conf_to_access_addr(0x0320); | 619 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320); |
620 | ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339); | ||
621 | ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336); | ||
599 | break; | 622 | break; |
600 | default: | 623 | default: |
601 | /* Default to 64 kb sector size. */ | 624 | /* Default to 64 kb sector size. */ |
602 | rest_addr = 0x3fff; | 625 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
603 | sec_mask = 0x7c000; | ||
604 | break; | 626 | break; |
605 | } | 627 | } |
606 | 628 | ||
629 | DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x " | ||
630 | "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id, | ||
631 | ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd, | ||
632 | ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable, | ||
633 | ha->fdt_block_size)); | ||
634 | } | ||
635 | |||
636 | static void | ||
637 | qla24xx_unprotect_flash(scsi_qla_host_t *ha) | ||
638 | { | ||
639 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
640 | |||
607 | /* Enable flash write. */ | 641 | /* Enable flash write. */ |
608 | WRT_REG_DWORD(®->ctrl_status, | 642 | WRT_REG_DWORD(®->ctrl_status, |
609 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); | 643 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); |
610 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 644 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
611 | 645 | ||
646 | if (!ha->fdt_wrt_disable) | ||
647 | return; | ||
648 | |||
612 | /* Disable flash write-protection. */ | 649 | /* Disable flash write-protection. */ |
613 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); | 650 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); |
614 | /* Some flash parts need an additional zero-write to clear bits.*/ | 651 | /* Some flash parts need an additional zero-write to clear bits.*/ |
615 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); | 652 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); |
653 | } | ||
654 | |||
655 | static void | ||
656 | qla24xx_protect_flash(scsi_qla_host_t *ha) | ||
657 | { | ||
658 | uint32_t cnt; | ||
659 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
660 | |||
661 | if (!ha->fdt_wrt_disable) | ||
662 | goto skip_wrt_protect; | ||
663 | |||
664 | /* Enable flash write-protection and wait for completion. */ | ||
665 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), | ||
666 | ha->fdt_wrt_disable); | ||
667 | for (cnt = 300; cnt && | ||
668 | qla24xx_read_flash_dword(ha, | ||
669 | flash_conf_to_access_addr(0x005)) & BIT_0; | ||
670 | cnt--) { | ||
671 | udelay(10); | ||
672 | } | ||
673 | |||
674 | skip_wrt_protect: | ||
675 | /* Disable flash write. */ | ||
676 | WRT_REG_DWORD(®->ctrl_status, | ||
677 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | ||
678 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | ||
679 | } | ||
680 | |||
681 | static int | ||
682 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | ||
683 | uint32_t dwords) | ||
684 | { | ||
685 | int ret; | ||
686 | uint32_t liter, miter; | ||
687 | uint32_t sec_mask, rest_addr; | ||
688 | uint32_t fdata, findex; | ||
689 | dma_addr_t optrom_dma; | ||
690 | void *optrom = NULL; | ||
691 | uint32_t *s, *d; | ||
692 | |||
693 | ret = QLA_SUCCESS; | ||
694 | |||
695 | /* Prepare burst-capable write on supported ISPs. */ | ||
696 | if (IS_QLA25XX(ha) && !(faddr & 0xfff) && | ||
697 | dwords > OPTROM_BURST_DWORDS) { | ||
698 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | ||
699 | &optrom_dma, GFP_KERNEL); | ||
700 | if (!optrom) { | ||
701 | qla_printk(KERN_DEBUG, ha, | ||
702 | "Unable to allocate memory for optrom burst write " | ||
703 | "(%x KB).\n", OPTROM_BURST_SIZE / 1024); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | rest_addr = (ha->fdt_block_size >> 2) - 1; | ||
708 | sec_mask = 0x80000 - (ha->fdt_block_size >> 2); | ||
709 | |||
710 | qla24xx_unprotect_flash(ha); | ||
616 | 711 | ||
617 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { | 712 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { |
618 | if (man_id == 0x1f) { | 713 | if (ha->fdt_odd_index) { |
619 | findex = faddr << 2; | 714 | findex = faddr << 2; |
620 | fdata = findex & sec_mask; | 715 | fdata = findex & sec_mask; |
621 | } else { | 716 | } else { |
@@ -625,13 +720,13 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
625 | 720 | ||
626 | /* Are we at the beginning of a sector? */ | 721 | /* Are we at the beginning of a sector? */ |
627 | if ((findex & rest_addr) == 0) { | 722 | if ((findex & rest_addr) == 0) { |
628 | /* Do sector unprotect at 4K boundry for Atmel part. */ | 723 | /* Do sector unprotect. */ |
629 | if (man_id == 0x1f) | 724 | if (ha->fdt_unprotect_sec_cmd) |
630 | qla24xx_write_flash_dword(ha, | 725 | qla24xx_write_flash_dword(ha, |
631 | flash_conf_to_access_addr(0x0339), | 726 | ha->fdt_unprotect_sec_cmd, |
632 | (fdata & 0xff00) | ((fdata << 16) & | 727 | (fdata & 0xff00) | ((fdata << 16) & |
633 | 0xff0000) | ((fdata >> 16) & 0xff)); | 728 | 0xff0000) | ((fdata >> 16) & 0xff)); |
634 | ret = qla24xx_write_flash_dword(ha, conf_addr, | 729 | ret = qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd, |
635 | (fdata & 0xff00) |((fdata << 16) & | 730 | (fdata & 0xff00) |((fdata << 16) & |
636 | 0xff0000) | ((fdata >> 16) & 0xff)); | 731 | 0xff0000) | ((fdata >> 16) & 0xff)); |
637 | if (ret != QLA_SUCCESS) { | 732 | if (ret != QLA_SUCCESS) { |
@@ -681,28 +776,16 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
681 | break; | 776 | break; |
682 | } | 777 | } |
683 | 778 | ||
684 | /* Do sector protect at 4K boundry for Atmel part. */ | 779 | /* Do sector protect. */ |
685 | if (man_id == 0x1f && | 780 | if (ha->fdt_unprotect_sec_cmd && |
686 | ((faddr & rest_addr) == rest_addr)) | 781 | ((faddr & rest_addr) == rest_addr)) |
687 | qla24xx_write_flash_dword(ha, | 782 | qla24xx_write_flash_dword(ha, |
688 | flash_conf_to_access_addr(0x0336), | 783 | ha->fdt_protect_sec_cmd, |
689 | (fdata & 0xff00) | ((fdata << 16) & | 784 | (fdata & 0xff00) | ((fdata << 16) & |
690 | 0xff0000) | ((fdata >> 16) & 0xff)); | 785 | 0xff0000) | ((fdata >> 16) & 0xff)); |
691 | } | 786 | } |
692 | 787 | ||
693 | /* Enable flash write-protection and wait for completion. */ | 788 | qla24xx_protect_flash(ha); |
694 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c); | ||
695 | for (cnt = 300; cnt && | ||
696 | qla24xx_read_flash_dword(ha, | ||
697 | flash_conf_to_access_addr(0x005)) & BIT_0; | ||
698 | cnt--) { | ||
699 | udelay(10); | ||
700 | } | ||
701 | |||
702 | /* Disable flash write. */ | ||
703 | WRT_REG_DWORD(®->ctrl_status, | ||
704 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | ||
705 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | ||
706 | 789 | ||
707 | if (optrom) | 790 | if (optrom) |
708 | dma_free_coherent(&ha->pdev->dev, | 791 | dma_free_coherent(&ha->pdev->dev, |
@@ -2221,3 +2304,107 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf) | |||
2221 | 2304 | ||
2222 | return ret; | 2305 | return ret; |
2223 | } | 2306 | } |
2307 | |||
2308 | static int | ||
2309 | qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) | ||
2310 | { | ||
2311 | uint32_t d[2], faddr; | ||
2312 | |||
2313 | /* Locate first empty entry. */ | ||
2314 | for (;;) { | ||
2315 | if (ha->hw_event_ptr >= | ||
2316 | ha->hw_event_start + FA_HW_EVENT_SIZE) { | ||
2317 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2318 | "HW event -- Log Full!\n")); | ||
2319 | return QLA_MEMORY_ALLOC_FAILED; | ||
2320 | } | ||
2321 | |||
2322 | qla24xx_read_flash_data(ha, d, ha->hw_event_ptr, 2); | ||
2323 | faddr = flash_data_to_access_addr(ha->hw_event_ptr); | ||
2324 | ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE; | ||
2325 | if (d[0] == __constant_cpu_to_le32(0xffffffff) && | ||
2326 | d[1] == __constant_cpu_to_le32(0xffffffff)) { | ||
2327 | qla24xx_unprotect_flash(ha); | ||
2328 | |||
2329 | qla24xx_write_flash_dword(ha, faddr++, | ||
2330 | cpu_to_le32(jiffies)); | ||
2331 | qla24xx_write_flash_dword(ha, faddr++, 0); | ||
2332 | qla24xx_write_flash_dword(ha, faddr++, *fdata++); | ||
2333 | qla24xx_write_flash_dword(ha, faddr++, *fdata); | ||
2334 | |||
2335 | qla24xx_protect_flash(ha); | ||
2336 | break; | ||
2337 | } | ||
2338 | } | ||
2339 | return QLA_SUCCESS; | ||
2340 | } | ||
2341 | |||
2342 | int | ||
2343 | qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1, | ||
2344 | uint16_t d2, uint16_t d3) | ||
2345 | { | ||
2346 | #define QMARK(a, b, c, d) \ | ||
2347 | cpu_to_le32(LSB(a) << 24 | LSB(b) << 16 | LSB(c) << 8 | LSB(d)) | ||
2348 | |||
2349 | int rval; | ||
2350 | uint32_t marker[2], fdata[4]; | ||
2351 | |||
2352 | if (ha->hw_event_start == 0) | ||
2353 | return QLA_FUNCTION_FAILED; | ||
2354 | |||
2355 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2356 | "HW event -- code=%x, d1=%x, d2=%x, d3=%x.\n", code, d1, d2, d3)); | ||
2357 | |||
2358 | /* If marker not already found, locate or write. */ | ||
2359 | if (!ha->flags.hw_event_marker_found) { | ||
2360 | /* Create marker. */ | ||
2361 | marker[0] = QMARK('L', ha->fw_major_version, | ||
2362 | ha->fw_minor_version, ha->fw_subminor_version); | ||
2363 | marker[1] = QMARK(QLA_DRIVER_MAJOR_VER, QLA_DRIVER_MINOR_VER, | ||
2364 | QLA_DRIVER_PATCH_VER, QLA_DRIVER_BETA_VER); | ||
2365 | |||
2366 | /* Locate marker. */ | ||
2367 | ha->hw_event_ptr = ha->hw_event_start; | ||
2368 | for (;;) { | ||
2369 | qla24xx_read_flash_data(ha, fdata, ha->hw_event_ptr, | ||
2370 | 4); | ||
2371 | if (fdata[0] == __constant_cpu_to_le32(0xffffffff) && | ||
2372 | fdata[1] == __constant_cpu_to_le32(0xffffffff)) | ||
2373 | break; | ||
2374 | ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE; | ||
2375 | if (ha->hw_event_ptr >= | ||
2376 | ha->hw_event_start + FA_HW_EVENT_SIZE) { | ||
2377 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2378 | "HW event -- Log Full!\n")); | ||
2379 | return QLA_MEMORY_ALLOC_FAILED; | ||
2380 | } | ||
2381 | if (fdata[2] == marker[0] && fdata[3] == marker[1]) { | ||
2382 | ha->flags.hw_event_marker_found = 1; | ||
2383 | break; | ||
2384 | } | ||
2385 | } | ||
2386 | /* No marker, write it. */ | ||
2387 | if (!ha->flags.hw_event_marker_found) { | ||
2388 | rval = qla2xxx_hw_event_store(ha, marker); | ||
2389 | if (rval != QLA_SUCCESS) { | ||
2390 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2391 | "HW event -- Failed marker write=%x.!\n", | ||
2392 | rval)); | ||
2393 | return rval; | ||
2394 | } | ||
2395 | ha->flags.hw_event_marker_found = 1; | ||
2396 | } | ||
2397 | } | ||
2398 | |||
2399 | /* Store error. */ | ||
2400 | fdata[0] = cpu_to_le32(code << 16 | d1); | ||
2401 | fdata[1] = cpu_to_le32(d2 << 16 | d3); | ||
2402 | rval = qla2xxx_hw_event_store(ha, fdata); | ||
2403 | if (rval != QLA_SUCCESS) { | ||
2404 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2405 | "HW event -- Failed error write=%x.!\n", | ||
2406 | rval)); | ||
2407 | } | ||
2408 | |||
2409 | return rval; | ||
2410 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index ea08a129fee9..f42f17acf2cf 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -1,15 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.02.00-k9" | 10 | #define QLA2XXX_VERSION "8.02.01-k1" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 2 | 13 | #define QLA_DRIVER_MINOR_VER 2 |
14 | #define QLA_DRIVER_PATCH_VER 0 | 14 | #define QLA_DRIVER_PATCH_VER 1 |
15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |