diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-04 00:27:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-04 00:27:18 -0400 |
commit | f7d57e42e7ebd085133506ef6325e70e822196dc (patch) | |
tree | 1851633f96b1eeaac58edcff94669bed3921dec7 | |
parent | 51bece910d2b0aca64cd3dee9fa2a8aa7feeadd9 (diff) | |
parent | c4e00fac42f268ed0a547cdd1d12bb8399864040 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (57 commits)
[SCSI] fix error handling in scsi_io_completion
[SCSI] qla1280: fix section mismatch warnings
[SCSI] mptsas: eliminate ghost devices
[SCSI] qla2xxx: make some more functions static
[SCSI] small whitespace cleanup for qlogic driver
[SCSI] mptbase: mpt_interrupt should return IRQ_NONE
[SCSI] mptsas: make two functions static
[SCSI] sg.c: Fix bad error handling in
[SCSI] 53c700: fix breakage caused by the autosense update
[SCSI] iscsi: add async notification of session events
[SCSI] iscsi: pass target nr to session creation
[SCSI] iscsi: break up session creation into two stages
[SCSI] iscsi: rm channel usage from iscsi
[SCSI] iscsi: fix session refcouting
[SCSI] iscsi: convert iscsi_tcp to new set/get param fns
[SCSI] iscsi: convert iser to new set/get param fns
[SCSI] iscsi: fixup set/get param functions
[SCSI] iscsi: add target discvery event to transport class
[SCSI] st: remove unused st_buffer.in_use
[SCSI] atp870u: reduce huge stack usage
...
74 files changed, 4502 insertions, 2864 deletions
diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas index 0a85a7e8120e..d9e5960dafd5 100644 --- a/Documentation/scsi/ChangeLog.megaraid_sas +++ b/Documentation/scsi/ChangeLog.megaraid_sas | |||
@@ -1,4 +1,20 @@ | |||
1 | 1 | ||
2 | 1 Release Date : Sun May 14 22:49:52 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com> | ||
3 | 2 Current Version : 00.00.03.01 | ||
4 | 3 Older Version : 00.00.02.04 | ||
5 | |||
6 | i. Added support for ZCR controller. | ||
7 | |||
8 | New device id 0x413 added. | ||
9 | |||
10 | ii. Bug fix : Disable controller interrupt before firing INIT cmd to FW. | ||
11 | |||
12 | Interrupt is enabled after required initialization is over. | ||
13 | This is done to ensure that driver is ready to handle interrupts when | ||
14 | it is generated by the controller. | ||
15 | |||
16 | -Sumant Patro <Sumant.Patro@lsil.com> | ||
17 | |||
2 | 1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com> | 18 | 1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com> |
3 | 2 Current Version : 00.00.02.04 | 19 | 2 Current Version : 00.00.02.04 |
4 | 3 Older Version : 00.00.02.04 | 20 | 3 Older Version : 00.00.02.04 |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index b2c033edb03c..34b0da5cfa0a 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -437,159 +437,50 @@ iscsi_iser_session_create(struct iscsi_transport *iscsit, | |||
437 | } | 437 | } |
438 | 438 | ||
439 | static int | 439 | static int |
440 | iscsi_iser_conn_set_param(struct iscsi_cls_conn *cls_conn, | 440 | iscsi_iser_set_param(struct iscsi_cls_conn *cls_conn, |
441 | enum iscsi_param param, uint32_t value) | 441 | enum iscsi_param param, char *buf, int buflen) |
442 | { | 442 | { |
443 | struct iscsi_conn *conn = cls_conn->dd_data; | 443 | int value; |
444 | struct iscsi_session *session = conn->session; | ||
445 | |||
446 | spin_lock_bh(&session->lock); | ||
447 | if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && | ||
448 | conn->stop_stage != STOP_CONN_RECOVER) { | ||
449 | printk(KERN_ERR "iscsi_iser: can not change parameter [%d]\n", | ||
450 | param); | ||
451 | spin_unlock_bh(&session->lock); | ||
452 | return 0; | ||
453 | } | ||
454 | spin_unlock_bh(&session->lock); | ||
455 | 444 | ||
456 | switch (param) { | 445 | switch (param) { |
457 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | 446 | case ISCSI_PARAM_MAX_RECV_DLENGTH: |
458 | /* TBD */ | 447 | /* TBD */ |
459 | break; | 448 | break; |
460 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
461 | conn->max_xmit_dlength = value; | ||
462 | break; | ||
463 | case ISCSI_PARAM_HDRDGST_EN: | 449 | case ISCSI_PARAM_HDRDGST_EN: |
450 | sscanf(buf, "%d", &value); | ||
464 | if (value) { | 451 | if (value) { |
465 | printk(KERN_ERR "DataDigest wasn't negotiated to None"); | 452 | printk(KERN_ERR "DataDigest wasn't negotiated to None"); |
466 | return -EPROTO; | 453 | return -EPROTO; |
467 | } | 454 | } |
468 | break; | 455 | break; |
469 | case ISCSI_PARAM_DATADGST_EN: | 456 | case ISCSI_PARAM_DATADGST_EN: |
457 | sscanf(buf, "%d", &value); | ||
470 | if (value) { | 458 | if (value) { |
471 | printk(KERN_ERR "DataDigest wasn't negotiated to None"); | 459 | printk(KERN_ERR "DataDigest wasn't negotiated to None"); |
472 | return -EPROTO; | 460 | return -EPROTO; |
473 | } | 461 | } |
474 | break; | 462 | break; |
475 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
476 | session->initial_r2t_en = value; | ||
477 | break; | ||
478 | case ISCSI_PARAM_IMM_DATA_EN: | ||
479 | session->imm_data_en = value; | ||
480 | break; | ||
481 | case ISCSI_PARAM_FIRST_BURST: | ||
482 | session->first_burst = value; | ||
483 | break; | ||
484 | case ISCSI_PARAM_MAX_BURST: | ||
485 | session->max_burst = value; | ||
486 | break; | ||
487 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
488 | session->pdu_inorder_en = value; | ||
489 | break; | ||
490 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
491 | session->dataseq_inorder_en = value; | ||
492 | break; | ||
493 | case ISCSI_PARAM_ERL: | ||
494 | session->erl = value; | ||
495 | break; | ||
496 | case ISCSI_PARAM_IFMARKER_EN: | 463 | case ISCSI_PARAM_IFMARKER_EN: |
464 | sscanf(buf, "%d", &value); | ||
497 | if (value) { | 465 | if (value) { |
498 | printk(KERN_ERR "IFMarker wasn't negotiated to No"); | 466 | printk(KERN_ERR "IFMarker wasn't negotiated to No"); |
499 | return -EPROTO; | 467 | return -EPROTO; |
500 | } | 468 | } |
501 | break; | 469 | break; |
502 | case ISCSI_PARAM_OFMARKER_EN: | 470 | case ISCSI_PARAM_OFMARKER_EN: |
471 | sscanf(buf, "%d", &value); | ||
503 | if (value) { | 472 | if (value) { |
504 | printk(KERN_ERR "OFMarker wasn't negotiated to No"); | 473 | printk(KERN_ERR "OFMarker wasn't negotiated to No"); |
505 | return -EPROTO; | 474 | return -EPROTO; |
506 | } | 475 | } |
507 | break; | 476 | break; |
508 | default: | 477 | default: |
509 | break; | 478 | return iscsi_set_param(cls_conn, param, buf, buflen); |
510 | } | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | static int | ||
516 | iscsi_iser_session_get_param(struct iscsi_cls_session *cls_session, | ||
517 | enum iscsi_param param, uint32_t *value) | ||
518 | { | ||
519 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
520 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
521 | |||
522 | switch (param) { | ||
523 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
524 | *value = session->initial_r2t_en; | ||
525 | break; | ||
526 | case ISCSI_PARAM_MAX_R2T: | ||
527 | *value = session->max_r2t; | ||
528 | break; | ||
529 | case ISCSI_PARAM_IMM_DATA_EN: | ||
530 | *value = session->imm_data_en; | ||
531 | break; | ||
532 | case ISCSI_PARAM_FIRST_BURST: | ||
533 | *value = session->first_burst; | ||
534 | break; | ||
535 | case ISCSI_PARAM_MAX_BURST: | ||
536 | *value = session->max_burst; | ||
537 | break; | ||
538 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
539 | *value = session->pdu_inorder_en; | ||
540 | break; | ||
541 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
542 | *value = session->dataseq_inorder_en; | ||
543 | break; | ||
544 | case ISCSI_PARAM_ERL: | ||
545 | *value = session->erl; | ||
546 | break; | ||
547 | case ISCSI_PARAM_IFMARKER_EN: | ||
548 | *value = 0; | ||
549 | break; | ||
550 | case ISCSI_PARAM_OFMARKER_EN: | ||
551 | *value = 0; | ||
552 | break; | ||
553 | default: | ||
554 | return ISCSI_ERR_PARAM_NOT_FOUND; | ||
555 | } | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | static int | ||
561 | iscsi_iser_conn_get_param(struct iscsi_cls_conn *cls_conn, | ||
562 | enum iscsi_param param, uint32_t *value) | ||
563 | { | ||
564 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
565 | |||
566 | switch(param) { | ||
567 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
568 | *value = conn->max_recv_dlength; | ||
569 | break; | ||
570 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
571 | *value = conn->max_xmit_dlength; | ||
572 | break; | ||
573 | case ISCSI_PARAM_HDRDGST_EN: | ||
574 | *value = 0; | ||
575 | break; | ||
576 | case ISCSI_PARAM_DATADGST_EN: | ||
577 | *value = 0; | ||
578 | break; | ||
579 | /*case ISCSI_PARAM_TARGET_RECV_DLENGTH: | ||
580 | *value = conn->target_recv_dlength; | ||
581 | break; | ||
582 | case ISCSI_PARAM_INITIATOR_RECV_DLENGTH: | ||
583 | *value = conn->initiator_recv_dlength; | ||
584 | break;*/ | ||
585 | default: | ||
586 | return ISCSI_ERR_PARAM_NOT_FOUND; | ||
587 | } | 479 | } |
588 | 480 | ||
589 | return 0; | 481 | return 0; |
590 | } | 482 | } |
591 | 483 | ||
592 | |||
593 | static void | 484 | static void |
594 | iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) | 485 | iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) |
595 | { | 486 | { |
@@ -701,7 +592,12 @@ static struct iscsi_transport iscsi_iser_transport = { | |||
701 | ISCSI_FIRST_BURST | | 592 | ISCSI_FIRST_BURST | |
702 | ISCSI_MAX_BURST | | 593 | ISCSI_MAX_BURST | |
703 | ISCSI_PDU_INORDER_EN | | 594 | ISCSI_PDU_INORDER_EN | |
704 | ISCSI_DATASEQ_INORDER_EN, | 595 | ISCSI_DATASEQ_INORDER_EN | |
596 | ISCSI_EXP_STATSN | | ||
597 | ISCSI_PERSISTENT_PORT | | ||
598 | ISCSI_PERSISTENT_ADDRESS | | ||
599 | ISCSI_TARGET_NAME | | ||
600 | ISCSI_TPGT, | ||
705 | .host_template = &iscsi_iser_sht, | 601 | .host_template = &iscsi_iser_sht, |
706 | .conndata_size = sizeof(struct iscsi_conn), | 602 | .conndata_size = sizeof(struct iscsi_conn), |
707 | .max_lun = ISCSI_ISER_MAX_LUN, | 603 | .max_lun = ISCSI_ISER_MAX_LUN, |
@@ -713,9 +609,9 @@ static struct iscsi_transport iscsi_iser_transport = { | |||
713 | .create_conn = iscsi_iser_conn_create, | 609 | .create_conn = iscsi_iser_conn_create, |
714 | .bind_conn = iscsi_iser_conn_bind, | 610 | .bind_conn = iscsi_iser_conn_bind, |
715 | .destroy_conn = iscsi_iser_conn_destroy, | 611 | .destroy_conn = iscsi_iser_conn_destroy, |
716 | .set_param = iscsi_iser_conn_set_param, | 612 | .set_param = iscsi_iser_set_param, |
717 | .get_conn_param = iscsi_iser_conn_get_param, | 613 | .get_conn_param = iscsi_conn_get_param, |
718 | .get_session_param = iscsi_iser_session_get_param, | 614 | .get_session_param = iscsi_session_get_param, |
719 | .start_conn = iscsi_iser_conn_start, | 615 | .start_conn = iscsi_iser_conn_start, |
720 | .stop_conn = iscsi_conn_stop, | 616 | .stop_conn = iscsi_conn_stop, |
721 | /* these are called as part of conn recovery */ | 617 | /* these are called as part of conn recovery */ |
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index 51740b346224..b114236f4395 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile | |||
@@ -33,6 +33,11 @@ | |||
33 | # For mptfc: | 33 | # For mptfc: |
34 | #CFLAGS_mptfc.o += -DMPT_DEBUG_FC | 34 | #CFLAGS_mptfc.o += -DMPT_DEBUG_FC |
35 | 35 | ||
36 | # For mptsas: | ||
37 | #CFLAGS_mptsas.o += -DMPT_DEBUG_SAS | ||
38 | #CFLAGS_mptsas.o += -DMPT_DEBUG_SAS_WIDE | ||
39 | |||
40 | |||
36 | #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC | 41 | #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC |
37 | 42 | ||
38 | obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o | 43 | obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o |
diff --git a/drivers/message/fusion/lsi/fc_log.h b/drivers/message/fusion/lsi/fc_log.h deleted file mode 100644 index dc98d46f9071..000000000000 --- a/drivers/message/fusion/lsi/fc_log.h +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved. | ||
3 | * | ||
4 | * NAME: fc_log.h | ||
5 | * SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips | ||
6 | * DESCRIPTION: Contains the enumerated list of values that may be returned | ||
7 | * in the IOCLogInfo field of a MPI Default Reply Message. | ||
8 | * | ||
9 | * CREATION DATE: 6/02/2000 | ||
10 | * ID: $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $ | ||
11 | */ | ||
12 | |||
13 | |||
14 | /* | ||
15 | * MpiIocLogInfo_t enum | ||
16 | * | ||
17 | * These 32 bit values are used in the IOCLogInfo field of the MPI reply | ||
18 | * messages. | ||
19 | * The value is 0xabcccccc where | ||
20 | * a = The type of log info as per the MPI spec. Since these codes are | ||
21 | * all for Fibre Channel this value will always be 2. | ||
22 | * b = Specifies a subclass of the firmware where | ||
23 | * 0 = FCP Initiator | ||
24 | * 1 = FCP Target | ||
25 | * 2 = LAN | ||
26 | * 3 = MPI Message Layer | ||
27 | * 4 = FC Link | ||
28 | * 5 = Context Manager | ||
29 | * 6 = Invalid Field Offset | ||
30 | * 7 = State Change Info | ||
31 | * all others are reserved for future use | ||
32 | * c = A specific value within the subclass. | ||
33 | * | ||
34 | * NOTE: Any new values should be added to the end of each subclass so that the | ||
35 | * codes remain consistent across firmware releases. | ||
36 | */ | ||
37 | typedef enum _MpiIocLogInfoFc | ||
38 | { | ||
39 | MPI_IOCLOGINFO_FC_INIT_BASE = 0x20000000, | ||
40 | MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */ | ||
41 | MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */ | ||
42 | MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primative */ | ||
43 | MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Bad Rx Frame, overrun */ | ||
44 | MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER = 0x20000005, /* Other errors caught by IOC which require retries */ | ||
45 | MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD = 0x20000006, /* Main processor could not initialize sub-processor */ | ||
46 | MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN = 0x20000007, /* Scatter Gather overrun */ | ||
47 | MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS = 0x20000008, /* Receiver detected context mismatch via invalid header */ | ||
48 | MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type */ | ||
49 | MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE = 0x2000000A, /* Link failure occurred */ | ||
50 | MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT = 0x2000000B, /* Transmitter timeout error */ | ||
51 | |||
52 | MPI_IOCLOGINFO_FC_TARGET_BASE = 0x21000000, | ||
53 | MPI_IOCLOGINFO_FC_TARGET_NO_PDISC = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */ | ||
54 | MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN = 0x21000002, /* not sent because we are not logged in to the remote node */ | ||
55 | MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP = 0x21000003, /* Data Out, Auto Response, not sent due to a LIP */ | ||
56 | MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP = 0x21000004, /* Data In, Auto Response, not sent due to a LIP */ | ||
57 | MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA = 0x21000005, /* Data In, Auto Response, missing data frames */ | ||
58 | MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP = 0x21000006, /* Data Out, No Response, not sent due to a LIP */ | ||
59 | MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP = 0x21000007, /* Auto-response after a write not sent due to a LIP */ | ||
60 | MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP = 0x21000008, /* Data In, No Response, not completed due to a LIP */ | ||
61 | MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA = 0x21000009, /* Data In, No Response, missing data frames */ | ||
62 | MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP = 0x2100000a, /* Manual Response not sent due to a LIP */ | ||
63 | MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3 = 0x2100000b, /* not sent because remote node does not support Class 3 */ | ||
64 | MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID = 0x2100000c, /* not sent because login to remote node not validated */ | ||
65 | MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND = 0x2100000e, /* cleared from the outbound queue after a logout */ | ||
66 | MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN = 0x2100000f, /* cleared waiting for data after a logout */ | ||
67 | |||
68 | MPI_IOCLOGINFO_FC_LAN_BASE = 0x22000000, | ||
69 | MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING = 0x22000001, /* Transaction Context Sgl Missing */ | ||
70 | MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE = 0x22000002, /* Transaction Context found before an EOB */ | ||
71 | MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET = 0x22000003, /* Transaction Context value has reserved bits set */ | ||
72 | MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG = 0x22000004, /* Invalid SGL Flags */ | ||
73 | |||
74 | MPI_IOCLOGINFO_FC_MSG_BASE = 0x23000000, | ||
75 | |||
76 | MPI_IOCLOGINFO_FC_LINK_BASE = 0x24000000, | ||
77 | MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT = 0x24000001, /* Loop initialization timed out */ | ||
78 | MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED = 0x24000002, /* Another system controller already initialized the loop */ | ||
79 | MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */ | ||
80 | MPI_IOCLOGINFO_FC_LINK_CRC_ERROR = 0x24000004, /* CRC check detected error on received frame */ | ||
81 | |||
82 | MPI_IOCLOGINFO_FC_CTX_BASE = 0x25000000, | ||
83 | |||
84 | MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */ | ||
85 | MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET = 0x26ffffff, | ||
86 | |||
87 | MPI_IOCLOGINFO_FC_STATE_CHANGE = 0x27000000 /* The lower 24 bits give additional information concerning state change */ | ||
88 | |||
89 | } MpiIocLogInfoFc_t; | ||
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h index 02cdc840a06b..81ad77622dac 100644 --- a/drivers/message/fusion/lsi/mpi.h +++ b/drivers/message/fusion/lsi/mpi.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Message independent structures and definitions | 6 | * Title: MPI Message independent structures and definitions |
7 | * Creation Date: July 27, 2000 | 7 | * Creation Date: July 27, 2000 |
8 | * | 8 | * |
9 | * mpi.h Version: 01.05.10 | 9 | * mpi.h Version: 01.05.11 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -76,6 +76,7 @@ | |||
76 | * Added EEDP IOCStatus codes. | 76 | * Added EEDP IOCStatus codes. |
77 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. | 77 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. |
78 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. | 78 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. |
79 | * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. | ||
79 | * -------------------------------------------------------------------------- | 80 | * -------------------------------------------------------------------------- |
80 | */ | 81 | */ |
81 | 82 | ||
@@ -106,7 +107,7 @@ | |||
106 | /* Note: The major versions of 0xe0 through 0xff are reserved */ | 107 | /* Note: The major versions of 0xe0 through 0xff are reserved */ |
107 | 108 | ||
108 | /* versioning for this MPI header set */ | 109 | /* versioning for this MPI header set */ |
109 | #define MPI_HEADER_VERSION_UNIT (0x0C) | 110 | #define MPI_HEADER_VERSION_UNIT (0x0D) |
110 | #define MPI_HEADER_VERSION_DEV (0x00) | 111 | #define MPI_HEADER_VERSION_DEV (0x00) |
111 | #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) | 112 | #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) |
112 | #define MPI_HEADER_VERSION_UNIT_SHIFT (8) | 113 | #define MPI_HEADER_VERSION_UNIT_SHIFT (8) |
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h index b1becec27e1b..47e13e360c10 100644 --- a/drivers/message/fusion/lsi/mpi_cnfg.h +++ b/drivers/message/fusion/lsi/mpi_cnfg.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Config message, structures, and Pages | 6 | * Title: MPI Config message, structures, and Pages |
7 | * Creation Date: July 27, 2000 | 7 | * Creation Date: July 27, 2000 |
8 | * | 8 | * |
9 | * mpi_cnfg.h Version: 01.05.11 | 9 | * mpi_cnfg.h Version: 01.05.12 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -266,6 +266,16 @@ | |||
266 | * Added postpone SATA Init bit to SAS IO Unit Page 1 | 266 | * Added postpone SATA Init bit to SAS IO Unit Page 1 |
267 | * ControlFlags. | 267 | * ControlFlags. |
268 | * Changed LogEntry format for Log Page 0. | 268 | * Changed LogEntry format for Log Page 0. |
269 | * 03-27-06 01.05.12 Added two new Flags defines for Manufacturing Page 4. | ||
270 | * Added Manufacturing Page 7. | ||
271 | * Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING. | ||
272 | * Added IOC Page 6. | ||
273 | * Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2. | ||
274 | * Added MaxLBAHigh field to RAID Volume Page 0. | ||
275 | * Added Nvdata version fields to SAS IO Unit Page 0. | ||
276 | * Added AdditionalControlFlags, MaxTargetPortConnectTime, | ||
277 | * ReportDeviceMissingDelay, and IODeviceMissingDelay | ||
278 | * fields to SAS IO Unit Page 1. | ||
269 | * -------------------------------------------------------------------------- | 279 | * -------------------------------------------------------------------------- |
270 | */ | 280 | */ |
271 | 281 | ||
@@ -631,9 +641,11 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4 | |||
631 | } CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4, | 641 | } CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4, |
632 | ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t; | 642 | ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t; |
633 | 643 | ||
634 | #define MPI_MANUFACTURING4_PAGEVERSION (0x03) | 644 | #define MPI_MANUFACTURING4_PAGEVERSION (0x04) |
635 | 645 | ||
636 | /* defines for the Flags field */ | 646 | /* defines for the Flags field */ |
647 | #define MPI_MANPAGE4_FORCE_BAD_BLOCK_TABLE (0x80) | ||
648 | #define MPI_MANPAGE4_FORCE_OFFLINE_FAILOVER (0x40) | ||
637 | #define MPI_MANPAGE4_IME_DISABLE (0x20) | 649 | #define MPI_MANPAGE4_IME_DISABLE (0x20) |
638 | #define MPI_MANPAGE4_IM_DISABLE (0x10) | 650 | #define MPI_MANPAGE4_IM_DISABLE (0x10) |
639 | #define MPI_MANPAGE4_IS_DISABLE (0x08) | 651 | #define MPI_MANPAGE4_IS_DISABLE (0x08) |
@@ -668,6 +680,66 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_6 | |||
668 | #define MPI_MANUFACTURING6_PAGEVERSION (0x00) | 680 | #define MPI_MANUFACTURING6_PAGEVERSION (0x00) |
669 | 681 | ||
670 | 682 | ||
683 | typedef struct _MPI_MANPAGE7_CONNECTOR_INFO | ||
684 | { | ||
685 | U32 Pinout; /* 00h */ | ||
686 | U8 Connector[16]; /* 04h */ | ||
687 | U8 Location; /* 14h */ | ||
688 | U8 Reserved1; /* 15h */ | ||
689 | U16 Slot; /* 16h */ | ||
690 | U32 Reserved2; /* 18h */ | ||
691 | } MPI_MANPAGE7_CONNECTOR_INFO, MPI_POINTER PTR_MPI_MANPAGE7_CONNECTOR_INFO, | ||
692 | MpiManPage7ConnectorInfo_t, MPI_POINTER pMpiManPage7ConnectorInfo_t; | ||
693 | |||
694 | /* defines for the Pinout field */ | ||
695 | #define MPI_MANPAGE7_PINOUT_SFF_8484_L4 (0x00080000) | ||
696 | #define MPI_MANPAGE7_PINOUT_SFF_8484_L3 (0x00040000) | ||
697 | #define MPI_MANPAGE7_PINOUT_SFF_8484_L2 (0x00020000) | ||
698 | #define MPI_MANPAGE7_PINOUT_SFF_8484_L1 (0x00010000) | ||
699 | #define MPI_MANPAGE7_PINOUT_SFF_8470_L4 (0x00000800) | ||
700 | #define MPI_MANPAGE7_PINOUT_SFF_8470_L3 (0x00000400) | ||
701 | #define MPI_MANPAGE7_PINOUT_SFF_8470_L2 (0x00000200) | ||
702 | #define MPI_MANPAGE7_PINOUT_SFF_8470_L1 (0x00000100) | ||
703 | #define MPI_MANPAGE7_PINOUT_SFF_8482 (0x00000002) | ||
704 | #define MPI_MANPAGE7_PINOUT_CONNECTION_UNKNOWN (0x00000001) | ||
705 | |||
706 | /* defines for the Location field */ | ||
707 | #define MPI_MANPAGE7_LOCATION_UNKNOWN (0x01) | ||
708 | #define MPI_MANPAGE7_LOCATION_INTERNAL (0x02) | ||
709 | #define MPI_MANPAGE7_LOCATION_EXTERNAL (0x04) | ||
710 | #define MPI_MANPAGE7_LOCATION_SWITCHABLE (0x08) | ||
711 | #define MPI_MANPAGE7_LOCATION_AUTO (0x10) | ||
712 | #define MPI_MANPAGE7_LOCATION_NOT_PRESENT (0x20) | ||
713 | #define MPI_MANPAGE7_LOCATION_NOT_CONNECTED (0x80) | ||
714 | |||
715 | /* | ||
716 | * Host code (drivers, BIOS, utilities, etc.) should leave this define set to | ||
717 | * one and check NumPhys at runtime. | ||
718 | */ | ||
719 | #ifndef MPI_MANPAGE7_CONNECTOR_INFO_MAX | ||
720 | #define MPI_MANPAGE7_CONNECTOR_INFO_MAX (1) | ||
721 | #endif | ||
722 | |||
723 | typedef struct _CONFIG_PAGE_MANUFACTURING_7 | ||
724 | { | ||
725 | CONFIG_PAGE_HEADER Header; /* 00h */ | ||
726 | U32 Reserved1; /* 04h */ | ||
727 | U32 Reserved2; /* 08h */ | ||
728 | U32 Flags; /* 0Ch */ | ||
729 | U8 EnclosureName[16]; /* 10h */ | ||
730 | U8 NumPhys; /* 20h */ | ||
731 | U8 Reserved3; /* 21h */ | ||
732 | U16 Reserved4; /* 22h */ | ||
733 | MPI_MANPAGE7_CONNECTOR_INFO ConnectorInfo[MPI_MANPAGE7_CONNECTOR_INFO_MAX]; /* 24h */ | ||
734 | } CONFIG_PAGE_MANUFACTURING_7, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_7, | ||
735 | ManufacturingPage7_t, MPI_POINTER pManufacturingPage7_t; | ||
736 | |||
737 | #define MPI_MANUFACTURING7_PAGEVERSION (0x00) | ||
738 | |||
739 | /* defines for the Flags field */ | ||
740 | #define MPI_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) | ||
741 | |||
742 | |||
671 | /**************************************************************************** | 743 | /**************************************************************************** |
672 | * IO Unit Config Pages | 744 | * IO Unit Config Pages |
673 | ****************************************************************************/ | 745 | ****************************************************************************/ |
@@ -867,7 +939,7 @@ typedef struct _CONFIG_PAGE_IOC_2 | |||
867 | } CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2, | 939 | } CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2, |
868 | IOCPage2_t, MPI_POINTER pIOCPage2_t; | 940 | IOCPage2_t, MPI_POINTER pIOCPage2_t; |
869 | 941 | ||
870 | #define MPI_IOCPAGE2_PAGEVERSION (0x03) | 942 | #define MPI_IOCPAGE2_PAGEVERSION (0x04) |
871 | 943 | ||
872 | /* IOC Page 2 Capabilities flags */ | 944 | /* IOC Page 2 Capabilities flags */ |
873 | 945 | ||
@@ -878,6 +950,7 @@ typedef struct _CONFIG_PAGE_IOC_2 | |||
878 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT (0x00000010) | 950 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT (0x00000010) |
879 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000020) | 951 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000020) |
880 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT (0x00000040) | 952 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT (0x00000040) |
953 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING (0x10000000) | ||
881 | #define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000) | 954 | #define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000) |
882 | #define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000) | 955 | #define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000) |
883 | #define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000) | 956 | #define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000) |
@@ -975,6 +1048,44 @@ typedef struct _CONFIG_PAGE_IOC_5 | |||
975 | 1048 | ||
976 | #define MPI_IOCPAGE5_PAGEVERSION (0x00) | 1049 | #define MPI_IOCPAGE5_PAGEVERSION (0x00) |
977 | 1050 | ||
1051 | typedef struct _CONFIG_PAGE_IOC_6 | ||
1052 | { | ||
1053 | CONFIG_PAGE_HEADER Header; /* 00h */ | ||
1054 | U32 CapabilitiesFlags; /* 04h */ | ||
1055 | U8 MaxDrivesIS; /* 08h */ | ||
1056 | U8 MaxDrivesIM; /* 09h */ | ||
1057 | U8 MaxDrivesIME; /* 0Ah */ | ||
1058 | U8 Reserved1; /* 0Bh */ | ||
1059 | U8 MinDrivesIS; /* 0Ch */ | ||
1060 | U8 MinDrivesIM; /* 0Dh */ | ||
1061 | U8 MinDrivesIME; /* 0Eh */ | ||
1062 | U8 Reserved2; /* 0Fh */ | ||
1063 | U8 MaxGlobalHotSpares; /* 10h */ | ||
1064 | U8 Reserved3; /* 11h */ | ||
1065 | U16 Reserved4; /* 12h */ | ||
1066 | U32 Reserved5; /* 14h */ | ||
1067 | U32 SupportedStripeSizeMapIS; /* 18h */ | ||
1068 | U32 SupportedStripeSizeMapIME; /* 1Ch */ | ||
1069 | U32 Reserved6; /* 20h */ | ||
1070 | U8 MetadataSize; /* 24h */ | ||
1071 | U8 Reserved7; /* 25h */ | ||
1072 | U16 Reserved8; /* 26h */ | ||
1073 | U16 MaxBadBlockTableEntries; /* 28h */ | ||
1074 | U16 Reserved9; /* 2Ah */ | ||
1075 | U16 IRNvsramUsage; /* 2Ch */ | ||
1076 | U16 Reserved10; /* 2Eh */ | ||
1077 | U32 IRNvsramVersion; /* 30h */ | ||
1078 | U32 Reserved11; /* 34h */ | ||
1079 | U32 Reserved12; /* 38h */ | ||
1080 | } CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6, | ||
1081 | IOCPage6_t, MPI_POINTER pIOCPage6_t; | ||
1082 | |||
1083 | #define MPI_IOCPAGE6_PAGEVERSION (0x00) | ||
1084 | |||
1085 | /* IOC Page 6 Capabilities Flags */ | ||
1086 | |||
1087 | #define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001) | ||
1088 | |||
978 | 1089 | ||
979 | /**************************************************************************** | 1090 | /**************************************************************************** |
980 | * BIOS Config Pages | 1091 | * BIOS Config Pages |
@@ -1218,13 +1329,13 @@ typedef struct _CONFIG_PAGE_BIOS_2 | |||
1218 | U32 Reserved5; /* 14h */ | 1329 | U32 Reserved5; /* 14h */ |
1219 | U32 Reserved6; /* 18h */ | 1330 | U32 Reserved6; /* 18h */ |
1220 | U8 BootDeviceForm; /* 1Ch */ | 1331 | U8 BootDeviceForm; /* 1Ch */ |
1221 | U8 Reserved7; /* 1Dh */ | 1332 | U8 PrevBootDeviceForm; /* 1Ch */ |
1222 | U16 Reserved8; /* 1Eh */ | 1333 | U16 Reserved8; /* 1Eh */ |
1223 | MPI_BIOSPAGE2_BOOT_DEVICE BootDevice; /* 20h */ | 1334 | MPI_BIOSPAGE2_BOOT_DEVICE BootDevice; /* 20h */ |
1224 | } CONFIG_PAGE_BIOS_2, MPI_POINTER PTR_CONFIG_PAGE_BIOS_2, | 1335 | } CONFIG_PAGE_BIOS_2, MPI_POINTER PTR_CONFIG_PAGE_BIOS_2, |
1225 | BIOSPage2_t, MPI_POINTER pBIOSPage2_t; | 1336 | BIOSPage2_t, MPI_POINTER pBIOSPage2_t; |
1226 | 1337 | ||
1227 | #define MPI_BIOSPAGE2_PAGEVERSION (0x01) | 1338 | #define MPI_BIOSPAGE2_PAGEVERSION (0x02) |
1228 | 1339 | ||
1229 | #define MPI_BIOSPAGE2_FORM_MASK (0x0F) | 1340 | #define MPI_BIOSPAGE2_FORM_MASK (0x0F) |
1230 | #define MPI_BIOSPAGE2_FORM_ADAPTER_ORDER (0x00) | 1341 | #define MPI_BIOSPAGE2_FORM_ADAPTER_ORDER (0x00) |
@@ -2080,7 +2191,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0 | |||
2080 | RAID_VOL0_STATUS VolumeStatus; /* 08h */ | 2191 | RAID_VOL0_STATUS VolumeStatus; /* 08h */ |
2081 | RAID_VOL0_SETTINGS VolumeSettings; /* 0Ch */ | 2192 | RAID_VOL0_SETTINGS VolumeSettings; /* 0Ch */ |
2082 | U32 MaxLBA; /* 10h */ | 2193 | U32 MaxLBA; /* 10h */ |
2083 | U32 Reserved1; /* 14h */ | 2194 | U32 MaxLBAHigh; /* 14h */ |
2084 | U32 StripeSize; /* 18h */ | 2195 | U32 StripeSize; /* 18h */ |
2085 | U32 Reserved2; /* 1Ch */ | 2196 | U32 Reserved2; /* 1Ch */ |
2086 | U32 Reserved3; /* 20h */ | 2197 | U32 Reserved3; /* 20h */ |
@@ -2092,7 +2203,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0 | |||
2092 | } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0, | 2203 | } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0, |
2093 | RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; | 2204 | RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; |
2094 | 2205 | ||
2095 | #define MPI_RAIDVOLPAGE0_PAGEVERSION (0x05) | 2206 | #define MPI_RAIDVOLPAGE0_PAGEVERSION (0x06) |
2096 | 2207 | ||
2097 | /* values for RAID Volume Page 0 InactiveStatus field */ | 2208 | /* values for RAID Volume Page 0 InactiveStatus field */ |
2098 | #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) | 2209 | #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) |
@@ -2324,7 +2435,8 @@ typedef struct _MPI_SAS_IO_UNIT0_PHY_DATA | |||
2324 | typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 | 2435 | typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 |
2325 | { | 2436 | { |
2326 | CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ | 2437 | CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ |
2327 | U32 Reserved1; /* 08h */ | 2438 | U16 NvdataVersionDefault; /* 08h */ |
2439 | U16 NvdataVersionPersistent; /* 0Ah */ | ||
2328 | U8 NumPhys; /* 0Ch */ | 2440 | U8 NumPhys; /* 0Ch */ |
2329 | U8 Reserved2; /* 0Dh */ | 2441 | U8 Reserved2; /* 0Dh */ |
2330 | U16 Reserved3; /* 0Eh */ | 2442 | U16 Reserved3; /* 0Eh */ |
@@ -2332,7 +2444,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 | |||
2332 | } CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0, | 2444 | } CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0, |
2333 | SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t; | 2445 | SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t; |
2334 | 2446 | ||
2335 | #define MPI_SASIOUNITPAGE0_PAGEVERSION (0x03) | 2447 | #define MPI_SASIOUNITPAGE0_PAGEVERSION (0x04) |
2336 | 2448 | ||
2337 | /* values for SAS IO Unit Page 0 PortFlags */ | 2449 | /* values for SAS IO Unit Page 0 PortFlags */ |
2338 | #define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08) | 2450 | #define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08) |
@@ -2373,12 +2485,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 | |||
2373 | 2485 | ||
2374 | typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA | 2486 | typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA |
2375 | { | 2487 | { |
2376 | U8 Port; /* 00h */ | 2488 | U8 Port; /* 00h */ |
2377 | U8 PortFlags; /* 01h */ | 2489 | U8 PortFlags; /* 01h */ |
2378 | U8 PhyFlags; /* 02h */ | 2490 | U8 PhyFlags; /* 02h */ |
2379 | U8 MaxMinLinkRate; /* 03h */ | 2491 | U8 MaxMinLinkRate; /* 03h */ |
2380 | U32 ControllerPhyDeviceInfo;/* 04h */ | 2492 | U32 ControllerPhyDeviceInfo; /* 04h */ |
2381 | U32 Reserved1; /* 08h */ | 2493 | U16 MaxTargetPortConnectTime; /* 08h */ |
2494 | U16 Reserved1; /* 0Ah */ | ||
2382 | } MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA, | 2495 | } MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA, |
2383 | SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData; | 2496 | SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData; |
2384 | 2497 | ||
@@ -2395,15 +2508,17 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 | |||
2395 | CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ | 2508 | CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ |
2396 | U16 ControlFlags; /* 08h */ | 2509 | U16 ControlFlags; /* 08h */ |
2397 | U16 MaxNumSATATargets; /* 0Ah */ | 2510 | U16 MaxNumSATATargets; /* 0Ah */ |
2398 | U32 Reserved1; /* 0Ch */ | 2511 | U16 AdditionalControlFlags; /* 0Ch */ |
2512 | U16 Reserved1; /* 0Eh */ | ||
2399 | U8 NumPhys; /* 10h */ | 2513 | U8 NumPhys; /* 10h */ |
2400 | U8 SATAMaxQDepth; /* 11h */ | 2514 | U8 SATAMaxQDepth; /* 11h */ |
2401 | U16 Reserved2; /* 12h */ | 2515 | U8 ReportDeviceMissingDelay; /* 12h */ |
2516 | U8 IODeviceMissingDelay; /* 13h */ | ||
2402 | MPI_SAS_IO_UNIT1_PHY_DATA PhyData[MPI_SAS_IOUNIT1_PHY_MAX]; /* 14h */ | 2517 | MPI_SAS_IO_UNIT1_PHY_DATA PhyData[MPI_SAS_IOUNIT1_PHY_MAX]; /* 14h */ |
2403 | } CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, | 2518 | } CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, |
2404 | SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; | 2519 | SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; |
2405 | 2520 | ||
2406 | #define MPI_SASIOUNITPAGE1_PAGEVERSION (0x05) | 2521 | #define MPI_SASIOUNITPAGE1_PAGEVERSION (0x06) |
2407 | 2522 | ||
2408 | /* values for SAS IO Unit Page 1 ControlFlags */ | 2523 | /* values for SAS IO Unit Page 1 ControlFlags */ |
2409 | #define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) | 2524 | #define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) |
@@ -2428,6 +2543,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 | |||
2428 | #define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002) | 2543 | #define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002) |
2429 | #define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) | 2544 | #define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) |
2430 | 2545 | ||
2546 | /* values for SAS IO Unit Page 1 AdditionalControlFlags */ | ||
2547 | #define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001) | ||
2548 | |||
2549 | /* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */ | ||
2550 | #define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F) | ||
2551 | #define MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16 (0x80) | ||
2552 | |||
2431 | /* values for SAS IO Unit Page 1 PortFlags */ | 2553 | /* values for SAS IO Unit Page 1 PortFlags */ |
2432 | #define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00) | 2554 | #define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00) |
2433 | #define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04) | 2555 | #define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04) |
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt index 4a5f8dd1d766..582cfe7c2aa1 100644 --- a/drivers/message/fusion/lsi/mpi_history.txt +++ b/drivers/message/fusion/lsi/mpi_history.txt | |||
@@ -6,25 +6,25 @@ | |||
6 | Copyright (c) 2000-2005 LSI Logic Corporation. | 6 | Copyright (c) 2000-2005 LSI Logic Corporation. |
7 | 7 | ||
8 | --------------------------------------- | 8 | --------------------------------------- |
9 | Header Set Release Version: 01.05.12 | 9 | Header Set Release Version: 01.05.13 |
10 | Header Set Release Date: 08-30-05 | 10 | Header Set Release Date: 03-27-06 |
11 | --------------------------------------- | 11 | --------------------------------------- |
12 | 12 | ||
13 | Filename Current version Prior version | 13 | Filename Current version Prior version |
14 | ---------- --------------- ------------- | 14 | ---------- --------------- ------------- |
15 | mpi.h 01.05.10 01.05.09 | 15 | mpi.h 01.05.11 01.05.10 |
16 | mpi_ioc.h 01.05.10 01.05.09 | 16 | mpi_ioc.h 01.05.11 01.05.10 |
17 | mpi_cnfg.h 01.05.11 01.05.10 | 17 | mpi_cnfg.h 01.05.12 01.05.11 |
18 | mpi_init.h 01.05.06 01.05.06 | 18 | mpi_init.h 01.05.07 01.05.06 |
19 | mpi_targ.h 01.05.05 01.05.05 | 19 | mpi_targ.h 01.05.06 01.05.05 |
20 | mpi_fc.h 01.05.01 01.05.01 | 20 | mpi_fc.h 01.05.01 01.05.01 |
21 | mpi_lan.h 01.05.01 01.05.01 | 21 | mpi_lan.h 01.05.01 01.05.01 |
22 | mpi_raid.h 01.05.02 01.05.02 | 22 | mpi_raid.h 01.05.02 01.05.02 |
23 | mpi_tool.h 01.05.03 01.05.03 | 23 | mpi_tool.h 01.05.03 01.05.03 |
24 | mpi_inb.h 01.05.01 01.05.01 | 24 | mpi_inb.h 01.05.01 01.05.01 |
25 | mpi_sas.h 01.05.02 01.05.01 | 25 | mpi_sas.h 01.05.03 01.05.02 |
26 | mpi_type.h 01.05.02 01.05.01 | 26 | mpi_type.h 01.05.02 01.05.02 |
27 | mpi_history.txt 01.05.12 01.05.11 | 27 | mpi_history.txt 01.05.13 01.05.12 |
28 | 28 | ||
29 | 29 | ||
30 | * Date Version Description | 30 | * Date Version Description |
@@ -93,6 +93,7 @@ mpi.h | |||
93 | * Added EEDP IOCStatus codes. | 93 | * Added EEDP IOCStatus codes. |
94 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. | 94 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. |
95 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. | 95 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. |
96 | * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. | ||
96 | * -------------------------------------------------------------------------- | 97 | * -------------------------------------------------------------------------- |
97 | 98 | ||
98 | mpi_ioc.h | 99 | mpi_ioc.h |
@@ -170,6 +171,17 @@ mpi_ioc.h | |||
170 | * Added new ReasonCode value for SAS Device Status Change | 171 | * Added new ReasonCode value for SAS Device Status Change |
171 | * event. | 172 | * event. |
172 | * Added new family code for FC949E. | 173 | * Added new family code for FC949E. |
174 | * 03-27-06 01.05.11 Added MPI_IOCFACTS_CAPABILITY_TLR. | ||
175 | * Added additional Reason Codes and more event data fields | ||
176 | * to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE. | ||
177 | * Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and | ||
178 | * new event. | ||
179 | * Added MPI_EVENT_SAS_SMP_ERROR and event data structure. | ||
180 | * Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event | ||
181 | * data structure. | ||
182 | * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event | ||
183 | * data structure. | ||
184 | * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. | ||
173 | * -------------------------------------------------------------------------- | 185 | * -------------------------------------------------------------------------- |
174 | 186 | ||
175 | mpi_cnfg.h | 187 | mpi_cnfg.h |
@@ -425,6 +437,16 @@ mpi_cnfg.h | |||
425 | * Added postpone SATA Init bit to SAS IO Unit Page 1 | 437 | * Added postpone SATA Init bit to SAS IO Unit Page 1 |
426 | * ControlFlags. | 438 | * ControlFlags. |
427 | * Changed LogEntry format for Log Page 0. | 439 | * Changed LogEntry format for Log Page 0. |
440 | * 03-27-06 01.05.12 Added two new Flags defines for Manufacturing Page 4. | ||
441 | * Added Manufacturing Page 7. | ||
442 | * Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING. | ||
443 | * Added IOC Page 6. | ||
444 | * Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2. | ||
445 | * Added MaxLBAHigh field to RAID Volume Page 0. | ||
446 | * Added Nvdata version fields to SAS IO Unit Page 0. | ||
447 | * Added AdditionalControlFlags, MaxTargetPortConnectTime, | ||
448 | * ReportDeviceMissingDelay, and IODeviceMissingDelay | ||
449 | * fields to SAS IO Unit Page 1. | ||
428 | * -------------------------------------------------------------------------- | 450 | * -------------------------------------------------------------------------- |
429 | 451 | ||
430 | mpi_init.h | 452 | mpi_init.h |
@@ -467,6 +489,7 @@ mpi_init.h | |||
467 | * Added four new defines for SEP SlotStatus. | 489 | * Added four new defines for SEP SlotStatus. |
468 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them | 490 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them |
469 | * unique in the first 32 characters. | 491 | * unique in the first 32 characters. |
492 | * 03-27-06 01.05.07 Added Task Management type of Clear ACA. | ||
470 | * -------------------------------------------------------------------------- | 493 | * -------------------------------------------------------------------------- |
471 | 494 | ||
472 | mpi_targ.h | 495 | mpi_targ.h |
@@ -511,6 +534,7 @@ mpi_targ.h | |||
511 | * 02-22-05 01.05.03 Changed a comment. | 534 | * 02-22-05 01.05.03 Changed a comment. |
512 | * 03-11-05 01.05.04 Removed TargetAssistExtended Request. | 535 | * 03-11-05 01.05.04 Removed TargetAssistExtended Request. |
513 | * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. | 536 | * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. |
537 | * 03-27-06 01.05.06 Added a comment. | ||
514 | * -------------------------------------------------------------------------- | 538 | * -------------------------------------------------------------------------- |
515 | 539 | ||
516 | mpi_fc.h | 540 | mpi_fc.h |
@@ -610,6 +634,10 @@ mpi_sas.h | |||
610 | * 08-30-05 01.05.02 Added DeviceInfo bit for SEP. | 634 | * 08-30-05 01.05.02 Added DeviceInfo bit for SEP. |
611 | * Added PrimFlags and Primitive field to SAS IO Unit | 635 | * Added PrimFlags and Primitive field to SAS IO Unit |
612 | * Control request, and added a new operation code. | 636 | * Control request, and added a new operation code. |
637 | * 03-27-06 01.05.03 Added Force Full Discovery, Transmit Port Select Signal, | ||
638 | * and Remove Device operations to SAS IO Unit Control. | ||
639 | * Added DevHandle field to SAS IO Unit Control request and | ||
640 | * reply. | ||
613 | * -------------------------------------------------------------------------- | 641 | * -------------------------------------------------------------------------- |
614 | 642 | ||
615 | mpi_type.h | 643 | mpi_type.h |
@@ -625,20 +653,20 @@ mpi_type.h | |||
625 | 653 | ||
626 | mpi_history.txt Parts list history | 654 | mpi_history.txt Parts list history |
627 | 655 | ||
628 | Filename 01.05.12 01.05.11 01.05.10 01.05.09 | 656 | Filename 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09 |
629 | ---------- -------- -------- -------- -------- | 657 | ---------- -------- -------- -------- -------- -------- |
630 | mpi.h 01.05.10 01.05.09 01.05.08 01.05.07 | 658 | mpi.h 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07 |
631 | mpi_ioc.h 01.05.10 01.05.09 01.05.09 01.05.08 | 659 | mpi_ioc.h 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08 |
632 | mpi_cnfg.h 01.05.11 01.05.10 01.05.09 01.05.08 | 660 | mpi_cnfg.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08 |
633 | mpi_init.h 01.05.06 01.05.06 01.05.05 01.05.04 | 661 | mpi_init.h 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04 |
634 | mpi_targ.h 01.05.05 01.05.05 01.05.05 01.05.04 | 662 | mpi_targ.h 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04 |
635 | mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 | 663 | mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 |
636 | mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 | 664 | mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 |
637 | mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 | 665 | mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02 |
638 | mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 | 666 | mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03 |
639 | mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 | 667 | mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 |
640 | mpi_sas.h 01.05.02 01.05.01 01.05.01 01.05.01 | 668 | mpi_sas.h 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01 |
641 | mpi_type.h 01.05.02 01.05.01 01.05.01 01.05.01 | 669 | mpi_type.h 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01 |
642 | 670 | ||
643 | Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 | 671 | Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 |
644 | ---------- -------- -------- -------- -------- -------- -------- | 672 | ---------- -------- -------- -------- -------- -------- -------- |
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h index 68941f459ca3..c1c678989a23 100644 --- a/drivers/message/fusion/lsi/mpi_init.h +++ b/drivers/message/fusion/lsi/mpi_init.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI initiator mode messages and structures | 6 | * Title: MPI initiator mode messages and structures |
7 | * Creation Date: June 8, 2000 | 7 | * Creation Date: June 8, 2000 |
8 | * | 8 | * |
9 | * mpi_init.h Version: 01.05.06 | 9 | * mpi_init.h Version: 01.05.07 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -52,6 +52,7 @@ | |||
52 | * Added four new defines for SEP SlotStatus. | 52 | * Added four new defines for SEP SlotStatus. |
53 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them | 53 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them |
54 | * unique in the first 32 characters. | 54 | * unique in the first 32 characters. |
55 | * 03-27-06 01.05.07 Added Task Management type of Clear ACA. | ||
55 | * -------------------------------------------------------------------------- | 56 | * -------------------------------------------------------------------------- |
56 | */ | 57 | */ |
57 | 58 | ||
@@ -427,6 +428,7 @@ typedef struct _MSG_SCSI_TASK_MGMT | |||
427 | #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) | 428 | #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) |
428 | #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) | 429 | #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) |
429 | #define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) | 430 | #define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) |
431 | #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08) | ||
430 | 432 | ||
431 | /* MsgFlags bits */ | 433 | /* MsgFlags bits */ |
432 | #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) | 434 | #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) |
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h index 2c5f43fa7c73..18ba407fd399 100644 --- a/drivers/message/fusion/lsi/mpi_ioc.h +++ b/drivers/message/fusion/lsi/mpi_ioc.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages | 6 | * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages |
7 | * Creation Date: August 11, 2000 | 7 | * Creation Date: August 11, 2000 |
8 | * | 8 | * |
9 | * mpi_ioc.h Version: 01.05.10 | 9 | * mpi_ioc.h Version: 01.05.11 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -87,6 +87,17 @@ | |||
87 | * Added new ReasonCode value for SAS Device Status Change | 87 | * Added new ReasonCode value for SAS Device Status Change |
88 | * event. | 88 | * event. |
89 | * Added new family code for FC949E. | 89 | * Added new family code for FC949E. |
90 | * 03-27-06 01.05.11 Added MPI_IOCFACTS_CAPABILITY_TLR. | ||
91 | * Added additional Reason Codes and more event data fields | ||
92 | * to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE. | ||
93 | * Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and | ||
94 | * new event. | ||
95 | * Added MPI_EVENT_SAS_SMP_ERROR and event data structure. | ||
96 | * Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event | ||
97 | * data structure. | ||
98 | * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event | ||
99 | * data structure. | ||
100 | * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. | ||
90 | * -------------------------------------------------------------------------- | 101 | * -------------------------------------------------------------------------- |
91 | */ | 102 | */ |
92 | 103 | ||
@@ -272,6 +283,7 @@ typedef struct _MSG_IOC_FACTS_REPLY | |||
272 | #define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) | 283 | #define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) |
273 | #define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200) | 284 | #define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200) |
274 | #define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400) | 285 | #define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400) |
286 | #define MPI_IOCFACTS_CAPABILITY_TLR (0x00000800) | ||
275 | 287 | ||
276 | 288 | ||
277 | /***************************************************************************** | 289 | /***************************************************************************** |
@@ -448,30 +460,34 @@ typedef struct _MSG_EVENT_ACK_REPLY | |||
448 | 460 | ||
449 | /* Event */ | 461 | /* Event */ |
450 | 462 | ||
451 | #define MPI_EVENT_NONE (0x00000000) | 463 | #define MPI_EVENT_NONE (0x00000000) |
452 | #define MPI_EVENT_LOG_DATA (0x00000001) | 464 | #define MPI_EVENT_LOG_DATA (0x00000001) |
453 | #define MPI_EVENT_STATE_CHANGE (0x00000002) | 465 | #define MPI_EVENT_STATE_CHANGE (0x00000002) |
454 | #define MPI_EVENT_UNIT_ATTENTION (0x00000003) | 466 | #define MPI_EVENT_UNIT_ATTENTION (0x00000003) |
455 | #define MPI_EVENT_IOC_BUS_RESET (0x00000004) | 467 | #define MPI_EVENT_IOC_BUS_RESET (0x00000004) |
456 | #define MPI_EVENT_EXT_BUS_RESET (0x00000005) | 468 | #define MPI_EVENT_EXT_BUS_RESET (0x00000005) |
457 | #define MPI_EVENT_RESCAN (0x00000006) | 469 | #define MPI_EVENT_RESCAN (0x00000006) |
458 | #define MPI_EVENT_LINK_STATUS_CHANGE (0x00000007) | 470 | #define MPI_EVENT_LINK_STATUS_CHANGE (0x00000007) |
459 | #define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008) | 471 | #define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008) |
460 | #define MPI_EVENT_LOGOUT (0x00000009) | 472 | #define MPI_EVENT_LOGOUT (0x00000009) |
461 | #define MPI_EVENT_EVENT_CHANGE (0x0000000A) | 473 | #define MPI_EVENT_EVENT_CHANGE (0x0000000A) |
462 | #define MPI_EVENT_INTEGRATED_RAID (0x0000000B) | 474 | #define MPI_EVENT_INTEGRATED_RAID (0x0000000B) |
463 | #define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C) | 475 | #define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C) |
464 | #define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D) | 476 | #define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D) |
465 | #define MPI_EVENT_QUEUE_FULL (0x0000000E) | 477 | #define MPI_EVENT_QUEUE_FULL (0x0000000E) |
466 | #define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F) | 478 | #define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F) |
467 | #define MPI_EVENT_SAS_SES (0x00000010) | 479 | #define MPI_EVENT_SAS_SES (0x00000010) |
468 | #define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011) | 480 | #define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011) |
469 | #define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012) | 481 | #define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012) |
470 | #define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013) | 482 | #define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013) |
471 | #define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014) | 483 | #define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014) |
472 | #define MPI_EVENT_IR2 (0x00000015) | 484 | #define MPI_EVENT_IR2 (0x00000015) |
473 | #define MPI_EVENT_SAS_DISCOVERY (0x00000016) | 485 | #define MPI_EVENT_SAS_DISCOVERY (0x00000016) |
474 | #define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021) | 486 | #define MPI_EVENT_SAS_BROADCAST_PRIMITIVE (0x00000017) |
487 | #define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018) | ||
488 | #define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW (0x00000019) | ||
489 | #define MPI_EVENT_SAS_SMP_ERROR (0x0000001A) | ||
490 | #define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021) | ||
475 | 491 | ||
476 | /* AckRequired field values */ | 492 | /* AckRequired field values */ |
477 | 493 | ||
@@ -558,18 +574,25 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE | |||
558 | U8 PhyNum; /* 0Eh */ | 574 | U8 PhyNum; /* 0Eh */ |
559 | U8 Reserved1; /* 0Fh */ | 575 | U8 Reserved1; /* 0Fh */ |
560 | U64 SASAddress; /* 10h */ | 576 | U64 SASAddress; /* 10h */ |
577 | U8 LUN[8]; /* 18h */ | ||
578 | U16 TaskTag; /* 20h */ | ||
579 | U16 Reserved2; /* 22h */ | ||
561 | } EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, | 580 | } EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, |
562 | MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, | 581 | MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, |
563 | MpiEventDataSasDeviceStatusChange_t, | 582 | MpiEventDataSasDeviceStatusChange_t, |
564 | MPI_POINTER pMpiEventDataSasDeviceStatusChange_t; | 583 | MPI_POINTER pMpiEventDataSasDeviceStatusChange_t; |
565 | 584 | ||
566 | /* MPI SAS Device Status Change Event data ReasonCode values */ | 585 | /* MPI SAS Device Status Change Event data ReasonCode values */ |
567 | #define MPI_EVENT_SAS_DEV_STAT_RC_ADDED (0x03) | 586 | #define MPI_EVENT_SAS_DEV_STAT_RC_ADDED (0x03) |
568 | #define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04) | 587 | #define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04) |
569 | #define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) | 588 | #define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) |
570 | #define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06) | 589 | #define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06) |
571 | #define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) | 590 | #define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) |
572 | #define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) | 591 | #define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) |
592 | #define MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09) | ||
593 | #define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) | ||
594 | #define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) | ||
595 | #define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) | ||
573 | 596 | ||
574 | 597 | ||
575 | /* SCSI Event data for Queue Full event */ | 598 | /* SCSI Event data for Queue Full event */ |
@@ -742,6 +765,27 @@ typedef struct _EVENT_DATA_SAS_SES | |||
742 | } EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES, | 765 | } EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES, |
743 | MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t; | 766 | MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t; |
744 | 767 | ||
768 | /* SAS Broadcast Primitive Event data */ | ||
769 | |||
770 | typedef struct _EVENT_DATA_SAS_BROADCAST_PRIMITIVE | ||
771 | { | ||
772 | U8 PhyNum; /* 00h */ | ||
773 | U8 Port; /* 01h */ | ||
774 | U8 PortWidth; /* 02h */ | ||
775 | U8 Primitive; /* 04h */ | ||
776 | } EVENT_DATA_SAS_BROADCAST_PRIMITIVE, | ||
777 | MPI_POINTER PTR_EVENT_DATA_SAS_BROADCAST_PRIMITIVE, | ||
778 | MpiEventDataSasBroadcastPrimitive_t, | ||
779 | MPI_POINTER pMpiEventDataSasBroadcastPrimitive_t; | ||
780 | |||
781 | #define MPI_EVENT_PRIMITIVE_CHANGE (0x01) | ||
782 | #define MPI_EVENT_PRIMITIVE_EXPANDER (0x03) | ||
783 | #define MPI_EVENT_PRIMITIVE_RESERVED2 (0x04) | ||
784 | #define MPI_EVENT_PRIMITIVE_RESERVED3 (0x05) | ||
785 | #define MPI_EVENT_PRIMITIVE_RESERVED4 (0x06) | ||
786 | #define MPI_EVENT_PRIMITIVE_CHANGE0_RESERVED (0x07) | ||
787 | #define MPI_EVENT_PRIMITIVE_CHANGE1_RESERVED (0x08) | ||
788 | |||
745 | /* SAS Phy Link Status Event data */ | 789 | /* SAS Phy Link Status Event data */ |
746 | 790 | ||
747 | typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS | 791 | typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS |
@@ -804,6 +848,53 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR | |||
804 | #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800) | 848 | #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800) |
805 | #define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000) | 849 | #define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000) |
806 | 850 | ||
851 | /* SAS SMP Error Event data */ | ||
852 | |||
853 | typedef struct _EVENT_DATA_SAS_SMP_ERROR | ||
854 | { | ||
855 | U8 Status; /* 00h */ | ||
856 | U8 Port; /* 01h */ | ||
857 | U8 SMPFunctionResult; /* 02h */ | ||
858 | U8 Reserved1; /* 03h */ | ||
859 | U64 SASAddress; /* 04h */ | ||
860 | } EVENT_DATA_SAS_SMP_ERROR, MPI_POINTER PTR_EVENT_DATA_SAS_SMP_ERROR, | ||
861 | MpiEventDataSasSmpError_t, MPI_POINTER pMpiEventDataSasSmpError_t; | ||
862 | |||
863 | /* defines for the Status field of the SAS SMP Error event */ | ||
864 | #define MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID (0x00) | ||
865 | #define MPI_EVENT_SAS_SMP_CRC_ERROR (0x01) | ||
866 | #define MPI_EVENT_SAS_SMP_TIMEOUT (0x02) | ||
867 | #define MPI_EVENT_SAS_SMP_NO_DESTINATION (0x03) | ||
868 | #define MPI_EVENT_SAS_SMP_BAD_DESTINATION (0x04) | ||
869 | |||
870 | /* SAS Initiator Device Status Change Event data */ | ||
871 | |||
872 | typedef struct _EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE | ||
873 | { | ||
874 | U8 ReasonCode; /* 00h */ | ||
875 | U8 Port; /* 01h */ | ||
876 | U16 DevHandle; /* 02h */ | ||
877 | U64 SASAddress; /* 04h */ | ||
878 | } EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, | ||
879 | MPI_POINTER PTR_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, | ||
880 | MpiEventDataSasInitDevStatusChange_t, | ||
881 | MPI_POINTER pMpiEventDataSasInitDevStatusChange_t; | ||
882 | |||
883 | /* defines for the ReasonCode field of the SAS Initiator Device Status Change event */ | ||
884 | #define MPI_EVENT_SAS_INIT_RC_ADDED (0x01) | ||
885 | |||
886 | /* SAS Initiator Device Table Overflow Event data */ | ||
887 | |||
888 | typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW | ||
889 | { | ||
890 | U8 MaxInit; /* 00h */ | ||
891 | U8 CurrentInit; /* 01h */ | ||
892 | U16 Reserved1; /* 02h */ | ||
893 | } EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, | ||
894 | MPI_POINTER PTR_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, | ||
895 | MpiEventDataSasInitTableOverflow_t, | ||
896 | MPI_POINTER pMpiEventDataSasInitTableOverflow_t; | ||
897 | |||
807 | 898 | ||
808 | /***************************************************************************** | 899 | /***************************************************************************** |
809 | * | 900 | * |
@@ -1013,5 +1104,6 @@ typedef struct _MPI_EXT_IMAGE_HEADER | |||
1013 | #define MPI_EXT_IMAGE_TYPE_FW (0x01) | 1104 | #define MPI_EXT_IMAGE_TYPE_FW (0x01) |
1014 | #define MPI_EXT_IMAGE_TYPE_NVDATA (0x03) | 1105 | #define MPI_EXT_IMAGE_TYPE_NVDATA (0x03) |
1015 | #define MPI_EXT_IMAGE_TYPE_BOOTLOADER (0x04) | 1106 | #define MPI_EXT_IMAGE_TYPE_BOOTLOADER (0x04) |
1107 | #define MPI_EXT_IMAGE_TYPE_INITIALIZATION (0x05) | ||
1016 | 1108 | ||
1017 | #endif | 1109 | #endif |
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index a9c14ad132ce..871ebc08b706 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h | |||
@@ -13,6 +13,8 @@ | |||
13 | #ifndef IOPI_IOCLOGINFO_H_INCLUDED | 13 | #ifndef IOPI_IOCLOGINFO_H_INCLUDED |
14 | #define IOPI_IOCLOGINFO_H_INCLUDED | 14 | #define IOPI_IOCLOGINFO_H_INCLUDED |
15 | 15 | ||
16 | #define SAS_LOGINFO_NEXUS_LOSS 0x31170000 | ||
17 | #define SAS_LOGINFO_MASK 0xFFFF0000 | ||
16 | 18 | ||
17 | /****************************************************************************/ | 19 | /****************************************************************************/ |
18 | /* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */ | 20 | /* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */ |
@@ -51,6 +53,9 @@ | |||
51 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */ | 53 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */ |
52 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */ | 54 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */ |
53 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */ | 55 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */ |
56 | |||
57 | #define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */ | ||
58 | |||
54 | #define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000) | 59 | #define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000) |
55 | 60 | ||
56 | #define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */ | 61 | #define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */ |
@@ -103,6 +108,7 @@ | |||
103 | #define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000) | 108 | #define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000) |
104 | #define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000) | 109 | #define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000) |
105 | #define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000) | 110 | #define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000) |
111 | #define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000) | ||
106 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100) | 112 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100) |
107 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101) | 113 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101) |
108 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */ | 114 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */ |
@@ -165,11 +171,81 @@ | |||
165 | /****************************************************************************/ | 171 | /****************************************************************************/ |
166 | /* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR */ | 172 | /* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR */ |
167 | /****************************************************************************/ | 173 | /****************************************************************************/ |
168 | #define IR_LOGINFO_CODE_UNUSED1 (0x00010000) | 174 | #define IR_LOGINFO_RAID_ACTION_ERROR (0x00010000) |
169 | #define IR_LOGINFO_CODE_UNUSED2 (0x00020000) | 175 | #define IR_LOGINFO_CODE_UNUSED2 (0x00020000) |
176 | |||
177 | /* Amount of information passed down for Create Volume is too large */ | ||
178 | #define IR_LOGINFO_VOLUME_CREATE_INVALID_LENGTH (0x00010001) | ||
179 | /* Creation of duplicate volume attempted (Bus/Target ID checked) */ | ||
180 | #define IR_LOGINFO_VOLUME_CREATE_DUPLICATE (0x00010002) | ||
181 | /* Creation failed due to maximum number of supported volumes exceeded */ | ||
182 | #define IR_LOGINFO_VOLUME_CREATE_NO_SLOTS (0x00010003) | ||
183 | /* Creation failed due to DMA error in trying to read from host */ | ||
184 | #define IR_LOGINFO_VOLUME_CREATE_DMA_ERROR (0x00010004) | ||
185 | /* Creation failed due to invalid volume type passed down */ | ||
186 | #define IR_LOGINFO_VOLUME_CREATE_INVALID_VOLUME_TYPE (0x00010005) | ||
187 | /* Creation failed due to error reading MFG Page 4 */ | ||
188 | #define IR_LOGINFO_VOLUME_MFG_PAGE4_ERROR (0x00010006) | ||
189 | /* Creation failed when trying to create internal structures */ | ||
190 | #define IR_LOGINFO_VOLUME_INTERNAL_CONFIG_STRUCTURE_ERROR (0x00010007) | ||
191 | |||
192 | /* Activation failed due to trying to activate an already active volume */ | ||
193 | #define IR_LOGINFO_VOLUME_ACTIVATING_AN_ACTIVE_VOLUME (0x00010010) | ||
194 | /* Activation failed due to trying to active unsupported volume type */ | ||
195 | #define IR_LOGINFO_VOLUME_ACTIVATING_INVALID_VOLUME_TYPE (0x00010011) | ||
196 | /* Activation failed due to trying to active too many volumes */ | ||
197 | #define IR_LOGINFO_VOLUME_ACTIVATING_TOO_MANY_VOLUMES (0x00010012) | ||
198 | /* Activation failed due to Volume ID in use already */ | ||
199 | #define IR_LOGINFO_VOLUME_ACTIVATING_VOLUME_ID_IN_USE (0x00010013) | ||
200 | /* Activation failed call to activateVolume returned failure */ | ||
201 | #define IR_LOGINFO_VOLUME_ACTIVATE_VOLUME_FAILED (0x00010014) | ||
202 | /* Activation failed trying to import the volume */ | ||
203 | #define IR_LOGINFO_VOLUME_ACTIVATING_IMPORT_VOLUME_FAILED (0x00010015) | ||
204 | |||
205 | /* Phys Disk failed, too many phys disks */ | ||
206 | #define IR_LOGINFO_PHYSDISK_CREATE_TOO_MANY_DISKS (0x00010020) | ||
207 | /* Amount of information passed down for Create Pnysdisk is too large */ | ||
208 | #define IR_LOGINFO_PHYSDISK_CREATE_INVALID_LENGTH (0x00010021) | ||
209 | /* Creation failed due to DMA error in trying to read from host */ | ||
210 | #define IR_LOGINFO_PHYSDISK_CREATE_DMA_ERROR (0x00010022) | ||
211 | /* Creation failed due to invalid Bus TargetID passed down */ | ||
212 | #define IR_LOGINFO_PHYSDISK_CREATE_BUS_TID_INVALID (0x00010023) | ||
213 | /* Creation failed due to error in creating RAID Phys Disk Config Page */ | ||
214 | #define IR_LOGINFO_PHYSDISK_CREATE_CONFIG_PAGE_ERROR (0x00010024) | ||
215 | |||
216 | |||
217 | /* Compatibility Error : IR Disabled */ | ||
218 | #define IR_LOGINFO_COMPAT_ERROR_RAID_DISABLED (0x00010030) | ||
219 | /* Compatibility Error : Inquiry Comand failed */ | ||
220 | #define IR_LOGINFO_COMPAT_ERROR_INQUIRY_FAILED (0x00010031) | ||
221 | /* Compatibility Error : Device not direct access device */ | ||
222 | #define IR_LOGINFO_COMPAT_ERROR_NOT_DIRECT_ACCESS (0x00010032) | ||
223 | /* Compatibility Error : Removable device found */ | ||
224 | #define IR_LOGINFO_COMPAT_ERROR_REMOVABLE_FOUND (0x00010033) | ||
225 | /* Compatibility Error : Device SCSI Version not 2 or higher */ | ||
226 | #define IR_LOGINFO_COMPAT_ERROR_NEED_SCSI_2_OR_HIGHER (0x00010034) | ||
227 | /* Compatibility Error : SATA device, 48 BIT LBA not supported */ | ||
228 | #define IR_LOGINFO_COMPAT_ERROR_SATA_48BIT_LBA_NOT_SUPPORTED (0x00010035) | ||
229 | /* Compatibility Error : Device does not have 512 byte block sizes */ | ||
230 | #define IR_LOGINFO_COMPAT_ERROR_DEVICE_NOT_512_BYTE_BLOCK (0x00010036) | ||
231 | /* Compatibility Error : Volume Type check failed */ | ||
232 | #define IR_LOGINFO_COMPAT_ERROR_VOLUME_TYPE_CHECK_FAILED (0x00010037) | ||
233 | /* Compatibility Error : Volume Type is unsupported by FW */ | ||
234 | #define IR_LOGINFO_COMPAT_ERROR_UNSUPPORTED_VOLUME_TYPE (0x00010038) | ||
235 | /* Compatibility Error : Disk drive too small for use in volume */ | ||
236 | #define IR_LOGINFO_COMPAT_ERROR_DISK_TOO_SMALL (0x00010039) | ||
237 | /* Compatibility Error : Phys disk for Create Volume not found */ | ||
238 | #define IR_LOGINFO_COMPAT_ERROR_PHYS_DISK_NOT_FOUND (0x0001003A) | ||
239 | /* Compatibility Error : membership count error, too many or too few disks for volume type */ | ||
240 | #define IR_LOGINFO_COMPAT_ERROR_MEMBERSHIP_COUNT (0x0001003B) | ||
241 | /* Compatibility Error : Disk stripe sizes must be 64KB */ | ||
242 | #define IR_LOGINFO_COMPAT_ERROR_NON_64K_STRIPE_SIZE (0x0001003C) | ||
243 | /* Compatibility Error : IME size limited to < 2TB */ | ||
244 | #define IR_LOGINFO_COMPAT_ERROR_IME_VOL_NOT_CURRENTLY_SUPPORTED (0x0001003D) | ||
245 | |||
170 | 246 | ||
171 | /****************************************************************************/ | 247 | /****************************************************************************/ |
172 | /* Defines for convienence */ | 248 | /* Defines for convenience */ |
173 | /****************************************************************************/ | 249 | /****************************************************************************/ |
174 | #define IOC_LOGINFO_PREFIX_IOP ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP) | 250 | #define IOC_LOGINFO_PREFIX_IOP ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP) |
175 | #define IOC_LOGINFO_PREFIX_PL ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL) | 251 | #define IOC_LOGINFO_PREFIX_PL ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL) |
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h index 70514867bddf..50b8f0a8f456 100644 --- a/drivers/message/fusion/lsi/mpi_sas.h +++ b/drivers/message/fusion/lsi/mpi_sas.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Serial Attached SCSI structures and definitions | 6 | * Title: MPI Serial Attached SCSI structures and definitions |
7 | * Creation Date: August 19, 2004 | 7 | * Creation Date: August 19, 2004 |
8 | * | 8 | * |
9 | * mpi_sas.h Version: 01.05.02 | 9 | * mpi_sas.h Version: 01.05.03 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -17,6 +17,10 @@ | |||
17 | * 08-30-05 01.05.02 Added DeviceInfo bit for SEP. | 17 | * 08-30-05 01.05.02 Added DeviceInfo bit for SEP. |
18 | * Added PrimFlags and Primitive field to SAS IO Unit | 18 | * Added PrimFlags and Primitive field to SAS IO Unit |
19 | * Control request, and added a new operation code. | 19 | * Control request, and added a new operation code. |
20 | * 03-27-06 01.05.03 Added Force Full Discovery, Transmit Port Select Signal, | ||
21 | * and Remove Device operations to SAS IO Unit Control. | ||
22 | * Added DevHandle field to SAS IO Unit Control request and | ||
23 | * reply. | ||
20 | * -------------------------------------------------------------------------- | 24 | * -------------------------------------------------------------------------- |
21 | */ | 25 | */ |
22 | 26 | ||
@@ -209,7 +213,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST | |||
209 | U8 Reserved1; /* 01h */ | 213 | U8 Reserved1; /* 01h */ |
210 | U8 ChainOffset; /* 02h */ | 214 | U8 ChainOffset; /* 02h */ |
211 | U8 Function; /* 03h */ | 215 | U8 Function; /* 03h */ |
212 | U16 Reserved2; /* 04h */ | 216 | U16 DevHandle; /* 04h */ |
213 | U8 Reserved3; /* 06h */ | 217 | U8 Reserved3; /* 06h */ |
214 | U8 MsgFlags; /* 07h */ | 218 | U8 MsgFlags; /* 07h */ |
215 | U32 MsgContext; /* 08h */ | 219 | U32 MsgContext; /* 08h */ |
@@ -231,6 +235,9 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST | |||
231 | #define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) | 235 | #define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) |
232 | #define MPI_SAS_OP_MAP_CURRENT (0x09) | 236 | #define MPI_SAS_OP_MAP_CURRENT (0x09) |
233 | #define MPI_SAS_OP_SEND_PRIMITIVE (0x0A) | 237 | #define MPI_SAS_OP_SEND_PRIMITIVE (0x0A) |
238 | #define MPI_SAS_OP_FORCE_FULL_DISCOVERY (0x0B) | ||
239 | #define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C) | ||
240 | #define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D) | ||
234 | 241 | ||
235 | /* values for the PrimFlags field */ | 242 | /* values for the PrimFlags field */ |
236 | #define MPI_SAS_PRIMFLAGS_SINGLE (0x08) | 243 | #define MPI_SAS_PRIMFLAGS_SINGLE (0x08) |
@@ -245,7 +252,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY | |||
245 | U8 Reserved1; /* 01h */ | 252 | U8 Reserved1; /* 01h */ |
246 | U8 MsgLength; /* 02h */ | 253 | U8 MsgLength; /* 02h */ |
247 | U8 Function; /* 03h */ | 254 | U8 Function; /* 03h */ |
248 | U16 Reserved2; /* 04h */ | 255 | U16 DevHandle; /* 04h */ |
249 | U8 Reserved3; /* 06h */ | 256 | U8 Reserved3; /* 06h */ |
250 | U8 MsgFlags; /* 07h */ | 257 | U8 MsgFlags; /* 07h */ |
251 | U32 MsgContext; /* 08h */ | 258 | U32 MsgContext; /* 08h */ |
diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h index 3f462859ceea..20b667315773 100644 --- a/drivers/message/fusion/lsi/mpi_targ.h +++ b/drivers/message/fusion/lsi/mpi_targ.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Target mode messages and structures | 6 | * Title: MPI Target mode messages and structures |
7 | * Creation Date: June 22, 2000 | 7 | * Creation Date: June 22, 2000 |
8 | * | 8 | * |
9 | * mpi_targ.h Version: 01.05.05 | 9 | * mpi_targ.h Version: 01.05.06 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -54,6 +54,7 @@ | |||
54 | * 02-22-05 01.05.03 Changed a comment. | 54 | * 02-22-05 01.05.03 Changed a comment. |
55 | * 03-11-05 01.05.04 Removed TargetAssistExtended Request. | 55 | * 03-11-05 01.05.04 Removed TargetAssistExtended Request. |
56 | * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. | 56 | * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. |
57 | * 03-27-06 01.05.06 Added a comment. | ||
57 | * -------------------------------------------------------------------------- | 58 | * -------------------------------------------------------------------------- |
58 | */ | 59 | */ |
59 | 60 | ||
@@ -351,7 +352,7 @@ typedef struct _MSG_TARGET_ASSIST_REQUEST | |||
351 | #define TARGET_ASSIST_FLAGS_CONFIRMED (0x08) | 352 | #define TARGET_ASSIST_FLAGS_CONFIRMED (0x08) |
352 | #define TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER (0x80) | 353 | #define TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER (0x80) |
353 | 354 | ||
354 | 355 | /* Standard Target Mode Reply message */ | |
355 | typedef struct _MSG_TARGET_ERROR_REPLY | 356 | typedef struct _MSG_TARGET_ERROR_REPLY |
356 | { | 357 | { |
357 | U16 Reserved; /* 00h */ | 358 | U16 Reserved; /* 00h */ |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 57543603d6c8..43308df64623 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -368,20 +368,21 @@ static irqreturn_t | |||
368 | mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) | 368 | mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) |
369 | { | 369 | { |
370 | MPT_ADAPTER *ioc = bus_id; | 370 | MPT_ADAPTER *ioc = bus_id; |
371 | u32 pa; | 371 | u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); |
372 | |||
373 | if (pa == 0xFFFFFFFF) | ||
374 | return IRQ_NONE; | ||
372 | 375 | ||
373 | /* | 376 | /* |
374 | * Drain the reply FIFO! | 377 | * Drain the reply FIFO! |
375 | */ | 378 | */ |
376 | while (1) { | 379 | do { |
377 | pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); | 380 | if (pa & MPI_ADDRESS_REPLY_A_BIT) |
378 | if (pa == 0xFFFFFFFF) | ||
379 | return IRQ_HANDLED; | ||
380 | else if (pa & MPI_ADDRESS_REPLY_A_BIT) | ||
381 | mpt_reply(ioc, pa); | 381 | mpt_reply(ioc, pa); |
382 | else | 382 | else |
383 | mpt_turbo_reply(ioc, pa); | 383 | mpt_turbo_reply(ioc, pa); |
384 | } | 384 | pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); |
385 | } while (pa != 0xFFFFFFFF); | ||
385 | 386 | ||
386 | return IRQ_HANDLED; | 387 | return IRQ_HANDLED; |
387 | } | 388 | } |
@@ -1219,31 +1220,25 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1219 | port = psize = 0; | 1220 | port = psize = 0; |
1220 | for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) { | 1221 | for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) { |
1221 | if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { | 1222 | if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { |
1223 | if (psize) | ||
1224 | continue; | ||
1222 | /* Get I/O space! */ | 1225 | /* Get I/O space! */ |
1223 | port = pci_resource_start(pdev, ii); | 1226 | port = pci_resource_start(pdev, ii); |
1224 | psize = pci_resource_len(pdev,ii); | 1227 | psize = pci_resource_len(pdev,ii); |
1225 | } else { | 1228 | } else { |
1229 | if (msize) | ||
1230 | continue; | ||
1226 | /* Get memmap */ | 1231 | /* Get memmap */ |
1227 | mem_phys = pci_resource_start(pdev, ii); | 1232 | mem_phys = pci_resource_start(pdev, ii); |
1228 | msize = pci_resource_len(pdev,ii); | 1233 | msize = pci_resource_len(pdev,ii); |
1229 | break; | ||
1230 | } | 1234 | } |
1231 | } | 1235 | } |
1232 | ioc->mem_size = msize; | 1236 | ioc->mem_size = msize; |
1233 | 1237 | ||
1234 | if (ii == DEVICE_COUNT_RESOURCE) { | ||
1235 | printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n"); | ||
1236 | kfree(ioc); | ||
1237 | return -EINVAL; | ||
1238 | } | ||
1239 | |||
1240 | dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize)); | ||
1241 | dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize)); | ||
1242 | |||
1243 | mem = NULL; | 1238 | mem = NULL; |
1244 | /* Get logical ptr for PciMem0 space */ | 1239 | /* Get logical ptr for PciMem0 space */ |
1245 | /*mem = ioremap(mem_phys, msize);*/ | 1240 | /*mem = ioremap(mem_phys, msize);*/ |
1246 | mem = ioremap(mem_phys, 0x100); | 1241 | mem = ioremap(mem_phys, msize); |
1247 | if (mem == NULL) { | 1242 | if (mem == NULL) { |
1248 | printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n"); | 1243 | printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n"); |
1249 | kfree(ioc); | 1244 | kfree(ioc); |
@@ -1343,11 +1338,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1343 | ioc->bus_type = SAS; | 1338 | ioc->bus_type = SAS; |
1344 | ioc->errata_flag_1064 = 1; | 1339 | ioc->errata_flag_1064 = 1; |
1345 | } | 1340 | } |
1346 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) { | ||
1347 | ioc->prod_name = "LSISAS1066"; | ||
1348 | ioc->bus_type = SAS; | ||
1349 | ioc->errata_flag_1064 = 1; | ||
1350 | } | ||
1351 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) { | 1341 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) { |
1352 | ioc->prod_name = "LSISAS1068"; | 1342 | ioc->prod_name = "LSISAS1068"; |
1353 | ioc->bus_type = SAS; | 1343 | ioc->bus_type = SAS; |
@@ -1357,14 +1347,14 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1357 | ioc->prod_name = "LSISAS1064E"; | 1347 | ioc->prod_name = "LSISAS1064E"; |
1358 | ioc->bus_type = SAS; | 1348 | ioc->bus_type = SAS; |
1359 | } | 1349 | } |
1360 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) { | ||
1361 | ioc->prod_name = "LSISAS1066E"; | ||
1362 | ioc->bus_type = SAS; | ||
1363 | } | ||
1364 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) { | 1350 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) { |
1365 | ioc->prod_name = "LSISAS1068E"; | 1351 | ioc->prod_name = "LSISAS1068E"; |
1366 | ioc->bus_type = SAS; | 1352 | ioc->bus_type = SAS; |
1367 | } | 1353 | } |
1354 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { | ||
1355 | ioc->prod_name = "LSISAS1078"; | ||
1356 | ioc->bus_type = SAS; | ||
1357 | } | ||
1368 | 1358 | ||
1369 | if (ioc->errata_flag_1064) | 1359 | if (ioc->errata_flag_1064) |
1370 | pci_disable_io_access(pdev); | 1360 | pci_disable_io_access(pdev); |
@@ -3184,6 +3174,37 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | |||
3184 | u32 diag1val = 0; | 3174 | u32 diag1val = 0; |
3185 | #endif | 3175 | #endif |
3186 | 3176 | ||
3177 | if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { | ||
3178 | drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " | ||
3179 | "address=%p\n", ioc->name, __FUNCTION__, | ||
3180 | &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); | ||
3181 | CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); | ||
3182 | if (sleepFlag == CAN_SLEEP) | ||
3183 | msleep(1); | ||
3184 | else | ||
3185 | mdelay(1); | ||
3186 | |||
3187 | for (count = 0; count < 60; count ++) { | ||
3188 | doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); | ||
3189 | doorbell &= MPI_IOC_STATE_MASK; | ||
3190 | |||
3191 | drsprintk((MYIOC_s_INFO_FMT | ||
3192 | "looking for READY STATE: doorbell=%x" | ||
3193 | " count=%d\n", | ||
3194 | ioc->name, doorbell, count)); | ||
3195 | if (doorbell == MPI_IOC_STATE_READY) { | ||
3196 | return 0; | ||
3197 | } | ||
3198 | |||
3199 | /* wait 1 sec */ | ||
3200 | if (sleepFlag == CAN_SLEEP) | ||
3201 | msleep(1000); | ||
3202 | else | ||
3203 | mdelay(1000); | ||
3204 | } | ||
3205 | return -1; | ||
3206 | } | ||
3207 | |||
3187 | /* Clear any existing interrupts */ | 3208 | /* Clear any existing interrupts */ |
3188 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); | 3209 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); |
3189 | 3210 | ||
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 32ae4d664545..a5ce10b67d02 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -75,8 +75,8 @@ | |||
75 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR | 75 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #define MPT_LINUX_VERSION_COMMON "3.03.10" | 78 | #define MPT_LINUX_VERSION_COMMON "3.04.00" |
79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.10" | 79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.00" |
80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" | 80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" |
81 | 81 | ||
82 | #define show_mptmod_ver(s,ver) \ | 82 | #define show_mptmod_ver(s,ver) \ |
@@ -307,7 +307,8 @@ typedef struct _SYSIF_REGS | |||
307 | u32 HostIndex; /* 50 Host Index register */ | 307 | u32 HostIndex; /* 50 Host Index register */ |
308 | u32 Reserved4[15]; /* 54-8F */ | 308 | u32 Reserved4[15]; /* 54-8F */ |
309 | u32 Fubar; /* 90 For Fubar usage */ | 309 | u32 Fubar; /* 90 For Fubar usage */ |
310 | u32 Reserved5[27]; /* 94-FF */ | 310 | u32 Reserved5[1050];/* 94-10F8 */ |
311 | u32 Reset_1078; /* 10FC Reset 1078 */ | ||
311 | } SYSIF_REGS; | 312 | } SYSIF_REGS; |
312 | 313 | ||
313 | /* | 314 | /* |
@@ -341,6 +342,7 @@ typedef struct _VirtTarget { | |||
341 | u8 negoFlags; /* bit field, see above */ | 342 | u8 negoFlags; /* bit field, see above */ |
342 | u8 raidVolume; /* set, if RAID Volume */ | 343 | u8 raidVolume; /* set, if RAID Volume */ |
343 | u8 type; /* byte 0 of Inquiry data */ | 344 | u8 type; /* byte 0 of Inquiry data */ |
345 | u8 deleted; /* target in process of being removed */ | ||
344 | u32 num_luns; | 346 | u32 num_luns; |
345 | u32 luns[8]; /* Max LUNs is 256 */ | 347 | u32 luns[8]; /* Max LUNs is 256 */ |
346 | } VirtTarget; | 348 | } VirtTarget; |
@@ -629,10 +631,11 @@ typedef struct _MPT_ADAPTER | |||
629 | struct mutex sas_discovery_mutex; | 631 | struct mutex sas_discovery_mutex; |
630 | u8 sas_discovery_runtime; | 632 | u8 sas_discovery_runtime; |
631 | u8 sas_discovery_ignore_events; | 633 | u8 sas_discovery_ignore_events; |
634 | u16 handle; | ||
632 | int sas_index; /* index refrencing */ | 635 | int sas_index; /* index refrencing */ |
633 | MPT_SAS_MGMT sas_mgmt; | 636 | MPT_SAS_MGMT sas_mgmt; |
634 | int num_ports; | 637 | int num_ports; |
635 | struct work_struct mptscsih_persistTask; | 638 | struct work_struct sas_persist_task; |
636 | 639 | ||
637 | struct work_struct fc_setup_reset_work; | 640 | struct work_struct fc_setup_reset_work; |
638 | struct list_head fc_rports; | 641 | struct list_head fc_rports; |
@@ -641,6 +644,7 @@ typedef struct _MPT_ADAPTER | |||
641 | struct work_struct fc_rescan_work; | 644 | struct work_struct fc_rescan_work; |
642 | char fc_rescan_work_q_name[KOBJ_NAME_LEN]; | 645 | char fc_rescan_work_q_name[KOBJ_NAME_LEN]; |
643 | struct workqueue_struct *fc_rescan_work_q; | 646 | struct workqueue_struct *fc_rescan_work_q; |
647 | u8 port_serial_number; | ||
644 | } MPT_ADAPTER; | 648 | } MPT_ADAPTER; |
645 | 649 | ||
646 | /* | 650 | /* |
@@ -892,6 +896,13 @@ typedef struct _mpt_sge { | |||
892 | #define DBG_DUMP_REQUEST_FRAME_HDR(mfp) | 896 | #define DBG_DUMP_REQUEST_FRAME_HDR(mfp) |
893 | #endif | 897 | #endif |
894 | 898 | ||
899 | // debug sas wide ports | ||
900 | #ifdef MPT_DEBUG_SAS_WIDE | ||
901 | #define dsaswideprintk(x) printk x | ||
902 | #else | ||
903 | #define dsaswideprintk(x) | ||
904 | #endif | ||
905 | |||
895 | 906 | ||
896 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 907 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
897 | 908 | ||
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 3ff8378ea660..a8f2fa985455 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -132,21 +132,21 @@ static struct scsi_host_template mptfc_driver_template = { | |||
132 | */ | 132 | */ |
133 | 133 | ||
134 | static struct pci_device_id mptfc_pci_table[] = { | 134 | static struct pci_device_id mptfc_pci_table[] = { |
135 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909, | 135 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909, |
136 | PCI_ANY_ID, PCI_ANY_ID }, | 136 | PCI_ANY_ID, PCI_ANY_ID }, |
137 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919, | 137 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919, |
138 | PCI_ANY_ID, PCI_ANY_ID }, | 138 | PCI_ANY_ID, PCI_ANY_ID }, |
139 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929, | 139 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929, |
140 | PCI_ANY_ID, PCI_ANY_ID }, | 140 | PCI_ANY_ID, PCI_ANY_ID }, |
141 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X, | 141 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X, |
142 | PCI_ANY_ID, PCI_ANY_ID }, | 142 | PCI_ANY_ID, PCI_ANY_ID }, |
143 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X, | 143 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X, |
144 | PCI_ANY_ID, PCI_ANY_ID }, | 144 | PCI_ANY_ID, PCI_ANY_ID }, |
145 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X, | 145 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X, |
146 | PCI_ANY_ID, PCI_ANY_ID }, | 146 | PCI_ANY_ID, PCI_ANY_ID }, |
147 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X, | 147 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X, |
148 | PCI_ANY_ID, PCI_ANY_ID }, | 148 | PCI_ANY_ID, PCI_ANY_ID }, |
149 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES, | 149 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E, |
150 | PCI_ANY_ID, PCI_ANY_ID }, | 150 | PCI_ANY_ID, PCI_ANY_ID }, |
151 | {0} /* Terminating entry */ | 151 | {0} /* Terminating entry */ |
152 | }; | 152 | }; |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 85689ab46cbc..f7bd8b11ed3b 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -50,11 +50,14 @@ | |||
50 | #include <linux/errno.h> | 50 | #include <linux/errno.h> |
51 | #include <linux/sched.h> | 51 | #include <linux/sched.h> |
52 | #include <linux/workqueue.h> | 52 | #include <linux/workqueue.h> |
53 | #include <linux/delay.h> /* for mdelay */ | ||
53 | 54 | ||
55 | #include <scsi/scsi.h> | ||
54 | #include <scsi/scsi_cmnd.h> | 56 | #include <scsi/scsi_cmnd.h> |
55 | #include <scsi/scsi_device.h> | 57 | #include <scsi/scsi_device.h> |
56 | #include <scsi/scsi_host.h> | 58 | #include <scsi/scsi_host.h> |
57 | #include <scsi/scsi_transport_sas.h> | 59 | #include <scsi/scsi_transport_sas.h> |
60 | #include <scsi/scsi_dbg.h> | ||
58 | 61 | ||
59 | #include "mptbase.h" | 62 | #include "mptbase.h" |
60 | #include "mptscsih.h" | 63 | #include "mptscsih.h" |
@@ -137,23 +140,37 @@ struct mptsas_devinfo { | |||
137 | u32 device_info; /* bitfield detailed info about this device */ | 140 | u32 device_info; /* bitfield detailed info about this device */ |
138 | }; | 141 | }; |
139 | 142 | ||
143 | /* | ||
144 | * Specific details on ports, wide/narrow | ||
145 | */ | ||
146 | struct mptsas_portinfo_details{ | ||
147 | u8 port_id; /* port number provided to transport */ | ||
148 | u16 num_phys; /* number of phys belong to this port */ | ||
149 | u64 phy_bitmask; /* TODO, extend support for 255 phys */ | ||
150 | struct sas_rphy *rphy; /* transport layer rphy object */ | ||
151 | struct sas_port *port; /* transport layer port object */ | ||
152 | struct scsi_target *starget; | ||
153 | struct mptsas_portinfo *port_info; | ||
154 | }; | ||
155 | |||
140 | struct mptsas_phyinfo { | 156 | struct mptsas_phyinfo { |
141 | u8 phy_id; /* phy index */ | 157 | u8 phy_id; /* phy index */ |
142 | u8 port_id; /* port number this phy is part of */ | 158 | u8 port_id; /* firmware port identifier */ |
143 | u8 negotiated_link_rate; /* nego'd link rate for this phy */ | 159 | u8 negotiated_link_rate; /* nego'd link rate for this phy */ |
144 | u8 hw_link_rate; /* hardware max/min phys link rate */ | 160 | u8 hw_link_rate; /* hardware max/min phys link rate */ |
145 | u8 programmed_link_rate; /* programmed max/min phy link rate */ | 161 | u8 programmed_link_rate; /* programmed max/min phy link rate */ |
162 | u8 sas_port_add_phy; /* flag to request sas_port_add_phy*/ | ||
146 | struct mptsas_devinfo identify; /* point to phy device info */ | 163 | struct mptsas_devinfo identify; /* point to phy device info */ |
147 | struct mptsas_devinfo attached; /* point to attached device info */ | 164 | struct mptsas_devinfo attached; /* point to attached device info */ |
148 | struct sas_phy *phy; | 165 | struct sas_phy *phy; /* transport layer phy object */ |
149 | struct sas_rphy *rphy; | 166 | struct mptsas_portinfo *portinfo; |
150 | struct scsi_target *starget; | 167 | struct mptsas_portinfo_details * port_details; |
151 | }; | 168 | }; |
152 | 169 | ||
153 | struct mptsas_portinfo { | 170 | struct mptsas_portinfo { |
154 | struct list_head list; | 171 | struct list_head list; |
155 | u16 handle; /* unique id to address this */ | 172 | u16 handle; /* unique id to address this */ |
156 | u8 num_phys; /* number of phys */ | 173 | u16 num_phys; /* number of phys */ |
157 | struct mptsas_phyinfo *phy_info; | 174 | struct mptsas_phyinfo *phy_info; |
158 | }; | 175 | }; |
159 | 176 | ||
@@ -169,7 +186,7 @@ struct mptsas_enclosure { | |||
169 | u8 sep_channel; /* SEP channel logical channel id */ | 186 | u8 sep_channel; /* SEP channel logical channel id */ |
170 | }; | 187 | }; |
171 | 188 | ||
172 | #ifdef SASDEBUG | 189 | #ifdef MPT_DEBUG_SAS |
173 | static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) | 190 | static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) |
174 | { | 191 | { |
175 | printk("---- IO UNIT PAGE 0 ------------\n"); | 192 | printk("---- IO UNIT PAGE 0 ------------\n"); |
@@ -305,7 +322,7 @@ mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle) | |||
305 | static inline int | 322 | static inline int |
306 | mptsas_is_end_device(struct mptsas_devinfo * attached) | 323 | mptsas_is_end_device(struct mptsas_devinfo * attached) |
307 | { | 324 | { |
308 | if ((attached->handle) && | 325 | if ((attached->sas_address) && |
309 | (attached->device_info & | 326 | (attached->device_info & |
310 | MPI_SAS_DEVICE_INFO_END_DEVICE) && | 327 | MPI_SAS_DEVICE_INFO_END_DEVICE) && |
311 | ((attached->device_info & | 328 | ((attached->device_info & |
@@ -319,6 +336,253 @@ mptsas_is_end_device(struct mptsas_devinfo * attached) | |||
319 | return 0; | 336 | return 0; |
320 | } | 337 | } |
321 | 338 | ||
339 | /* no mutex */ | ||
340 | static void | ||
341 | mptsas_port_delete(struct mptsas_portinfo_details * port_details) | ||
342 | { | ||
343 | struct mptsas_portinfo *port_info; | ||
344 | struct mptsas_phyinfo *phy_info; | ||
345 | u8 i; | ||
346 | |||
347 | if (!port_details) | ||
348 | return; | ||
349 | |||
350 | port_info = port_details->port_info; | ||
351 | phy_info = port_info->phy_info; | ||
352 | |||
353 | dsaswideprintk((KERN_DEBUG "%s: [%p]: port=%02d num_phys=%02d " | ||
354 | "bitmask=0x%016llX\n", | ||
355 | __FUNCTION__, port_details, port_details->port_id, | ||
356 | port_details->num_phys, port_details->phy_bitmask)); | ||
357 | |||
358 | for (i = 0; i < port_info->num_phys; i++, phy_info++) { | ||
359 | if(phy_info->port_details != port_details) | ||
360 | continue; | ||
361 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); | ||
362 | phy_info->port_details = NULL; | ||
363 | } | ||
364 | kfree(port_details); | ||
365 | } | ||
366 | |||
367 | static inline struct sas_rphy * | ||
368 | mptsas_get_rphy(struct mptsas_phyinfo *phy_info) | ||
369 | { | ||
370 | if (phy_info->port_details) | ||
371 | return phy_info->port_details->rphy; | ||
372 | else | ||
373 | return NULL; | ||
374 | } | ||
375 | |||
376 | static inline void | ||
377 | mptsas_set_rphy(struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy) | ||
378 | { | ||
379 | if (phy_info->port_details) { | ||
380 | phy_info->port_details->rphy = rphy; | ||
381 | dsaswideprintk((KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy)); | ||
382 | } | ||
383 | |||
384 | #ifdef MPT_DEBUG_SAS_WIDE | ||
385 | if (rphy) { | ||
386 | dev_printk(KERN_DEBUG, &rphy->dev, "add:"); | ||
387 | printk("rphy=%p release=%p\n", | ||
388 | rphy, rphy->dev.release); | ||
389 | } | ||
390 | #endif | ||
391 | } | ||
392 | |||
393 | static inline struct sas_port * | ||
394 | mptsas_get_port(struct mptsas_phyinfo *phy_info) | ||
395 | { | ||
396 | if (phy_info->port_details) | ||
397 | return phy_info->port_details->port; | ||
398 | else | ||
399 | return NULL; | ||
400 | } | ||
401 | |||
402 | static inline void | ||
403 | mptsas_set_port(struct mptsas_phyinfo *phy_info, struct sas_port *port) | ||
404 | { | ||
405 | if (phy_info->port_details) | ||
406 | phy_info->port_details->port = port; | ||
407 | |||
408 | #ifdef MPT_DEBUG_SAS_WIDE | ||
409 | if (port) { | ||
410 | dev_printk(KERN_DEBUG, &port->dev, "add: "); | ||
411 | printk("port=%p release=%p\n", | ||
412 | port, port->dev.release); | ||
413 | } | ||
414 | #endif | ||
415 | } | ||
416 | |||
417 | static inline struct scsi_target * | ||
418 | mptsas_get_starget(struct mptsas_phyinfo *phy_info) | ||
419 | { | ||
420 | if (phy_info->port_details) | ||
421 | return phy_info->port_details->starget; | ||
422 | else | ||
423 | return NULL; | ||
424 | } | ||
425 | |||
426 | static inline void | ||
427 | mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target * | ||
428 | starget) | ||
429 | { | ||
430 | if (phy_info->port_details) | ||
431 | phy_info->port_details->starget = starget; | ||
432 | } | ||
433 | |||
434 | |||
435 | /* | ||
436 | * mptsas_setup_wide_ports | ||
437 | * | ||
438 | * Updates for new and existing narrow/wide port configuration | ||
439 | * in the sas_topology | ||
440 | */ | ||
441 | static void | ||
442 | mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | ||
443 | { | ||
444 | struct mptsas_portinfo_details * port_details; | ||
445 | struct mptsas_phyinfo *phy_info, *phy_info_cmp; | ||
446 | u64 sas_address; | ||
447 | int i, j; | ||
448 | |||
449 | mutex_lock(&ioc->sas_topology_mutex); | ||
450 | |||
451 | phy_info = port_info->phy_info; | ||
452 | for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) { | ||
453 | if (phy_info->attached.handle) | ||
454 | continue; | ||
455 | port_details = phy_info->port_details; | ||
456 | if (!port_details) | ||
457 | continue; | ||
458 | if (port_details->num_phys < 2) | ||
459 | continue; | ||
460 | /* | ||
461 | * Removing a phy from a port, letting the last | ||
462 | * phy be removed by firmware events. | ||
463 | */ | ||
464 | dsaswideprintk((KERN_DEBUG | ||
465 | "%s: [%p]: port=%d deleting phy = %d\n", | ||
466 | __FUNCTION__, port_details, | ||
467 | port_details->port_id, i)); | ||
468 | port_details->num_phys--; | ||
469 | port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); | ||
470 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); | ||
471 | sas_port_delete_phy(port_details->port, phy_info->phy); | ||
472 | phy_info->port_details = NULL; | ||
473 | } | ||
474 | |||
475 | /* | ||
476 | * Populate and refresh the tree | ||
477 | */ | ||
478 | phy_info = port_info->phy_info; | ||
479 | for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) { | ||
480 | sas_address = phy_info->attached.sas_address; | ||
481 | dsaswideprintk((KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n", | ||
482 | i, sas_address)); | ||
483 | if (!sas_address) | ||
484 | continue; | ||
485 | port_details = phy_info->port_details; | ||
486 | /* | ||
487 | * Forming a port | ||
488 | */ | ||
489 | if (!port_details) { | ||
490 | port_details = kzalloc(sizeof(*port_details), | ||
491 | GFP_KERNEL); | ||
492 | if (!port_details) | ||
493 | goto out; | ||
494 | port_details->num_phys = 1; | ||
495 | port_details->port_info = port_info; | ||
496 | port_details->port_id = ioc->port_serial_number++; | ||
497 | if (phy_info->phy_id < 64 ) | ||
498 | port_details->phy_bitmask |= | ||
499 | (1 << phy_info->phy_id); | ||
500 | phy_info->sas_port_add_phy=1; | ||
501 | dsaswideprintk((KERN_DEBUG "\t\tForming port\n\t\t" | ||
502 | "phy_id=%d sas_address=0x%018llX\n", | ||
503 | i, sas_address)); | ||
504 | phy_info->port_details = port_details; | ||
505 | } | ||
506 | |||
507 | if (i == port_info->num_phys - 1) | ||
508 | continue; | ||
509 | phy_info_cmp = &port_info->phy_info[i + 1]; | ||
510 | for (j = i + 1 ; j < port_info->num_phys ; j++, | ||
511 | phy_info_cmp++) { | ||
512 | if (!phy_info_cmp->attached.sas_address) | ||
513 | continue; | ||
514 | if (sas_address != phy_info_cmp->attached.sas_address) | ||
515 | continue; | ||
516 | if (phy_info_cmp->port_details == port_details ) | ||
517 | continue; | ||
518 | dsaswideprintk((KERN_DEBUG | ||
519 | "\t\tphy_id=%d sas_address=0x%018llX\n", | ||
520 | j, phy_info_cmp->attached.sas_address)); | ||
521 | if (phy_info_cmp->port_details) { | ||
522 | port_details->rphy = | ||
523 | mptsas_get_rphy(phy_info_cmp); | ||
524 | port_details->port = | ||
525 | mptsas_get_port(phy_info_cmp); | ||
526 | port_details->starget = | ||
527 | mptsas_get_starget(phy_info_cmp); | ||
528 | port_details->port_id = | ||
529 | phy_info_cmp->port_details->port_id; | ||
530 | port_details->num_phys = | ||
531 | phy_info_cmp->port_details->num_phys; | ||
532 | // port_info->port_serial_number--; | ||
533 | ioc->port_serial_number--; | ||
534 | if (!phy_info_cmp->port_details->num_phys) | ||
535 | kfree(phy_info_cmp->port_details); | ||
536 | } else | ||
537 | phy_info_cmp->sas_port_add_phy=1; | ||
538 | /* | ||
539 | * Adding a phy to a port | ||
540 | */ | ||
541 | phy_info_cmp->port_details = port_details; | ||
542 | if (phy_info_cmp->phy_id < 64 ) | ||
543 | port_details->phy_bitmask |= | ||
544 | (1 << phy_info_cmp->phy_id); | ||
545 | port_details->num_phys++; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | out: | ||
550 | |||
551 | #ifdef MPT_DEBUG_SAS_WIDE | ||
552 | for (i = 0; i < port_info->num_phys; i++) { | ||
553 | port_details = port_info->phy_info[i].port_details; | ||
554 | if (!port_details) | ||
555 | continue; | ||
556 | dsaswideprintk((KERN_DEBUG | ||
557 | "%s: [%p]: phy_id=%02d port_id=%02d num_phys=%02d " | ||
558 | "bitmask=0x%016llX\n", | ||
559 | __FUNCTION__, | ||
560 | port_details, i, port_details->port_id, | ||
561 | port_details->num_phys, port_details->phy_bitmask)); | ||
562 | dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n", | ||
563 | port_details->port, port_details->rphy)); | ||
564 | } | ||
565 | dsaswideprintk((KERN_DEBUG"\n")); | ||
566 | #endif | ||
567 | mutex_unlock(&ioc->sas_topology_mutex); | ||
568 | } | ||
569 | |||
570 | static void | ||
571 | mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget) | ||
572 | { | ||
573 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; | ||
574 | |||
575 | if (mptscsih_TMHandler(hd, | ||
576 | MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | ||
577 | vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) { | ||
578 | hd->tmPending = 0; | ||
579 | hd->tmState = TM_STATE_NONE; | ||
580 | printk(MYIOC_s_WARN_FMT | ||
581 | "Error processing TaskMgmt id=%d TARGET_RESET\n", | ||
582 | ioc->name, vtarget->target_id); | ||
583 | } | ||
584 | } | ||
585 | |||
322 | static int | 586 | static int |
323 | mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, | 587 | mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, |
324 | u32 form, u32 form_specific) | 588 | u32 form, u32 form_specific) |
@@ -400,11 +664,105 @@ mptsas_slave_configure(struct scsi_device *sdev) | |||
400 | return mptscsih_slave_configure(sdev); | 664 | return mptscsih_slave_configure(sdev); |
401 | } | 665 | } |
402 | 666 | ||
403 | /* | 667 | static int |
404 | * This is pretty ugly. We will be able to seriously clean it up | 668 | mptsas_target_alloc(struct scsi_target *starget) |
405 | * once the DV code in mptscsih goes away and we can properly | 669 | { |
406 | * implement ->target_alloc. | 670 | struct Scsi_Host *host = dev_to_shost(&starget->dev); |
407 | */ | 671 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
672 | VirtTarget *vtarget; | ||
673 | u32 target_id; | ||
674 | u32 channel; | ||
675 | struct sas_rphy *rphy; | ||
676 | struct mptsas_portinfo *p; | ||
677 | int i; | ||
678 | |||
679 | vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); | ||
680 | if (!vtarget) | ||
681 | return -ENOMEM; | ||
682 | |||
683 | vtarget->starget = starget; | ||
684 | vtarget->ioc_id = hd->ioc->id; | ||
685 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
686 | |||
687 | target_id = starget->id; | ||
688 | channel = 0; | ||
689 | |||
690 | hd->Targets[target_id] = vtarget; | ||
691 | |||
692 | /* | ||
693 | * RAID volumes placed beyond the last expected port. | ||
694 | */ | ||
695 | if (starget->channel == hd->ioc->num_ports) | ||
696 | goto out; | ||
697 | |||
698 | rphy = dev_to_rphy(starget->dev.parent); | ||
699 | mutex_lock(&hd->ioc->sas_topology_mutex); | ||
700 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { | ||
701 | for (i = 0; i < p->num_phys; i++) { | ||
702 | if (p->phy_info[i].attached.sas_address != | ||
703 | rphy->identify.sas_address) | ||
704 | continue; | ||
705 | target_id = p->phy_info[i].attached.id; | ||
706 | channel = p->phy_info[i].attached.channel; | ||
707 | mptsas_set_starget(&p->phy_info[i], starget); | ||
708 | |||
709 | /* | ||
710 | * Exposing hidden raid components | ||
711 | */ | ||
712 | if (mptscsih_is_phys_disk(hd->ioc, target_id)) { | ||
713 | target_id = mptscsih_raid_id_to_num(hd, | ||
714 | target_id); | ||
715 | vtarget->tflags |= | ||
716 | MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
717 | } | ||
718 | mutex_unlock(&hd->ioc->sas_topology_mutex); | ||
719 | goto out; | ||
720 | } | ||
721 | } | ||
722 | mutex_unlock(&hd->ioc->sas_topology_mutex); | ||
723 | |||
724 | kfree(vtarget); | ||
725 | return -ENXIO; | ||
726 | |||
727 | out: | ||
728 | vtarget->target_id = target_id; | ||
729 | vtarget->bus_id = channel; | ||
730 | starget->hostdata = vtarget; | ||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static void | ||
735 | mptsas_target_destroy(struct scsi_target *starget) | ||
736 | { | ||
737 | struct Scsi_Host *host = dev_to_shost(&starget->dev); | ||
738 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
739 | struct sas_rphy *rphy; | ||
740 | struct mptsas_portinfo *p; | ||
741 | int i; | ||
742 | |||
743 | if (!starget->hostdata) | ||
744 | return; | ||
745 | |||
746 | if (starget->channel == hd->ioc->num_ports) | ||
747 | goto out; | ||
748 | |||
749 | rphy = dev_to_rphy(starget->dev.parent); | ||
750 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { | ||
751 | for (i = 0; i < p->num_phys; i++) { | ||
752 | if (p->phy_info[i].attached.sas_address != | ||
753 | rphy->identify.sas_address) | ||
754 | continue; | ||
755 | mptsas_set_starget(&p->phy_info[i], NULL); | ||
756 | goto out; | ||
757 | } | ||
758 | } | ||
759 | |||
760 | out: | ||
761 | kfree(starget->hostdata); | ||
762 | starget->hostdata = NULL; | ||
763 | } | ||
764 | |||
765 | |||
408 | static int | 766 | static int |
409 | mptsas_slave_alloc(struct scsi_device *sdev) | 767 | mptsas_slave_alloc(struct scsi_device *sdev) |
410 | { | 768 | { |
@@ -412,61 +770,41 @@ mptsas_slave_alloc(struct scsi_device *sdev) | |||
412 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 770 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
413 | struct sas_rphy *rphy; | 771 | struct sas_rphy *rphy; |
414 | struct mptsas_portinfo *p; | 772 | struct mptsas_portinfo *p; |
415 | VirtTarget *vtarget; | ||
416 | VirtDevice *vdev; | 773 | VirtDevice *vdev; |
417 | struct scsi_target *starget; | 774 | struct scsi_target *starget; |
418 | u32 target_id; | 775 | int i; |
419 | int i; | ||
420 | 776 | ||
421 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); | 777 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); |
422 | if (!vdev) { | 778 | if (!vdev) { |
423 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | 779 | printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n", |
424 | hd->ioc->name, sizeof(VirtDevice)); | 780 | hd->ioc->name, sizeof(VirtDevice)); |
425 | return -ENOMEM; | 781 | return -ENOMEM; |
426 | } | 782 | } |
427 | sdev->hostdata = vdev; | ||
428 | starget = scsi_target(sdev); | 783 | starget = scsi_target(sdev); |
429 | vtarget = starget->hostdata; | 784 | vdev->vtarget = starget->hostdata; |
430 | vtarget->ioc_id = hd->ioc->id; | ||
431 | vdev->vtarget = vtarget; | ||
432 | if (vtarget->num_luns == 0) { | ||
433 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
434 | hd->Targets[sdev->id] = vtarget; | ||
435 | } | ||
436 | 785 | ||
437 | /* | 786 | /* |
438 | RAID volumes placed beyond the last expected port. | 787 | * RAID volumes placed beyond the last expected port. |
439 | */ | 788 | */ |
440 | if (sdev->channel == hd->ioc->num_ports) { | 789 | if (sdev->channel == hd->ioc->num_ports) |
441 | target_id = sdev->id; | ||
442 | vtarget->bus_id = 0; | ||
443 | vdev->lun = 0; | ||
444 | goto out; | 790 | goto out; |
445 | } | ||
446 | 791 | ||
447 | rphy = dev_to_rphy(sdev->sdev_target->dev.parent); | 792 | rphy = dev_to_rphy(sdev->sdev_target->dev.parent); |
448 | mutex_lock(&hd->ioc->sas_topology_mutex); | 793 | mutex_lock(&hd->ioc->sas_topology_mutex); |
449 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { | 794 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { |
450 | for (i = 0; i < p->num_phys; i++) { | 795 | for (i = 0; i < p->num_phys; i++) { |
451 | if (p->phy_info[i].attached.sas_address == | 796 | if (p->phy_info[i].attached.sas_address != |
452 | rphy->identify.sas_address) { | 797 | rphy->identify.sas_address) |
453 | target_id = p->phy_info[i].attached.id; | 798 | continue; |
454 | vtarget->bus_id = p->phy_info[i].attached.channel; | 799 | vdev->lun = sdev->lun; |
455 | vdev->lun = sdev->lun; | 800 | /* |
456 | p->phy_info[i].starget = sdev->sdev_target; | 801 | * Exposing hidden raid components |
457 | /* | 802 | */ |
458 | * Exposing hidden disk (RAID) | 803 | if (mptscsih_is_phys_disk(hd->ioc, |
459 | */ | 804 | p->phy_info[i].attached.id)) |
460 | if (mptscsih_is_phys_disk(hd->ioc, target_id)) { | 805 | sdev->no_uld_attach = 1; |
461 | target_id = mptscsih_raid_id_to_num(hd, | 806 | mutex_unlock(&hd->ioc->sas_topology_mutex); |
462 | target_id); | 807 | goto out; |
463 | vdev->vtarget->tflags |= | ||
464 | MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
465 | sdev->no_uld_attach = 1; | ||
466 | } | ||
467 | mutex_unlock(&hd->ioc->sas_topology_mutex); | ||
468 | goto out; | ||
469 | } | ||
470 | } | 808 | } |
471 | } | 809 | } |
472 | mutex_unlock(&hd->ioc->sas_topology_mutex); | 810 | mutex_unlock(&hd->ioc->sas_topology_mutex); |
@@ -475,57 +813,39 @@ mptsas_slave_alloc(struct scsi_device *sdev) | |||
475 | return -ENXIO; | 813 | return -ENXIO; |
476 | 814 | ||
477 | out: | 815 | out: |
478 | vtarget->target_id = target_id; | 816 | vdev->vtarget->num_luns++; |
479 | vtarget->num_luns++; | 817 | sdev->hostdata = vdev; |
480 | return 0; | 818 | return 0; |
481 | } | 819 | } |
482 | 820 | ||
483 | static void | 821 | static int |
484 | mptsas_slave_destroy(struct scsi_device *sdev) | 822 | mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) |
485 | { | 823 | { |
486 | struct Scsi_Host *host = sdev->host; | 824 | VirtDevice *vdev = SCpnt->device->hostdata; |
487 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
488 | VirtDevice *vdev; | ||
489 | 825 | ||
490 | /* | 826 | // scsi_print_command(SCpnt); |
491 | * Issue target reset to flush firmware outstanding commands. | 827 | if (vdev->vtarget->deleted) { |
492 | */ | 828 | SCpnt->result = DID_NO_CONNECT << 16; |
493 | vdev = sdev->hostdata; | 829 | done(SCpnt); |
494 | if (vdev->configured_lun){ | 830 | return 0; |
495 | if (mptscsih_TMHandler(hd, | ||
496 | MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | ||
497 | vdev->vtarget->bus_id, | ||
498 | vdev->vtarget->target_id, | ||
499 | 0, 0, 5 /* 5 second timeout */) | ||
500 | < 0){ | ||
501 | |||
502 | /* The TM request failed! | ||
503 | * Fatal error case. | ||
504 | */ | ||
505 | printk(MYIOC_s_WARN_FMT | ||
506 | "Error processing TaskMgmt id=%d TARGET_RESET\n", | ||
507 | hd->ioc->name, | ||
508 | vdev->vtarget->target_id); | ||
509 | |||
510 | hd->tmPending = 0; | ||
511 | hd->tmState = TM_STATE_NONE; | ||
512 | } | ||
513 | } | 831 | } |
514 | mptscsih_slave_destroy(sdev); | 832 | |
833 | return mptscsih_qcmd(SCpnt,done); | ||
515 | } | 834 | } |
516 | 835 | ||
836 | |||
517 | static struct scsi_host_template mptsas_driver_template = { | 837 | static struct scsi_host_template mptsas_driver_template = { |
518 | .module = THIS_MODULE, | 838 | .module = THIS_MODULE, |
519 | .proc_name = "mptsas", | 839 | .proc_name = "mptsas", |
520 | .proc_info = mptscsih_proc_info, | 840 | .proc_info = mptscsih_proc_info, |
521 | .name = "MPT SPI Host", | 841 | .name = "MPT SPI Host", |
522 | .info = mptscsih_info, | 842 | .info = mptscsih_info, |
523 | .queuecommand = mptscsih_qcmd, | 843 | .queuecommand = mptsas_qcmd, |
524 | .target_alloc = mptscsih_target_alloc, | 844 | .target_alloc = mptsas_target_alloc, |
525 | .slave_alloc = mptsas_slave_alloc, | 845 | .slave_alloc = mptsas_slave_alloc, |
526 | .slave_configure = mptsas_slave_configure, | 846 | .slave_configure = mptsas_slave_configure, |
527 | .target_destroy = mptscsih_target_destroy, | 847 | .target_destroy = mptsas_target_destroy, |
528 | .slave_destroy = mptsas_slave_destroy, | 848 | .slave_destroy = mptscsih_slave_destroy, |
529 | .change_queue_depth = mptscsih_change_queue_depth, | 849 | .change_queue_depth = mptscsih_change_queue_depth, |
530 | .eh_abort_handler = mptscsih_abort, | 850 | .eh_abort_handler = mptscsih_abort, |
531 | .eh_device_reset_handler = mptscsih_dev_reset, | 851 | .eh_device_reset_handler = mptscsih_dev_reset, |
@@ -795,7 +1115,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
795 | 1115 | ||
796 | port_info->num_phys = buffer->NumPhys; | 1116 | port_info->num_phys = buffer->NumPhys; |
797 | port_info->phy_info = kcalloc(port_info->num_phys, | 1117 | port_info->phy_info = kcalloc(port_info->num_phys, |
798 | sizeof(struct mptsas_phyinfo),GFP_KERNEL); | 1118 | sizeof(*port_info->phy_info),GFP_KERNEL); |
799 | if (!port_info->phy_info) { | 1119 | if (!port_info->phy_info) { |
800 | error = -ENOMEM; | 1120 | error = -ENOMEM; |
801 | goto out_free_consistent; | 1121 | goto out_free_consistent; |
@@ -811,6 +1131,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
811 | buffer->PhyData[i].Port; | 1131 | buffer->PhyData[i].Port; |
812 | port_info->phy_info[i].negotiated_link_rate = | 1132 | port_info->phy_info[i].negotiated_link_rate = |
813 | buffer->PhyData[i].NegotiatedLinkRate; | 1133 | buffer->PhyData[i].NegotiatedLinkRate; |
1134 | port_info->phy_info[i].portinfo = port_info; | ||
814 | } | 1135 | } |
815 | 1136 | ||
816 | out_free_consistent: | 1137 | out_free_consistent: |
@@ -968,7 +1289,7 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, | |||
968 | CONFIGPARMS cfg; | 1289 | CONFIGPARMS cfg; |
969 | SasExpanderPage0_t *buffer; | 1290 | SasExpanderPage0_t *buffer; |
970 | dma_addr_t dma_handle; | 1291 | dma_addr_t dma_handle; |
971 | int error; | 1292 | int i, error; |
972 | 1293 | ||
973 | hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; | 1294 | hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; |
974 | hdr.ExtPageLength = 0; | 1295 | hdr.ExtPageLength = 0; |
@@ -1013,12 +1334,15 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, | |||
1013 | port_info->num_phys = buffer->NumPhys; | 1334 | port_info->num_phys = buffer->NumPhys; |
1014 | port_info->handle = le16_to_cpu(buffer->DevHandle); | 1335 | port_info->handle = le16_to_cpu(buffer->DevHandle); |
1015 | port_info->phy_info = kcalloc(port_info->num_phys, | 1336 | port_info->phy_info = kcalloc(port_info->num_phys, |
1016 | sizeof(struct mptsas_phyinfo),GFP_KERNEL); | 1337 | sizeof(*port_info->phy_info),GFP_KERNEL); |
1017 | if (!port_info->phy_info) { | 1338 | if (!port_info->phy_info) { |
1018 | error = -ENOMEM; | 1339 | error = -ENOMEM; |
1019 | goto out_free_consistent; | 1340 | goto out_free_consistent; |
1020 | } | 1341 | } |
1021 | 1342 | ||
1343 | for (i = 0; i < port_info->num_phys; i++) | ||
1344 | port_info->phy_info[i].portinfo = port_info; | ||
1345 | |||
1022 | out_free_consistent: | 1346 | out_free_consistent: |
1023 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, | 1347 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, |
1024 | buffer, dma_handle); | 1348 | buffer, dma_handle); |
@@ -1161,19 +1485,23 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
1161 | { | 1485 | { |
1162 | MPT_ADAPTER *ioc; | 1486 | MPT_ADAPTER *ioc; |
1163 | struct sas_phy *phy; | 1487 | struct sas_phy *phy; |
1164 | int error; | 1488 | struct sas_port *port; |
1489 | int error = 0; | ||
1165 | 1490 | ||
1166 | if (!dev) | 1491 | if (!dev) { |
1167 | return -ENODEV; | 1492 | error = -ENODEV; |
1493 | goto out; | ||
1494 | } | ||
1168 | 1495 | ||
1169 | if (!phy_info->phy) { | 1496 | if (!phy_info->phy) { |
1170 | phy = sas_phy_alloc(dev, index); | 1497 | phy = sas_phy_alloc(dev, index); |
1171 | if (!phy) | 1498 | if (!phy) { |
1172 | return -ENOMEM; | 1499 | error = -ENOMEM; |
1500 | goto out; | ||
1501 | } | ||
1173 | } else | 1502 | } else |
1174 | phy = phy_info->phy; | 1503 | phy = phy_info->phy; |
1175 | 1504 | ||
1176 | phy->port_identifier = phy_info->port_id; | ||
1177 | mptsas_parse_device_info(&phy->identify, &phy_info->identify); | 1505 | mptsas_parse_device_info(&phy->identify, &phy_info->identify); |
1178 | 1506 | ||
1179 | /* | 1507 | /* |
@@ -1265,19 +1593,52 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
1265 | error = sas_phy_add(phy); | 1593 | error = sas_phy_add(phy); |
1266 | if (error) { | 1594 | if (error) { |
1267 | sas_phy_free(phy); | 1595 | sas_phy_free(phy); |
1268 | return error; | 1596 | goto out; |
1269 | } | 1597 | } |
1270 | phy_info->phy = phy; | 1598 | phy_info->phy = phy; |
1271 | } | 1599 | } |
1272 | 1600 | ||
1273 | if ((phy_info->attached.handle) && | 1601 | if (!phy_info->attached.handle || |
1274 | (!phy_info->rphy)) { | 1602 | !phy_info->port_details) |
1603 | goto out; | ||
1604 | |||
1605 | port = mptsas_get_port(phy_info); | ||
1606 | ioc = phy_to_ioc(phy_info->phy); | ||
1607 | |||
1608 | if (phy_info->sas_port_add_phy) { | ||
1609 | |||
1610 | if (!port) { | ||
1611 | port = sas_port_alloc(dev, | ||
1612 | phy_info->port_details->port_id); | ||
1613 | dsaswideprintk((KERN_DEBUG | ||
1614 | "sas_port_alloc: port=%p dev=%p port_id=%d\n", | ||
1615 | port, dev, phy_info->port_details->port_id)); | ||
1616 | if (!port) { | ||
1617 | error = -ENOMEM; | ||
1618 | goto out; | ||
1619 | } | ||
1620 | error = sas_port_add(port); | ||
1621 | if (error) { | ||
1622 | dfailprintk((MYIOC_s_ERR_FMT | ||
1623 | "%s: exit at line=%d\n", ioc->name, | ||
1624 | __FUNCTION__, __LINE__)); | ||
1625 | goto out; | ||
1626 | } | ||
1627 | mptsas_set_port(phy_info, port); | ||
1628 | } | ||
1629 | dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n", | ||
1630 | phy_info->phy_id)); | ||
1631 | sas_port_add_phy(port, phy_info->phy); | ||
1632 | phy_info->sas_port_add_phy = 0; | ||
1633 | } | ||
1634 | |||
1635 | if (!mptsas_get_rphy(phy_info) && port && !port->rphy) { | ||
1275 | 1636 | ||
1276 | struct sas_rphy *rphy; | 1637 | struct sas_rphy *rphy; |
1638 | struct device *parent; | ||
1277 | struct sas_identify identify; | 1639 | struct sas_identify identify; |
1278 | 1640 | ||
1279 | ioc = phy_to_ioc(phy_info->phy); | 1641 | parent = dev->parent->parent; |
1280 | |||
1281 | /* | 1642 | /* |
1282 | * Let the hotplug_work thread handle processing | 1643 | * Let the hotplug_work thread handle processing |
1283 | * the adding/removing of devices that occur | 1644 | * the adding/removing of devices that occur |
@@ -1285,36 +1646,63 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
1285 | */ | 1646 | */ |
1286 | if (ioc->sas_discovery_runtime && | 1647 | if (ioc->sas_discovery_runtime && |
1287 | mptsas_is_end_device(&phy_info->attached)) | 1648 | mptsas_is_end_device(&phy_info->attached)) |
1288 | return 0; | 1649 | goto out; |
1289 | 1650 | ||
1290 | mptsas_parse_device_info(&identify, &phy_info->attached); | 1651 | mptsas_parse_device_info(&identify, &phy_info->attached); |
1652 | if (scsi_is_host_device(parent)) { | ||
1653 | struct mptsas_portinfo *port_info; | ||
1654 | int i; | ||
1655 | |||
1656 | mutex_lock(&ioc->sas_topology_mutex); | ||
1657 | port_info = mptsas_find_portinfo_by_handle(ioc, | ||
1658 | ioc->handle); | ||
1659 | mutex_unlock(&ioc->sas_topology_mutex); | ||
1660 | |||
1661 | for (i = 0; i < port_info->num_phys; i++) | ||
1662 | if (port_info->phy_info[i].identify.sas_address == | ||
1663 | identify.sas_address) | ||
1664 | goto out; | ||
1665 | |||
1666 | } else if (scsi_is_sas_rphy(parent)) { | ||
1667 | struct sas_rphy *parent_rphy = dev_to_rphy(parent); | ||
1668 | if (identify.sas_address == | ||
1669 | parent_rphy->identify.sas_address) | ||
1670 | goto out; | ||
1671 | } | ||
1672 | |||
1291 | switch (identify.device_type) { | 1673 | switch (identify.device_type) { |
1292 | case SAS_END_DEVICE: | 1674 | case SAS_END_DEVICE: |
1293 | rphy = sas_end_device_alloc(phy); | 1675 | rphy = sas_end_device_alloc(port); |
1294 | break; | 1676 | break; |
1295 | case SAS_EDGE_EXPANDER_DEVICE: | 1677 | case SAS_EDGE_EXPANDER_DEVICE: |
1296 | case SAS_FANOUT_EXPANDER_DEVICE: | 1678 | case SAS_FANOUT_EXPANDER_DEVICE: |
1297 | rphy = sas_expander_alloc(phy, identify.device_type); | 1679 | rphy = sas_expander_alloc(port, identify.device_type); |
1298 | break; | 1680 | break; |
1299 | default: | 1681 | default: |
1300 | rphy = NULL; | 1682 | rphy = NULL; |
1301 | break; | 1683 | break; |
1302 | } | 1684 | } |
1303 | if (!rphy) | 1685 | if (!rphy) { |
1304 | return 0; /* non-fatal: an rphy can be added later */ | 1686 | dfailprintk((MYIOC_s_ERR_FMT |
1687 | "%s: exit at line=%d\n", ioc->name, | ||
1688 | __FUNCTION__, __LINE__)); | ||
1689 | goto out; | ||
1690 | } | ||
1305 | 1691 | ||
1306 | rphy->identify = identify; | 1692 | rphy->identify = identify; |
1307 | |||
1308 | error = sas_rphy_add(rphy); | 1693 | error = sas_rphy_add(rphy); |
1309 | if (error) { | 1694 | if (error) { |
1695 | dfailprintk((MYIOC_s_ERR_FMT | ||
1696 | "%s: exit at line=%d\n", ioc->name, | ||
1697 | __FUNCTION__, __LINE__)); | ||
1310 | sas_rphy_free(rphy); | 1698 | sas_rphy_free(rphy); |
1311 | return error; | 1699 | goto out; |
1312 | } | 1700 | } |
1313 | 1701 | mptsas_set_rphy(phy_info, rphy); | |
1314 | phy_info->rphy = rphy; | ||
1315 | } | 1702 | } |
1316 | 1703 | ||
1317 | return 0; | 1704 | out: |
1705 | return error; | ||
1318 | } | 1706 | } |
1319 | 1707 | ||
1320 | static int | 1708 | static int |
@@ -1333,6 +1721,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1333 | goto out_free_port_info; | 1721 | goto out_free_port_info; |
1334 | 1722 | ||
1335 | mutex_lock(&ioc->sas_topology_mutex); | 1723 | mutex_lock(&ioc->sas_topology_mutex); |
1724 | ioc->handle = hba->handle; | ||
1336 | port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle); | 1725 | port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle); |
1337 | if (!port_info) { | 1726 | if (!port_info) { |
1338 | port_info = hba; | 1727 | port_info = hba; |
@@ -1342,8 +1731,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1342 | for (i = 0; i < hba->num_phys; i++) | 1731 | for (i = 0; i < hba->num_phys; i++) |
1343 | port_info->phy_info[i].negotiated_link_rate = | 1732 | port_info->phy_info[i].negotiated_link_rate = |
1344 | hba->phy_info[i].negotiated_link_rate; | 1733 | hba->phy_info[i].negotiated_link_rate; |
1345 | if (hba->phy_info) | 1734 | kfree(hba->phy_info); |
1346 | kfree(hba->phy_info); | ||
1347 | kfree(hba); | 1735 | kfree(hba); |
1348 | hba = NULL; | 1736 | hba = NULL; |
1349 | } | 1737 | } |
@@ -1362,18 +1750,19 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1362 | port_info->phy_info[i].phy_id; | 1750 | port_info->phy_info[i].phy_id; |
1363 | handle = port_info->phy_info[i].identify.handle; | 1751 | handle = port_info->phy_info[i].identify.handle; |
1364 | 1752 | ||
1365 | if (port_info->phy_info[i].attached.handle) { | 1753 | if (port_info->phy_info[i].attached.handle) |
1366 | mptsas_sas_device_pg0(ioc, | 1754 | mptsas_sas_device_pg0(ioc, |
1367 | &port_info->phy_info[i].attached, | 1755 | &port_info->phy_info[i].attached, |
1368 | (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << | 1756 | (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << |
1369 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), | 1757 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), |
1370 | port_info->phy_info[i].attached.handle); | 1758 | port_info->phy_info[i].attached.handle); |
1371 | } | 1759 | } |
1760 | |||
1761 | mptsas_setup_wide_ports(ioc, port_info); | ||
1372 | 1762 | ||
1763 | for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++) | ||
1373 | mptsas_probe_one_phy(&ioc->sh->shost_gendev, | 1764 | mptsas_probe_one_phy(&ioc->sh->shost_gendev, |
1374 | &port_info->phy_info[i], ioc->sas_index, 1); | 1765 | &port_info->phy_info[i], ioc->sas_index, 1); |
1375 | ioc->sas_index++; | ||
1376 | } | ||
1377 | 1766 | ||
1378 | return 0; | 1767 | return 0; |
1379 | 1768 | ||
@@ -1387,6 +1776,8 @@ static int | |||
1387 | mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) | 1776 | mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) |
1388 | { | 1777 | { |
1389 | struct mptsas_portinfo *port_info, *p, *ex; | 1778 | struct mptsas_portinfo *port_info, *p, *ex; |
1779 | struct device *parent; | ||
1780 | struct sas_rphy *rphy; | ||
1390 | int error = -ENOMEM, i, j; | 1781 | int error = -ENOMEM, i, j; |
1391 | 1782 | ||
1392 | ex = kzalloc(sizeof(*port_info), GFP_KERNEL); | 1783 | ex = kzalloc(sizeof(*port_info), GFP_KERNEL); |
@@ -1408,16 +1799,13 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) | |||
1408 | list_add_tail(&port_info->list, &ioc->sas_topology); | 1799 | list_add_tail(&port_info->list, &ioc->sas_topology); |
1409 | } else { | 1800 | } else { |
1410 | port_info->handle = ex->handle; | 1801 | port_info->handle = ex->handle; |
1411 | if (ex->phy_info) | 1802 | kfree(ex->phy_info); |
1412 | kfree(ex->phy_info); | ||
1413 | kfree(ex); | 1803 | kfree(ex); |
1414 | ex = NULL; | 1804 | ex = NULL; |
1415 | } | 1805 | } |
1416 | mutex_unlock(&ioc->sas_topology_mutex); | 1806 | mutex_unlock(&ioc->sas_topology_mutex); |
1417 | 1807 | ||
1418 | for (i = 0; i < port_info->num_phys; i++) { | 1808 | for (i = 0; i < port_info->num_phys; i++) { |
1419 | struct device *parent; | ||
1420 | |||
1421 | mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i], | 1809 | mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i], |
1422 | (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM << | 1810 | (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM << |
1423 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle); | 1811 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle); |
@@ -1441,34 +1829,34 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) | |||
1441 | port_info->phy_info[i].attached.phy_id = | 1829 | port_info->phy_info[i].attached.phy_id = |
1442 | port_info->phy_info[i].phy_id; | 1830 | port_info->phy_info[i].phy_id; |
1443 | } | 1831 | } |
1832 | } | ||
1444 | 1833 | ||
1445 | /* | 1834 | parent = &ioc->sh->shost_gendev; |
1446 | * If we find a parent port handle this expander is | 1835 | for (i = 0; i < port_info->num_phys; i++) { |
1447 | * attached to another expander, else it hangs of the | ||
1448 | * HBA phys. | ||
1449 | */ | ||
1450 | parent = &ioc->sh->shost_gendev; | ||
1451 | mutex_lock(&ioc->sas_topology_mutex); | 1836 | mutex_lock(&ioc->sas_topology_mutex); |
1452 | list_for_each_entry(p, &ioc->sas_topology, list) { | 1837 | list_for_each_entry(p, &ioc->sas_topology, list) { |
1453 | for (j = 0; j < p->num_phys; j++) { | 1838 | for (j = 0; j < p->num_phys; j++) { |
1454 | if (port_info->phy_info[i].identify.handle == | 1839 | if (port_info->phy_info[i].identify.handle != |
1455 | p->phy_info[j].attached.handle) | 1840 | p->phy_info[j].attached.handle) |
1456 | parent = &p->phy_info[j].rphy->dev; | 1841 | continue; |
1842 | rphy = mptsas_get_rphy(&p->phy_info[j]); | ||
1843 | parent = &rphy->dev; | ||
1457 | } | 1844 | } |
1458 | } | 1845 | } |
1459 | mutex_unlock(&ioc->sas_topology_mutex); | 1846 | mutex_unlock(&ioc->sas_topology_mutex); |
1847 | } | ||
1848 | |||
1849 | mptsas_setup_wide_ports(ioc, port_info); | ||
1460 | 1850 | ||
1851 | for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++) | ||
1461 | mptsas_probe_one_phy(parent, &port_info->phy_info[i], | 1852 | mptsas_probe_one_phy(parent, &port_info->phy_info[i], |
1462 | ioc->sas_index, 0); | 1853 | ioc->sas_index, 0); |
1463 | ioc->sas_index++; | ||
1464 | } | ||
1465 | 1854 | ||
1466 | return 0; | 1855 | return 0; |
1467 | 1856 | ||
1468 | out_free_port_info: | 1857 | out_free_port_info: |
1469 | if (ex) { | 1858 | if (ex) { |
1470 | if (ex->phy_info) | 1859 | kfree(ex->phy_info); |
1471 | kfree(ex->phy_info); | ||
1472 | kfree(ex); | 1860 | kfree(ex); |
1473 | } | 1861 | } |
1474 | out: | 1862 | out: |
@@ -1487,7 +1875,12 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) | |||
1487 | { | 1875 | { |
1488 | struct mptsas_portinfo buffer; | 1876 | struct mptsas_portinfo buffer; |
1489 | struct mptsas_portinfo *port_info, *n, *parent; | 1877 | struct mptsas_portinfo *port_info, *n, *parent; |
1878 | struct mptsas_phyinfo *phy_info; | ||
1879 | struct scsi_target * starget; | ||
1880 | VirtTarget * vtarget; | ||
1881 | struct sas_port * port; | ||
1490 | int i; | 1882 | int i; |
1883 | u64 expander_sas_address; | ||
1491 | 1884 | ||
1492 | mutex_lock(&ioc->sas_topology_mutex); | 1885 | mutex_lock(&ioc->sas_topology_mutex); |
1493 | list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) { | 1886 | list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) { |
@@ -1502,6 +1895,25 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) | |||
1502 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) { | 1895 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) { |
1503 | 1896 | ||
1504 | /* | 1897 | /* |
1898 | * Issue target reset to all child end devices | ||
1899 | * then mark them deleted to prevent further | ||
1900 | * IO going to them. | ||
1901 | */ | ||
1902 | phy_info = port_info->phy_info; | ||
1903 | for (i = 0; i < port_info->num_phys; i++, phy_info++) { | ||
1904 | starget = mptsas_get_starget(phy_info); | ||
1905 | if (!starget) | ||
1906 | continue; | ||
1907 | vtarget = starget->hostdata; | ||
1908 | if(vtarget->deleted) | ||
1909 | continue; | ||
1910 | vtarget->deleted = 1; | ||
1911 | mptsas_target_reset(ioc, vtarget); | ||
1912 | sas_port_delete(mptsas_get_port(phy_info)); | ||
1913 | mptsas_port_delete(phy_info->port_details); | ||
1914 | } | ||
1915 | |||
1916 | /* | ||
1505 | * Obtain the port_info instance to the parent port | 1917 | * Obtain the port_info instance to the parent port |
1506 | */ | 1918 | */ |
1507 | parent = mptsas_find_portinfo_by_handle(ioc, | 1919 | parent = mptsas_find_portinfo_by_handle(ioc, |
@@ -1510,34 +1922,43 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) | |||
1510 | if (!parent) | 1922 | if (!parent) |
1511 | goto next_port; | 1923 | goto next_port; |
1512 | 1924 | ||
1925 | expander_sas_address = | ||
1926 | port_info->phy_info[0].identify.sas_address; | ||
1927 | |||
1513 | /* | 1928 | /* |
1514 | * Delete rphys in the parent that point | 1929 | * Delete rphys in the parent that point |
1515 | * to this expander. The transport layer will | 1930 | * to this expander. The transport layer will |
1516 | * cleanup all the children. | 1931 | * cleanup all the children. |
1517 | */ | 1932 | */ |
1518 | for (i = 0; i < parent->num_phys; i++) { | 1933 | phy_info = parent->phy_info; |
1519 | if ((!parent->phy_info[i].rphy) || | 1934 | for (i = 0; i < parent->num_phys; i++, phy_info++) { |
1520 | (parent->phy_info[i].attached.sas_address != | 1935 | port = mptsas_get_port(phy_info); |
1521 | port_info->phy_info[i].identify.sas_address)) | 1936 | if (!port) |
1937 | continue; | ||
1938 | if (phy_info->attached.sas_address != | ||
1939 | expander_sas_address) | ||
1522 | continue; | 1940 | continue; |
1523 | sas_rphy_delete(parent->phy_info[i].rphy); | 1941 | #ifdef MPT_DEBUG_SAS_WIDE |
1524 | memset(&parent->phy_info[i].attached, 0, | 1942 | dev_printk(KERN_DEBUG, &port->dev, "delete\n"); |
1525 | sizeof(struct mptsas_devinfo)); | 1943 | #endif |
1526 | parent->phy_info[i].rphy = NULL; | 1944 | sas_port_delete(port); |
1527 | parent->phy_info[i].starget = NULL; | 1945 | mptsas_port_delete(phy_info->port_details); |
1528 | } | 1946 | } |
1529 | next_port: | 1947 | next_port: |
1948 | |||
1949 | phy_info = port_info->phy_info; | ||
1950 | for (i = 0; i < port_info->num_phys; i++, phy_info++) | ||
1951 | mptsas_port_delete(phy_info->port_details); | ||
1952 | |||
1530 | list_del(&port_info->list); | 1953 | list_del(&port_info->list); |
1531 | if (port_info->phy_info) | 1954 | kfree(port_info->phy_info); |
1532 | kfree(port_info->phy_info); | ||
1533 | kfree(port_info); | 1955 | kfree(port_info); |
1534 | } | 1956 | } |
1535 | /* | 1957 | /* |
1536 | * Free this memory allocated from inside | 1958 | * Free this memory allocated from inside |
1537 | * mptsas_sas_expander_pg0 | 1959 | * mptsas_sas_expander_pg0 |
1538 | */ | 1960 | */ |
1539 | if (buffer.phy_info) | 1961 | kfree(buffer.phy_info); |
1540 | kfree(buffer.phy_info); | ||
1541 | } | 1962 | } |
1542 | mutex_unlock(&ioc->sas_topology_mutex); | 1963 | mutex_unlock(&ioc->sas_topology_mutex); |
1543 | } | 1964 | } |
@@ -1573,60 +1994,59 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc) | |||
1573 | /* | 1994 | /* |
1574 | * Work queue thread to handle Runtime discovery | 1995 | * Work queue thread to handle Runtime discovery |
1575 | * Mere purpose is the hot add/delete of expanders | 1996 | * Mere purpose is the hot add/delete of expanders |
1997 | *(Mutex UNLOCKED) | ||
1576 | */ | 1998 | */ |
1577 | static void | 1999 | static void |
1578 | mptscsih_discovery_work(void * arg) | 2000 | __mptsas_discovery_work(MPT_ADAPTER *ioc) |
1579 | { | 2001 | { |
1580 | struct mptsas_discovery_event *ev = arg; | ||
1581 | MPT_ADAPTER *ioc = ev->ioc; | ||
1582 | u32 handle = 0xFFFF; | 2002 | u32 handle = 0xFFFF; |
1583 | 2003 | ||
1584 | mutex_lock(&ioc->sas_discovery_mutex); | ||
1585 | ioc->sas_discovery_runtime=1; | 2004 | ioc->sas_discovery_runtime=1; |
1586 | mptsas_delete_expander_phys(ioc); | 2005 | mptsas_delete_expander_phys(ioc); |
1587 | mptsas_probe_hba_phys(ioc); | 2006 | mptsas_probe_hba_phys(ioc); |
1588 | while (!mptsas_probe_expander_phys(ioc, &handle)) | 2007 | while (!mptsas_probe_expander_phys(ioc, &handle)) |
1589 | ; | 2008 | ; |
1590 | kfree(ev); | ||
1591 | ioc->sas_discovery_runtime=0; | 2009 | ioc->sas_discovery_runtime=0; |
2010 | } | ||
2011 | |||
2012 | /* | ||
2013 | * Work queue thread to handle Runtime discovery | ||
2014 | * Mere purpose is the hot add/delete of expanders | ||
2015 | *(Mutex LOCKED) | ||
2016 | */ | ||
2017 | static void | ||
2018 | mptsas_discovery_work(void * arg) | ||
2019 | { | ||
2020 | struct mptsas_discovery_event *ev = arg; | ||
2021 | MPT_ADAPTER *ioc = ev->ioc; | ||
2022 | |||
2023 | mutex_lock(&ioc->sas_discovery_mutex); | ||
2024 | __mptsas_discovery_work(ioc); | ||
1592 | mutex_unlock(&ioc->sas_discovery_mutex); | 2025 | mutex_unlock(&ioc->sas_discovery_mutex); |
2026 | kfree(ev); | ||
1593 | } | 2027 | } |
1594 | 2028 | ||
1595 | static struct mptsas_phyinfo * | 2029 | static struct mptsas_phyinfo * |
1596 | mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id) | 2030 | mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address) |
1597 | { | 2031 | { |
1598 | struct mptsas_portinfo *port_info; | 2032 | struct mptsas_portinfo *port_info; |
1599 | struct mptsas_devinfo device_info; | ||
1600 | struct mptsas_phyinfo *phy_info = NULL; | 2033 | struct mptsas_phyinfo *phy_info = NULL; |
1601 | int i, error; | 2034 | int i; |
1602 | |||
1603 | /* | ||
1604 | * Retrieve the parent sas_address | ||
1605 | */ | ||
1606 | error = mptsas_sas_device_pg0(ioc, &device_info, | ||
1607 | (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << | ||
1608 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), | ||
1609 | parent_handle); | ||
1610 | if (error) | ||
1611 | return NULL; | ||
1612 | 2035 | ||
1613 | /* | ||
1614 | * The phy_info structures are never deallocated during lifetime of | ||
1615 | * a host, so the code below is safe without additional refcounting. | ||
1616 | */ | ||
1617 | mutex_lock(&ioc->sas_topology_mutex); | 2036 | mutex_lock(&ioc->sas_topology_mutex); |
1618 | list_for_each_entry(port_info, &ioc->sas_topology, list) { | 2037 | list_for_each_entry(port_info, &ioc->sas_topology, list) { |
1619 | for (i = 0; i < port_info->num_phys; i++) { | 2038 | for (i = 0; i < port_info->num_phys; i++) { |
1620 | if (port_info->phy_info[i].identify.sas_address == | 2039 | if (port_info->phy_info[i].attached.sas_address |
1621 | device_info.sas_address && | 2040 | != sas_address) |
1622 | port_info->phy_info[i].phy_id == phy_id) { | 2041 | continue; |
1623 | phy_info = &port_info->phy_info[i]; | 2042 | if (!mptsas_is_end_device( |
1624 | break; | 2043 | &port_info->phy_info[i].attached)) |
1625 | } | 2044 | continue; |
2045 | phy_info = &port_info->phy_info[i]; | ||
2046 | break; | ||
1626 | } | 2047 | } |
1627 | } | 2048 | } |
1628 | mutex_unlock(&ioc->sas_topology_mutex); | 2049 | mutex_unlock(&ioc->sas_topology_mutex); |
1629 | |||
1630 | return phy_info; | 2050 | return phy_info; |
1631 | } | 2051 | } |
1632 | 2052 | ||
@@ -1637,21 +2057,19 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) | |||
1637 | struct mptsas_phyinfo *phy_info = NULL; | 2057 | struct mptsas_phyinfo *phy_info = NULL; |
1638 | int i; | 2058 | int i; |
1639 | 2059 | ||
1640 | /* | ||
1641 | * The phy_info structures are never deallocated during lifetime of | ||
1642 | * a host, so the code below is safe without additional refcounting. | ||
1643 | */ | ||
1644 | mutex_lock(&ioc->sas_topology_mutex); | 2060 | mutex_lock(&ioc->sas_topology_mutex); |
1645 | list_for_each_entry(port_info, &ioc->sas_topology, list) { | 2061 | list_for_each_entry(port_info, &ioc->sas_topology, list) { |
1646 | for (i = 0; i < port_info->num_phys; i++) | 2062 | for (i = 0; i < port_info->num_phys; i++) { |
1647 | if (mptsas_is_end_device(&port_info->phy_info[i].attached)) | 2063 | if (port_info->phy_info[i].attached.id != id) |
1648 | if (port_info->phy_info[i].attached.id == id) { | 2064 | continue; |
1649 | phy_info = &port_info->phy_info[i]; | 2065 | if (!mptsas_is_end_device( |
1650 | break; | 2066 | &port_info->phy_info[i].attached)) |
1651 | } | 2067 | continue; |
2068 | phy_info = &port_info->phy_info[i]; | ||
2069 | break; | ||
2070 | } | ||
1652 | } | 2071 | } |
1653 | mutex_unlock(&ioc->sas_topology_mutex); | 2072 | mutex_unlock(&ioc->sas_topology_mutex); |
1654 | |||
1655 | return phy_info; | 2073 | return phy_info; |
1656 | } | 2074 | } |
1657 | 2075 | ||
@@ -1659,7 +2077,7 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) | |||
1659 | * Work queue thread to clear the persitency table | 2077 | * Work queue thread to clear the persitency table |
1660 | */ | 2078 | */ |
1661 | static void | 2079 | static void |
1662 | mptscsih_sas_persist_clear_table(void * arg) | 2080 | mptsas_persist_clear_table(void * arg) |
1663 | { | 2081 | { |
1664 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; | 2082 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; |
1665 | 2083 | ||
@@ -1680,7 +2098,6 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach) | |||
1680 | mptsas_reprobe_lun); | 2098 | mptsas_reprobe_lun); |
1681 | } | 2099 | } |
1682 | 2100 | ||
1683 | |||
1684 | /* | 2101 | /* |
1685 | * Work queue thread to handle SAS hotplug events | 2102 | * Work queue thread to handle SAS hotplug events |
1686 | */ | 2103 | */ |
@@ -1691,14 +2108,17 @@ mptsas_hotplug_work(void *arg) | |||
1691 | MPT_ADAPTER *ioc = ev->ioc; | 2108 | MPT_ADAPTER *ioc = ev->ioc; |
1692 | struct mptsas_phyinfo *phy_info; | 2109 | struct mptsas_phyinfo *phy_info; |
1693 | struct sas_rphy *rphy; | 2110 | struct sas_rphy *rphy; |
2111 | struct sas_port *port; | ||
1694 | struct scsi_device *sdev; | 2112 | struct scsi_device *sdev; |
2113 | struct scsi_target * starget; | ||
1695 | struct sas_identify identify; | 2114 | struct sas_identify identify; |
1696 | char *ds = NULL; | 2115 | char *ds = NULL; |
1697 | struct mptsas_devinfo sas_device; | 2116 | struct mptsas_devinfo sas_device; |
1698 | VirtTarget *vtarget; | 2117 | VirtTarget *vtarget; |
2118 | VirtDevice *vdevice; | ||
1699 | 2119 | ||
1700 | mutex_lock(&ioc->sas_discovery_mutex); | ||
1701 | 2120 | ||
2121 | mutex_lock(&ioc->sas_discovery_mutex); | ||
1702 | switch (ev->event_type) { | 2122 | switch (ev->event_type) { |
1703 | case MPTSAS_DEL_DEVICE: | 2123 | case MPTSAS_DEL_DEVICE: |
1704 | 2124 | ||
@@ -1707,24 +2127,50 @@ mptsas_hotplug_work(void *arg) | |||
1707 | /* | 2127 | /* |
1708 | * Sanity checks, for non-existing phys and remote rphys. | 2128 | * Sanity checks, for non-existing phys and remote rphys. |
1709 | */ | 2129 | */ |
1710 | if (!phy_info) | 2130 | if (!phy_info || !phy_info->port_details) { |
2131 | dfailprintk((MYIOC_s_ERR_FMT | ||
2132 | "%s: exit at line=%d\n", ioc->name, | ||
2133 | __FUNCTION__, __LINE__)); | ||
1711 | break; | 2134 | break; |
1712 | if (!phy_info->rphy) | 2135 | } |
2136 | rphy = mptsas_get_rphy(phy_info); | ||
2137 | if (!rphy) { | ||
2138 | dfailprintk((MYIOC_s_ERR_FMT | ||
2139 | "%s: exit at line=%d\n", ioc->name, | ||
2140 | __FUNCTION__, __LINE__)); | ||
1713 | break; | 2141 | break; |
1714 | if (phy_info->starget) { | 2142 | } |
1715 | vtarget = phy_info->starget->hostdata; | 2143 | port = mptsas_get_port(phy_info); |
2144 | if (!port) { | ||
2145 | dfailprintk((MYIOC_s_ERR_FMT | ||
2146 | "%s: exit at line=%d\n", ioc->name, | ||
2147 | __FUNCTION__, __LINE__)); | ||
2148 | break; | ||
2149 | } | ||
1716 | 2150 | ||
1717 | if (!vtarget) | 2151 | starget = mptsas_get_starget(phy_info); |
2152 | if (starget) { | ||
2153 | vtarget = starget->hostdata; | ||
2154 | |||
2155 | if (!vtarget) { | ||
2156 | dfailprintk((MYIOC_s_ERR_FMT | ||
2157 | "%s: exit at line=%d\n", ioc->name, | ||
2158 | __FUNCTION__, __LINE__)); | ||
1718 | break; | 2159 | break; |
2160 | } | ||
2161 | |||
1719 | /* | 2162 | /* |
1720 | * Handling RAID components | 2163 | * Handling RAID components |
1721 | */ | 2164 | */ |
1722 | if (ev->phys_disk_num_valid) { | 2165 | if (ev->phys_disk_num_valid) { |
1723 | vtarget->target_id = ev->phys_disk_num; | 2166 | vtarget->target_id = ev->phys_disk_num; |
1724 | vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; | 2167 | vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; |
1725 | mptsas_reprobe_target(vtarget->starget, 1); | 2168 | mptsas_reprobe_target(starget, 1); |
1726 | break; | 2169 | break; |
1727 | } | 2170 | } |
2171 | |||
2172 | vtarget->deleted = 1; | ||
2173 | mptsas_target_reset(ioc, vtarget); | ||
1728 | } | 2174 | } |
1729 | 2175 | ||
1730 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) | 2176 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) |
@@ -1738,10 +2184,11 @@ mptsas_hotplug_work(void *arg) | |||
1738 | "removing %s device, channel %d, id %d, phy %d\n", | 2184 | "removing %s device, channel %d, id %d, phy %d\n", |
1739 | ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); | 2185 | ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); |
1740 | 2186 | ||
1741 | sas_rphy_delete(phy_info->rphy); | 2187 | #ifdef MPT_DEBUG_SAS_WIDE |
1742 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); | 2188 | dev_printk(KERN_DEBUG, &port->dev, "delete\n"); |
1743 | phy_info->rphy = NULL; | 2189 | #endif |
1744 | phy_info->starget = NULL; | 2190 | sas_port_delete(port); |
2191 | mptsas_port_delete(phy_info->port_details); | ||
1745 | break; | 2192 | break; |
1746 | case MPTSAS_ADD_DEVICE: | 2193 | case MPTSAS_ADD_DEVICE: |
1747 | 2194 | ||
@@ -1753,59 +2200,60 @@ mptsas_hotplug_work(void *arg) | |||
1753 | */ | 2200 | */ |
1754 | if (mptsas_sas_device_pg0(ioc, &sas_device, | 2201 | if (mptsas_sas_device_pg0(ioc, &sas_device, |
1755 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << | 2202 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << |
1756 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) | 2203 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) { |
2204 | dfailprintk((MYIOC_s_ERR_FMT | ||
2205 | "%s: exit at line=%d\n", ioc->name, | ||
2206 | __FUNCTION__, __LINE__)); | ||
1757 | break; | 2207 | break; |
2208 | } | ||
1758 | 2209 | ||
1759 | phy_info = mptsas_find_phyinfo_by_parent(ioc, | 2210 | ssleep(2); |
1760 | sas_device.handle_parent, sas_device.phy_id); | 2211 | __mptsas_discovery_work(ioc); |
1761 | 2212 | ||
1762 | if (!phy_info) { | 2213 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, |
1763 | u32 handle = 0xFFFF; | 2214 | sas_device.sas_address); |
1764 | 2215 | ||
1765 | /* | 2216 | if (!phy_info || !phy_info->port_details) { |
1766 | * Its possible when an expander has been hot added | 2217 | dfailprintk((MYIOC_s_ERR_FMT |
1767 | * containing attached devices, the sas firmware | 2218 | "%s: exit at line=%d\n", ioc->name, |
1768 | * may send a RC_ADDED event prior to the | 2219 | __FUNCTION__, __LINE__)); |
1769 | * DISCOVERY STOP event. If that occurs, our | 2220 | break; |
1770 | * view of the topology in the driver in respect to this | ||
1771 | * expander might of not been setup, and we hit this | ||
1772 | * condition. | ||
1773 | * Therefore, this code kicks off discovery to | ||
1774 | * refresh the data. | ||
1775 | * Then again, we check whether the parent phy has | ||
1776 | * been created. | ||
1777 | */ | ||
1778 | ioc->sas_discovery_runtime=1; | ||
1779 | mptsas_delete_expander_phys(ioc); | ||
1780 | mptsas_probe_hba_phys(ioc); | ||
1781 | while (!mptsas_probe_expander_phys(ioc, &handle)) | ||
1782 | ; | ||
1783 | ioc->sas_discovery_runtime=0; | ||
1784 | |||
1785 | phy_info = mptsas_find_phyinfo_by_parent(ioc, | ||
1786 | sas_device.handle_parent, sas_device.phy_id); | ||
1787 | if (!phy_info) | ||
1788 | break; | ||
1789 | } | 2221 | } |
1790 | 2222 | ||
1791 | if (phy_info->starget) { | 2223 | starget = mptsas_get_starget(phy_info); |
1792 | vtarget = phy_info->starget->hostdata; | 2224 | if (starget) { |
2225 | vtarget = starget->hostdata; | ||
1793 | 2226 | ||
1794 | if (!vtarget) | 2227 | if (!vtarget) { |
2228 | dfailprintk((MYIOC_s_ERR_FMT | ||
2229 | "%s: exit at line=%d\n", ioc->name, | ||
2230 | __FUNCTION__, __LINE__)); | ||
1795 | break; | 2231 | break; |
2232 | } | ||
1796 | /* | 2233 | /* |
1797 | * Handling RAID components | 2234 | * Handling RAID components |
1798 | */ | 2235 | */ |
1799 | if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2236 | if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { |
1800 | vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; | 2237 | vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; |
1801 | vtarget->target_id = ev->id; | 2238 | vtarget->target_id = ev->id; |
1802 | mptsas_reprobe_target(phy_info->starget, 0); | 2239 | mptsas_reprobe_target(starget, 0); |
1803 | } | 2240 | } |
1804 | break; | 2241 | break; |
1805 | } | 2242 | } |
1806 | 2243 | ||
1807 | if (phy_info->rphy) | 2244 | if (mptsas_get_rphy(phy_info)) { |
2245 | dfailprintk((MYIOC_s_ERR_FMT | ||
2246 | "%s: exit at line=%d\n", ioc->name, | ||
2247 | __FUNCTION__, __LINE__)); | ||
1808 | break; | 2248 | break; |
2249 | } | ||
2250 | port = mptsas_get_port(phy_info); | ||
2251 | if (!port) { | ||
2252 | dfailprintk((MYIOC_s_ERR_FMT | ||
2253 | "%s: exit at line=%d\n", ioc->name, | ||
2254 | __FUNCTION__, __LINE__)); | ||
2255 | break; | ||
2256 | } | ||
1809 | 2257 | ||
1810 | memcpy(&phy_info->attached, &sas_device, | 2258 | memcpy(&phy_info->attached, &sas_device, |
1811 | sizeof(struct mptsas_devinfo)); | 2259 | sizeof(struct mptsas_devinfo)); |
@@ -1822,28 +2270,23 @@ mptsas_hotplug_work(void *arg) | |||
1822 | ioc->name, ds, ev->channel, ev->id, ev->phy_id); | 2270 | ioc->name, ds, ev->channel, ev->id, ev->phy_id); |
1823 | 2271 | ||
1824 | mptsas_parse_device_info(&identify, &phy_info->attached); | 2272 | mptsas_parse_device_info(&identify, &phy_info->attached); |
1825 | switch (identify.device_type) { | 2273 | rphy = sas_end_device_alloc(port); |
1826 | case SAS_END_DEVICE: | 2274 | if (!rphy) { |
1827 | rphy = sas_end_device_alloc(phy_info->phy); | 2275 | dfailprintk((MYIOC_s_ERR_FMT |
1828 | break; | 2276 | "%s: exit at line=%d\n", ioc->name, |
1829 | case SAS_EDGE_EXPANDER_DEVICE: | 2277 | __FUNCTION__, __LINE__)); |
1830 | case SAS_FANOUT_EXPANDER_DEVICE: | ||
1831 | rphy = sas_expander_alloc(phy_info->phy, identify.device_type); | ||
1832 | break; | ||
1833 | default: | ||
1834 | rphy = NULL; | ||
1835 | break; | ||
1836 | } | ||
1837 | if (!rphy) | ||
1838 | break; /* non-fatal: an rphy can be added later */ | 2278 | break; /* non-fatal: an rphy can be added later */ |
2279 | } | ||
1839 | 2280 | ||
1840 | rphy->identify = identify; | 2281 | rphy->identify = identify; |
1841 | if (sas_rphy_add(rphy)) { | 2282 | if (sas_rphy_add(rphy)) { |
2283 | dfailprintk((MYIOC_s_ERR_FMT | ||
2284 | "%s: exit at line=%d\n", ioc->name, | ||
2285 | __FUNCTION__, __LINE__)); | ||
1842 | sas_rphy_free(rphy); | 2286 | sas_rphy_free(rphy); |
1843 | break; | 2287 | break; |
1844 | } | 2288 | } |
1845 | 2289 | mptsas_set_rphy(phy_info, rphy); | |
1846 | phy_info->rphy = rphy; | ||
1847 | break; | 2290 | break; |
1848 | case MPTSAS_ADD_RAID: | 2291 | case MPTSAS_ADD_RAID: |
1849 | sdev = scsi_device_lookup( | 2292 | sdev = scsi_device_lookup( |
@@ -1875,6 +2318,9 @@ mptsas_hotplug_work(void *arg) | |||
1875 | printk(MYIOC_s_INFO_FMT | 2318 | printk(MYIOC_s_INFO_FMT |
1876 | "removing raid volume, channel %d, id %d\n", | 2319 | "removing raid volume, channel %d, id %d\n", |
1877 | ioc->name, ioc->num_ports, ev->id); | 2320 | ioc->name, ioc->num_ports, ev->id); |
2321 | vdevice = sdev->hostdata; | ||
2322 | vdevice->vtarget->deleted = 1; | ||
2323 | mptsas_target_reset(ioc, vdevice->vtarget); | ||
1878 | scsi_remove_device(sdev); | 2324 | scsi_remove_device(sdev); |
1879 | scsi_device_put(sdev); | 2325 | scsi_device_put(sdev); |
1880 | mpt_findImVolumes(ioc); | 2326 | mpt_findImVolumes(ioc); |
@@ -1884,12 +2330,13 @@ mptsas_hotplug_work(void *arg) | |||
1884 | break; | 2330 | break; |
1885 | } | 2331 | } |
1886 | 2332 | ||
1887 | kfree(ev); | ||
1888 | mutex_unlock(&ioc->sas_discovery_mutex); | 2333 | mutex_unlock(&ioc->sas_discovery_mutex); |
2334 | kfree(ev); | ||
2335 | |||
1889 | } | 2336 | } |
1890 | 2337 | ||
1891 | static void | 2338 | static void |
1892 | mptscsih_send_sas_event(MPT_ADAPTER *ioc, | 2339 | mptsas_send_sas_event(MPT_ADAPTER *ioc, |
1893 | EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data) | 2340 | EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data) |
1894 | { | 2341 | { |
1895 | struct mptsas_hotplug_event *ev; | 2342 | struct mptsas_hotplug_event *ev; |
@@ -1905,7 +2352,7 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc, | |||
1905 | switch (sas_event_data->ReasonCode) { | 2352 | switch (sas_event_data->ReasonCode) { |
1906 | case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: | 2353 | case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: |
1907 | case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: | 2354 | case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: |
1908 | ev = kmalloc(sizeof(*ev), GFP_ATOMIC); | 2355 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
1909 | if (!ev) { | 2356 | if (!ev) { |
1910 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); | 2357 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); |
1911 | break; | 2358 | break; |
@@ -1935,10 +2382,9 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc, | |||
1935 | /* | 2382 | /* |
1936 | * Persistent table is full. | 2383 | * Persistent table is full. |
1937 | */ | 2384 | */ |
1938 | INIT_WORK(&ioc->mptscsih_persistTask, | 2385 | INIT_WORK(&ioc->sas_persist_task, |
1939 | mptscsih_sas_persist_clear_table, | 2386 | mptsas_persist_clear_table, (void *)ioc); |
1940 | (void *)ioc); | 2387 | schedule_work(&ioc->sas_persist_task); |
1941 | schedule_work(&ioc->mptscsih_persistTask); | ||
1942 | break; | 2388 | break; |
1943 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: | 2389 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: |
1944 | /* TODO */ | 2390 | /* TODO */ |
@@ -1950,7 +2396,7 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc, | |||
1950 | } | 2396 | } |
1951 | 2397 | ||
1952 | static void | 2398 | static void |
1953 | mptscsih_send_raid_event(MPT_ADAPTER *ioc, | 2399 | mptsas_send_raid_event(MPT_ADAPTER *ioc, |
1954 | EVENT_DATA_RAID *raid_event_data) | 2400 | EVENT_DATA_RAID *raid_event_data) |
1955 | { | 2401 | { |
1956 | struct mptsas_hotplug_event *ev; | 2402 | struct mptsas_hotplug_event *ev; |
@@ -1960,13 +2406,12 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, | |||
1960 | if (ioc->bus_type != SAS) | 2406 | if (ioc->bus_type != SAS) |
1961 | return; | 2407 | return; |
1962 | 2408 | ||
1963 | ev = kmalloc(sizeof(*ev), GFP_ATOMIC); | 2409 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
1964 | if (!ev) { | 2410 | if (!ev) { |
1965 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); | 2411 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); |
1966 | return; | 2412 | return; |
1967 | } | 2413 | } |
1968 | 2414 | ||
1969 | memset(ev,0,sizeof(struct mptsas_hotplug_event)); | ||
1970 | INIT_WORK(&ev->work, mptsas_hotplug_work, ev); | 2415 | INIT_WORK(&ev->work, mptsas_hotplug_work, ev); |
1971 | ev->ioc = ioc; | 2416 | ev->ioc = ioc; |
1972 | ev->id = raid_event_data->VolumeID; | 2417 | ev->id = raid_event_data->VolumeID; |
@@ -2028,7 +2473,7 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, | |||
2028 | } | 2473 | } |
2029 | 2474 | ||
2030 | static void | 2475 | static void |
2031 | mptscsih_send_discovery(MPT_ADAPTER *ioc, | 2476 | mptsas_send_discovery_event(MPT_ADAPTER *ioc, |
2032 | EVENT_DATA_SAS_DISCOVERY *discovery_data) | 2477 | EVENT_DATA_SAS_DISCOVERY *discovery_data) |
2033 | { | 2478 | { |
2034 | struct mptsas_discovery_event *ev; | 2479 | struct mptsas_discovery_event *ev; |
@@ -2043,11 +2488,10 @@ mptscsih_send_discovery(MPT_ADAPTER *ioc, | |||
2043 | if (discovery_data->DiscoveryStatus) | 2488 | if (discovery_data->DiscoveryStatus) |
2044 | return; | 2489 | return; |
2045 | 2490 | ||
2046 | ev = kmalloc(sizeof(*ev), GFP_ATOMIC); | 2491 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
2047 | if (!ev) | 2492 | if (!ev) |
2048 | return; | 2493 | return; |
2049 | memset(ev,0,sizeof(struct mptsas_discovery_event)); | 2494 | INIT_WORK(&ev->work, mptsas_discovery_work, ev); |
2050 | INIT_WORK(&ev->work, mptscsih_discovery_work, ev); | ||
2051 | ev->ioc = ioc; | 2495 | ev->ioc = ioc; |
2052 | schedule_work(&ev->work); | 2496 | schedule_work(&ev->work); |
2053 | }; | 2497 | }; |
@@ -2075,21 +2519,21 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | |||
2075 | 2519 | ||
2076 | switch (event) { | 2520 | switch (event) { |
2077 | case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: | 2521 | case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: |
2078 | mptscsih_send_sas_event(ioc, | 2522 | mptsas_send_sas_event(ioc, |
2079 | (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data); | 2523 | (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data); |
2080 | break; | 2524 | break; |
2081 | case MPI_EVENT_INTEGRATED_RAID: | 2525 | case MPI_EVENT_INTEGRATED_RAID: |
2082 | mptscsih_send_raid_event(ioc, | 2526 | mptsas_send_raid_event(ioc, |
2083 | (EVENT_DATA_RAID *)reply->Data); | 2527 | (EVENT_DATA_RAID *)reply->Data); |
2084 | break; | 2528 | break; |
2085 | case MPI_EVENT_PERSISTENT_TABLE_FULL: | 2529 | case MPI_EVENT_PERSISTENT_TABLE_FULL: |
2086 | INIT_WORK(&ioc->mptscsih_persistTask, | 2530 | INIT_WORK(&ioc->sas_persist_task, |
2087 | mptscsih_sas_persist_clear_table, | 2531 | mptsas_persist_clear_table, |
2088 | (void *)ioc); | 2532 | (void *)ioc); |
2089 | schedule_work(&ioc->mptscsih_persistTask); | 2533 | schedule_work(&ioc->sas_persist_task); |
2090 | break; | 2534 | break; |
2091 | case MPI_EVENT_SAS_DISCOVERY: | 2535 | case MPI_EVENT_SAS_DISCOVERY: |
2092 | mptscsih_send_discovery(ioc, | 2536 | mptsas_send_discovery_event(ioc, |
2093 | (EVENT_DATA_SAS_DISCOVERY *)reply->Data); | 2537 | (EVENT_DATA_SAS_DISCOVERY *)reply->Data); |
2094 | break; | 2538 | break; |
2095 | default: | 2539 | default: |
@@ -2308,7 +2752,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2308 | 2752 | ||
2309 | return 0; | 2753 | return 0; |
2310 | 2754 | ||
2311 | out_mptsas_probe: | 2755 | out_mptsas_probe: |
2312 | 2756 | ||
2313 | mptscsih_remove(pdev); | 2757 | mptscsih_remove(pdev); |
2314 | return error; | 2758 | return error; |
@@ -2318,6 +2762,7 @@ static void __devexit mptsas_remove(struct pci_dev *pdev) | |||
2318 | { | 2762 | { |
2319 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); | 2763 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); |
2320 | struct mptsas_portinfo *p, *n; | 2764 | struct mptsas_portinfo *p, *n; |
2765 | int i; | ||
2321 | 2766 | ||
2322 | ioc->sas_discovery_ignore_events=1; | 2767 | ioc->sas_discovery_ignore_events=1; |
2323 | sas_remove_host(ioc->sh); | 2768 | sas_remove_host(ioc->sh); |
@@ -2325,8 +2770,9 @@ static void __devexit mptsas_remove(struct pci_dev *pdev) | |||
2325 | mutex_lock(&ioc->sas_topology_mutex); | 2770 | mutex_lock(&ioc->sas_topology_mutex); |
2326 | list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { | 2771 | list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { |
2327 | list_del(&p->list); | 2772 | list_del(&p->list); |
2328 | if (p->phy_info) | 2773 | for (i = 0 ; i < p->num_phys ; i++) |
2329 | kfree(p->phy_info); | 2774 | mptsas_port_delete(p->phy_info[i].port_details); |
2775 | kfree(p->phy_info); | ||
2330 | kfree(p); | 2776 | kfree(p); |
2331 | } | 2777 | } |
2332 | mutex_unlock(&ioc->sas_topology_mutex); | 2778 | mutex_unlock(&ioc->sas_topology_mutex); |
@@ -2335,17 +2781,15 @@ static void __devexit mptsas_remove(struct pci_dev *pdev) | |||
2335 | } | 2781 | } |
2336 | 2782 | ||
2337 | static struct pci_device_id mptsas_pci_table[] = { | 2783 | static struct pci_device_id mptsas_pci_table[] = { |
2338 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064, | 2784 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064, |
2339 | PCI_ANY_ID, PCI_ANY_ID }, | ||
2340 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066, | ||
2341 | PCI_ANY_ID, PCI_ANY_ID }, | 2785 | PCI_ANY_ID, PCI_ANY_ID }, |
2342 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068, | 2786 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068, |
2343 | PCI_ANY_ID, PCI_ANY_ID }, | 2787 | PCI_ANY_ID, PCI_ANY_ID }, |
2344 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E, | 2788 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E, |
2345 | PCI_ANY_ID, PCI_ANY_ID }, | 2789 | PCI_ANY_ID, PCI_ANY_ID }, |
2346 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E, | 2790 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E, |
2347 | PCI_ANY_ID, PCI_ANY_ID }, | 2791 | PCI_ANY_ID, PCI_ANY_ID }, |
2348 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E, | 2792 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078, |
2349 | PCI_ANY_ID, PCI_ANY_ID }, | 2793 | PCI_ANY_ID, PCI_ANY_ID }, |
2350 | {0} /* Terminating entry */ | 2794 | {0} /* Terminating entry */ |
2351 | }; | 2795 | }; |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 3201de053943..0a1ff762205f 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -775,9 +775,9 @@ static struct spi_function_template mptspi_transport_functions = { | |||
775 | */ | 775 | */ |
776 | 776 | ||
777 | static struct pci_device_id mptspi_pci_table[] = { | 777 | static struct pci_device_id mptspi_pci_table[] = { |
778 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030, | 778 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030, |
779 | PCI_ANY_ID, PCI_ANY_ID }, | 779 | PCI_ANY_ID, PCI_ANY_ID }, |
780 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035, | 780 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035, |
781 | PCI_ANY_ID, PCI_ANY_ID }, | 781 | PCI_ANY_ID, PCI_ANY_ID }, |
782 | {0} /* Terminating entry */ | 782 | {0} /* Terminating entry */ |
783 | }; | 783 | }; |
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index eb7a6a4ded75..657a3ab75399 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c | |||
@@ -173,6 +173,7 @@ STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt); | |||
173 | STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt); | 173 | STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt); |
174 | STATIC void NCR_700_chip_setup(struct Scsi_Host *host); | 174 | STATIC void NCR_700_chip_setup(struct Scsi_Host *host); |
175 | STATIC void NCR_700_chip_reset(struct Scsi_Host *host); | 175 | STATIC void NCR_700_chip_reset(struct Scsi_Host *host); |
176 | STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt); | ||
176 | STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); | 177 | STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); |
177 | STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); | 178 | STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); |
178 | static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); | 179 | static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); |
@@ -182,10 +183,6 @@ STATIC struct device_attribute *NCR_700_dev_attrs[]; | |||
182 | 183 | ||
183 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; | 184 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; |
184 | 185 | ||
185 | struct NCR_700_sense { | ||
186 | unsigned char cmnd[MAX_COMMAND_SIZE]; | ||
187 | }; | ||
188 | |||
189 | static char *NCR_700_phase[] = { | 186 | static char *NCR_700_phase[] = { |
190 | "", | 187 | "", |
191 | "after selection", | 188 | "after selection", |
@@ -333,6 +330,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, | |||
333 | tpnt->use_clustering = ENABLE_CLUSTERING; | 330 | tpnt->use_clustering = ENABLE_CLUSTERING; |
334 | tpnt->slave_configure = NCR_700_slave_configure; | 331 | tpnt->slave_configure = NCR_700_slave_configure; |
335 | tpnt->slave_destroy = NCR_700_slave_destroy; | 332 | tpnt->slave_destroy = NCR_700_slave_destroy; |
333 | tpnt->slave_alloc = NCR_700_slave_alloc; | ||
336 | tpnt->change_queue_depth = NCR_700_change_queue_depth; | 334 | tpnt->change_queue_depth = NCR_700_change_queue_depth; |
337 | tpnt->change_queue_type = NCR_700_change_queue_type; | 335 | tpnt->change_queue_type = NCR_700_change_queue_type; |
338 | 336 | ||
@@ -611,9 +609,10 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
611 | struct NCR_700_command_slot *slot = | 609 | struct NCR_700_command_slot *slot = |
612 | (struct NCR_700_command_slot *)SCp->host_scribble; | 610 | (struct NCR_700_command_slot *)SCp->host_scribble; |
613 | 611 | ||
614 | NCR_700_unmap(hostdata, SCp, slot); | 612 | dma_unmap_single(hostdata->dev, slot->pCmd, |
613 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | ||
615 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { | 614 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { |
616 | struct NCR_700_sense *sense = SCp->device->hostdata; | 615 | char *cmnd = NCR_700_get_sense_cmnd(SCp->device); |
617 | #ifdef NCR_700_DEBUG | 616 | #ifdef NCR_700_DEBUG |
618 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", | 617 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", |
619 | SCp, SCp->cmnd[7], result); | 618 | SCp, SCp->cmnd[7], result); |
@@ -624,10 +623,9 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
624 | /* restore the old result if the request sense was | 623 | /* restore the old result if the request sense was |
625 | * successful */ | 624 | * successful */ |
626 | if(result == 0) | 625 | if(result == 0) |
627 | result = sense->cmnd[7]; | 626 | result = cmnd[7]; |
628 | } else | 627 | } else |
629 | dma_unmap_single(hostdata->dev, slot->pCmd, | 628 | NCR_700_unmap(hostdata, SCp, slot); |
630 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | ||
631 | 629 | ||
632 | free_slot(slot, hostdata); | 630 | free_slot(slot, hostdata); |
633 | #ifdef NCR_700_DEBUG | 631 | #ifdef NCR_700_DEBUG |
@@ -969,14 +967,15 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
969 | status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { | 967 | status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { |
970 | struct NCR_700_command_slot *slot = | 968 | struct NCR_700_command_slot *slot = |
971 | (struct NCR_700_command_slot *)SCp->host_scribble; | 969 | (struct NCR_700_command_slot *)SCp->host_scribble; |
972 | if(SCp->cmnd[0] == REQUEST_SENSE) { | 970 | if(slot->flags == NCR_700_FLAG_AUTOSENSE) { |
973 | /* OOPS: bad device, returning another | 971 | /* OOPS: bad device, returning another |
974 | * contingent allegiance condition */ | 972 | * contingent allegiance condition */ |
975 | scmd_printk(KERN_ERR, SCp, | 973 | scmd_printk(KERN_ERR, SCp, |
976 | "broken device is looping in contingent allegiance: ignoring\n"); | 974 | "broken device is looping in contingent allegiance: ignoring\n"); |
977 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); | 975 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); |
978 | } else { | 976 | } else { |
979 | struct NCR_700_sense *sense = SCp->device->hostdata; | 977 | char *cmnd = |
978 | NCR_700_get_sense_cmnd(SCp->device); | ||
980 | #ifdef NCR_DEBUG | 979 | #ifdef NCR_DEBUG |
981 | scsi_print_command(SCp); | 980 | scsi_print_command(SCp); |
982 | printk(" cmd %p has status %d, requesting sense\n", | 981 | printk(" cmd %p has status %d, requesting sense\n", |
@@ -994,21 +993,21 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
994 | sizeof(SCp->cmnd), | 993 | sizeof(SCp->cmnd), |
995 | DMA_TO_DEVICE); | 994 | DMA_TO_DEVICE); |
996 | 995 | ||
997 | sense->cmnd[0] = REQUEST_SENSE; | 996 | cmnd[0] = REQUEST_SENSE; |
998 | sense->cmnd[1] = (SCp->device->lun & 0x7) << 5; | 997 | cmnd[1] = (SCp->device->lun & 0x7) << 5; |
999 | sense->cmnd[2] = 0; | 998 | cmnd[2] = 0; |
1000 | sense->cmnd[3] = 0; | 999 | cmnd[3] = 0; |
1001 | sense->cmnd[4] = sizeof(SCp->sense_buffer); | 1000 | cmnd[4] = sizeof(SCp->sense_buffer); |
1002 | sense->cmnd[5] = 0; | 1001 | cmnd[5] = 0; |
1003 | /* Here's a quiet hack: the | 1002 | /* Here's a quiet hack: the |
1004 | * REQUEST_SENSE command is six bytes, | 1003 | * REQUEST_SENSE command is six bytes, |
1005 | * so store a flag indicating that | 1004 | * so store a flag indicating that |
1006 | * this was an internal sense request | 1005 | * this was an internal sense request |
1007 | * and the original status at the end | 1006 | * and the original status at the end |
1008 | * of the command */ | 1007 | * of the command */ |
1009 | sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; | 1008 | cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; |
1010 | sense->cmnd[7] = hostdata->status[0]; | 1009 | cmnd[7] = hostdata->status[0]; |
1011 | slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE); | 1010 | slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE); |
1012 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | 1011 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); |
1013 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); | 1012 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); |
1014 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); | 1013 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); |
@@ -1530,7 +1529,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
1530 | 1529 | ||
1531 | /* clear all the negotiated parameters */ | 1530 | /* clear all the negotiated parameters */ |
1532 | __shost_for_each_device(SDp, host) | 1531 | __shost_for_each_device(SDp, host) |
1533 | SDp->hostdata = NULL; | 1532 | NCR_700_clear_flag(SDp, ~0); |
1534 | 1533 | ||
1535 | /* clear all the slots and their pending commands */ | 1534 | /* clear all the slots and their pending commands */ |
1536 | for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) { | 1535 | for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) { |
@@ -2035,7 +2034,17 @@ NCR_700_set_offset(struct scsi_target *STp, int offset) | |||
2035 | spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; | 2034 | spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; |
2036 | } | 2035 | } |
2037 | 2036 | ||
2037 | STATIC int | ||
2038 | NCR_700_slave_alloc(struct scsi_device *SDp) | ||
2039 | { | ||
2040 | SDp->hostdata = kzalloc(sizeof(struct NCR_700_Device_Parameters), | ||
2041 | GFP_KERNEL); | ||
2038 | 2042 | ||
2043 | if (!SDp->hostdata) | ||
2044 | return -ENOMEM; | ||
2045 | |||
2046 | return 0; | ||
2047 | } | ||
2039 | 2048 | ||
2040 | STATIC int | 2049 | STATIC int |
2041 | NCR_700_slave_configure(struct scsi_device *SDp) | 2050 | NCR_700_slave_configure(struct scsi_device *SDp) |
@@ -2043,11 +2052,6 @@ NCR_700_slave_configure(struct scsi_device *SDp) | |||
2043 | struct NCR_700_Host_Parameters *hostdata = | 2052 | struct NCR_700_Host_Parameters *hostdata = |
2044 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; | 2053 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; |
2045 | 2054 | ||
2046 | SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense)); | ||
2047 | |||
2048 | if (!SDp->hostdata) | ||
2049 | return -ENOMEM; | ||
2050 | |||
2051 | /* to do here: allocate memory; build a queue_full list */ | 2055 | /* to do here: allocate memory; build a queue_full list */ |
2052 | if(SDp->tagged_supported) { | 2056 | if(SDp->tagged_supported) { |
2053 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); | 2057 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); |
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h index 7f22a06fe5ec..97ebe71b701b 100644 --- a/drivers/scsi/53c700.h +++ b/drivers/scsi/53c700.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <asm/io.h> | 12 | #include <asm/io.h> |
13 | 13 | ||
14 | #include <scsi/scsi_device.h> | 14 | #include <scsi/scsi_device.h> |
15 | 15 | #include <scsi/scsi_cmnd.h> | |
16 | 16 | ||
17 | /* Turn on for general debugging---too verbose for normal use */ | 17 | /* Turn on for general debugging---too verbose for normal use */ |
18 | #undef NCR_700_DEBUG | 18 | #undef NCR_700_DEBUG |
@@ -76,11 +76,16 @@ struct NCR_700_SG_List { | |||
76 | #define SCRIPT_RETURN 0x90080000 | 76 | #define SCRIPT_RETURN 0x90080000 |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* We use device->hostdata to store negotiated parameters. This is | 79 | struct NCR_700_Device_Parameters { |
80 | * supposed to be a pointer to a device private area, but we cannot | 80 | /* space for creating a request sense command. Really, except |
81 | * really use it as such since it will never be freed, so just use the | 81 | * for the annoying SCSI-2 requirement for LUN information in |
82 | * 32 bits to cram the information. The SYNC negotiation sequence looks | 82 | * cmnd[1], this could be in static storage */ |
83 | * like: | 83 | unsigned char cmnd[MAX_COMMAND_SIZE]; |
84 | __u8 depth; | ||
85 | }; | ||
86 | |||
87 | |||
88 | /* The SYNC negotiation sequence looks like: | ||
84 | * | 89 | * |
85 | * If DEV_NEGOTIATED_SYNC not set, tack and SDTR message on to the | 90 | * If DEV_NEGOTIATED_SYNC not set, tack and SDTR message on to the |
86 | * initial identify for the device and set DEV_BEGIN_SYNC_NEGOTATION | 91 | * initial identify for the device and set DEV_BEGIN_SYNC_NEGOTATION |
@@ -98,19 +103,26 @@ struct NCR_700_SG_List { | |||
98 | #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17) | 103 | #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17) |
99 | #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19) | 104 | #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19) |
100 | 105 | ||
106 | static inline char *NCR_700_get_sense_cmnd(struct scsi_device *SDp) | ||
107 | { | ||
108 | struct NCR_700_Device_Parameters *hostdata = SDp->hostdata; | ||
109 | |||
110 | return hostdata->cmnd; | ||
111 | } | ||
112 | |||
101 | static inline void | 113 | static inline void |
102 | NCR_700_set_depth(struct scsi_device *SDp, __u8 depth) | 114 | NCR_700_set_depth(struct scsi_device *SDp, __u8 depth) |
103 | { | 115 | { |
104 | long l = (long)SDp->hostdata; | 116 | struct NCR_700_Device_Parameters *hostdata = SDp->hostdata; |
105 | 117 | ||
106 | l &= 0xffff00ff; | 118 | hostdata->depth = depth; |
107 | l |= 0xff00 & (depth << 8); | ||
108 | SDp->hostdata = (void *)l; | ||
109 | } | 119 | } |
110 | static inline __u8 | 120 | static inline __u8 |
111 | NCR_700_get_depth(struct scsi_device *SDp) | 121 | NCR_700_get_depth(struct scsi_device *SDp) |
112 | { | 122 | { |
113 | return ((((unsigned long)SDp->hostdata) & 0xff00)>>8); | 123 | struct NCR_700_Device_Parameters *hostdata = SDp->hostdata; |
124 | |||
125 | return hostdata->depth; | ||
114 | } | 126 | } |
115 | static inline int | 127 | static inline int |
116 | NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag) | 128 | NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag) |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 7cea514e810a..1cd3584ba7ff 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -92,31 +92,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
92 | init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys); | 92 | init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys); |
93 | init->AdapterFibsSize = cpu_to_le32(fibsize); | 93 | init->AdapterFibsSize = cpu_to_le32(fibsize); |
94 | init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); | 94 | init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); |
95 | /* | 95 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); |
96 | * number of 4k pages of host physical memory. The aacraid fw needs | ||
97 | * this number to be less than 4gb worth of pages. num_physpages is in | ||
98 | * system page units. New firmware doesn't have any issues with the | ||
99 | * mapping system, but older Firmware did, and had *troubles* dealing | ||
100 | * with the math overloading past 32 bits, thus we must limit this | ||
101 | * field. | ||
102 | * | ||
103 | * This assumes the memory is mapped zero->n, which isnt | ||
104 | * always true on real computers. It also has some slight problems | ||
105 | * with the GART on x86-64. I've btw never tried DMA from PCI space | ||
106 | * on this platform but don't be surprised if its problematic. | ||
107 | * [AK: something is very very wrong when a driver tests this symbol. | ||
108 | * Someone should figure out what the comment writer really meant here and fix | ||
109 | * the code. Or just remove that bad code. ] | ||
110 | */ | ||
111 | #ifndef CONFIG_IOMMU | ||
112 | if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) { | ||
113 | init->HostPhysMemPages = | ||
114 | cpu_to_le32(num_physpages << (PAGE_SHIFT-12)); | ||
115 | } else | ||
116 | #endif | ||
117 | { | ||
118 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); | ||
119 | } | ||
120 | 96 | ||
121 | init->InitFlags = 0; | 97 | init->InitFlags = 0; |
122 | if (dev->new_comm_interface) { | 98 | if (dev->new_comm_interface) { |
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index eb7745692682..df3346b5caf8 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h | |||
@@ -1487,6 +1487,7 @@ typedef enum { | |||
1487 | } ahd_queue_alg; | 1487 | } ahd_queue_alg; |
1488 | 1488 | ||
1489 | void ahd_set_tags(struct ahd_softc *ahd, | 1489 | void ahd_set_tags(struct ahd_softc *ahd, |
1490 | struct scsi_cmnd *cmd, | ||
1490 | struct ahd_devinfo *devinfo, | 1491 | struct ahd_devinfo *devinfo, |
1491 | ahd_queue_alg alg); | 1492 | ahd_queue_alg alg); |
1492 | 1493 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 801fc81d0b20..a1e8ca758594 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -1090,7 +1090,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) | |||
1090 | 1090 | ||
1091 | /* Notify XPT */ | 1091 | /* Notify XPT */ |
1092 | ahd_send_async(ahd, devinfo.channel, devinfo.target, | 1092 | ahd_send_async(ahd, devinfo.channel, devinfo.target, |
1093 | CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); | 1093 | CAM_LUN_WILDCARD, AC_SENT_BDR); |
1094 | 1094 | ||
1095 | /* | 1095 | /* |
1096 | * Allow the sequencer to continue with | 1096 | * Allow the sequencer to continue with |
@@ -3062,7 +3062,7 @@ ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3062 | tinfo->curr.ppr_options = ppr_options; | 3062 | tinfo->curr.ppr_options = ppr_options; |
3063 | 3063 | ||
3064 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 3064 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
3065 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); | 3065 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG); |
3066 | if (bootverbose) { | 3066 | if (bootverbose) { |
3067 | if (offset != 0) { | 3067 | if (offset != 0) { |
3068 | int options; | 3068 | int options; |
@@ -3184,7 +3184,7 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3184 | 3184 | ||
3185 | tinfo->curr.width = width; | 3185 | tinfo->curr.width = width; |
3186 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 3186 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
3187 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); | 3187 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG); |
3188 | if (bootverbose) { | 3188 | if (bootverbose) { |
3189 | printf("%s: target %d using %dbit transfers\n", | 3189 | printf("%s: target %d using %dbit transfers\n", |
3190 | ahd_name(ahd), devinfo->target, | 3190 | ahd_name(ahd), devinfo->target, |
@@ -3211,12 +3211,14 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3211 | * Update the current state of tagged queuing for a given target. | 3211 | * Update the current state of tagged queuing for a given target. |
3212 | */ | 3212 | */ |
3213 | void | 3213 | void |
3214 | ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | 3214 | ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd, |
3215 | ahd_queue_alg alg) | 3215 | struct ahd_devinfo *devinfo, ahd_queue_alg alg) |
3216 | { | 3216 | { |
3217 | ahd_platform_set_tags(ahd, devinfo, alg); | 3217 | struct scsi_device *sdev = cmd->device; |
3218 | |||
3219 | ahd_platform_set_tags(ahd, sdev, devinfo, alg); | ||
3218 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 3220 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
3219 | devinfo->lun, AC_TRANSFER_NEG, &alg); | 3221 | devinfo->lun, AC_TRANSFER_NEG); |
3220 | } | 3222 | } |
3221 | 3223 | ||
3222 | static void | 3224 | static void |
@@ -4746,7 +4748,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) | |||
4746 | printf("(%s:%c:%d:%d): refuses tagged commands. " | 4748 | printf("(%s:%c:%d:%d): refuses tagged commands. " |
4747 | "Performing non-tagged I/O\n", ahd_name(ahd), | 4749 | "Performing non-tagged I/O\n", ahd_name(ahd), |
4748 | devinfo->channel, devinfo->target, devinfo->lun); | 4750 | devinfo->channel, devinfo->target, devinfo->lun); |
4749 | ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE); | 4751 | ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_NONE); |
4750 | mask = ~0x23; | 4752 | mask = ~0x23; |
4751 | } else { | 4753 | } else { |
4752 | printf("(%s:%c:%d:%d): refuses %s tagged commands. " | 4754 | printf("(%s:%c:%d:%d): refuses %s tagged commands. " |
@@ -4754,7 +4756,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) | |||
4754 | ahd_name(ahd), devinfo->channel, devinfo->target, | 4756 | ahd_name(ahd), devinfo->channel, devinfo->target, |
4755 | devinfo->lun, tag_type == MSG_ORDERED_TASK | 4757 | devinfo->lun, tag_type == MSG_ORDERED_TASK |
4756 | ? "ordered" : "head of queue"); | 4758 | ? "ordered" : "head of queue"); |
4757 | ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC); | 4759 | ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_BASIC); |
4758 | mask = ~0x03; | 4760 | mask = ~0x03; |
4759 | } | 4761 | } |
4760 | 4762 | ||
@@ -5098,7 +5100,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
5098 | 5100 | ||
5099 | if (status != CAM_SEL_TIMEOUT) | 5101 | if (status != CAM_SEL_TIMEOUT) |
5100 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 5102 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
5101 | CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); | 5103 | CAM_LUN_WILDCARD, AC_SENT_BDR); |
5102 | 5104 | ||
5103 | if (message != NULL && bootverbose) | 5105 | if (message != NULL && bootverbose) |
5104 | printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), | 5106 | printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), |
@@ -7952,7 +7954,7 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) | |||
7952 | #endif | 7954 | #endif |
7953 | /* Notify the XPT that a bus reset occurred */ | 7955 | /* Notify the XPT that a bus reset occurred */ |
7954 | ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, | 7956 | ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, |
7955 | CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); | 7957 | CAM_LUN_WILDCARD, AC_BUS_RESET); |
7956 | 7958 | ||
7957 | /* | 7959 | /* |
7958 | * Revert to async/narrow transfers until we renegotiate. | 7960 | * Revert to async/narrow transfers until we renegotiate. |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index e0ccdf362200..b244c7124179 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -484,7 +484,6 @@ ahd_linux_target_alloc(struct scsi_target *starget) | |||
484 | struct seeprom_config *sc = ahd->seep_config; | 484 | struct seeprom_config *sc = ahd->seep_config; |
485 | unsigned long flags; | 485 | unsigned long flags; |
486 | struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget); | 486 | struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget); |
487 | struct ahd_linux_target *targ = scsi_transport_target_data(starget); | ||
488 | struct ahd_devinfo devinfo; | 487 | struct ahd_devinfo devinfo; |
489 | struct ahd_initiator_tinfo *tinfo; | 488 | struct ahd_initiator_tinfo *tinfo; |
490 | struct ahd_tmode_tstate *tstate; | 489 | struct ahd_tmode_tstate *tstate; |
@@ -495,7 +494,6 @@ ahd_linux_target_alloc(struct scsi_target *starget) | |||
495 | BUG_ON(*ahd_targp != NULL); | 494 | BUG_ON(*ahd_targp != NULL); |
496 | 495 | ||
497 | *ahd_targp = starget; | 496 | *ahd_targp = starget; |
498 | memset(targ, 0, sizeof(*targ)); | ||
499 | 497 | ||
500 | if (sc) { | 498 | if (sc) { |
501 | int flags = sc->device_flags[starget->id]; | 499 | int flags = sc->device_flags[starget->id]; |
@@ -551,15 +549,11 @@ ahd_linux_slave_alloc(struct scsi_device *sdev) | |||
551 | { | 549 | { |
552 | struct ahd_softc *ahd = | 550 | struct ahd_softc *ahd = |
553 | *((struct ahd_softc **)sdev->host->hostdata); | 551 | *((struct ahd_softc **)sdev->host->hostdata); |
554 | struct scsi_target *starget = sdev->sdev_target; | ||
555 | struct ahd_linux_target *targ = scsi_transport_target_data(starget); | ||
556 | struct ahd_linux_device *dev; | 552 | struct ahd_linux_device *dev; |
557 | 553 | ||
558 | if (bootverbose) | 554 | if (bootverbose) |
559 | printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id); | 555 | printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id); |
560 | 556 | ||
561 | BUG_ON(targ->sdev[sdev->lun] != NULL); | ||
562 | |||
563 | dev = scsi_transport_device_data(sdev); | 557 | dev = scsi_transport_device_data(sdev); |
564 | memset(dev, 0, sizeof(*dev)); | 558 | memset(dev, 0, sizeof(*dev)); |
565 | 559 | ||
@@ -576,8 +570,6 @@ ahd_linux_slave_alloc(struct scsi_device *sdev) | |||
576 | */ | 570 | */ |
577 | dev->maxtags = 0; | 571 | dev->maxtags = 0; |
578 | 572 | ||
579 | targ->sdev[sdev->lun] = sdev; | ||
580 | |||
581 | return (0); | 573 | return (0); |
582 | } | 574 | } |
583 | 575 | ||
@@ -599,23 +591,6 @@ ahd_linux_slave_configure(struct scsi_device *sdev) | |||
599 | return 0; | 591 | return 0; |
600 | } | 592 | } |
601 | 593 | ||
602 | static void | ||
603 | ahd_linux_slave_destroy(struct scsi_device *sdev) | ||
604 | { | ||
605 | struct ahd_softc *ahd; | ||
606 | struct ahd_linux_device *dev = scsi_transport_device_data(sdev); | ||
607 | struct ahd_linux_target *targ = scsi_transport_target_data(sdev->sdev_target); | ||
608 | |||
609 | ahd = *((struct ahd_softc **)sdev->host->hostdata); | ||
610 | if (bootverbose) | ||
611 | printf("%s: Slave Destroy %d\n", ahd_name(ahd), sdev->id); | ||
612 | |||
613 | BUG_ON(dev->active); | ||
614 | |||
615 | targ->sdev[sdev->lun] = NULL; | ||
616 | |||
617 | } | ||
618 | |||
619 | #if defined(__i386__) | 594 | #if defined(__i386__) |
620 | /* | 595 | /* |
621 | * Return the disk geometry for the given SCSI device. | 596 | * Return the disk geometry for the given SCSI device. |
@@ -822,7 +797,6 @@ struct scsi_host_template aic79xx_driver_template = { | |||
822 | .use_clustering = ENABLE_CLUSTERING, | 797 | .use_clustering = ENABLE_CLUSTERING, |
823 | .slave_alloc = ahd_linux_slave_alloc, | 798 | .slave_alloc = ahd_linux_slave_alloc, |
824 | .slave_configure = ahd_linux_slave_configure, | 799 | .slave_configure = ahd_linux_slave_configure, |
825 | .slave_destroy = ahd_linux_slave_destroy, | ||
826 | .target_alloc = ahd_linux_target_alloc, | 800 | .target_alloc = ahd_linux_target_alloc, |
827 | .target_destroy = ahd_linux_target_destroy, | 801 | .target_destroy = ahd_linux_target_destroy, |
828 | }; | 802 | }; |
@@ -1249,20 +1223,13 @@ void | |||
1249 | ahd_platform_free(struct ahd_softc *ahd) | 1223 | ahd_platform_free(struct ahd_softc *ahd) |
1250 | { | 1224 | { |
1251 | struct scsi_target *starget; | 1225 | struct scsi_target *starget; |
1252 | int i, j; | 1226 | int i; |
1253 | 1227 | ||
1254 | if (ahd->platform_data != NULL) { | 1228 | if (ahd->platform_data != NULL) { |
1255 | /* destroy all of the device and target objects */ | 1229 | /* destroy all of the device and target objects */ |
1256 | for (i = 0; i < AHD_NUM_TARGETS; i++) { | 1230 | for (i = 0; i < AHD_NUM_TARGETS; i++) { |
1257 | starget = ahd->platform_data->starget[i]; | 1231 | starget = ahd->platform_data->starget[i]; |
1258 | if (starget != NULL) { | 1232 | if (starget != NULL) { |
1259 | for (j = 0; j < AHD_NUM_LUNS; j++) { | ||
1260 | struct ahd_linux_target *targ = | ||
1261 | scsi_transport_target_data(starget); | ||
1262 | if (targ->sdev[j] == NULL) | ||
1263 | continue; | ||
1264 | targ->sdev[j] = NULL; | ||
1265 | } | ||
1266 | ahd->platform_data->starget[i] = NULL; | 1233 | ahd->platform_data->starget[i] = NULL; |
1267 | } | 1234 | } |
1268 | } | 1235 | } |
@@ -1318,20 +1285,13 @@ ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb) | |||
1318 | } | 1285 | } |
1319 | 1286 | ||
1320 | void | 1287 | void |
1321 | ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | 1288 | ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, |
1322 | ahd_queue_alg alg) | 1289 | struct ahd_devinfo *devinfo, ahd_queue_alg alg) |
1323 | { | 1290 | { |
1324 | struct scsi_target *starget; | ||
1325 | struct ahd_linux_target *targ; | ||
1326 | struct ahd_linux_device *dev; | 1291 | struct ahd_linux_device *dev; |
1327 | struct scsi_device *sdev; | ||
1328 | int was_queuing; | 1292 | int was_queuing; |
1329 | int now_queuing; | 1293 | int now_queuing; |
1330 | 1294 | ||
1331 | starget = ahd->platform_data->starget[devinfo->target]; | ||
1332 | targ = scsi_transport_target_data(starget); | ||
1333 | BUG_ON(targ == NULL); | ||
1334 | sdev = targ->sdev[devinfo->lun]; | ||
1335 | if (sdev == NULL) | 1295 | if (sdev == NULL) |
1336 | return; | 1296 | return; |
1337 | 1297 | ||
@@ -1467,11 +1427,15 @@ ahd_linux_device_queue_depth(struct scsi_device *sdev) | |||
1467 | tags = ahd_linux_user_tagdepth(ahd, &devinfo); | 1427 | tags = ahd_linux_user_tagdepth(ahd, &devinfo); |
1468 | if (tags != 0 && sdev->tagged_supported != 0) { | 1428 | if (tags != 0 && sdev->tagged_supported != 0) { |
1469 | 1429 | ||
1470 | ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED); | 1430 | ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED); |
1431 | ahd_send_async(ahd, devinfo.channel, devinfo.target, | ||
1432 | devinfo.lun, AC_TRANSFER_NEG); | ||
1471 | ahd_print_devinfo(ahd, &devinfo); | 1433 | ahd_print_devinfo(ahd, &devinfo); |
1472 | printf("Tagged Queuing enabled. Depth %d\n", tags); | 1434 | printf("Tagged Queuing enabled. Depth %d\n", tags); |
1473 | } else { | 1435 | } else { |
1474 | ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE); | 1436 | ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE); |
1437 | ahd_send_async(ahd, devinfo.channel, devinfo.target, | ||
1438 | devinfo.lun, AC_TRANSFER_NEG); | ||
1475 | } | 1439 | } |
1476 | } | 1440 | } |
1477 | 1441 | ||
@@ -1629,7 +1593,7 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs) | |||
1629 | 1593 | ||
1630 | void | 1594 | void |
1631 | ahd_send_async(struct ahd_softc *ahd, char channel, | 1595 | ahd_send_async(struct ahd_softc *ahd, char channel, |
1632 | u_int target, u_int lun, ac_code code, void *arg) | 1596 | u_int target, u_int lun, ac_code code) |
1633 | { | 1597 | { |
1634 | switch (code) { | 1598 | switch (code) { |
1635 | case AC_TRANSFER_NEG: | 1599 | case AC_TRANSFER_NEG: |
@@ -1956,7 +1920,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, | |||
1956 | } | 1920 | } |
1957 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); | 1921 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); |
1958 | ahd_set_scsi_status(scb, SCSI_STATUS_OK); | 1922 | ahd_set_scsi_status(scb, SCSI_STATUS_OK); |
1959 | ahd_platform_set_tags(ahd, &devinfo, | 1923 | ahd_platform_set_tags(ahd, sdev, &devinfo, |
1960 | (dev->flags & AHD_DEV_Q_BASIC) | 1924 | (dev->flags & AHD_DEV_Q_BASIC) |
1961 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); | 1925 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); |
1962 | break; | 1926 | break; |
@@ -1966,7 +1930,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, | |||
1966 | * as if the target returned BUSY SCSI status. | 1930 | * as if the target returned BUSY SCSI status. |
1967 | */ | 1931 | */ |
1968 | dev->openings = 1; | 1932 | dev->openings = 1; |
1969 | ahd_platform_set_tags(ahd, &devinfo, | 1933 | ahd_platform_set_tags(ahd, sdev, &devinfo, |
1970 | (dev->flags & AHD_DEV_Q_BASIC) | 1934 | (dev->flags & AHD_DEV_Q_BASIC) |
1971 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); | 1935 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); |
1972 | ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); | 1936 | ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); |
@@ -2778,8 +2742,6 @@ ahd_linux_init(void) | |||
2778 | if (!ahd_linux_transport_template) | 2742 | if (!ahd_linux_transport_template) |
2779 | return -ENODEV; | 2743 | return -ENODEV; |
2780 | 2744 | ||
2781 | scsi_transport_reserve_target(ahd_linux_transport_template, | ||
2782 | sizeof(struct ahd_linux_target)); | ||
2783 | scsi_transport_reserve_device(ahd_linux_transport_template, | 2745 | scsi_transport_reserve_device(ahd_linux_transport_template, |
2784 | sizeof(struct ahd_linux_device)); | 2746 | sizeof(struct ahd_linux_device)); |
2785 | 2747 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 92c6154575e7..9e871de23835 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h | |||
@@ -262,7 +262,6 @@ typedef enum { | |||
262 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ | 262 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ |
263 | } ahd_linux_dev_flags; | 263 | } ahd_linux_dev_flags; |
264 | 264 | ||
265 | struct ahd_linux_target; | ||
266 | struct ahd_linux_device { | 265 | struct ahd_linux_device { |
267 | TAILQ_ENTRY(ahd_linux_device) links; | 266 | TAILQ_ENTRY(ahd_linux_device) links; |
268 | 267 | ||
@@ -342,12 +341,6 @@ struct ahd_linux_device { | |||
342 | #define AHD_OTAG_THRESH 500 | 341 | #define AHD_OTAG_THRESH 500 |
343 | }; | 342 | }; |
344 | 343 | ||
345 | struct ahd_linux_target { | ||
346 | struct scsi_device *sdev[AHD_NUM_LUNS]; | ||
347 | struct ahd_transinfo last_tinfo; | ||
348 | struct ahd_softc *ahd; | ||
349 | }; | ||
350 | |||
351 | /********************* Definitions Required by the Core ***********************/ | 344 | /********************* Definitions Required by the Core ***********************/ |
352 | /* | 345 | /* |
353 | * Number of SG segments we require. So long as the S/G segments for | 346 | * Number of SG segments we require. So long as the S/G segments for |
@@ -864,7 +857,7 @@ ahd_freeze_scb(struct scb *scb) | |||
864 | } | 857 | } |
865 | } | 858 | } |
866 | 859 | ||
867 | void ahd_platform_set_tags(struct ahd_softc *ahd, | 860 | void ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, |
868 | struct ahd_devinfo *devinfo, ahd_queue_alg); | 861 | struct ahd_devinfo *devinfo, ahd_queue_alg); |
869 | int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, | 862 | int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, |
870 | char channel, int lun, u_int tag, | 863 | char channel, int lun, u_int tag, |
@@ -873,7 +866,7 @@ irqreturn_t | |||
873 | ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); | 866 | ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); |
874 | void ahd_done(struct ahd_softc*, struct scb*); | 867 | void ahd_done(struct ahd_softc*, struct scb*); |
875 | void ahd_send_async(struct ahd_softc *, char channel, | 868 | void ahd_send_async(struct ahd_softc *, char channel, |
876 | u_int target, u_int lun, ac_code, void *); | 869 | u_int target, u_int lun, ac_code); |
877 | void ahd_print_path(struct ahd_softc *, struct scb *); | 870 | void ahd_print_path(struct ahd_softc *, struct scb *); |
878 | 871 | ||
879 | #ifdef CONFIG_PCI | 872 | #ifdef CONFIG_PCI |
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index 24fd59a230bf..c5f0ee591509 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c | |||
@@ -47,7 +47,7 @@ static int copy_info(struct info_str *info, char *fmt, ...); | |||
47 | static void ahd_dump_target_state(struct ahd_softc *ahd, | 47 | static void ahd_dump_target_state(struct ahd_softc *ahd, |
48 | struct info_str *info, | 48 | struct info_str *info, |
49 | u_int our_id, char channel, | 49 | u_int our_id, char channel, |
50 | u_int target_id, u_int target_offset); | 50 | u_int target_id); |
51 | static void ahd_dump_device_state(struct info_str *info, | 51 | static void ahd_dump_device_state(struct info_str *info, |
52 | struct scsi_device *sdev); | 52 | struct scsi_device *sdev); |
53 | static int ahd_proc_write_seeprom(struct ahd_softc *ahd, | 53 | static int ahd_proc_write_seeprom(struct ahd_softc *ahd, |
@@ -204,10 +204,8 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) | |||
204 | 204 | ||
205 | static void | 205 | static void |
206 | ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | 206 | ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, |
207 | u_int our_id, char channel, u_int target_id, | 207 | u_int our_id, char channel, u_int target_id) |
208 | u_int target_offset) | ||
209 | { | 208 | { |
210 | struct ahd_linux_target *targ; | ||
211 | struct scsi_target *starget; | 209 | struct scsi_target *starget; |
212 | struct ahd_initiator_tinfo *tinfo; | 210 | struct ahd_initiator_tinfo *tinfo; |
213 | struct ahd_tmode_tstate *tstate; | 211 | struct ahd_tmode_tstate *tstate; |
@@ -218,10 +216,9 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | |||
218 | copy_info(info, "Target %d Negotiation Settings\n", target_id); | 216 | copy_info(info, "Target %d Negotiation Settings\n", target_id); |
219 | copy_info(info, "\tUser: "); | 217 | copy_info(info, "\tUser: "); |
220 | ahd_format_transinfo(info, &tinfo->user); | 218 | ahd_format_transinfo(info, &tinfo->user); |
221 | starget = ahd->platform_data->starget[target_offset]; | 219 | starget = ahd->platform_data->starget[target_id]; |
222 | if (starget == NULL) | 220 | if (starget == NULL) |
223 | return; | 221 | return; |
224 | targ = scsi_transport_target_data(starget); | ||
225 | 222 | ||
226 | copy_info(info, "\tGoal: "); | 223 | copy_info(info, "\tGoal: "); |
227 | ahd_format_transinfo(info, &tinfo->goal); | 224 | ahd_format_transinfo(info, &tinfo->goal); |
@@ -231,7 +228,7 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | |||
231 | for (lun = 0; lun < AHD_NUM_LUNS; lun++) { | 228 | for (lun = 0; lun < AHD_NUM_LUNS; lun++) { |
232 | struct scsi_device *dev; | 229 | struct scsi_device *dev; |
233 | 230 | ||
234 | dev = targ->sdev[lun]; | 231 | dev = scsi_device_lookup_by_target(starget, lun); |
235 | 232 | ||
236 | if (dev == NULL) | 233 | if (dev == NULL) |
237 | continue; | 234 | continue; |
@@ -355,7 +352,7 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
355 | copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", | 352 | copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", |
356 | ahd->scb_data.numscbs, AHD_NSEG); | 353 | ahd->scb_data.numscbs, AHD_NSEG); |
357 | 354 | ||
358 | max_targ = 15; | 355 | max_targ = 16; |
359 | 356 | ||
360 | if (ahd->seep_config == NULL) | 357 | if (ahd->seep_config == NULL) |
361 | copy_info(&info, "No Serial EEPROM\n"); | 358 | copy_info(&info, "No Serial EEPROM\n"); |
@@ -373,12 +370,12 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
373 | copy_info(&info, "\n"); | 370 | copy_info(&info, "\n"); |
374 | 371 | ||
375 | if ((ahd->features & AHD_WIDE) == 0) | 372 | if ((ahd->features & AHD_WIDE) == 0) |
376 | max_targ = 7; | 373 | max_targ = 8; |
377 | 374 | ||
378 | for (i = 0; i <= max_targ; i++) { | 375 | for (i = 0; i < max_targ; i++) { |
379 | 376 | ||
380 | ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', | 377 | ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', |
381 | /*target_id*/i, /*target_offset*/i); | 378 | /*target_id*/i); |
382 | } | 379 | } |
383 | retval = info.pos > info.offset ? info.pos - info.offset : 0; | 380 | retval = info.pos > info.offset ? info.pos - info.offset : 0; |
384 | done: | 381 | done: |
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 412f8301b757..0ec41f34f462 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
@@ -2625,29 +2625,32 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2625 | unsigned int base_io, tmport, error,n; | 2625 | unsigned int base_io, tmport, error,n; |
2626 | unsigned char host_id; | 2626 | unsigned char host_id; |
2627 | struct Scsi_Host *shpnt = NULL; | 2627 | struct Scsi_Host *shpnt = NULL; |
2628 | struct atp_unit atp_dev, *p; | 2628 | struct atp_unit *atpdev, *p; |
2629 | unsigned char setupdata[2][16]; | 2629 | unsigned char setupdata[2][16]; |
2630 | int count = 0; | 2630 | int count = 0; |
2631 | 2631 | ||
2632 | atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL); | ||
2633 | if (!atpdev) | ||
2634 | return -ENOMEM; | ||
2635 | |||
2632 | if (pci_enable_device(pdev)) | 2636 | if (pci_enable_device(pdev)) |
2633 | return -EIO; | 2637 | goto err_eio; |
2634 | 2638 | ||
2635 | if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | 2639 | if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
2636 | printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); | 2640 | printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); |
2637 | } else { | 2641 | } else { |
2638 | printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); | 2642 | printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); |
2639 | return -EIO; | 2643 | goto err_eio; |
2640 | } | 2644 | } |
2641 | 2645 | ||
2642 | memset(&atp_dev, 0, sizeof atp_dev); | ||
2643 | /* | 2646 | /* |
2644 | * It's probably easier to weed out some revisions like | 2647 | * It's probably easier to weed out some revisions like |
2645 | * this than via the PCI device table | 2648 | * this than via the PCI device table |
2646 | */ | 2649 | */ |
2647 | if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { | 2650 | if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { |
2648 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); | 2651 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); |
2649 | if (atp_dev.chip_ver < 2) | 2652 | if (atpdev->chip_ver < 2) |
2650 | return -EIO; | 2653 | goto err_eio; |
2651 | } | 2654 | } |
2652 | 2655 | ||
2653 | switch (ent->device) { | 2656 | switch (ent->device) { |
@@ -2656,15 +2659,15 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2656 | case ATP880_DEVID1: | 2659 | case ATP880_DEVID1: |
2657 | case ATP880_DEVID2: | 2660 | case ATP880_DEVID2: |
2658 | case ATP885_DEVID: | 2661 | case ATP885_DEVID: |
2659 | atp_dev.chip_ver = 0x04; | 2662 | atpdev->chip_ver = 0x04; |
2660 | default: | 2663 | default: |
2661 | break; | 2664 | break; |
2662 | } | 2665 | } |
2663 | base_io = pci_resource_start(pdev, 0); | 2666 | base_io = pci_resource_start(pdev, 0); |
2664 | base_io &= 0xfffffff8; | 2667 | base_io &= 0xfffffff8; |
2665 | 2668 | ||
2666 | if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { | 2669 | if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { |
2667 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); | 2670 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); |
2668 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 | 2671 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 |
2669 | 2672 | ||
2670 | host_id = inb(base_io + 0x39); | 2673 | host_id = inb(base_io + 0x39); |
@@ -2672,17 +2675,17 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2672 | 2675 | ||
2673 | printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" | 2676 | printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" |
2674 | " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); | 2677 | " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
2675 | atp_dev.ioport[0] = base_io + 0x40; | 2678 | atpdev->ioport[0] = base_io + 0x40; |
2676 | atp_dev.pciport[0] = base_io + 0x28; | 2679 | atpdev->pciport[0] = base_io + 0x28; |
2677 | atp_dev.dev_id = ent->device; | 2680 | atpdev->dev_id = ent->device; |
2678 | atp_dev.host_id[0] = host_id; | 2681 | atpdev->host_id[0] = host_id; |
2679 | 2682 | ||
2680 | tmport = base_io + 0x22; | 2683 | tmport = base_io + 0x22; |
2681 | atp_dev.scam_on = inb(tmport); | 2684 | atpdev->scam_on = inb(tmport); |
2682 | tmport += 0x13; | 2685 | tmport += 0x13; |
2683 | atp_dev.global_map[0] = inb(tmport); | 2686 | atpdev->global_map[0] = inb(tmport); |
2684 | tmport += 0x07; | 2687 | tmport += 0x07; |
2685 | atp_dev.ultra_map[0] = inw(tmport); | 2688 | atpdev->ultra_map[0] = inw(tmport); |
2686 | 2689 | ||
2687 | n = 0x3f09; | 2690 | n = 0x3f09; |
2688 | next_fblk_880: | 2691 | next_fblk_880: |
@@ -2695,57 +2698,57 @@ next_fblk_880: | |||
2695 | if (inb(base_io + 0x30) == 0xff) | 2698 | if (inb(base_io + 0x30) == 0xff) |
2696 | goto flash_ok_880; | 2699 | goto flash_ok_880; |
2697 | 2700 | ||
2698 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2701 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2699 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2702 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2700 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2703 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2701 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2704 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2702 | outw(n, base_io + 0x34); | 2705 | outw(n, base_io + 0x34); |
2703 | n += 0x0002; | 2706 | n += 0x0002; |
2704 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2707 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2705 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2708 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2706 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2709 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2707 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2710 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2708 | outw(n, base_io + 0x34); | 2711 | outw(n, base_io + 0x34); |
2709 | n += 0x0002; | 2712 | n += 0x0002; |
2710 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2713 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2711 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2714 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2712 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2715 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2713 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2716 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2714 | outw(n, base_io + 0x34); | 2717 | outw(n, base_io + 0x34); |
2715 | n += 0x0002; | 2718 | n += 0x0002; |
2716 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2719 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2717 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2720 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2718 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2721 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2719 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2722 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2720 | n += 0x0018; | 2723 | n += 0x0018; |
2721 | goto next_fblk_880; | 2724 | goto next_fblk_880; |
2722 | flash_ok_880: | 2725 | flash_ok_880: |
2723 | outw(0, base_io + 0x34); | 2726 | outw(0, base_io + 0x34); |
2724 | atp_dev.ultra_map[0] = 0; | 2727 | atpdev->ultra_map[0] = 0; |
2725 | atp_dev.async[0] = 0; | 2728 | atpdev->async[0] = 0; |
2726 | for (k = 0; k < 16; k++) { | 2729 | for (k = 0; k < 16; k++) { |
2727 | n = 1; | 2730 | n = 1; |
2728 | n = n << k; | 2731 | n = n << k; |
2729 | if (atp_dev.sp[0][k] > 1) { | 2732 | if (atpdev->sp[0][k] > 1) { |
2730 | atp_dev.ultra_map[0] |= n; | 2733 | atpdev->ultra_map[0] |= n; |
2731 | } else { | 2734 | } else { |
2732 | if (atp_dev.sp[0][k] == 0) | 2735 | if (atpdev->sp[0][k] == 0) |
2733 | atp_dev.async[0] |= n; | 2736 | atpdev->async[0] |= n; |
2734 | } | 2737 | } |
2735 | } | 2738 | } |
2736 | atp_dev.async[0] = ~(atp_dev.async[0]); | 2739 | atpdev->async[0] = ~(atpdev->async[0]); |
2737 | outb(atp_dev.global_map[0], base_io + 0x35); | 2740 | outb(atpdev->global_map[0], base_io + 0x35); |
2738 | 2741 | ||
2739 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2742 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2740 | if (!shpnt) | 2743 | if (!shpnt) |
2741 | return -ENOMEM; | 2744 | goto err_nomem; |
2742 | 2745 | ||
2743 | p = (struct atp_unit *)&shpnt->hostdata; | 2746 | p = (struct atp_unit *)&shpnt->hostdata; |
2744 | 2747 | ||
2745 | atp_dev.host = shpnt; | 2748 | atpdev->host = shpnt; |
2746 | atp_dev.pdev = pdev; | 2749 | atpdev->pdev = pdev; |
2747 | pci_set_drvdata(pdev, p); | 2750 | pci_set_drvdata(pdev, p); |
2748 | memcpy(p, &atp_dev, sizeof atp_dev); | 2751 | memcpy(p, atpdev, sizeof(*atpdev)); |
2749 | if (atp870u_init_tables(shpnt) < 0) { | 2752 | if (atp870u_init_tables(shpnt) < 0) { |
2750 | printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); | 2753 | printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); |
2751 | goto unregister; | 2754 | goto unregister; |
@@ -2798,24 +2801,24 @@ flash_ok_880: | |||
2798 | printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" | 2801 | printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" |
2799 | , base_io, pdev->irq); | 2802 | , base_io, pdev->irq); |
2800 | 2803 | ||
2801 | atp_dev.pdev = pdev; | 2804 | atpdev->pdev = pdev; |
2802 | atp_dev.dev_id = ent->device; | 2805 | atpdev->dev_id = ent->device; |
2803 | atp_dev.baseport = base_io; | 2806 | atpdev->baseport = base_io; |
2804 | atp_dev.ioport[0] = base_io + 0x80; | 2807 | atpdev->ioport[0] = base_io + 0x80; |
2805 | atp_dev.ioport[1] = base_io + 0xc0; | 2808 | atpdev->ioport[1] = base_io + 0xc0; |
2806 | atp_dev.pciport[0] = base_io + 0x40; | 2809 | atpdev->pciport[0] = base_io + 0x40; |
2807 | atp_dev.pciport[1] = base_io + 0x50; | 2810 | atpdev->pciport[1] = base_io + 0x50; |
2808 | 2811 | ||
2809 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2812 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2810 | if (!shpnt) | 2813 | if (!shpnt) |
2811 | return -ENOMEM; | 2814 | goto err_nomem; |
2812 | 2815 | ||
2813 | p = (struct atp_unit *)&shpnt->hostdata; | 2816 | p = (struct atp_unit *)&shpnt->hostdata; |
2814 | 2817 | ||
2815 | atp_dev.host = shpnt; | 2818 | atpdev->host = shpnt; |
2816 | atp_dev.pdev = pdev; | 2819 | atpdev->pdev = pdev; |
2817 | pci_set_drvdata(pdev, p); | 2820 | pci_set_drvdata(pdev, p); |
2818 | memcpy(p, &atp_dev, sizeof(struct atp_unit)); | 2821 | memcpy(p, atpdev, sizeof(struct atp_unit)); |
2819 | if (atp870u_init_tables(shpnt) < 0) | 2822 | if (atp870u_init_tables(shpnt) < 0) |
2820 | goto unregister; | 2823 | goto unregister; |
2821 | 2824 | ||
@@ -2974,33 +2977,33 @@ flash_ok_885: | |||
2974 | printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " | 2977 | printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " |
2975 | "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); | 2978 | "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
2976 | 2979 | ||
2977 | atp_dev.ioport[0] = base_io; | 2980 | atpdev->ioport[0] = base_io; |
2978 | atp_dev.pciport[0] = base_io + 0x20; | 2981 | atpdev->pciport[0] = base_io + 0x20; |
2979 | atp_dev.dev_id = ent->device; | 2982 | atpdev->dev_id = ent->device; |
2980 | host_id &= 0x07; | 2983 | host_id &= 0x07; |
2981 | atp_dev.host_id[0] = host_id; | 2984 | atpdev->host_id[0] = host_id; |
2982 | tmport = base_io + 0x22; | 2985 | tmport = base_io + 0x22; |
2983 | atp_dev.scam_on = inb(tmport); | 2986 | atpdev->scam_on = inb(tmport); |
2984 | tmport += 0x0b; | 2987 | tmport += 0x0b; |
2985 | atp_dev.global_map[0] = inb(tmport++); | 2988 | atpdev->global_map[0] = inb(tmport++); |
2986 | atp_dev.ultra_map[0] = inw(tmport); | 2989 | atpdev->ultra_map[0] = inw(tmport); |
2987 | 2990 | ||
2988 | if (atp_dev.ultra_map[0] == 0) { | 2991 | if (atpdev->ultra_map[0] == 0) { |
2989 | atp_dev.scam_on = 0x00; | 2992 | atpdev->scam_on = 0x00; |
2990 | atp_dev.global_map[0] = 0x20; | 2993 | atpdev->global_map[0] = 0x20; |
2991 | atp_dev.ultra_map[0] = 0xffff; | 2994 | atpdev->ultra_map[0] = 0xffff; |
2992 | } | 2995 | } |
2993 | 2996 | ||
2994 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2997 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2995 | if (!shpnt) | 2998 | if (!shpnt) |
2996 | return -ENOMEM; | 2999 | goto err_nomem; |
2997 | 3000 | ||
2998 | p = (struct atp_unit *)&shpnt->hostdata; | 3001 | p = (struct atp_unit *)&shpnt->hostdata; |
2999 | 3002 | ||
3000 | atp_dev.host = shpnt; | 3003 | atpdev->host = shpnt; |
3001 | atp_dev.pdev = pdev; | 3004 | atpdev->pdev = pdev; |
3002 | pci_set_drvdata(pdev, p); | 3005 | pci_set_drvdata(pdev, p); |
3003 | memcpy(p, &atp_dev, sizeof atp_dev); | 3006 | memcpy(p, atpdev, sizeof(*atpdev)); |
3004 | if (atp870u_init_tables(shpnt) < 0) | 3007 | if (atp870u_init_tables(shpnt) < 0) |
3005 | goto unregister; | 3008 | goto unregister; |
3006 | 3009 | ||
@@ -3010,7 +3013,7 @@ flash_ok_885: | |||
3010 | } | 3013 | } |
3011 | 3014 | ||
3012 | spin_lock_irqsave(shpnt->host_lock, flags); | 3015 | spin_lock_irqsave(shpnt->host_lock, flags); |
3013 | if (atp_dev.chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ | 3016 | if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ |
3014 | tmport = base_io + 0x3e; | 3017 | tmport = base_io + 0x3e; |
3015 | outb(0x00, tmport); | 3018 | outb(0x00, tmport); |
3016 | } | 3019 | } |
@@ -3044,7 +3047,7 @@ flash_ok_885: | |||
3044 | outb((inb(tmport) & 0xef), tmport); | 3047 | outb((inb(tmport) & 0xef), tmport); |
3045 | tmport++; | 3048 | tmport++; |
3046 | outb((inb(tmport) | 0x20), tmport); | 3049 | outb((inb(tmport) | 0x20), tmport); |
3047 | if (atp_dev.chip_ver == 4) | 3050 | if (atpdev->chip_ver == 4) |
3048 | shpnt->max_id = 16; | 3051 | shpnt->max_id = 16; |
3049 | else | 3052 | else |
3050 | shpnt->max_id = 8; | 3053 | shpnt->max_id = 8; |
@@ -3093,6 +3096,12 @@ unregister: | |||
3093 | printk("atp870u_prob:unregister\n"); | 3096 | printk("atp870u_prob:unregister\n"); |
3094 | scsi_host_put(shpnt); | 3097 | scsi_host_put(shpnt); |
3095 | return -1; | 3098 | return -1; |
3099 | err_eio: | ||
3100 | kfree(atpdev); | ||
3101 | return -EIO; | ||
3102 | err_nomem: | ||
3103 | kfree(atpdev); | ||
3104 | return -ENOMEM; | ||
3096 | } | 3105 | } |
3097 | 3106 | ||
3098 | /* The abort command does not leave the device in a clean state where | 3107 | /* The abort command does not leave the device in a clean state where |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 944fc1203ebd..669ea4fff166 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -535,6 +535,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
535 | struct ibmvscsi_host_data *hostdata) | 535 | struct ibmvscsi_host_data *hostdata) |
536 | { | 536 | { |
537 | u64 *crq_as_u64 = (u64 *) &evt_struct->crq; | 537 | u64 *crq_as_u64 = (u64 *) &evt_struct->crq; |
538 | int request_status; | ||
538 | int rc; | 539 | int rc; |
539 | 540 | ||
540 | /* If we have exhausted our request limit, just fail this request. | 541 | /* If we have exhausted our request limit, just fail this request. |
@@ -542,9 +543,18 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
542 | * (such as task management requests) that the mid layer may think we | 543 | * (such as task management requests) that the mid layer may think we |
543 | * can handle more requests (can_queue) when we actually can't | 544 | * can handle more requests (can_queue) when we actually can't |
544 | */ | 545 | */ |
545 | if ((evt_struct->crq.format == VIOSRP_SRP_FORMAT) && | 546 | if (evt_struct->crq.format == VIOSRP_SRP_FORMAT) { |
546 | (atomic_dec_if_positive(&hostdata->request_limit) < 0)) | 547 | request_status = |
547 | goto send_error; | 548 | atomic_dec_if_positive(&hostdata->request_limit); |
549 | /* If request limit was -1 when we started, it is now even | ||
550 | * less than that | ||
551 | */ | ||
552 | if (request_status < -1) | ||
553 | goto send_error; | ||
554 | /* Otherwise, if we have run out of requests */ | ||
555 | else if (request_status < 0) | ||
556 | goto send_busy; | ||
557 | } | ||
548 | 558 | ||
549 | /* Copy the IU into the transfer area */ | 559 | /* Copy the IU into the transfer area */ |
550 | *evt_struct->xfer_iu = evt_struct->iu; | 560 | *evt_struct->xfer_iu = evt_struct->iu; |
@@ -567,11 +577,23 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
567 | 577 | ||
568 | return 0; | 578 | return 0; |
569 | 579 | ||
570 | send_error: | 580 | send_busy: |
571 | unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); | 581 | unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); |
572 | 582 | ||
573 | free_event_struct(&hostdata->pool, evt_struct); | 583 | free_event_struct(&hostdata->pool, evt_struct); |
574 | return SCSI_MLQUEUE_HOST_BUSY; | 584 | return SCSI_MLQUEUE_HOST_BUSY; |
585 | |||
586 | send_error: | ||
587 | unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); | ||
588 | |||
589 | if (evt_struct->cmnd != NULL) { | ||
590 | evt_struct->cmnd->result = DID_ERROR << 16; | ||
591 | evt_struct->cmnd_done(evt_struct->cmnd); | ||
592 | } else if (evt_struct->done) | ||
593 | evt_struct->done(evt_struct); | ||
594 | |||
595 | free_event_struct(&hostdata->pool, evt_struct); | ||
596 | return 0; | ||
575 | } | 597 | } |
576 | 598 | ||
577 | /** | 599 | /** |
@@ -1184,27 +1206,37 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1184 | return; | 1206 | return; |
1185 | case 0xFF: /* Hypervisor telling us the connection is closed */ | 1207 | case 0xFF: /* Hypervisor telling us the connection is closed */ |
1186 | scsi_block_requests(hostdata->host); | 1208 | scsi_block_requests(hostdata->host); |
1209 | atomic_set(&hostdata->request_limit, 0); | ||
1187 | if (crq->format == 0x06) { | 1210 | if (crq->format == 0x06) { |
1188 | /* We need to re-setup the interpartition connection */ | 1211 | /* We need to re-setup the interpartition connection */ |
1189 | printk(KERN_INFO | 1212 | printk(KERN_INFO |
1190 | "ibmvscsi: Re-enabling adapter!\n"); | 1213 | "ibmvscsi: Re-enabling adapter!\n"); |
1191 | atomic_set(&hostdata->request_limit, -1); | ||
1192 | purge_requests(hostdata, DID_REQUEUE); | 1214 | purge_requests(hostdata, DID_REQUEUE); |
1193 | if (ibmvscsi_reenable_crq_queue(&hostdata->queue, | 1215 | if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, |
1194 | hostdata) == 0) | 1216 | hostdata) == 0) || |
1195 | if (ibmvscsi_send_crq(hostdata, | 1217 | (ibmvscsi_send_crq(hostdata, |
1196 | 0xC001000000000000LL, 0)) | 1218 | 0xC001000000000000LL, 0))) { |
1219 | atomic_set(&hostdata->request_limit, | ||
1220 | -1); | ||
1197 | printk(KERN_ERR | 1221 | printk(KERN_ERR |
1198 | "ibmvscsi: transmit error after" | 1222 | "ibmvscsi: error after" |
1199 | " enable\n"); | 1223 | " enable\n"); |
1224 | } | ||
1200 | } else { | 1225 | } else { |
1201 | printk(KERN_INFO | 1226 | printk(KERN_INFO |
1202 | "ibmvscsi: Virtual adapter failed rc %d!\n", | 1227 | "ibmvscsi: Virtual adapter failed rc %d!\n", |
1203 | crq->format); | 1228 | crq->format); |
1204 | 1229 | ||
1205 | atomic_set(&hostdata->request_limit, -1); | ||
1206 | purge_requests(hostdata, DID_ERROR); | 1230 | purge_requests(hostdata, DID_ERROR); |
1207 | ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata); | 1231 | if ((ibmvscsi_reset_crq_queue(&hostdata->queue, |
1232 | hostdata)) || | ||
1233 | (ibmvscsi_send_crq(hostdata, | ||
1234 | 0xC001000000000000LL, 0))) { | ||
1235 | atomic_set(&hostdata->request_limit, | ||
1236 | -1); | ||
1237 | printk(KERN_ERR | ||
1238 | "ibmvscsi: error after reset\n"); | ||
1239 | } | ||
1208 | } | 1240 | } |
1209 | scsi_unblock_requests(hostdata->host); | 1241 | scsi_unblock_requests(hostdata->host); |
1210 | return; | 1242 | return; |
@@ -1467,6 +1499,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1467 | struct Scsi_Host *host; | 1499 | struct Scsi_Host *host; |
1468 | struct device *dev = &vdev->dev; | 1500 | struct device *dev = &vdev->dev; |
1469 | unsigned long wait_switch = 0; | 1501 | unsigned long wait_switch = 0; |
1502 | int rc; | ||
1470 | 1503 | ||
1471 | vdev->dev.driver_data = NULL; | 1504 | vdev->dev.driver_data = NULL; |
1472 | 1505 | ||
@@ -1484,8 +1517,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1484 | atomic_set(&hostdata->request_limit, -1); | 1517 | atomic_set(&hostdata->request_limit, -1); |
1485 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ | 1518 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ |
1486 | 1519 | ||
1487 | if (ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, | 1520 | rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests); |
1488 | max_requests) != 0) { | 1521 | if (rc != 0 && rc != H_RESOURCE) { |
1489 | printk(KERN_ERR "ibmvscsi: couldn't initialize crq\n"); | 1522 | printk(KERN_ERR "ibmvscsi: couldn't initialize crq\n"); |
1490 | goto init_crq_failed; | 1523 | goto init_crq_failed; |
1491 | } | 1524 | } |
@@ -1505,7 +1538,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1505 | * to fail if the other end is not acive. In that case we don't | 1538 | * to fail if the other end is not acive. In that case we don't |
1506 | * want to scan | 1539 | * want to scan |
1507 | */ | 1540 | */ |
1508 | if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0) { | 1541 | if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 |
1542 | || rc == H_RESOURCE) { | ||
1509 | /* | 1543 | /* |
1510 | * Wait around max init_timeout secs for the adapter to finish | 1544 | * Wait around max init_timeout secs for the adapter to finish |
1511 | * initializing. When we are done initializing, we will have a | 1545 | * initializing. When we are done initializing, we will have a |
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 1a9992bdfef8..242b8873b333 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c | |||
@@ -208,6 +208,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
208 | int max_requests) | 208 | int max_requests) |
209 | { | 209 | { |
210 | int rc; | 210 | int rc; |
211 | int retrc; | ||
211 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 212 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
212 | 213 | ||
213 | queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL); | 214 | queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL); |
@@ -226,7 +227,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
226 | gather_partition_info(); | 227 | gather_partition_info(); |
227 | set_adapter_info(hostdata); | 228 | set_adapter_info(hostdata); |
228 | 229 | ||
229 | rc = plpar_hcall_norets(H_REG_CRQ, | 230 | retrc = rc = plpar_hcall_norets(H_REG_CRQ, |
230 | vdev->unit_address, | 231 | vdev->unit_address, |
231 | queue->msg_token, PAGE_SIZE); | 232 | queue->msg_token, PAGE_SIZE); |
232 | if (rc == H_RESOURCE) | 233 | if (rc == H_RESOURCE) |
@@ -263,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
263 | tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, | 264 | tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, |
264 | (unsigned long)hostdata); | 265 | (unsigned long)hostdata); |
265 | 266 | ||
266 | return 0; | 267 | return retrc; |
267 | 268 | ||
268 | req_irq_failed: | 269 | req_irq_failed: |
269 | do { | 270 | do { |
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index b4743a9ecc80..848fb2aa4ca3 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -2130,19 +2130,21 @@ iscsi_r2tpool_free(struct iscsi_session *session) | |||
2130 | 2130 | ||
2131 | static int | 2131 | static int |
2132 | iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | 2132 | iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, |
2133 | uint32_t value) | 2133 | char *buf, int buflen) |
2134 | { | 2134 | { |
2135 | struct iscsi_conn *conn = cls_conn->dd_data; | 2135 | struct iscsi_conn *conn = cls_conn->dd_data; |
2136 | struct iscsi_session *session = conn->session; | 2136 | struct iscsi_session *session = conn->session; |
2137 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 2137 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
2138 | int value; | ||
2138 | 2139 | ||
2139 | switch(param) { | 2140 | switch(param) { |
2140 | case ISCSI_PARAM_MAX_RECV_DLENGTH: { | 2141 | case ISCSI_PARAM_MAX_RECV_DLENGTH: { |
2141 | char *saveptr = tcp_conn->data; | 2142 | char *saveptr = tcp_conn->data; |
2142 | gfp_t flags = GFP_KERNEL; | 2143 | gfp_t flags = GFP_KERNEL; |
2143 | 2144 | ||
2145 | sscanf(buf, "%d", &value); | ||
2144 | if (tcp_conn->data_size >= value) { | 2146 | if (tcp_conn->data_size >= value) { |
2145 | conn->max_recv_dlength = value; | 2147 | iscsi_set_param(cls_conn, param, buf, buflen); |
2146 | break; | 2148 | break; |
2147 | } | 2149 | } |
2148 | 2150 | ||
@@ -2165,15 +2167,12 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
2165 | else | 2167 | else |
2166 | free_pages((unsigned long)saveptr, | 2168 | free_pages((unsigned long)saveptr, |
2167 | get_order(tcp_conn->data_size)); | 2169 | get_order(tcp_conn->data_size)); |
2168 | conn->max_recv_dlength = value; | 2170 | iscsi_set_param(cls_conn, param, buf, buflen); |
2169 | tcp_conn->data_size = value; | 2171 | tcp_conn->data_size = value; |
2170 | } | ||
2171 | break; | ||
2172 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
2173 | conn->max_xmit_dlength = value; | ||
2174 | break; | 2172 | break; |
2173 | } | ||
2175 | case ISCSI_PARAM_HDRDGST_EN: | 2174 | case ISCSI_PARAM_HDRDGST_EN: |
2176 | conn->hdrdgst_en = value; | 2175 | iscsi_set_param(cls_conn, param, buf, buflen); |
2177 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); | 2176 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); |
2178 | if (conn->hdrdgst_en) { | 2177 | if (conn->hdrdgst_en) { |
2179 | tcp_conn->hdr_size += sizeof(__u32); | 2178 | tcp_conn->hdr_size += sizeof(__u32); |
@@ -2197,7 +2196,7 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
2197 | } | 2196 | } |
2198 | break; | 2197 | break; |
2199 | case ISCSI_PARAM_DATADGST_EN: | 2198 | case ISCSI_PARAM_DATADGST_EN: |
2200 | conn->datadgst_en = value; | 2199 | iscsi_set_param(cls_conn, param, buf, buflen); |
2201 | if (conn->datadgst_en) { | 2200 | if (conn->datadgst_en) { |
2202 | if (!tcp_conn->data_tx_tfm) | 2201 | if (!tcp_conn->data_tx_tfm) |
2203 | tcp_conn->data_tx_tfm = | 2202 | tcp_conn->data_tx_tfm = |
@@ -2220,121 +2219,36 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
2220 | tcp_conn->sendpage = conn->datadgst_en ? | 2219 | tcp_conn->sendpage = conn->datadgst_en ? |
2221 | sock_no_sendpage : tcp_conn->sock->ops->sendpage; | 2220 | sock_no_sendpage : tcp_conn->sock->ops->sendpage; |
2222 | break; | 2221 | break; |
2223 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
2224 | session->initial_r2t_en = value; | ||
2225 | break; | ||
2226 | case ISCSI_PARAM_MAX_R2T: | 2222 | case ISCSI_PARAM_MAX_R2T: |
2223 | sscanf(buf, "%d", &value); | ||
2227 | if (session->max_r2t == roundup_pow_of_two(value)) | 2224 | if (session->max_r2t == roundup_pow_of_two(value)) |
2228 | break; | 2225 | break; |
2229 | iscsi_r2tpool_free(session); | 2226 | iscsi_r2tpool_free(session); |
2230 | session->max_r2t = value; | 2227 | iscsi_set_param(cls_conn, param, buf, buflen); |
2231 | if (session->max_r2t & (session->max_r2t - 1)) | 2228 | if (session->max_r2t & (session->max_r2t - 1)) |
2232 | session->max_r2t = roundup_pow_of_two(session->max_r2t); | 2229 | session->max_r2t = roundup_pow_of_two(session->max_r2t); |
2233 | if (iscsi_r2tpool_alloc(session)) | 2230 | if (iscsi_r2tpool_alloc(session)) |
2234 | return -ENOMEM; | 2231 | return -ENOMEM; |
2235 | break; | 2232 | break; |
2236 | case ISCSI_PARAM_IMM_DATA_EN: | ||
2237 | session->imm_data_en = value; | ||
2238 | break; | ||
2239 | case ISCSI_PARAM_FIRST_BURST: | ||
2240 | session->first_burst = value; | ||
2241 | break; | ||
2242 | case ISCSI_PARAM_MAX_BURST: | ||
2243 | session->max_burst = value; | ||
2244 | break; | ||
2245 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
2246 | session->pdu_inorder_en = value; | ||
2247 | break; | ||
2248 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
2249 | session->dataseq_inorder_en = value; | ||
2250 | break; | ||
2251 | case ISCSI_PARAM_ERL: | ||
2252 | session->erl = value; | ||
2253 | break; | ||
2254 | case ISCSI_PARAM_IFMARKER_EN: | ||
2255 | BUG_ON(value); | ||
2256 | session->ifmarker_en = value; | ||
2257 | break; | ||
2258 | case ISCSI_PARAM_OFMARKER_EN: | ||
2259 | BUG_ON(value); | ||
2260 | session->ofmarker_en = value; | ||
2261 | break; | ||
2262 | case ISCSI_PARAM_EXP_STATSN: | ||
2263 | conn->exp_statsn = value; | ||
2264 | break; | ||
2265 | default: | ||
2266 | break; | ||
2267 | } | ||
2268 | |||
2269 | return 0; | ||
2270 | } | ||
2271 | |||
2272 | static int | ||
2273 | iscsi_session_get_param(struct iscsi_cls_session *cls_session, | ||
2274 | enum iscsi_param param, uint32_t *value) | ||
2275 | { | ||
2276 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
2277 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
2278 | |||
2279 | switch(param) { | ||
2280 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
2281 | *value = session->initial_r2t_en; | ||
2282 | break; | ||
2283 | case ISCSI_PARAM_MAX_R2T: | ||
2284 | *value = session->max_r2t; | ||
2285 | break; | ||
2286 | case ISCSI_PARAM_IMM_DATA_EN: | ||
2287 | *value = session->imm_data_en; | ||
2288 | break; | ||
2289 | case ISCSI_PARAM_FIRST_BURST: | ||
2290 | *value = session->first_burst; | ||
2291 | break; | ||
2292 | case ISCSI_PARAM_MAX_BURST: | ||
2293 | *value = session->max_burst; | ||
2294 | break; | ||
2295 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
2296 | *value = session->pdu_inorder_en; | ||
2297 | break; | ||
2298 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
2299 | *value = session->dataseq_inorder_en; | ||
2300 | break; | ||
2301 | case ISCSI_PARAM_ERL: | ||
2302 | *value = session->erl; | ||
2303 | break; | ||
2304 | case ISCSI_PARAM_IFMARKER_EN: | ||
2305 | *value = session->ifmarker_en; | ||
2306 | break; | ||
2307 | case ISCSI_PARAM_OFMARKER_EN: | ||
2308 | *value = session->ofmarker_en; | ||
2309 | break; | ||
2310 | default: | 2233 | default: |
2311 | return -EINVAL; | 2234 | return iscsi_set_param(cls_conn, param, buf, buflen); |
2312 | } | 2235 | } |
2313 | 2236 | ||
2314 | return 0; | 2237 | return 0; |
2315 | } | 2238 | } |
2316 | 2239 | ||
2317 | static int | 2240 | static int |
2318 | iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | 2241 | iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, |
2319 | enum iscsi_param param, uint32_t *value) | 2242 | enum iscsi_param param, char *buf) |
2320 | { | 2243 | { |
2321 | struct iscsi_conn *conn = cls_conn->dd_data; | 2244 | struct iscsi_conn *conn = cls_conn->dd_data; |
2322 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 2245 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
2323 | struct inet_sock *inet; | 2246 | struct inet_sock *inet; |
2247 | struct ipv6_pinfo *np; | ||
2248 | struct sock *sk; | ||
2249 | int len; | ||
2324 | 2250 | ||
2325 | switch(param) { | 2251 | switch(param) { |
2326 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
2327 | *value = conn->max_recv_dlength; | ||
2328 | break; | ||
2329 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
2330 | *value = conn->max_xmit_dlength; | ||
2331 | break; | ||
2332 | case ISCSI_PARAM_HDRDGST_EN: | ||
2333 | *value = conn->hdrdgst_en; | ||
2334 | break; | ||
2335 | case ISCSI_PARAM_DATADGST_EN: | ||
2336 | *value = conn->datadgst_en; | ||
2337 | break; | ||
2338 | case ISCSI_PARAM_CONN_PORT: | 2252 | case ISCSI_PARAM_CONN_PORT: |
2339 | mutex_lock(&conn->xmitmutex); | 2253 | mutex_lock(&conn->xmitmutex); |
2340 | if (!tcp_conn->sock) { | 2254 | if (!tcp_conn->sock) { |
@@ -2343,30 +2257,9 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
2343 | } | 2257 | } |
2344 | 2258 | ||
2345 | inet = inet_sk(tcp_conn->sock->sk); | 2259 | inet = inet_sk(tcp_conn->sock->sk); |
2346 | *value = be16_to_cpu(inet->dport); | 2260 | len = sprintf(buf, "%hu\n", be16_to_cpu(inet->dport)); |
2347 | mutex_unlock(&conn->xmitmutex); | 2261 | mutex_unlock(&conn->xmitmutex); |
2348 | case ISCSI_PARAM_EXP_STATSN: | ||
2349 | *value = conn->exp_statsn; | ||
2350 | break; | 2262 | break; |
2351 | default: | ||
2352 | return -EINVAL; | ||
2353 | } | ||
2354 | |||
2355 | return 0; | ||
2356 | } | ||
2357 | |||
2358 | static int | ||
2359 | iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn, | ||
2360 | enum iscsi_param param, char *buf) | ||
2361 | { | ||
2362 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
2363 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | ||
2364 | struct sock *sk; | ||
2365 | struct inet_sock *inet; | ||
2366 | struct ipv6_pinfo *np; | ||
2367 | int len = 0; | ||
2368 | |||
2369 | switch (param) { | ||
2370 | case ISCSI_PARAM_CONN_ADDRESS: | 2263 | case ISCSI_PARAM_CONN_ADDRESS: |
2371 | mutex_lock(&conn->xmitmutex); | 2264 | mutex_lock(&conn->xmitmutex); |
2372 | if (!tcp_conn->sock) { | 2265 | if (!tcp_conn->sock) { |
@@ -2388,7 +2281,7 @@ iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn, | |||
2388 | mutex_unlock(&conn->xmitmutex); | 2281 | mutex_unlock(&conn->xmitmutex); |
2389 | break; | 2282 | break; |
2390 | default: | 2283 | default: |
2391 | return -EINVAL; | 2284 | return iscsi_conn_get_param(cls_conn, param, buf); |
2392 | } | 2285 | } |
2393 | 2286 | ||
2394 | return len; | 2287 | return len; |
@@ -2501,7 +2394,11 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
2501 | ISCSI_ERL | | 2394 | ISCSI_ERL | |
2502 | ISCSI_CONN_PORT | | 2395 | ISCSI_CONN_PORT | |
2503 | ISCSI_CONN_ADDRESS | | 2396 | ISCSI_CONN_ADDRESS | |
2504 | ISCSI_EXP_STATSN, | 2397 | ISCSI_EXP_STATSN | |
2398 | ISCSI_PERSISTENT_PORT | | ||
2399 | ISCSI_PERSISTENT_ADDRESS | | ||
2400 | ISCSI_TARGET_NAME | | ||
2401 | ISCSI_TPGT, | ||
2505 | .host_template = &iscsi_sht, | 2402 | .host_template = &iscsi_sht, |
2506 | .conndata_size = sizeof(struct iscsi_conn), | 2403 | .conndata_size = sizeof(struct iscsi_conn), |
2507 | .max_conn = 1, | 2404 | .max_conn = 1, |
@@ -2514,8 +2411,7 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
2514 | .bind_conn = iscsi_tcp_conn_bind, | 2411 | .bind_conn = iscsi_tcp_conn_bind, |
2515 | .destroy_conn = iscsi_tcp_conn_destroy, | 2412 | .destroy_conn = iscsi_tcp_conn_destroy, |
2516 | .set_param = iscsi_conn_set_param, | 2413 | .set_param = iscsi_conn_set_param, |
2517 | .get_conn_param = iscsi_conn_get_param, | 2414 | .get_conn_param = iscsi_tcp_conn_get_param, |
2518 | .get_conn_str_param = iscsi_conn_get_str_param, | ||
2519 | .get_session_param = iscsi_session_get_param, | 2415 | .get_session_param = iscsi_session_get_param, |
2520 | .start_conn = iscsi_conn_start, | 2416 | .start_conn = iscsi_conn_start, |
2521 | .stop_conn = iscsi_conn_stop, | 2417 | .stop_conn = iscsi_conn_stop, |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 2673a11a9495..7e6e031cc41b 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -1287,13 +1287,18 @@ iscsi_session_setup(struct iscsi_transport *iscsit, | |||
1287 | if (scsi_add_host(shost, NULL)) | 1287 | if (scsi_add_host(shost, NULL)) |
1288 | goto add_host_fail; | 1288 | goto add_host_fail; |
1289 | 1289 | ||
1290 | if (!try_module_get(iscsit->owner)) | ||
1291 | goto cls_session_fail; | ||
1292 | |||
1290 | cls_session = iscsi_create_session(shost, iscsit, 0); | 1293 | cls_session = iscsi_create_session(shost, iscsit, 0); |
1291 | if (!cls_session) | 1294 | if (!cls_session) |
1292 | goto cls_session_fail; | 1295 | goto module_put; |
1293 | *(unsigned long*)shost->hostdata = (unsigned long)cls_session; | 1296 | *(unsigned long*)shost->hostdata = (unsigned long)cls_session; |
1294 | 1297 | ||
1295 | return cls_session; | 1298 | return cls_session; |
1296 | 1299 | ||
1300 | module_put: | ||
1301 | module_put(iscsit->owner); | ||
1297 | cls_session_fail: | 1302 | cls_session_fail: |
1298 | scsi_remove_host(shost); | 1303 | scsi_remove_host(shost); |
1299 | add_host_fail: | 1304 | add_host_fail: |
@@ -1325,6 +1330,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
1325 | 1330 | ||
1326 | iscsi_destroy_session(cls_session); | 1331 | iscsi_destroy_session(cls_session); |
1327 | scsi_host_put(shost); | 1332 | scsi_host_put(shost); |
1333 | module_put(cls_session->transport->owner); | ||
1328 | } | 1334 | } |
1329 | EXPORT_SYMBOL_GPL(iscsi_session_teardown); | 1335 | EXPORT_SYMBOL_GPL(iscsi_session_teardown); |
1330 | 1336 | ||
@@ -1697,6 +1703,185 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session, | |||
1697 | } | 1703 | } |
1698 | EXPORT_SYMBOL_GPL(iscsi_conn_bind); | 1704 | EXPORT_SYMBOL_GPL(iscsi_conn_bind); |
1699 | 1705 | ||
1706 | |||
1707 | int iscsi_set_param(struct iscsi_cls_conn *cls_conn, | ||
1708 | enum iscsi_param param, char *buf, int buflen) | ||
1709 | { | ||
1710 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
1711 | struct iscsi_session *session = conn->session; | ||
1712 | uint32_t value; | ||
1713 | |||
1714 | switch(param) { | ||
1715 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
1716 | sscanf(buf, "%d", &conn->max_recv_dlength); | ||
1717 | break; | ||
1718 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
1719 | sscanf(buf, "%d", &conn->max_xmit_dlength); | ||
1720 | break; | ||
1721 | case ISCSI_PARAM_HDRDGST_EN: | ||
1722 | sscanf(buf, "%d", &conn->hdrdgst_en); | ||
1723 | break; | ||
1724 | case ISCSI_PARAM_DATADGST_EN: | ||
1725 | sscanf(buf, "%d", &conn->datadgst_en); | ||
1726 | break; | ||
1727 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
1728 | sscanf(buf, "%d", &session->initial_r2t_en); | ||
1729 | break; | ||
1730 | case ISCSI_PARAM_MAX_R2T: | ||
1731 | sscanf(buf, "%d", &session->max_r2t); | ||
1732 | break; | ||
1733 | case ISCSI_PARAM_IMM_DATA_EN: | ||
1734 | sscanf(buf, "%d", &session->imm_data_en); | ||
1735 | break; | ||
1736 | case ISCSI_PARAM_FIRST_BURST: | ||
1737 | sscanf(buf, "%d", &session->first_burst); | ||
1738 | break; | ||
1739 | case ISCSI_PARAM_MAX_BURST: | ||
1740 | sscanf(buf, "%d", &session->max_burst); | ||
1741 | break; | ||
1742 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
1743 | sscanf(buf, "%d", &session->pdu_inorder_en); | ||
1744 | break; | ||
1745 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
1746 | sscanf(buf, "%d", &session->dataseq_inorder_en); | ||
1747 | break; | ||
1748 | case ISCSI_PARAM_ERL: | ||
1749 | sscanf(buf, "%d", &session->erl); | ||
1750 | break; | ||
1751 | case ISCSI_PARAM_IFMARKER_EN: | ||
1752 | sscanf(buf, "%d", &value); | ||
1753 | BUG_ON(value); | ||
1754 | break; | ||
1755 | case ISCSI_PARAM_OFMARKER_EN: | ||
1756 | sscanf(buf, "%d", &value); | ||
1757 | BUG_ON(value); | ||
1758 | break; | ||
1759 | case ISCSI_PARAM_EXP_STATSN: | ||
1760 | sscanf(buf, "%u", &conn->exp_statsn); | ||
1761 | break; | ||
1762 | case ISCSI_PARAM_TARGET_NAME: | ||
1763 | /* this should not change between logins */ | ||
1764 | if (session->targetname) | ||
1765 | break; | ||
1766 | |||
1767 | session->targetname = kstrdup(buf, GFP_KERNEL); | ||
1768 | if (!session->targetname) | ||
1769 | return -ENOMEM; | ||
1770 | break; | ||
1771 | case ISCSI_PARAM_TPGT: | ||
1772 | sscanf(buf, "%d", &session->tpgt); | ||
1773 | break; | ||
1774 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
1775 | sscanf(buf, "%d", &conn->persistent_port); | ||
1776 | break; | ||
1777 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
1778 | /* | ||
1779 | * this is the address returned in discovery so it should | ||
1780 | * not change between logins. | ||
1781 | */ | ||
1782 | if (conn->persistent_address) | ||
1783 | break; | ||
1784 | |||
1785 | conn->persistent_address = kstrdup(buf, GFP_KERNEL); | ||
1786 | if (!conn->persistent_address) | ||
1787 | return -ENOMEM; | ||
1788 | break; | ||
1789 | default: | ||
1790 | return -ENOSYS; | ||
1791 | } | ||
1792 | |||
1793 | return 0; | ||
1794 | } | ||
1795 | EXPORT_SYMBOL_GPL(iscsi_set_param); | ||
1796 | |||
1797 | int iscsi_session_get_param(struct iscsi_cls_session *cls_session, | ||
1798 | enum iscsi_param param, char *buf) | ||
1799 | { | ||
1800 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
1801 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
1802 | int len; | ||
1803 | |||
1804 | switch(param) { | ||
1805 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
1806 | len = sprintf(buf, "%d\n", session->initial_r2t_en); | ||
1807 | break; | ||
1808 | case ISCSI_PARAM_MAX_R2T: | ||
1809 | len = sprintf(buf, "%hu\n", session->max_r2t); | ||
1810 | break; | ||
1811 | case ISCSI_PARAM_IMM_DATA_EN: | ||
1812 | len = sprintf(buf, "%d\n", session->imm_data_en); | ||
1813 | break; | ||
1814 | case ISCSI_PARAM_FIRST_BURST: | ||
1815 | len = sprintf(buf, "%u\n", session->first_burst); | ||
1816 | break; | ||
1817 | case ISCSI_PARAM_MAX_BURST: | ||
1818 | len = sprintf(buf, "%u\n", session->max_burst); | ||
1819 | break; | ||
1820 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
1821 | len = sprintf(buf, "%d\n", session->pdu_inorder_en); | ||
1822 | break; | ||
1823 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
1824 | len = sprintf(buf, "%d\n", session->dataseq_inorder_en); | ||
1825 | break; | ||
1826 | case ISCSI_PARAM_ERL: | ||
1827 | len = sprintf(buf, "%d\n", session->erl); | ||
1828 | break; | ||
1829 | case ISCSI_PARAM_TARGET_NAME: | ||
1830 | len = sprintf(buf, "%s\n", session->targetname); | ||
1831 | break; | ||
1832 | case ISCSI_PARAM_TPGT: | ||
1833 | len = sprintf(buf, "%d\n", session->tpgt); | ||
1834 | break; | ||
1835 | default: | ||
1836 | return -ENOSYS; | ||
1837 | } | ||
1838 | |||
1839 | return len; | ||
1840 | } | ||
1841 | EXPORT_SYMBOL_GPL(iscsi_session_get_param); | ||
1842 | |||
1843 | int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | ||
1844 | enum iscsi_param param, char *buf) | ||
1845 | { | ||
1846 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
1847 | int len; | ||
1848 | |||
1849 | switch(param) { | ||
1850 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
1851 | len = sprintf(buf, "%u\n", conn->max_recv_dlength); | ||
1852 | break; | ||
1853 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
1854 | len = sprintf(buf, "%u\n", conn->max_xmit_dlength); | ||
1855 | break; | ||
1856 | case ISCSI_PARAM_HDRDGST_EN: | ||
1857 | len = sprintf(buf, "%d\n", conn->hdrdgst_en); | ||
1858 | break; | ||
1859 | case ISCSI_PARAM_DATADGST_EN: | ||
1860 | len = sprintf(buf, "%d\n", conn->datadgst_en); | ||
1861 | break; | ||
1862 | case ISCSI_PARAM_IFMARKER_EN: | ||
1863 | len = sprintf(buf, "%d\n", conn->ifmarker_en); | ||
1864 | break; | ||
1865 | case ISCSI_PARAM_OFMARKER_EN: | ||
1866 | len = sprintf(buf, "%d\n", conn->ofmarker_en); | ||
1867 | break; | ||
1868 | case ISCSI_PARAM_EXP_STATSN: | ||
1869 | len = sprintf(buf, "%u\n", conn->exp_statsn); | ||
1870 | break; | ||
1871 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
1872 | len = sprintf(buf, "%d\n", conn->persistent_port); | ||
1873 | break; | ||
1874 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
1875 | len = sprintf(buf, "%s\n", conn->persistent_address); | ||
1876 | break; | ||
1877 | default: | ||
1878 | return -ENOSYS; | ||
1879 | } | ||
1880 | |||
1881 | return len; | ||
1882 | } | ||
1883 | EXPORT_SYMBOL_GPL(iscsi_conn_get_param); | ||
1884 | |||
1700 | MODULE_AUTHOR("Mike Christie"); | 1885 | MODULE_AUTHOR("Mike Christie"); |
1701 | MODULE_DESCRIPTION("iSCSI library functions"); | 1886 | MODULE_DESCRIPTION("iSCSI library functions"); |
1702 | MODULE_LICENSE("GPL"); | 1887 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 087c44539a16..f81691fcf177 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -174,7 +174,6 @@ struct lpfc_hba { | |||
174 | dma_addr_t slim2p_mapping; | 174 | dma_addr_t slim2p_mapping; |
175 | uint16_t pci_cfg_value; | 175 | uint16_t pci_cfg_value; |
176 | 176 | ||
177 | struct semaphore hba_can_block; | ||
178 | int32_t hba_state; | 177 | int32_t hba_state; |
179 | 178 | ||
180 | #define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */ | 179 | #define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */ |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 283b7d824c34..4126fd87956f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -821,7 +821,7 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) | |||
821 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 821 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
822 | 822 | ||
823 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 823 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
824 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, 0, did, | 824 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, NULL, did, |
825 | ELS_CMD_PLOGI); | 825 | ELS_CMD_PLOGI); |
826 | if (!elsiocb) | 826 | if (!elsiocb) |
827 | return 1; | 827 | return 1; |
@@ -2791,8 +2791,8 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
2791 | 2791 | ||
2792 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 2792 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
2793 | xri = (uint16_t) ((unsigned long)(pmb->context1)); | 2793 | xri = (uint16_t) ((unsigned long)(pmb->context1)); |
2794 | pmb->context1 = 0; | 2794 | pmb->context1 = NULL; |
2795 | pmb->context2 = 0; | 2795 | pmb->context2 = NULL; |
2796 | 2796 | ||
2797 | if (mb->mbxStatus) { | 2797 | if (mb->mbxStatus) { |
2798 | mempool_free( pmb, phba->mbox_mem_pool); | 2798 | mempool_free( pmb, phba->mbox_mem_pool); |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5a28d9bf8e4d..81755a3f7c68 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -939,12 +939,12 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | |||
939 | "10-port ", "PCIe"}; | 939 | "10-port ", "PCIe"}; |
940 | break; | 940 | break; |
941 | default: | 941 | default: |
942 | m = (typeof(m)){ 0 }; | 942 | m = (typeof(m)){ NULL }; |
943 | break; | 943 | break; |
944 | } | 944 | } |
945 | break; | 945 | break; |
946 | default: | 946 | default: |
947 | m = (typeof(m)){ 0 }; | 947 | m = (typeof(m)){ NULL }; |
948 | break; | 948 | break; |
949 | } | 949 | } |
950 | 950 | ||
@@ -1451,7 +1451,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1451 | goto out_put_host; | 1451 | goto out_put_host; |
1452 | 1452 | ||
1453 | host->unique_id = phba->brd_no; | 1453 | host->unique_id = phba->brd_no; |
1454 | init_MUTEX(&phba->hba_can_block); | ||
1455 | INIT_LIST_HEAD(&phba->ctrspbuflist); | 1454 | INIT_LIST_HEAD(&phba->ctrspbuflist); |
1456 | INIT_LIST_HEAD(&phba->rnidrspbuflist); | 1455 | INIT_LIST_HEAD(&phba->rnidrspbuflist); |
1457 | INIT_LIST_HEAD(&phba->freebufList); | 1456 | INIT_LIST_HEAD(&phba->freebufList); |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 7dc4c2e6bed2..aea1ee472f3d 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -41,20 +41,6 @@ | |||
41 | #define LPFC_ABORT_WAIT 2 | 41 | #define LPFC_ABORT_WAIT 2 |
42 | 42 | ||
43 | 43 | ||
44 | static inline void | ||
45 | lpfc_block_requests(struct lpfc_hba * phba) | ||
46 | { | ||
47 | down(&phba->hba_can_block); | ||
48 | scsi_block_requests(phba->host); | ||
49 | } | ||
50 | |||
51 | static inline void | ||
52 | lpfc_unblock_requests(struct lpfc_hba * phba) | ||
53 | { | ||
54 | scsi_unblock_requests(phba->host); | ||
55 | up(&phba->hba_can_block); | ||
56 | } | ||
57 | |||
58 | /* | 44 | /* |
59 | * This routine allocates a scsi buffer, which contains all the necessary | 45 | * This routine allocates a scsi buffer, which contains all the necessary |
60 | * information needed to initiate a SCSI I/O. The non-DMAable buffer region | 46 | * information needed to initiate a SCSI I/O. The non-DMAable buffer region |
@@ -859,7 +845,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
859 | unsigned int loop_count = 0; | 845 | unsigned int loop_count = 0; |
860 | int ret = SUCCESS; | 846 | int ret = SUCCESS; |
861 | 847 | ||
862 | lpfc_block_requests(phba); | ||
863 | spin_lock_irq(shost->host_lock); | 848 | spin_lock_irq(shost->host_lock); |
864 | 849 | ||
865 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | 850 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
@@ -945,7 +930,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
945 | cmnd->device->lun, cmnd->serial_number); | 930 | cmnd->device->lun, cmnd->serial_number); |
946 | 931 | ||
947 | spin_unlock_irq(shost->host_lock); | 932 | spin_unlock_irq(shost->host_lock); |
948 | lpfc_unblock_requests(phba); | ||
949 | 933 | ||
950 | return ret; | 934 | return ret; |
951 | } | 935 | } |
@@ -963,7 +947,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
963 | int ret = FAILED; | 947 | int ret = FAILED; |
964 | int cnt, loopcnt; | 948 | int cnt, loopcnt; |
965 | 949 | ||
966 | lpfc_block_requests(phba); | ||
967 | spin_lock_irq(shost->host_lock); | 950 | spin_lock_irq(shost->host_lock); |
968 | /* | 951 | /* |
969 | * If target is not in a MAPPED state, delay the reset until | 952 | * If target is not in a MAPPED state, delay the reset until |
@@ -1065,7 +1048,6 @@ out_free_scsi_buf: | |||
1065 | 1048 | ||
1066 | out: | 1049 | out: |
1067 | spin_unlock_irq(shost->host_lock); | 1050 | spin_unlock_irq(shost->host_lock); |
1068 | lpfc_unblock_requests(phba); | ||
1069 | return ret; | 1051 | return ret; |
1070 | } | 1052 | } |
1071 | 1053 | ||
@@ -1080,7 +1062,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1080 | int cnt, loopcnt; | 1062 | int cnt, loopcnt; |
1081 | struct lpfc_scsi_buf * lpfc_cmd; | 1063 | struct lpfc_scsi_buf * lpfc_cmd; |
1082 | 1064 | ||
1083 | lpfc_block_requests(phba); | ||
1084 | spin_lock_irq(shost->host_lock); | 1065 | spin_lock_irq(shost->host_lock); |
1085 | 1066 | ||
1086 | lpfc_cmd = lpfc_get_scsi_buf(phba); | 1067 | lpfc_cmd = lpfc_get_scsi_buf(phba); |
@@ -1163,7 +1144,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1163 | phba->brd_no, ret); | 1144 | phba->brd_no, ret); |
1164 | out: | 1145 | out: |
1165 | spin_unlock_irq(shost->host_lock); | 1146 | spin_unlock_irq(shost->host_lock); |
1166 | lpfc_unblock_requests(phba); | ||
1167 | return ret; | 1147 | return ret; |
1168 | } | 1148 | } |
1169 | 1149 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index e5c017ccda59..a8c9627a15c4 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * FILE : megaraid_sas.c | 12 | * FILE : megaraid_sas.c |
13 | * Version : v00.00.02.04 | 13 | * Version : v00.00.03.01 |
14 | * | 14 | * |
15 | * Authors: | 15 | * Authors: |
16 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> | 16 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> |
@@ -55,19 +55,25 @@ static struct pci_device_id megasas_pci_table[] = { | |||
55 | 55 | ||
56 | { | 56 | { |
57 | PCI_VENDOR_ID_LSI_LOGIC, | 57 | PCI_VENDOR_ID_LSI_LOGIC, |
58 | PCI_DEVICE_ID_LSI_SAS1064R, // xscale IOP | 58 | PCI_DEVICE_ID_LSI_SAS1064R, /* xscale IOP */ |
59 | PCI_ANY_ID, | 59 | PCI_ANY_ID, |
60 | PCI_ANY_ID, | 60 | PCI_ANY_ID, |
61 | }, | 61 | }, |
62 | { | 62 | { |
63 | PCI_VENDOR_ID_LSI_LOGIC, | 63 | PCI_VENDOR_ID_LSI_LOGIC, |
64 | PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP | 64 | PCI_DEVICE_ID_LSI_SAS1078R, /* ppc IOP */ |
65 | PCI_ANY_ID, | 65 | PCI_ANY_ID, |
66 | PCI_ANY_ID, | 66 | PCI_ANY_ID, |
67 | }, | 67 | }, |
68 | { | 68 | { |
69 | PCI_VENDOR_ID_LSI_LOGIC, | ||
70 | PCI_DEVICE_ID_LSI_VERDE_ZCR, /* xscale IOP, vega */ | ||
71 | PCI_ANY_ID, | ||
72 | PCI_ANY_ID, | ||
73 | }, | ||
74 | { | ||
69 | PCI_VENDOR_ID_DELL, | 75 | PCI_VENDOR_ID_DELL, |
70 | PCI_DEVICE_ID_DELL_PERC5, // xscale IOP | 76 | PCI_DEVICE_ID_DELL_PERC5, /* xscale IOP */ |
71 | PCI_ANY_ID, | 77 | PCI_ANY_ID, |
72 | PCI_ANY_ID, | 78 | PCI_ANY_ID, |
73 | }, | 79 | }, |
@@ -289,9 +295,14 @@ static struct megasas_instance_template megasas_instance_template_ppc = { | |||
289 | * @regs: MFI register set | 295 | * @regs: MFI register set |
290 | */ | 296 | */ |
291 | static inline void | 297 | static inline void |
292 | megasas_disable_intr(struct megasas_register_set __iomem * regs) | 298 | megasas_disable_intr(struct megasas_instance *instance) |
293 | { | 299 | { |
294 | u32 mask = 0x1f; | 300 | u32 mask = 0x1f; |
301 | struct megasas_register_set __iomem *regs = instance->reg_set; | ||
302 | |||
303 | if(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078R) | ||
304 | mask = 0xffffffff; | ||
305 | |||
295 | writel(mask, ®s->outbound_intr_mask); | 306 | writel(mask, ®s->outbound_intr_mask); |
296 | 307 | ||
297 | /* Dummy readl to force pci flush */ | 308 | /* Dummy readl to force pci flush */ |
@@ -1260,7 +1271,7 @@ megasas_transition_to_ready(struct megasas_instance* instance) | |||
1260 | /* | 1271 | /* |
1261 | * Bring it to READY state; assuming max wait 2 secs | 1272 | * Bring it to READY state; assuming max wait 2 secs |
1262 | */ | 1273 | */ |
1263 | megasas_disable_intr(instance->reg_set); | 1274 | megasas_disable_intr(instance); |
1264 | writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); | 1275 | writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); |
1265 | 1276 | ||
1266 | max_wait = 10; | 1277 | max_wait = 10; |
@@ -1757,6 +1768,11 @@ static int megasas_init_mfi(struct megasas_instance *instance) | |||
1757 | init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); | 1768 | init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); |
1758 | 1769 | ||
1759 | /* | 1770 | /* |
1771 | * disable the intr before firing the init frame to FW | ||
1772 | */ | ||
1773 | megasas_disable_intr(instance); | ||
1774 | |||
1775 | /* | ||
1760 | * Issue the init frame in polled mode | 1776 | * Issue the init frame in polled mode |
1761 | */ | 1777 | */ |
1762 | if (megasas_issue_polled(instance, cmd)) { | 1778 | if (megasas_issue_polled(instance, cmd)) { |
@@ -2234,7 +2250,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2234 | megasas_mgmt_info.max_index--; | 2250 | megasas_mgmt_info.max_index--; |
2235 | 2251 | ||
2236 | pci_set_drvdata(pdev, NULL); | 2252 | pci_set_drvdata(pdev, NULL); |
2237 | megasas_disable_intr(instance->reg_set); | 2253 | megasas_disable_intr(instance); |
2238 | free_irq(instance->pdev->irq, instance); | 2254 | free_irq(instance->pdev->irq, instance); |
2239 | 2255 | ||
2240 | megasas_release_mfi(instance); | 2256 | megasas_release_mfi(instance); |
@@ -2364,7 +2380,7 @@ static void megasas_detach_one(struct pci_dev *pdev) | |||
2364 | 2380 | ||
2365 | pci_set_drvdata(instance->pdev, NULL); | 2381 | pci_set_drvdata(instance->pdev, NULL); |
2366 | 2382 | ||
2367 | megasas_disable_intr(instance->reg_set); | 2383 | megasas_disable_intr(instance); |
2368 | 2384 | ||
2369 | free_irq(instance->pdev->irq, instance); | 2385 | free_irq(instance->pdev->irq, instance); |
2370 | 2386 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 927d6ffef05f..3531a14222a7 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -18,9 +18,16 @@ | |||
18 | /** | 18 | /** |
19 | * MegaRAID SAS Driver meta data | 19 | * MegaRAID SAS Driver meta data |
20 | */ | 20 | */ |
21 | #define MEGASAS_VERSION "00.00.02.04" | 21 | #define MEGASAS_VERSION "00.00.03.01" |
22 | #define MEGASAS_RELDATE "Feb 03, 2006" | 22 | #define MEGASAS_RELDATE "May 14, 2006" |
23 | #define MEGASAS_EXT_VERSION "Fri Feb 03 14:31:44 PST 2006" | 23 | #define MEGASAS_EXT_VERSION "Sun May 14 22:49:52 PDT 2006" |
24 | |||
25 | /* | ||
26 | * Device IDs | ||
27 | */ | ||
28 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 | ||
29 | #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 | ||
30 | |||
24 | /* | 31 | /* |
25 | * ===================================== | 32 | * ===================================== |
26 | * MegaRAID SAS MFI firmware definitions | 33 | * MegaRAID SAS MFI firmware definitions |
@@ -554,7 +561,11 @@ struct megasas_ctrl_info { | |||
554 | #define MFI_POLL_TIMEOUT_SECS 10 | 561 | #define MFI_POLL_TIMEOUT_SECS 10 |
555 | 562 | ||
556 | #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 | 563 | #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 |
557 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x00000060 | 564 | |
565 | /* | ||
566 | * register set for both 1068 and 1078 controllers | ||
567 | * structure extended for 1078 registers | ||
568 | */ | ||
558 | 569 | ||
559 | struct megasas_register_set { | 570 | struct megasas_register_set { |
560 | u32 reserved_0[4]; /*0000h*/ | 571 | u32 reserved_0[4]; /*0000h*/ |
@@ -1150,10 +1161,10 @@ struct compat_megasas_iocpacket { | |||
1150 | struct compat_iovec sgl[MAX_IOCTL_SGE]; | 1161 | struct compat_iovec sgl[MAX_IOCTL_SGE]; |
1151 | } __attribute__ ((packed)); | 1162 | } __attribute__ ((packed)); |
1152 | 1163 | ||
1164 | #define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket) | ||
1153 | #endif | 1165 | #endif |
1154 | 1166 | ||
1155 | #define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket) | 1167 | #define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket) |
1156 | #define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket) | ||
1157 | #define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen) | 1168 | #define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen) |
1158 | 1169 | ||
1159 | struct megasas_mgmt_info { | 1170 | struct megasas_mgmt_info { |
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index bd337a914298..bfb4f49e125d 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c | |||
@@ -2866,8 +2866,7 @@ static int nsp32_detect(struct scsi_host_template *sht) | |||
2866 | */ | 2866 | */ |
2867 | nsp32_do_bus_reset(data); | 2867 | nsp32_do_bus_reset(data); |
2868 | 2868 | ||
2869 | ret = request_irq(host->irq, do_nsp32_isr, | 2869 | ret = request_irq(host->irq, do_nsp32_isr, IRQF_SHARED, "nsp32", data); |
2870 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "nsp32", data); | ||
2871 | if (ret < 0) { | 2870 | if (ret < 0) { |
2872 | nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NinjaSCSI32 " | 2871 | nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NinjaSCSI32 " |
2873 | "SCSI PCI controller. Interrupt: %d", host->irq); | 2872 | "SCSI PCI controller. Interrupt: %d", host->irq); |
@@ -2886,12 +2885,19 @@ static int nsp32_detect(struct scsi_host_template *sht) | |||
2886 | } | 2885 | } |
2887 | 2886 | ||
2888 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | 2887 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) |
2889 | scsi_add_host (host, &PCIDEV->dev); | 2888 | ret = scsi_add_host(host, &PCIDEV->dev); |
2889 | if (ret) { | ||
2890 | nsp32_msg(KERN_ERR, "failed to add scsi host"); | ||
2891 | goto free_region; | ||
2892 | } | ||
2890 | scsi_scan_host(host); | 2893 | scsi_scan_host(host); |
2891 | #endif | 2894 | #endif |
2892 | pci_set_drvdata(PCIDEV, host); | 2895 | pci_set_drvdata(PCIDEV, host); |
2893 | return DETECT_OK; | 2896 | return DETECT_OK; |
2894 | 2897 | ||
2898 | free_region: | ||
2899 | release_region(host->io_port, host->n_io_port); | ||
2900 | |||
2895 | free_irq: | 2901 | free_irq: |
2896 | free_irq(host->irq, data); | 2902 | free_irq(host->irq, data); |
2897 | 2903 | ||
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 7ff5851c040b..0d4c04e1f3de 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -1623,7 +1623,7 @@ static int nsp_cs_probe(struct pcmcia_device *link) | |||
1623 | /* Interrupt handler */ | 1623 | /* Interrupt handler */ |
1624 | link->irq.Handler = &nspintr; | 1624 | link->irq.Handler = &nspintr; |
1625 | link->irq.Instance = info; | 1625 | link->irq.Instance = info; |
1626 | link->irq.Attributes |= (IRQF_SHARED | IRQF_SAMPLE_RANDOM); | 1626 | link->irq.Attributes |= IRQF_SHARED; |
1627 | 1627 | ||
1628 | /* General socket configuration */ | 1628 | /* General socket configuration */ |
1629 | link->conf.Attributes = CONF_ENABLE_IRQ; | 1629 | link->conf.Attributes = CONF_ENABLE_IRQ; |
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index b818b9bfe678..8953991462d7 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -4209,7 +4209,7 @@ qla1280_setup(char *s) | |||
4209 | } | 4209 | } |
4210 | 4210 | ||
4211 | 4211 | ||
4212 | static int | 4212 | static int __init |
4213 | qla1280_get_token(char *str) | 4213 | qla1280_get_token(char *str) |
4214 | { | 4214 | { |
4215 | char *sep; | 4215 | char *sep; |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index e96d58ded57c..87f90c4f08e9 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -16,15 +16,16 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
16 | { | 16 | { |
17 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 17 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, |
18 | struct device, kobj))); | 18 | struct device, kobj))); |
19 | char *rbuf = (char *)ha->fw_dump; | ||
19 | 20 | ||
20 | if (ha->fw_dump_reading == 0) | 21 | if (ha->fw_dump_reading == 0) |
21 | return 0; | 22 | return 0; |
22 | if (off > ha->fw_dump_buffer_len) | 23 | if (off > ha->fw_dump_len) |
23 | return 0; | 24 | return 0; |
24 | if (off + count > ha->fw_dump_buffer_len) | 25 | if (off + count > ha->fw_dump_len) |
25 | count = ha->fw_dump_buffer_len - off; | 26 | count = ha->fw_dump_len - off; |
26 | 27 | ||
27 | memcpy(buf, &ha->fw_dump_buffer[off], count); | 28 | memcpy(buf, &rbuf[off], count); |
28 | 29 | ||
29 | return (count); | 30 | return (count); |
30 | } | 31 | } |
@@ -36,7 +37,6 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
36 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 37 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, |
37 | struct device, kobj))); | 38 | struct device, kobj))); |
38 | int reading; | 39 | int reading; |
39 | uint32_t dump_size; | ||
40 | 40 | ||
41 | if (off != 0) | 41 | if (off != 0) |
42 | return (0); | 42 | return (0); |
@@ -44,46 +44,27 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
44 | reading = simple_strtol(buf, NULL, 10); | 44 | reading = simple_strtol(buf, NULL, 10); |
45 | switch (reading) { | 45 | switch (reading) { |
46 | case 0: | 46 | case 0: |
47 | if (ha->fw_dump_reading == 1) { | 47 | if (!ha->fw_dump_reading) |
48 | qla_printk(KERN_INFO, ha, | 48 | break; |
49 | "Firmware dump cleared on (%ld).\n", ha->host_no); | ||
50 | 49 | ||
51 | vfree(ha->fw_dump_buffer); | 50 | qla_printk(KERN_INFO, ha, |
52 | ha->fw_dump_buffer = NULL; | 51 | "Firmware dump cleared on (%ld).\n", ha->host_no); |
53 | ha->fw_dump_reading = 0; | 52 | |
54 | ha->fw_dumped = 0; | 53 | ha->fw_dump_reading = 0; |
55 | } | 54 | ha->fw_dumped = 0; |
56 | break; | 55 | break; |
57 | case 1: | 56 | case 1: |
58 | if (ha->fw_dumped && !ha->fw_dump_reading) { | 57 | if (ha->fw_dumped && !ha->fw_dump_reading) { |
59 | ha->fw_dump_reading = 1; | 58 | ha->fw_dump_reading = 1; |
60 | 59 | ||
61 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | ||
62 | dump_size = FW_DUMP_SIZE_24XX; | ||
63 | else { | ||
64 | dump_size = FW_DUMP_SIZE_1M; | ||
65 | if (ha->fw_memory_size < 0x20000) | ||
66 | dump_size = FW_DUMP_SIZE_128K; | ||
67 | else if (ha->fw_memory_size < 0x80000) | ||
68 | dump_size = FW_DUMP_SIZE_512K; | ||
69 | } | ||
70 | ha->fw_dump_buffer = (char *)vmalloc(dump_size); | ||
71 | if (ha->fw_dump_buffer == NULL) { | ||
72 | qla_printk(KERN_WARNING, ha, | ||
73 | "Unable to allocate memory for firmware " | ||
74 | "dump buffer (%d).\n", dump_size); | ||
75 | |||
76 | ha->fw_dump_reading = 0; | ||
77 | return (count); | ||
78 | } | ||
79 | qla_printk(KERN_INFO, ha, | 60 | qla_printk(KERN_INFO, ha, |
80 | "Firmware dump ready for read on (%ld).\n", | 61 | "Raw firmware dump ready for read on (%ld).\n", |
81 | ha->host_no); | 62 | ha->host_no); |
82 | memset(ha->fw_dump_buffer, 0, dump_size); | ||
83 | ha->isp_ops.ascii_fw_dump(ha); | ||
84 | ha->fw_dump_buffer_len = strlen(ha->fw_dump_buffer); | ||
85 | } | 63 | } |
86 | break; | 64 | break; |
65 | case 2: | ||
66 | qla2x00_alloc_fw_dump(ha); | ||
67 | break; | ||
87 | } | 68 | } |
88 | return (count); | 69 | return (count); |
89 | } | 70 | } |
@@ -313,9 +294,6 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off, | |||
313 | if (!capable(CAP_SYS_ADMIN) || off != 0) | 294 | if (!capable(CAP_SYS_ADMIN) || off != 0) |
314 | return 0; | 295 | return 0; |
315 | 296 | ||
316 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
317 | return -ENOTSUPP; | ||
318 | |||
319 | /* Read NVRAM. */ | 297 | /* Read NVRAM. */ |
320 | spin_lock_irqsave(&ha->hardware_lock, flags); | 298 | spin_lock_irqsave(&ha->hardware_lock, flags); |
321 | ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); | 299 | ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); |
@@ -335,9 +313,6 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off, | |||
335 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) | 313 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) |
336 | return 0; | 314 | return 0; |
337 | 315 | ||
338 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
339 | return -ENOTSUPP; | ||
340 | |||
341 | /* Write NVRAM. */ | 316 | /* Write NVRAM. */ |
342 | spin_lock_irqsave(&ha->hardware_lock, flags); | 317 | spin_lock_irqsave(&ha->hardware_lock, flags); |
343 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); | 318 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); |
@@ -357,6 +332,53 @@ static struct bin_attribute sysfs_vpd_attr = { | |||
357 | .write = qla2x00_sysfs_write_vpd, | 332 | .write = qla2x00_sysfs_write_vpd, |
358 | }; | 333 | }; |
359 | 334 | ||
335 | static ssize_t | ||
336 | qla2x00_sysfs_read_sfp(struct kobject *kobj, char *buf, loff_t off, | ||
337 | size_t count) | ||
338 | { | ||
339 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | ||
340 | struct device, kobj))); | ||
341 | uint16_t iter, addr, offset; | ||
342 | int rval; | ||
343 | |||
344 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2) | ||
345 | return 0; | ||
346 | |||
347 | addr = 0xa0; | ||
348 | for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE; | ||
349 | iter++, offset += SFP_BLOCK_SIZE) { | ||
350 | if (iter == 4) { | ||
351 | /* Skip to next device address. */ | ||
352 | addr = 0xa2; | ||
353 | offset = 0; | ||
354 | } | ||
355 | |||
356 | rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset, | ||
357 | SFP_BLOCK_SIZE); | ||
358 | if (rval != QLA_SUCCESS) { | ||
359 | qla_printk(KERN_WARNING, ha, | ||
360 | "Unable to read SFP data (%x/%x/%x).\n", rval, | ||
361 | addr, offset); | ||
362 | count = 0; | ||
363 | break; | ||
364 | } | ||
365 | memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE); | ||
366 | buf += SFP_BLOCK_SIZE; | ||
367 | } | ||
368 | |||
369 | return count; | ||
370 | } | ||
371 | |||
372 | static struct bin_attribute sysfs_sfp_attr = { | ||
373 | .attr = { | ||
374 | .name = "sfp", | ||
375 | .mode = S_IRUSR | S_IWUSR, | ||
376 | .owner = THIS_MODULE, | ||
377 | }, | ||
378 | .size = SFP_DEV_SIZE * 2, | ||
379 | .read = qla2x00_sysfs_read_sfp, | ||
380 | }; | ||
381 | |||
360 | void | 382 | void |
361 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | 383 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) |
362 | { | 384 | { |
@@ -367,7 +389,12 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | |||
367 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | 389 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); |
368 | sysfs_create_bin_file(&host->shost_gendev.kobj, | 390 | sysfs_create_bin_file(&host->shost_gendev.kobj, |
369 | &sysfs_optrom_ctl_attr); | 391 | &sysfs_optrom_ctl_attr); |
370 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); | 392 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
393 | sysfs_create_bin_file(&host->shost_gendev.kobj, | ||
394 | &sysfs_vpd_attr); | ||
395 | sysfs_create_bin_file(&host->shost_gendev.kobj, | ||
396 | &sysfs_sfp_attr); | ||
397 | } | ||
371 | } | 398 | } |
372 | 399 | ||
373 | void | 400 | void |
@@ -380,7 +407,12 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | |||
380 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | 407 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); |
381 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | 408 | sysfs_remove_bin_file(&host->shost_gendev.kobj, |
382 | &sysfs_optrom_ctl_attr); | 409 | &sysfs_optrom_ctl_attr); |
383 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); | 410 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
411 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | ||
412 | &sysfs_vpd_attr); | ||
413 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | ||
414 | &sysfs_sfp_attr); | ||
415 | } | ||
384 | 416 | ||
385 | if (ha->beacon_blink_led == 1) | 417 | if (ha->beacon_blink_led == 1) |
386 | ha->isp_ops.beacon_off(ha); | 418 | ha->isp_ops.beacon_off(ha); |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 74e54713aa7c..f6ed6962bc2b 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -8,7 +8,34 @@ | |||
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | 10 | ||
11 | static int qla_uprintf(char **, char *, ...); | 11 | static inline void |
12 | qla2xxx_prep_dump(scsi_qla_host_t *ha, struct qla2xxx_fw_dump *fw_dump) | ||
13 | { | ||
14 | fw_dump->fw_major_version = htonl(ha->fw_major_version); | ||
15 | fw_dump->fw_minor_version = htonl(ha->fw_minor_version); | ||
16 | fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version); | ||
17 | fw_dump->fw_attributes = htonl(ha->fw_attributes); | ||
18 | |||
19 | fw_dump->vendor = htonl(ha->pdev->vendor); | ||
20 | fw_dump->device = htonl(ha->pdev->device); | ||
21 | fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor); | ||
22 | fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device); | ||
23 | } | ||
24 | |||
25 | static inline void * | ||
26 | qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr) | ||
27 | { | ||
28 | /* Request queue. */ | ||
29 | memcpy(ptr, ha->request_ring, ha->request_q_length * | ||
30 | sizeof(request_t)); | ||
31 | |||
32 | /* Response queue. */ | ||
33 | ptr += ha->request_q_length * sizeof(request_t); | ||
34 | memcpy(ptr, ha->response_ring, ha->response_q_length * | ||
35 | sizeof(response_t)); | ||
36 | |||
37 | return ptr + (ha->response_q_length * sizeof(response_t)); | ||
38 | } | ||
12 | 39 | ||
13 | /** | 40 | /** |
14 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | 41 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. |
@@ -49,10 +76,11 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
49 | "request...\n", ha->fw_dump); | 76 | "request...\n", ha->fw_dump); |
50 | goto qla2300_fw_dump_failed; | 77 | goto qla2300_fw_dump_failed; |
51 | } | 78 | } |
52 | fw = ha->fw_dump; | 79 | fw = &ha->fw_dump->isp.isp23; |
80 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
53 | 81 | ||
54 | rval = QLA_SUCCESS; | 82 | rval = QLA_SUCCESS; |
55 | fw->hccr = RD_REG_WORD(®->hccr); | 83 | fw->hccr = htons(RD_REG_WORD(®->hccr)); |
56 | 84 | ||
57 | /* Pause RISC. */ | 85 | /* Pause RISC. */ |
58 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | 86 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); |
@@ -73,85 +101,86 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
73 | if (rval == QLA_SUCCESS) { | 101 | if (rval == QLA_SUCCESS) { |
74 | dmp_reg = (uint16_t __iomem *)(reg + 0); | 102 | dmp_reg = (uint16_t __iomem *)(reg + 0); |
75 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | 103 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) |
76 | fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++); | 104 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
77 | 105 | ||
78 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | 106 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); |
79 | for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) | 107 | for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) |
80 | fw->risc_host_reg[cnt] = RD_REG_WORD(dmp_reg++); | 108 | fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
81 | 109 | ||
82 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40); | 110 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40); |
83 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 111 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) |
84 | fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++); | 112 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
85 | 113 | ||
86 | WRT_REG_WORD(®->ctrl_status, 0x40); | 114 | WRT_REG_WORD(®->ctrl_status, 0x40); |
87 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 115 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
88 | for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) | 116 | for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) |
89 | fw->resp_dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | 117 | fw->resp_dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
90 | 118 | ||
91 | WRT_REG_WORD(®->ctrl_status, 0x50); | 119 | WRT_REG_WORD(®->ctrl_status, 0x50); |
92 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 120 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
93 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | 121 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) |
94 | fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | 122 | fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
95 | 123 | ||
96 | WRT_REG_WORD(®->ctrl_status, 0x00); | 124 | WRT_REG_WORD(®->ctrl_status, 0x00); |
97 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | 125 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); |
98 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | 126 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) |
99 | fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 127 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
100 | 128 | ||
101 | WRT_REG_WORD(®->pcr, 0x2000); | 129 | WRT_REG_WORD(®->pcr, 0x2000); |
102 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 130 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
103 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | 131 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) |
104 | fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 132 | fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
105 | 133 | ||
106 | WRT_REG_WORD(®->pcr, 0x2200); | 134 | WRT_REG_WORD(®->pcr, 0x2200); |
107 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 135 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
108 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | 136 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) |
109 | fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 137 | fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
110 | 138 | ||
111 | WRT_REG_WORD(®->pcr, 0x2400); | 139 | WRT_REG_WORD(®->pcr, 0x2400); |
112 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 140 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
113 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | 141 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) |
114 | fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++); | 142 | fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
115 | 143 | ||
116 | WRT_REG_WORD(®->pcr, 0x2600); | 144 | WRT_REG_WORD(®->pcr, 0x2600); |
117 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 145 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
118 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | 146 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) |
119 | fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++); | 147 | fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
120 | 148 | ||
121 | WRT_REG_WORD(®->pcr, 0x2800); | 149 | WRT_REG_WORD(®->pcr, 0x2800); |
122 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 150 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
123 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | 151 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) |
124 | fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++); | 152 | fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
125 | 153 | ||
126 | WRT_REG_WORD(®->pcr, 0x2A00); | 154 | WRT_REG_WORD(®->pcr, 0x2A00); |
127 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 155 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
128 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | 156 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) |
129 | fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++); | 157 | fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
130 | 158 | ||
131 | WRT_REG_WORD(®->pcr, 0x2C00); | 159 | WRT_REG_WORD(®->pcr, 0x2C00); |
132 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 160 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
133 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | 161 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) |
134 | fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++); | 162 | fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
135 | 163 | ||
136 | WRT_REG_WORD(®->pcr, 0x2E00); | 164 | WRT_REG_WORD(®->pcr, 0x2E00); |
137 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 165 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
138 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | 166 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) |
139 | fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++); | 167 | fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
140 | 168 | ||
141 | WRT_REG_WORD(®->ctrl_status, 0x10); | 169 | WRT_REG_WORD(®->ctrl_status, 0x10); |
142 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 170 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
143 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | 171 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) |
144 | fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 172 | fw->frame_buf_hdw_reg[cnt] = |
173 | htons(RD_REG_WORD(dmp_reg++)); | ||
145 | 174 | ||
146 | WRT_REG_WORD(®->ctrl_status, 0x20); | 175 | WRT_REG_WORD(®->ctrl_status, 0x20); |
147 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 176 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
148 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | 177 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) |
149 | fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 178 | fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
150 | 179 | ||
151 | WRT_REG_WORD(®->ctrl_status, 0x30); | 180 | WRT_REG_WORD(®->ctrl_status, 0x30); |
152 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 181 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
153 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | 182 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) |
154 | fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 183 | fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
155 | 184 | ||
156 | /* Reset RISC. */ | 185 | /* Reset RISC. */ |
157 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | 186 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); |
@@ -226,7 +255,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
226 | 255 | ||
227 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 256 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
228 | rval = mb0 & MBS_MASK; | 257 | rval = mb0 & MBS_MASK; |
229 | fw->risc_ram[cnt] = mb2; | 258 | fw->risc_ram[cnt] = htons(mb2); |
230 | } else { | 259 | } else { |
231 | rval = QLA_FUNCTION_FAILED; | 260 | rval = QLA_FUNCTION_FAILED; |
232 | } | 261 | } |
@@ -285,7 +314,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
285 | 314 | ||
286 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 315 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
287 | rval = mb0 & MBS_MASK; | 316 | rval = mb0 & MBS_MASK; |
288 | fw->stack_ram[cnt] = mb2; | 317 | fw->stack_ram[cnt] = htons(mb2); |
289 | } else { | 318 | } else { |
290 | rval = QLA_FUNCTION_FAILED; | 319 | rval = QLA_FUNCTION_FAILED; |
291 | } | 320 | } |
@@ -345,12 +374,15 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
345 | 374 | ||
346 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 375 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
347 | rval = mb0 & MBS_MASK; | 376 | rval = mb0 & MBS_MASK; |
348 | fw->data_ram[cnt] = mb2; | 377 | fw->data_ram[cnt] = htons(mb2); |
349 | } else { | 378 | } else { |
350 | rval = QLA_FUNCTION_FAILED; | 379 | rval = QLA_FUNCTION_FAILED; |
351 | } | 380 | } |
352 | } | 381 | } |
353 | 382 | ||
383 | if (rval == QLA_SUCCESS) | ||
384 | qla2xxx_copy_queues(ha, &fw->data_ram[cnt]); | ||
385 | |||
354 | if (rval != QLA_SUCCESS) { | 386 | if (rval != QLA_SUCCESS) { |
355 | qla_printk(KERN_WARNING, ha, | 387 | qla_printk(KERN_WARNING, ha, |
356 | "Failed to dump firmware (%x)!!!\n", rval); | 388 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -369,193 +401,6 @@ qla2300_fw_dump_failed: | |||
369 | } | 401 | } |
370 | 402 | ||
371 | /** | 403 | /** |
372 | * qla2300_ascii_fw_dump() - Converts a binary firmware dump to ASCII. | ||
373 | * @ha: HA context | ||
374 | */ | ||
375 | void | ||
376 | qla2300_ascii_fw_dump(scsi_qla_host_t *ha) | ||
377 | { | ||
378 | uint32_t cnt; | ||
379 | char *uiter; | ||
380 | char fw_info[30]; | ||
381 | struct qla2300_fw_dump *fw; | ||
382 | uint32_t data_ram_cnt; | ||
383 | |||
384 | uiter = ha->fw_dump_buffer; | ||
385 | fw = ha->fw_dump; | ||
386 | |||
387 | qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number, | ||
388 | ha->isp_ops.fw_version_str(ha, fw_info)); | ||
389 | |||
390 | qla_uprintf(&uiter, "\n[==>BEG]\n"); | ||
391 | |||
392 | qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr); | ||
393 | |||
394 | qla_uprintf(&uiter, "PBIU Registers:"); | ||
395 | for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) { | ||
396 | if (cnt % 8 == 0) { | ||
397 | qla_uprintf(&uiter, "\n"); | ||
398 | } | ||
399 | qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]); | ||
400 | } | ||
401 | |||
402 | qla_uprintf(&uiter, "\n\nReqQ-RspQ-Risc2Host Status registers:"); | ||
403 | for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) { | ||
404 | if (cnt % 8 == 0) { | ||
405 | qla_uprintf(&uiter, "\n"); | ||
406 | } | ||
407 | qla_uprintf(&uiter, "%04x ", fw->risc_host_reg[cnt]); | ||
408 | } | ||
409 | |||
410 | qla_uprintf(&uiter, "\n\nMailbox Registers:"); | ||
411 | for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { | ||
412 | if (cnt % 8 == 0) { | ||
413 | qla_uprintf(&uiter, "\n"); | ||
414 | } | ||
415 | qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]); | ||
416 | } | ||
417 | |||
418 | qla_uprintf(&uiter, "\n\nAuto Request Response DMA Registers:"); | ||
419 | for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) { | ||
420 | if (cnt % 8 == 0) { | ||
421 | qla_uprintf(&uiter, "\n"); | ||
422 | } | ||
423 | qla_uprintf(&uiter, "%04x ", fw->resp_dma_reg[cnt]); | ||
424 | } | ||
425 | |||
426 | qla_uprintf(&uiter, "\n\nDMA Registers:"); | ||
427 | for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) { | ||
428 | if (cnt % 8 == 0) { | ||
429 | qla_uprintf(&uiter, "\n"); | ||
430 | } | ||
431 | qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]); | ||
432 | } | ||
433 | |||
434 | qla_uprintf(&uiter, "\n\nRISC Hardware Registers:"); | ||
435 | for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) { | ||
436 | if (cnt % 8 == 0) { | ||
437 | qla_uprintf(&uiter, "\n"); | ||
438 | } | ||
439 | qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]); | ||
440 | } | ||
441 | |||
442 | qla_uprintf(&uiter, "\n\nRISC GP0 Registers:"); | ||
443 | for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) { | ||
444 | if (cnt % 8 == 0) { | ||
445 | qla_uprintf(&uiter, "\n"); | ||
446 | } | ||
447 | qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]); | ||
448 | } | ||
449 | |||
450 | qla_uprintf(&uiter, "\n\nRISC GP1 Registers:"); | ||
451 | for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) { | ||
452 | if (cnt % 8 == 0) { | ||
453 | qla_uprintf(&uiter, "\n"); | ||
454 | } | ||
455 | qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]); | ||
456 | } | ||
457 | |||
458 | qla_uprintf(&uiter, "\n\nRISC GP2 Registers:"); | ||
459 | for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) { | ||
460 | if (cnt % 8 == 0) { | ||
461 | qla_uprintf(&uiter, "\n"); | ||
462 | } | ||
463 | qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]); | ||
464 | } | ||
465 | |||
466 | qla_uprintf(&uiter, "\n\nRISC GP3 Registers:"); | ||
467 | for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) { | ||
468 | if (cnt % 8 == 0) { | ||
469 | qla_uprintf(&uiter, "\n"); | ||
470 | } | ||
471 | qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]); | ||
472 | } | ||
473 | |||
474 | qla_uprintf(&uiter, "\n\nRISC GP4 Registers:"); | ||
475 | for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) { | ||
476 | if (cnt % 8 == 0) { | ||
477 | qla_uprintf(&uiter, "\n"); | ||
478 | } | ||
479 | qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]); | ||
480 | } | ||
481 | |||
482 | qla_uprintf(&uiter, "\n\nRISC GP5 Registers:"); | ||
483 | for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) { | ||
484 | if (cnt % 8 == 0) { | ||
485 | qla_uprintf(&uiter, "\n"); | ||
486 | } | ||
487 | qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]); | ||
488 | } | ||
489 | |||
490 | qla_uprintf(&uiter, "\n\nRISC GP6 Registers:"); | ||
491 | for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) { | ||
492 | if (cnt % 8 == 0) { | ||
493 | qla_uprintf(&uiter, "\n"); | ||
494 | } | ||
495 | qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]); | ||
496 | } | ||
497 | |||
498 | qla_uprintf(&uiter, "\n\nRISC GP7 Registers:"); | ||
499 | for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) { | ||
500 | if (cnt % 8 == 0) { | ||
501 | qla_uprintf(&uiter, "\n"); | ||
502 | } | ||
503 | qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]); | ||
504 | } | ||
505 | |||
506 | qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:"); | ||
507 | for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) { | ||
508 | if (cnt % 8 == 0) { | ||
509 | qla_uprintf(&uiter, "\n"); | ||
510 | } | ||
511 | qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]); | ||
512 | } | ||
513 | |||
514 | qla_uprintf(&uiter, "\n\nFPM B0 Registers:"); | ||
515 | for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) { | ||
516 | if (cnt % 8 == 0) { | ||
517 | qla_uprintf(&uiter, "\n"); | ||
518 | } | ||
519 | qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]); | ||
520 | } | ||
521 | |||
522 | qla_uprintf(&uiter, "\n\nFPM B1 Registers:"); | ||
523 | for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) { | ||
524 | if (cnt % 8 == 0) { | ||
525 | qla_uprintf(&uiter, "\n"); | ||
526 | } | ||
527 | qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]); | ||
528 | } | ||
529 | |||
530 | qla_uprintf(&uiter, "\n\nCode RAM Dump:"); | ||
531 | for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) { | ||
532 | if (cnt % 8 == 0) { | ||
533 | qla_uprintf(&uiter, "\n%04x: ", cnt + 0x0800); | ||
534 | } | ||
535 | qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]); | ||
536 | } | ||
537 | |||
538 | qla_uprintf(&uiter, "\n\nStack RAM Dump:"); | ||
539 | for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) { | ||
540 | if (cnt % 8 == 0) { | ||
541 | qla_uprintf(&uiter, "\n%05x: ", cnt + 0x10000); | ||
542 | } | ||
543 | qla_uprintf(&uiter, "%04x ", fw->stack_ram[cnt]); | ||
544 | } | ||
545 | |||
546 | qla_uprintf(&uiter, "\n\nData RAM Dump:"); | ||
547 | data_ram_cnt = ha->fw_memory_size - 0x11000 + 1; | ||
548 | for (cnt = 0; cnt < data_ram_cnt; cnt++) { | ||
549 | if (cnt % 8 == 0) { | ||
550 | qla_uprintf(&uiter, "\n%05x: ", cnt + 0x11000); | ||
551 | } | ||
552 | qla_uprintf(&uiter, "%04x ", fw->data_ram[cnt]); | ||
553 | } | ||
554 | |||
555 | qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump."); | ||
556 | } | ||
557 | |||
558 | /** | ||
559 | * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. | 404 | * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. |
560 | * @ha: HA context | 405 | * @ha: HA context |
561 | * @hardware_locked: Called with the hardware_lock | 406 | * @hardware_locked: Called with the hardware_lock |
@@ -591,10 +436,11 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
591 | "request...\n", ha->fw_dump); | 436 | "request...\n", ha->fw_dump); |
592 | goto qla2100_fw_dump_failed; | 437 | goto qla2100_fw_dump_failed; |
593 | } | 438 | } |
594 | fw = ha->fw_dump; | 439 | fw = &ha->fw_dump->isp.isp21; |
440 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
595 | 441 | ||
596 | rval = QLA_SUCCESS; | 442 | rval = QLA_SUCCESS; |
597 | fw->hccr = RD_REG_WORD(®->hccr); | 443 | fw->hccr = htons(RD_REG_WORD(®->hccr)); |
598 | 444 | ||
599 | /* Pause RISC. */ | 445 | /* Pause RISC. */ |
600 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | 446 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); |
@@ -608,79 +454,81 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
608 | if (rval == QLA_SUCCESS) { | 454 | if (rval == QLA_SUCCESS) { |
609 | dmp_reg = (uint16_t __iomem *)(reg + 0); | 455 | dmp_reg = (uint16_t __iomem *)(reg + 0); |
610 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | 456 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) |
611 | fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++); | 457 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
612 | 458 | ||
613 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | 459 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); |
614 | for (cnt = 0; cnt < ha->mbx_count; cnt++) { | 460 | for (cnt = 0; cnt < ha->mbx_count; cnt++) { |
615 | if (cnt == 8) { | 461 | if (cnt == 8) { |
616 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xe0); | 462 | dmp_reg = (uint16_t __iomem *) |
463 | ((uint8_t __iomem *)reg + 0xe0); | ||
617 | } | 464 | } |
618 | fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++); | 465 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
619 | } | 466 | } |
620 | 467 | ||
621 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20); | 468 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20); |
622 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | 469 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) |
623 | fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | 470 | fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
624 | 471 | ||
625 | WRT_REG_WORD(®->ctrl_status, 0x00); | 472 | WRT_REG_WORD(®->ctrl_status, 0x00); |
626 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | 473 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); |
627 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | 474 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) |
628 | fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 475 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
629 | 476 | ||
630 | WRT_REG_WORD(®->pcr, 0x2000); | 477 | WRT_REG_WORD(®->pcr, 0x2000); |
631 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 478 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
632 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | 479 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) |
633 | fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 480 | fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
634 | 481 | ||
635 | WRT_REG_WORD(®->pcr, 0x2100); | 482 | WRT_REG_WORD(®->pcr, 0x2100); |
636 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 483 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
637 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | 484 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) |
638 | fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 485 | fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
639 | 486 | ||
640 | WRT_REG_WORD(®->pcr, 0x2200); | 487 | WRT_REG_WORD(®->pcr, 0x2200); |
641 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 488 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
642 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | 489 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) |
643 | fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++); | 490 | fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
644 | 491 | ||
645 | WRT_REG_WORD(®->pcr, 0x2300); | 492 | WRT_REG_WORD(®->pcr, 0x2300); |
646 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 493 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
647 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | 494 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) |
648 | fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++); | 495 | fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
649 | 496 | ||
650 | WRT_REG_WORD(®->pcr, 0x2400); | 497 | WRT_REG_WORD(®->pcr, 0x2400); |
651 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 498 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
652 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | 499 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) |
653 | fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++); | 500 | fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
654 | 501 | ||
655 | WRT_REG_WORD(®->pcr, 0x2500); | 502 | WRT_REG_WORD(®->pcr, 0x2500); |
656 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 503 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
657 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | 504 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) |
658 | fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++); | 505 | fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
659 | 506 | ||
660 | WRT_REG_WORD(®->pcr, 0x2600); | 507 | WRT_REG_WORD(®->pcr, 0x2600); |
661 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 508 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
662 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | 509 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) |
663 | fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++); | 510 | fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
664 | 511 | ||
665 | WRT_REG_WORD(®->pcr, 0x2700); | 512 | WRT_REG_WORD(®->pcr, 0x2700); |
666 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 513 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
667 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | 514 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) |
668 | fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++); | 515 | fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
669 | 516 | ||
670 | WRT_REG_WORD(®->ctrl_status, 0x10); | 517 | WRT_REG_WORD(®->ctrl_status, 0x10); |
671 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 518 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
672 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | 519 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) |
673 | fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 520 | fw->frame_buf_hdw_reg[cnt] = |
521 | htons(RD_REG_WORD(dmp_reg++)); | ||
674 | 522 | ||
675 | WRT_REG_WORD(®->ctrl_status, 0x20); | 523 | WRT_REG_WORD(®->ctrl_status, 0x20); |
676 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 524 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
677 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | 525 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) |
678 | fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 526 | fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
679 | 527 | ||
680 | WRT_REG_WORD(®->ctrl_status, 0x30); | 528 | WRT_REG_WORD(®->ctrl_status, 0x30); |
681 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 529 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
682 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | 530 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) |
683 | fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 531 | fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
684 | 532 | ||
685 | /* Reset the ISP. */ | 533 | /* Reset the ISP. */ |
686 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | 534 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); |
@@ -755,12 +603,15 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
755 | 603 | ||
756 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 604 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
757 | rval = mb0 & MBS_MASK; | 605 | rval = mb0 & MBS_MASK; |
758 | fw->risc_ram[cnt] = mb2; | 606 | fw->risc_ram[cnt] = htons(mb2); |
759 | } else { | 607 | } else { |
760 | rval = QLA_FUNCTION_FAILED; | 608 | rval = QLA_FUNCTION_FAILED; |
761 | } | 609 | } |
762 | } | 610 | } |
763 | 611 | ||
612 | if (rval == QLA_SUCCESS) | ||
613 | qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]); | ||
614 | |||
764 | if (rval != QLA_SUCCESS) { | 615 | if (rval != QLA_SUCCESS) { |
765 | qla_printk(KERN_WARNING, ha, | 616 | qla_printk(KERN_WARNING, ha, |
766 | "Failed to dump firmware (%x)!!!\n", rval); | 617 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -778,179 +629,6 @@ qla2100_fw_dump_failed: | |||
778 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 629 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
779 | } | 630 | } |
780 | 631 | ||
781 | /** | ||
782 | * qla2100_ascii_fw_dump() - Converts a binary firmware dump to ASCII. | ||
783 | * @ha: HA context | ||
784 | */ | ||
785 | void | ||
786 | qla2100_ascii_fw_dump(scsi_qla_host_t *ha) | ||
787 | { | ||
788 | uint32_t cnt; | ||
789 | char *uiter; | ||
790 | char fw_info[30]; | ||
791 | struct qla2100_fw_dump *fw; | ||
792 | |||
793 | uiter = ha->fw_dump_buffer; | ||
794 | fw = ha->fw_dump; | ||
795 | |||
796 | qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number, | ||
797 | ha->isp_ops.fw_version_str(ha, fw_info)); | ||
798 | |||
799 | qla_uprintf(&uiter, "\n[==>BEG]\n"); | ||
800 | |||
801 | qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr); | ||
802 | |||
803 | qla_uprintf(&uiter, "PBIU Registers:"); | ||
804 | for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) { | ||
805 | if (cnt % 8 == 0) { | ||
806 | qla_uprintf(&uiter, "\n"); | ||
807 | } | ||
808 | qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]); | ||
809 | } | ||
810 | |||
811 | qla_uprintf(&uiter, "\n\nMailbox Registers:"); | ||
812 | for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { | ||
813 | if (cnt % 8 == 0) { | ||
814 | qla_uprintf(&uiter, "\n"); | ||
815 | } | ||
816 | qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]); | ||
817 | } | ||
818 | |||
819 | qla_uprintf(&uiter, "\n\nDMA Registers:"); | ||
820 | for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) { | ||
821 | if (cnt % 8 == 0) { | ||
822 | qla_uprintf(&uiter, "\n"); | ||
823 | } | ||
824 | qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]); | ||
825 | } | ||
826 | |||
827 | qla_uprintf(&uiter, "\n\nRISC Hardware Registers:"); | ||
828 | for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) { | ||
829 | if (cnt % 8 == 0) { | ||
830 | qla_uprintf(&uiter, "\n"); | ||
831 | } | ||
832 | qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]); | ||
833 | } | ||
834 | |||
835 | qla_uprintf(&uiter, "\n\nRISC GP0 Registers:"); | ||
836 | for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) { | ||
837 | if (cnt % 8 == 0) { | ||
838 | qla_uprintf(&uiter, "\n"); | ||
839 | } | ||
840 | qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]); | ||
841 | } | ||
842 | |||
843 | qla_uprintf(&uiter, "\n\nRISC GP1 Registers:"); | ||
844 | for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) { | ||
845 | if (cnt % 8 == 0) { | ||
846 | qla_uprintf(&uiter, "\n"); | ||
847 | } | ||
848 | qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]); | ||
849 | } | ||
850 | |||
851 | qla_uprintf(&uiter, "\n\nRISC GP2 Registers:"); | ||
852 | for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) { | ||
853 | if (cnt % 8 == 0) { | ||
854 | qla_uprintf(&uiter, "\n"); | ||
855 | } | ||
856 | qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]); | ||
857 | } | ||
858 | |||
859 | qla_uprintf(&uiter, "\n\nRISC GP3 Registers:"); | ||
860 | for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) { | ||
861 | if (cnt % 8 == 0) { | ||
862 | qla_uprintf(&uiter, "\n"); | ||
863 | } | ||
864 | qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]); | ||
865 | } | ||
866 | |||
867 | qla_uprintf(&uiter, "\n\nRISC GP4 Registers:"); | ||
868 | for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) { | ||
869 | if (cnt % 8 == 0) { | ||
870 | qla_uprintf(&uiter, "\n"); | ||
871 | } | ||
872 | qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]); | ||
873 | } | ||
874 | |||
875 | qla_uprintf(&uiter, "\n\nRISC GP5 Registers:"); | ||
876 | for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) { | ||
877 | if (cnt % 8 == 0) { | ||
878 | qla_uprintf(&uiter, "\n"); | ||
879 | } | ||
880 | qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]); | ||
881 | } | ||
882 | |||
883 | qla_uprintf(&uiter, "\n\nRISC GP6 Registers:"); | ||
884 | for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) { | ||
885 | if (cnt % 8 == 0) { | ||
886 | qla_uprintf(&uiter, "\n"); | ||
887 | } | ||
888 | qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]); | ||
889 | } | ||
890 | |||
891 | qla_uprintf(&uiter, "\n\nRISC GP7 Registers:"); | ||
892 | for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) { | ||
893 | if (cnt % 8 == 0) { | ||
894 | qla_uprintf(&uiter, "\n"); | ||
895 | } | ||
896 | qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]); | ||
897 | } | ||
898 | |||
899 | qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:"); | ||
900 | for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) { | ||
901 | if (cnt % 8 == 0) { | ||
902 | qla_uprintf(&uiter, "\n"); | ||
903 | } | ||
904 | qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]); | ||
905 | } | ||
906 | |||
907 | qla_uprintf(&uiter, "\n\nFPM B0 Registers:"); | ||
908 | for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) { | ||
909 | if (cnt % 8 == 0) { | ||
910 | qla_uprintf(&uiter, "\n"); | ||
911 | } | ||
912 | qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]); | ||
913 | } | ||
914 | |||
915 | qla_uprintf(&uiter, "\n\nFPM B1 Registers:"); | ||
916 | for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) { | ||
917 | if (cnt % 8 == 0) { | ||
918 | qla_uprintf(&uiter, "\n"); | ||
919 | } | ||
920 | qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]); | ||
921 | } | ||
922 | |||
923 | qla_uprintf(&uiter, "\n\nRISC SRAM:"); | ||
924 | for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) { | ||
925 | if (cnt % 8 == 0) { | ||
926 | qla_uprintf(&uiter, "\n%04x: ", cnt + 0x1000); | ||
927 | } | ||
928 | qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]); | ||
929 | } | ||
930 | |||
931 | qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump."); | ||
932 | |||
933 | return; | ||
934 | } | ||
935 | |||
936 | static int | ||
937 | qla_uprintf(char **uiter, char *fmt, ...) | ||
938 | { | ||
939 | int iter, len; | ||
940 | char buf[128]; | ||
941 | va_list args; | ||
942 | |||
943 | va_start(args, fmt); | ||
944 | len = vsprintf(buf, fmt, args); | ||
945 | va_end(args); | ||
946 | |||
947 | for (iter = 0; iter < len; iter++, *uiter += 1) | ||
948 | *uiter[0] = buf[iter]; | ||
949 | |||
950 | return (len); | ||
951 | } | ||
952 | |||
953 | |||
954 | void | 632 | void |
955 | qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | 633 | qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) |
956 | { | 634 | { |
@@ -967,6 +645,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
967 | unsigned long flags; | 645 | unsigned long flags; |
968 | struct qla24xx_fw_dump *fw; | 646 | struct qla24xx_fw_dump *fw; |
969 | uint32_t ext_mem_cnt; | 647 | uint32_t ext_mem_cnt; |
648 | void *eft; | ||
970 | 649 | ||
971 | risc_address = ext_mem_cnt = 0; | 650 | risc_address = ext_mem_cnt = 0; |
972 | memset(mb, 0, sizeof(mb)); | 651 | memset(mb, 0, sizeof(mb)); |
@@ -987,10 +666,11 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
987 | "request...\n", ha->fw_dump); | 666 | "request...\n", ha->fw_dump); |
988 | goto qla24xx_fw_dump_failed; | 667 | goto qla24xx_fw_dump_failed; |
989 | } | 668 | } |
990 | fw = ha->fw_dump; | 669 | fw = &ha->fw_dump->isp.isp24; |
670 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
991 | 671 | ||
992 | rval = QLA_SUCCESS; | 672 | rval = QLA_SUCCESS; |
993 | fw->host_status = RD_REG_DWORD(®->host_status); | 673 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); |
994 | 674 | ||
995 | /* Pause RISC. */ | 675 | /* Pause RISC. */ |
996 | if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { | 676 | if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { |
@@ -1012,7 +692,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1012 | /* Host interface registers. */ | 692 | /* Host interface registers. */ |
1013 | dmp_reg = (uint32_t __iomem *)(reg + 0); | 693 | dmp_reg = (uint32_t __iomem *)(reg + 0); |
1014 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) | 694 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) |
1015 | fw->host_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 695 | fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1016 | 696 | ||
1017 | /* Disable interrupts. */ | 697 | /* Disable interrupts. */ |
1018 | WRT_REG_DWORD(®->ictrl, 0); | 698 | WRT_REG_DWORD(®->ictrl, 0); |
@@ -1024,470 +704,471 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1024 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 704 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1025 | WRT_REG_DWORD(dmp_reg, 0xB0000000); | 705 | WRT_REG_DWORD(dmp_reg, 0xB0000000); |
1026 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 706 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1027 | fw->shadow_reg[0] = RD_REG_DWORD(dmp_reg); | 707 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(dmp_reg)); |
1028 | 708 | ||
1029 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 709 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1030 | WRT_REG_DWORD(dmp_reg, 0xB0100000); | 710 | WRT_REG_DWORD(dmp_reg, 0xB0100000); |
1031 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 711 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1032 | fw->shadow_reg[1] = RD_REG_DWORD(dmp_reg); | 712 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(dmp_reg)); |
1033 | 713 | ||
1034 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 714 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1035 | WRT_REG_DWORD(dmp_reg, 0xB0200000); | 715 | WRT_REG_DWORD(dmp_reg, 0xB0200000); |
1036 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 716 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1037 | fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg); | 717 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(dmp_reg)); |
1038 | 718 | ||
1039 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 719 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1040 | WRT_REG_DWORD(dmp_reg, 0xB0300000); | 720 | WRT_REG_DWORD(dmp_reg, 0xB0300000); |
1041 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 721 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1042 | fw->shadow_reg[3] = RD_REG_DWORD(dmp_reg); | 722 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(dmp_reg)); |
1043 | 723 | ||
1044 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 724 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1045 | WRT_REG_DWORD(dmp_reg, 0xB0400000); | 725 | WRT_REG_DWORD(dmp_reg, 0xB0400000); |
1046 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 726 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1047 | fw->shadow_reg[4] = RD_REG_DWORD(dmp_reg); | 727 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(dmp_reg)); |
1048 | 728 | ||
1049 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 729 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1050 | WRT_REG_DWORD(dmp_reg, 0xB0500000); | 730 | WRT_REG_DWORD(dmp_reg, 0xB0500000); |
1051 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 731 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1052 | fw->shadow_reg[5] = RD_REG_DWORD(dmp_reg); | 732 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(dmp_reg)); |
1053 | 733 | ||
1054 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 734 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1055 | WRT_REG_DWORD(dmp_reg, 0xB0600000); | 735 | WRT_REG_DWORD(dmp_reg, 0xB0600000); |
1056 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 736 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1057 | fw->shadow_reg[6] = RD_REG_DWORD(dmp_reg); | 737 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(dmp_reg)); |
1058 | 738 | ||
1059 | /* Mailbox registers. */ | 739 | /* Mailbox registers. */ |
1060 | mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 740 | mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
1061 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 741 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) |
1062 | fw->mailbox_reg[cnt] = RD_REG_WORD(mbx_reg++); | 742 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); |
1063 | 743 | ||
1064 | /* Transfer sequence registers. */ | 744 | /* Transfer sequence registers. */ |
1065 | iter_reg = fw->xseq_gp_reg; | 745 | iter_reg = fw->xseq_gp_reg; |
1066 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); | 746 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); |
1067 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 747 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1068 | for (cnt = 0; cnt < 16; cnt++) | 748 | for (cnt = 0; cnt < 16; cnt++) |
1069 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 749 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1070 | 750 | ||
1071 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); | 751 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); |
1072 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 752 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1073 | for (cnt = 0; cnt < 16; cnt++) | 753 | for (cnt = 0; cnt < 16; cnt++) |
1074 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 754 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1075 | 755 | ||
1076 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); | 756 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); |
1077 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 757 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1078 | for (cnt = 0; cnt < 16; cnt++) | 758 | for (cnt = 0; cnt < 16; cnt++) |
1079 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 759 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1080 | 760 | ||
1081 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); | 761 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); |
1082 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 762 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1083 | for (cnt = 0; cnt < 16; cnt++) | 763 | for (cnt = 0; cnt < 16; cnt++) |
1084 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 764 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1085 | 765 | ||
1086 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); | 766 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); |
1087 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 767 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1088 | for (cnt = 0; cnt < 16; cnt++) | 768 | for (cnt = 0; cnt < 16; cnt++) |
1089 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 769 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1090 | 770 | ||
1091 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); | 771 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); |
1092 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 772 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1093 | for (cnt = 0; cnt < 16; cnt++) | 773 | for (cnt = 0; cnt < 16; cnt++) |
1094 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 774 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1095 | 775 | ||
1096 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); | 776 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); |
1097 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 777 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1098 | for (cnt = 0; cnt < 16; cnt++) | 778 | for (cnt = 0; cnt < 16; cnt++) |
1099 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 779 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1100 | 780 | ||
1101 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); | 781 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); |
1102 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 782 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1103 | for (cnt = 0; cnt < 16; cnt++) | 783 | for (cnt = 0; cnt < 16; cnt++) |
1104 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 784 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1105 | 785 | ||
1106 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); | 786 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); |
1107 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 787 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1108 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) | 788 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) |
1109 | fw->xseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 789 | fw->xseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1110 | 790 | ||
1111 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); | 791 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); |
1112 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 792 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1113 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) | 793 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) |
1114 | fw->xseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 794 | fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1115 | 795 | ||
1116 | /* Receive sequence registers. */ | 796 | /* Receive sequence registers. */ |
1117 | iter_reg = fw->rseq_gp_reg; | 797 | iter_reg = fw->rseq_gp_reg; |
1118 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); | 798 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); |
1119 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 799 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1120 | for (cnt = 0; cnt < 16; cnt++) | 800 | for (cnt = 0; cnt < 16; cnt++) |
1121 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 801 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1122 | 802 | ||
1123 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); | 803 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); |
1124 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 804 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1125 | for (cnt = 0; cnt < 16; cnt++) | 805 | for (cnt = 0; cnt < 16; cnt++) |
1126 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 806 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1127 | 807 | ||
1128 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); | 808 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); |
1129 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 809 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1130 | for (cnt = 0; cnt < 16; cnt++) | 810 | for (cnt = 0; cnt < 16; cnt++) |
1131 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 811 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1132 | 812 | ||
1133 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); | 813 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); |
1134 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 814 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1135 | for (cnt = 0; cnt < 16; cnt++) | 815 | for (cnt = 0; cnt < 16; cnt++) |
1136 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 816 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1137 | 817 | ||
1138 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); | 818 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); |
1139 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 819 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1140 | for (cnt = 0; cnt < 16; cnt++) | 820 | for (cnt = 0; cnt < 16; cnt++) |
1141 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 821 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1142 | 822 | ||
1143 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); | 823 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); |
1144 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 824 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1145 | for (cnt = 0; cnt < 16; cnt++) | 825 | for (cnt = 0; cnt < 16; cnt++) |
1146 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 826 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1147 | 827 | ||
1148 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); | 828 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); |
1149 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 829 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1150 | for (cnt = 0; cnt < 16; cnt++) | 830 | for (cnt = 0; cnt < 16; cnt++) |
1151 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 831 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1152 | 832 | ||
1153 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); | 833 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); |
1154 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 834 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1155 | for (cnt = 0; cnt < 16; cnt++) | 835 | for (cnt = 0; cnt < 16; cnt++) |
1156 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 836 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1157 | 837 | ||
1158 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); | 838 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); |
1159 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 839 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1160 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) | 840 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) |
1161 | fw->rseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 841 | fw->rseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1162 | 842 | ||
1163 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); | 843 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); |
1164 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 844 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1165 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) | 845 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) |
1166 | fw->rseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 846 | fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1167 | 847 | ||
1168 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); | 848 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); |
1169 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 849 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1170 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) | 850 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) |
1171 | fw->rseq_2_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 851 | fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1172 | 852 | ||
1173 | /* Command DMA registers. */ | 853 | /* Command DMA registers. */ |
1174 | WRT_REG_DWORD(®->iobase_addr, 0x7100); | 854 | WRT_REG_DWORD(®->iobase_addr, 0x7100); |
1175 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 855 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1176 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) | 856 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) |
1177 | fw->cmd_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 857 | fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1178 | 858 | ||
1179 | /* Queues. */ | 859 | /* Queues. */ |
1180 | iter_reg = fw->req0_dma_reg; | 860 | iter_reg = fw->req0_dma_reg; |
1181 | WRT_REG_DWORD(®->iobase_addr, 0x7200); | 861 | WRT_REG_DWORD(®->iobase_addr, 0x7200); |
1182 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 862 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1183 | for (cnt = 0; cnt < 8; cnt++) | 863 | for (cnt = 0; cnt < 8; cnt++) |
1184 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 864 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1185 | 865 | ||
1186 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 866 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); |
1187 | for (cnt = 0; cnt < 7; cnt++) | 867 | for (cnt = 0; cnt < 7; cnt++) |
1188 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 868 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1189 | 869 | ||
1190 | iter_reg = fw->resp0_dma_reg; | 870 | iter_reg = fw->resp0_dma_reg; |
1191 | WRT_REG_DWORD(®->iobase_addr, 0x7300); | 871 | WRT_REG_DWORD(®->iobase_addr, 0x7300); |
1192 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 872 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1193 | for (cnt = 0; cnt < 8; cnt++) | 873 | for (cnt = 0; cnt < 8; cnt++) |
1194 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 874 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1195 | 875 | ||
1196 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 876 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); |
1197 | for (cnt = 0; cnt < 7; cnt++) | 877 | for (cnt = 0; cnt < 7; cnt++) |
1198 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 878 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1199 | 879 | ||
1200 | iter_reg = fw->req1_dma_reg; | 880 | iter_reg = fw->req1_dma_reg; |
1201 | WRT_REG_DWORD(®->iobase_addr, 0x7400); | 881 | WRT_REG_DWORD(®->iobase_addr, 0x7400); |
1202 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 882 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1203 | for (cnt = 0; cnt < 8; cnt++) | 883 | for (cnt = 0; cnt < 8; cnt++) |
1204 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 884 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1205 | 885 | ||
1206 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 886 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); |
1207 | for (cnt = 0; cnt < 7; cnt++) | 887 | for (cnt = 0; cnt < 7; cnt++) |
1208 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 888 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1209 | 889 | ||
1210 | /* Transmit DMA registers. */ | 890 | /* Transmit DMA registers. */ |
1211 | iter_reg = fw->xmt0_dma_reg; | 891 | iter_reg = fw->xmt0_dma_reg; |
1212 | WRT_REG_DWORD(®->iobase_addr, 0x7600); | 892 | WRT_REG_DWORD(®->iobase_addr, 0x7600); |
1213 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 893 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1214 | for (cnt = 0; cnt < 16; cnt++) | 894 | for (cnt = 0; cnt < 16; cnt++) |
1215 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 895 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1216 | 896 | ||
1217 | WRT_REG_DWORD(®->iobase_addr, 0x7610); | 897 | WRT_REG_DWORD(®->iobase_addr, 0x7610); |
1218 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 898 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1219 | for (cnt = 0; cnt < 16; cnt++) | 899 | for (cnt = 0; cnt < 16; cnt++) |
1220 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 900 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1221 | 901 | ||
1222 | iter_reg = fw->xmt1_dma_reg; | 902 | iter_reg = fw->xmt1_dma_reg; |
1223 | WRT_REG_DWORD(®->iobase_addr, 0x7620); | 903 | WRT_REG_DWORD(®->iobase_addr, 0x7620); |
1224 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 904 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1225 | for (cnt = 0; cnt < 16; cnt++) | 905 | for (cnt = 0; cnt < 16; cnt++) |
1226 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 906 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1227 | 907 | ||
1228 | WRT_REG_DWORD(®->iobase_addr, 0x7630); | 908 | WRT_REG_DWORD(®->iobase_addr, 0x7630); |
1229 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 909 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1230 | for (cnt = 0; cnt < 16; cnt++) | 910 | for (cnt = 0; cnt < 16; cnt++) |
1231 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 911 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1232 | 912 | ||
1233 | iter_reg = fw->xmt2_dma_reg; | 913 | iter_reg = fw->xmt2_dma_reg; |
1234 | WRT_REG_DWORD(®->iobase_addr, 0x7640); | 914 | WRT_REG_DWORD(®->iobase_addr, 0x7640); |
1235 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 915 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1236 | for (cnt = 0; cnt < 16; cnt++) | 916 | for (cnt = 0; cnt < 16; cnt++) |
1237 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 917 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1238 | 918 | ||
1239 | WRT_REG_DWORD(®->iobase_addr, 0x7650); | 919 | WRT_REG_DWORD(®->iobase_addr, 0x7650); |
1240 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 920 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1241 | for (cnt = 0; cnt < 16; cnt++) | 921 | for (cnt = 0; cnt < 16; cnt++) |
1242 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 922 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1243 | 923 | ||
1244 | iter_reg = fw->xmt3_dma_reg; | 924 | iter_reg = fw->xmt3_dma_reg; |
1245 | WRT_REG_DWORD(®->iobase_addr, 0x7660); | 925 | WRT_REG_DWORD(®->iobase_addr, 0x7660); |
1246 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 926 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1247 | for (cnt = 0; cnt < 16; cnt++) | 927 | for (cnt = 0; cnt < 16; cnt++) |
1248 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 928 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1249 | 929 | ||
1250 | WRT_REG_DWORD(®->iobase_addr, 0x7670); | 930 | WRT_REG_DWORD(®->iobase_addr, 0x7670); |
1251 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 931 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1252 | for (cnt = 0; cnt < 16; cnt++) | 932 | for (cnt = 0; cnt < 16; cnt++) |
1253 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 933 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1254 | 934 | ||
1255 | iter_reg = fw->xmt4_dma_reg; | 935 | iter_reg = fw->xmt4_dma_reg; |
1256 | WRT_REG_DWORD(®->iobase_addr, 0x7680); | 936 | WRT_REG_DWORD(®->iobase_addr, 0x7680); |
1257 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 937 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1258 | for (cnt = 0; cnt < 16; cnt++) | 938 | for (cnt = 0; cnt < 16; cnt++) |
1259 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 939 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1260 | 940 | ||
1261 | WRT_REG_DWORD(®->iobase_addr, 0x7690); | 941 | WRT_REG_DWORD(®->iobase_addr, 0x7690); |
1262 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 942 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1263 | for (cnt = 0; cnt < 16; cnt++) | 943 | for (cnt = 0; cnt < 16; cnt++) |
1264 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 944 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1265 | 945 | ||
1266 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); | 946 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); |
1267 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 947 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1268 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) | 948 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) |
1269 | fw->xmt_data_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 949 | fw->xmt_data_dma_reg[cnt] = |
950 | htonl(RD_REG_DWORD(dmp_reg++)); | ||
1270 | 951 | ||
1271 | /* Receive DMA registers. */ | 952 | /* Receive DMA registers. */ |
1272 | iter_reg = fw->rcvt0_data_dma_reg; | 953 | iter_reg = fw->rcvt0_data_dma_reg; |
1273 | WRT_REG_DWORD(®->iobase_addr, 0x7700); | 954 | WRT_REG_DWORD(®->iobase_addr, 0x7700); |
1274 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 955 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1275 | for (cnt = 0; cnt < 16; cnt++) | 956 | for (cnt = 0; cnt < 16; cnt++) |
1276 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 957 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1277 | 958 | ||
1278 | WRT_REG_DWORD(®->iobase_addr, 0x7710); | 959 | WRT_REG_DWORD(®->iobase_addr, 0x7710); |
1279 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 960 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1280 | for (cnt = 0; cnt < 16; cnt++) | 961 | for (cnt = 0; cnt < 16; cnt++) |
1281 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 962 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1282 | 963 | ||
1283 | iter_reg = fw->rcvt1_data_dma_reg; | 964 | iter_reg = fw->rcvt1_data_dma_reg; |
1284 | WRT_REG_DWORD(®->iobase_addr, 0x7720); | 965 | WRT_REG_DWORD(®->iobase_addr, 0x7720); |
1285 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 966 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1286 | for (cnt = 0; cnt < 16; cnt++) | 967 | for (cnt = 0; cnt < 16; cnt++) |
1287 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 968 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1288 | 969 | ||
1289 | WRT_REG_DWORD(®->iobase_addr, 0x7730); | 970 | WRT_REG_DWORD(®->iobase_addr, 0x7730); |
1290 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 971 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1291 | for (cnt = 0; cnt < 16; cnt++) | 972 | for (cnt = 0; cnt < 16; cnt++) |
1292 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 973 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1293 | 974 | ||
1294 | /* RISC registers. */ | 975 | /* RISC registers. */ |
1295 | iter_reg = fw->risc_gp_reg; | 976 | iter_reg = fw->risc_gp_reg; |
1296 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); | 977 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); |
1297 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 978 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1298 | for (cnt = 0; cnt < 16; cnt++) | 979 | for (cnt = 0; cnt < 16; cnt++) |
1299 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 980 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1300 | 981 | ||
1301 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); | 982 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); |
1302 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 983 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1303 | for (cnt = 0; cnt < 16; cnt++) | 984 | for (cnt = 0; cnt < 16; cnt++) |
1304 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 985 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1305 | 986 | ||
1306 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); | 987 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); |
1307 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 988 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1308 | for (cnt = 0; cnt < 16; cnt++) | 989 | for (cnt = 0; cnt < 16; cnt++) |
1309 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 990 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1310 | 991 | ||
1311 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); | 992 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); |
1312 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 993 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1313 | for (cnt = 0; cnt < 16; cnt++) | 994 | for (cnt = 0; cnt < 16; cnt++) |
1314 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 995 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1315 | 996 | ||
1316 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); | 997 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); |
1317 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 998 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1318 | for (cnt = 0; cnt < 16; cnt++) | 999 | for (cnt = 0; cnt < 16; cnt++) |
1319 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1000 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1320 | 1001 | ||
1321 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); | 1002 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); |
1322 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1003 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1323 | for (cnt = 0; cnt < 16; cnt++) | 1004 | for (cnt = 0; cnt < 16; cnt++) |
1324 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1005 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1325 | 1006 | ||
1326 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); | 1007 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); |
1327 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1008 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1328 | for (cnt = 0; cnt < 16; cnt++) | 1009 | for (cnt = 0; cnt < 16; cnt++) |
1329 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1010 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1330 | 1011 | ||
1331 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | 1012 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); |
1332 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1013 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1333 | for (cnt = 0; cnt < 16; cnt++) | 1014 | for (cnt = 0; cnt < 16; cnt++) |
1334 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1015 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1335 | 1016 | ||
1336 | /* Local memory controller registers. */ | 1017 | /* Local memory controller registers. */ |
1337 | iter_reg = fw->lmc_reg; | 1018 | iter_reg = fw->lmc_reg; |
1338 | WRT_REG_DWORD(®->iobase_addr, 0x3000); | 1019 | WRT_REG_DWORD(®->iobase_addr, 0x3000); |
1339 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1020 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1340 | for (cnt = 0; cnt < 16; cnt++) | 1021 | for (cnt = 0; cnt < 16; cnt++) |
1341 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1022 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1342 | 1023 | ||
1343 | WRT_REG_DWORD(®->iobase_addr, 0x3010); | 1024 | WRT_REG_DWORD(®->iobase_addr, 0x3010); |
1344 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1025 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1345 | for (cnt = 0; cnt < 16; cnt++) | 1026 | for (cnt = 0; cnt < 16; cnt++) |
1346 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1027 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1347 | 1028 | ||
1348 | WRT_REG_DWORD(®->iobase_addr, 0x3020); | 1029 | WRT_REG_DWORD(®->iobase_addr, 0x3020); |
1349 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1030 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1350 | for (cnt = 0; cnt < 16; cnt++) | 1031 | for (cnt = 0; cnt < 16; cnt++) |
1351 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1032 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1352 | 1033 | ||
1353 | WRT_REG_DWORD(®->iobase_addr, 0x3030); | 1034 | WRT_REG_DWORD(®->iobase_addr, 0x3030); |
1354 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1035 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1355 | for (cnt = 0; cnt < 16; cnt++) | 1036 | for (cnt = 0; cnt < 16; cnt++) |
1356 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1037 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1357 | 1038 | ||
1358 | WRT_REG_DWORD(®->iobase_addr, 0x3040); | 1039 | WRT_REG_DWORD(®->iobase_addr, 0x3040); |
1359 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1040 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1360 | for (cnt = 0; cnt < 16; cnt++) | 1041 | for (cnt = 0; cnt < 16; cnt++) |
1361 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1042 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1362 | 1043 | ||
1363 | WRT_REG_DWORD(®->iobase_addr, 0x3050); | 1044 | WRT_REG_DWORD(®->iobase_addr, 0x3050); |
1364 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1045 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1365 | for (cnt = 0; cnt < 16; cnt++) | 1046 | for (cnt = 0; cnt < 16; cnt++) |
1366 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1047 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1367 | 1048 | ||
1368 | WRT_REG_DWORD(®->iobase_addr, 0x3060); | 1049 | WRT_REG_DWORD(®->iobase_addr, 0x3060); |
1369 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1050 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1370 | for (cnt = 0; cnt < 16; cnt++) | 1051 | for (cnt = 0; cnt < 16; cnt++) |
1371 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1052 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1372 | 1053 | ||
1373 | /* Fibre Protocol Module registers. */ | 1054 | /* Fibre Protocol Module registers. */ |
1374 | iter_reg = fw->fpm_hdw_reg; | 1055 | iter_reg = fw->fpm_hdw_reg; |
1375 | WRT_REG_DWORD(®->iobase_addr, 0x4000); | 1056 | WRT_REG_DWORD(®->iobase_addr, 0x4000); |
1376 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1057 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1377 | for (cnt = 0; cnt < 16; cnt++) | 1058 | for (cnt = 0; cnt < 16; cnt++) |
1378 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1059 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1379 | 1060 | ||
1380 | WRT_REG_DWORD(®->iobase_addr, 0x4010); | 1061 | WRT_REG_DWORD(®->iobase_addr, 0x4010); |
1381 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1062 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1382 | for (cnt = 0; cnt < 16; cnt++) | 1063 | for (cnt = 0; cnt < 16; cnt++) |
1383 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1064 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1384 | 1065 | ||
1385 | WRT_REG_DWORD(®->iobase_addr, 0x4020); | 1066 | WRT_REG_DWORD(®->iobase_addr, 0x4020); |
1386 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1067 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1387 | for (cnt = 0; cnt < 16; cnt++) | 1068 | for (cnt = 0; cnt < 16; cnt++) |
1388 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1069 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1389 | 1070 | ||
1390 | WRT_REG_DWORD(®->iobase_addr, 0x4030); | 1071 | WRT_REG_DWORD(®->iobase_addr, 0x4030); |
1391 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1072 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1392 | for (cnt = 0; cnt < 16; cnt++) | 1073 | for (cnt = 0; cnt < 16; cnt++) |
1393 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1074 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1394 | 1075 | ||
1395 | WRT_REG_DWORD(®->iobase_addr, 0x4040); | 1076 | WRT_REG_DWORD(®->iobase_addr, 0x4040); |
1396 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1077 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1397 | for (cnt = 0; cnt < 16; cnt++) | 1078 | for (cnt = 0; cnt < 16; cnt++) |
1398 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1079 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1399 | 1080 | ||
1400 | WRT_REG_DWORD(®->iobase_addr, 0x4050); | 1081 | WRT_REG_DWORD(®->iobase_addr, 0x4050); |
1401 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1082 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1402 | for (cnt = 0; cnt < 16; cnt++) | 1083 | for (cnt = 0; cnt < 16; cnt++) |
1403 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1084 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1404 | 1085 | ||
1405 | WRT_REG_DWORD(®->iobase_addr, 0x4060); | 1086 | WRT_REG_DWORD(®->iobase_addr, 0x4060); |
1406 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1087 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1407 | for (cnt = 0; cnt < 16; cnt++) | 1088 | for (cnt = 0; cnt < 16; cnt++) |
1408 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1089 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1409 | 1090 | ||
1410 | WRT_REG_DWORD(®->iobase_addr, 0x4070); | 1091 | WRT_REG_DWORD(®->iobase_addr, 0x4070); |
1411 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1092 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1412 | for (cnt = 0; cnt < 16; cnt++) | 1093 | for (cnt = 0; cnt < 16; cnt++) |
1413 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1094 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1414 | 1095 | ||
1415 | WRT_REG_DWORD(®->iobase_addr, 0x4080); | 1096 | WRT_REG_DWORD(®->iobase_addr, 0x4080); |
1416 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1097 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1417 | for (cnt = 0; cnt < 16; cnt++) | 1098 | for (cnt = 0; cnt < 16; cnt++) |
1418 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1099 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1419 | 1100 | ||
1420 | WRT_REG_DWORD(®->iobase_addr, 0x4090); | 1101 | WRT_REG_DWORD(®->iobase_addr, 0x4090); |
1421 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1102 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1422 | for (cnt = 0; cnt < 16; cnt++) | 1103 | for (cnt = 0; cnt < 16; cnt++) |
1423 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1104 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1424 | 1105 | ||
1425 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); | 1106 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); |
1426 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1107 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1427 | for (cnt = 0; cnt < 16; cnt++) | 1108 | for (cnt = 0; cnt < 16; cnt++) |
1428 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1109 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1429 | 1110 | ||
1430 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); | 1111 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); |
1431 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1112 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1432 | for (cnt = 0; cnt < 16; cnt++) | 1113 | for (cnt = 0; cnt < 16; cnt++) |
1433 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1114 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1434 | 1115 | ||
1435 | /* Frame Buffer registers. */ | 1116 | /* Frame Buffer registers. */ |
1436 | iter_reg = fw->fb_hdw_reg; | 1117 | iter_reg = fw->fb_hdw_reg; |
1437 | WRT_REG_DWORD(®->iobase_addr, 0x6000); | 1118 | WRT_REG_DWORD(®->iobase_addr, 0x6000); |
1438 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1119 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1439 | for (cnt = 0; cnt < 16; cnt++) | 1120 | for (cnt = 0; cnt < 16; cnt++) |
1440 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1121 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1441 | 1122 | ||
1442 | WRT_REG_DWORD(®->iobase_addr, 0x6010); | 1123 | WRT_REG_DWORD(®->iobase_addr, 0x6010); |
1443 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1124 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1444 | for (cnt = 0; cnt < 16; cnt++) | 1125 | for (cnt = 0; cnt < 16; cnt++) |
1445 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1126 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1446 | 1127 | ||
1447 | WRT_REG_DWORD(®->iobase_addr, 0x6020); | 1128 | WRT_REG_DWORD(®->iobase_addr, 0x6020); |
1448 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1129 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1449 | for (cnt = 0; cnt < 16; cnt++) | 1130 | for (cnt = 0; cnt < 16; cnt++) |
1450 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1131 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1451 | 1132 | ||
1452 | WRT_REG_DWORD(®->iobase_addr, 0x6030); | 1133 | WRT_REG_DWORD(®->iobase_addr, 0x6030); |
1453 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1134 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1454 | for (cnt = 0; cnt < 16; cnt++) | 1135 | for (cnt = 0; cnt < 16; cnt++) |
1455 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1136 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1456 | 1137 | ||
1457 | WRT_REG_DWORD(®->iobase_addr, 0x6040); | 1138 | WRT_REG_DWORD(®->iobase_addr, 0x6040); |
1458 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1139 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1459 | for (cnt = 0; cnt < 16; cnt++) | 1140 | for (cnt = 0; cnt < 16; cnt++) |
1460 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1141 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1461 | 1142 | ||
1462 | WRT_REG_DWORD(®->iobase_addr, 0x6100); | 1143 | WRT_REG_DWORD(®->iobase_addr, 0x6100); |
1463 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1144 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1464 | for (cnt = 0; cnt < 16; cnt++) | 1145 | for (cnt = 0; cnt < 16; cnt++) |
1465 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1146 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1466 | 1147 | ||
1467 | WRT_REG_DWORD(®->iobase_addr, 0x6130); | 1148 | WRT_REG_DWORD(®->iobase_addr, 0x6130); |
1468 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1149 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1469 | for (cnt = 0; cnt < 16; cnt++) | 1150 | for (cnt = 0; cnt < 16; cnt++) |
1470 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1151 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1471 | 1152 | ||
1472 | WRT_REG_DWORD(®->iobase_addr, 0x6150); | 1153 | WRT_REG_DWORD(®->iobase_addr, 0x6150); |
1473 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1154 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1474 | for (cnt = 0; cnt < 16; cnt++) | 1155 | for (cnt = 0; cnt < 16; cnt++) |
1475 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1156 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1476 | 1157 | ||
1477 | WRT_REG_DWORD(®->iobase_addr, 0x6170); | 1158 | WRT_REG_DWORD(®->iobase_addr, 0x6170); |
1478 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1159 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1479 | for (cnt = 0; cnt < 16; cnt++) | 1160 | for (cnt = 0; cnt < 16; cnt++) |
1480 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1161 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1481 | 1162 | ||
1482 | WRT_REG_DWORD(®->iobase_addr, 0x6190); | 1163 | WRT_REG_DWORD(®->iobase_addr, 0x6190); |
1483 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1164 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1484 | for (cnt = 0; cnt < 16; cnt++) | 1165 | for (cnt = 0; cnt < 16; cnt++) |
1485 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1166 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1486 | 1167 | ||
1487 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); | 1168 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); |
1488 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1169 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1489 | for (cnt = 0; cnt < 16; cnt++) | 1170 | for (cnt = 0; cnt < 16; cnt++) |
1490 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1171 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1491 | 1172 | ||
1492 | /* Reset RISC. */ | 1173 | /* Reset RISC. */ |
1493 | WRT_REG_DWORD(®->ctrl_status, | 1174 | WRT_REG_DWORD(®->ctrl_status, |
@@ -1577,7 +1258,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1577 | 1258 | ||
1578 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 1259 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
1579 | rval = mb[0] & MBS_MASK; | 1260 | rval = mb[0] & MBS_MASK; |
1580 | fw->code_ram[cnt] = (mb[3] << 16) | mb[2]; | 1261 | fw->code_ram[cnt] = htonl((mb[3] << 16) | mb[2]); |
1581 | } else { | 1262 | } else { |
1582 | rval = QLA_FUNCTION_FAILED; | 1263 | rval = QLA_FUNCTION_FAILED; |
1583 | } | 1264 | } |
@@ -1627,12 +1308,18 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1627 | 1308 | ||
1628 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 1309 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
1629 | rval = mb[0] & MBS_MASK; | 1310 | rval = mb[0] & MBS_MASK; |
1630 | fw->ext_mem[cnt] = (mb[3] << 16) | mb[2]; | 1311 | fw->ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]); |
1631 | } else { | 1312 | } else { |
1632 | rval = QLA_FUNCTION_FAILED; | 1313 | rval = QLA_FUNCTION_FAILED; |
1633 | } | 1314 | } |
1634 | } | 1315 | } |
1635 | 1316 | ||
1317 | if (rval == QLA_SUCCESS) { | ||
1318 | eft = qla2xxx_copy_queues(ha, &fw->ext_mem[cnt]); | ||
1319 | if (ha->eft) | ||
1320 | memcpy(eft, ha->eft, ntohl(ha->fw_dump->eft_size)); | ||
1321 | } | ||
1322 | |||
1636 | if (rval != QLA_SUCCESS) { | 1323 | if (rval != QLA_SUCCESS) { |
1637 | qla_printk(KERN_WARNING, ha, | 1324 | qla_printk(KERN_WARNING, ha, |
1638 | "Failed to dump firmware (%x)!!!\n", rval); | 1325 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -1650,252 +1337,6 @@ qla24xx_fw_dump_failed: | |||
1650 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1337 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1651 | } | 1338 | } |
1652 | 1339 | ||
1653 | void | ||
1654 | qla24xx_ascii_fw_dump(scsi_qla_host_t *ha) | ||
1655 | { | ||
1656 | uint32_t cnt; | ||
1657 | char *uiter; | ||
1658 | struct qla24xx_fw_dump *fw; | ||
1659 | uint32_t ext_mem_cnt; | ||
1660 | |||
1661 | uiter = ha->fw_dump_buffer; | ||
1662 | fw = ha->fw_dump; | ||
1663 | |||
1664 | qla_uprintf(&uiter, "ISP FW Version %d.%02d.%02d Attributes %04x\n", | ||
1665 | ha->fw_major_version, ha->fw_minor_version, | ||
1666 | ha->fw_subminor_version, ha->fw_attributes); | ||
1667 | |||
1668 | qla_uprintf(&uiter, "\nR2H Status Register\n%04x\n", fw->host_status); | ||
1669 | |||
1670 | qla_uprintf(&uiter, "\nHost Interface Registers"); | ||
1671 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) { | ||
1672 | if (cnt % 8 == 0) | ||
1673 | qla_uprintf(&uiter, "\n"); | ||
1674 | |||
1675 | qla_uprintf(&uiter, "%08x ", fw->host_reg[cnt]); | ||
1676 | } | ||
1677 | |||
1678 | qla_uprintf(&uiter, "\n\nShadow Registers"); | ||
1679 | for (cnt = 0; cnt < sizeof(fw->shadow_reg) / 4; cnt++) { | ||
1680 | if (cnt % 8 == 0) | ||
1681 | qla_uprintf(&uiter, "\n"); | ||
1682 | |||
1683 | qla_uprintf(&uiter, "%08x ", fw->shadow_reg[cnt]); | ||
1684 | } | ||
1685 | |||
1686 | qla_uprintf(&uiter, "\n\nMailbox Registers"); | ||
1687 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) { | ||
1688 | if (cnt % 8 == 0) | ||
1689 | qla_uprintf(&uiter, "\n"); | ||
1690 | |||
1691 | qla_uprintf(&uiter, "%08x ", fw->mailbox_reg[cnt]); | ||
1692 | } | ||
1693 | |||
1694 | qla_uprintf(&uiter, "\n\nXSEQ GP Registers"); | ||
1695 | for (cnt = 0; cnt < sizeof(fw->xseq_gp_reg) / 4; cnt++) { | ||
1696 | if (cnt % 8 == 0) | ||
1697 | qla_uprintf(&uiter, "\n"); | ||
1698 | |||
1699 | qla_uprintf(&uiter, "%08x ", fw->xseq_gp_reg[cnt]); | ||
1700 | } | ||
1701 | |||
1702 | qla_uprintf(&uiter, "\n\nXSEQ-0 Registers"); | ||
1703 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) { | ||
1704 | if (cnt % 8 == 0) | ||
1705 | qla_uprintf(&uiter, "\n"); | ||
1706 | |||
1707 | qla_uprintf(&uiter, "%08x ", fw->xseq_0_reg[cnt]); | ||
1708 | } | ||
1709 | |||
1710 | qla_uprintf(&uiter, "\n\nXSEQ-1 Registers"); | ||
1711 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) { | ||
1712 | if (cnt % 8 == 0) | ||
1713 | qla_uprintf(&uiter, "\n"); | ||
1714 | |||
1715 | qla_uprintf(&uiter, "%08x ", fw->xseq_1_reg[cnt]); | ||
1716 | } | ||
1717 | |||
1718 | qla_uprintf(&uiter, "\n\nRSEQ GP Registers"); | ||
1719 | for (cnt = 0; cnt < sizeof(fw->rseq_gp_reg) / 4; cnt++) { | ||
1720 | if (cnt % 8 == 0) | ||
1721 | qla_uprintf(&uiter, "\n"); | ||
1722 | |||
1723 | qla_uprintf(&uiter, "%08x ", fw->rseq_gp_reg[cnt]); | ||
1724 | } | ||
1725 | |||
1726 | qla_uprintf(&uiter, "\n\nRSEQ-0 Registers"); | ||
1727 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) { | ||
1728 | if (cnt % 8 == 0) | ||
1729 | qla_uprintf(&uiter, "\n"); | ||
1730 | |||
1731 | qla_uprintf(&uiter, "%08x ", fw->rseq_0_reg[cnt]); | ||
1732 | } | ||
1733 | |||
1734 | qla_uprintf(&uiter, "\n\nRSEQ-1 Registers"); | ||
1735 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) { | ||
1736 | if (cnt % 8 == 0) | ||
1737 | qla_uprintf(&uiter, "\n"); | ||
1738 | |||
1739 | qla_uprintf(&uiter, "%08x ", fw->rseq_1_reg[cnt]); | ||
1740 | } | ||
1741 | |||
1742 | qla_uprintf(&uiter, "\n\nRSEQ-2 Registers"); | ||
1743 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) { | ||
1744 | if (cnt % 8 == 0) | ||
1745 | qla_uprintf(&uiter, "\n"); | ||
1746 | |||
1747 | qla_uprintf(&uiter, "%08x ", fw->rseq_2_reg[cnt]); | ||
1748 | } | ||
1749 | |||
1750 | qla_uprintf(&uiter, "\n\nCommand DMA Registers"); | ||
1751 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) { | ||
1752 | if (cnt % 8 == 0) | ||
1753 | qla_uprintf(&uiter, "\n"); | ||
1754 | |||
1755 | qla_uprintf(&uiter, "%08x ", fw->cmd_dma_reg[cnt]); | ||
1756 | } | ||
1757 | |||
1758 | qla_uprintf(&uiter, "\n\nRequest0 Queue DMA Channel Registers"); | ||
1759 | for (cnt = 0; cnt < sizeof(fw->req0_dma_reg) / 4; cnt++) { | ||
1760 | if (cnt % 8 == 0) | ||
1761 | qla_uprintf(&uiter, "\n"); | ||
1762 | |||
1763 | qla_uprintf(&uiter, "%08x ", fw->req0_dma_reg[cnt]); | ||
1764 | } | ||
1765 | |||
1766 | qla_uprintf(&uiter, "\n\nResponse0 Queue DMA Channel Registers"); | ||
1767 | for (cnt = 0; cnt < sizeof(fw->resp0_dma_reg) / 4; cnt++) { | ||
1768 | if (cnt % 8 == 0) | ||
1769 | qla_uprintf(&uiter, "\n"); | ||
1770 | |||
1771 | qla_uprintf(&uiter, "%08x ", fw->resp0_dma_reg[cnt]); | ||
1772 | } | ||
1773 | |||
1774 | qla_uprintf(&uiter, "\n\nRequest1 Queue DMA Channel Registers"); | ||
1775 | for (cnt = 0; cnt < sizeof(fw->req1_dma_reg) / 4; cnt++) { | ||
1776 | if (cnt % 8 == 0) | ||
1777 | qla_uprintf(&uiter, "\n"); | ||
1778 | |||
1779 | qla_uprintf(&uiter, "%08x ", fw->req1_dma_reg[cnt]); | ||
1780 | } | ||
1781 | |||
1782 | qla_uprintf(&uiter, "\n\nXMT0 Data DMA Registers"); | ||
1783 | for (cnt = 0; cnt < sizeof(fw->xmt0_dma_reg) / 4; cnt++) { | ||
1784 | if (cnt % 8 == 0) | ||
1785 | qla_uprintf(&uiter, "\n"); | ||
1786 | |||
1787 | qla_uprintf(&uiter, "%08x ", fw->xmt0_dma_reg[cnt]); | ||
1788 | } | ||
1789 | |||
1790 | qla_uprintf(&uiter, "\n\nXMT1 Data DMA Registers"); | ||
1791 | for (cnt = 0; cnt < sizeof(fw->xmt1_dma_reg) / 4; cnt++) { | ||
1792 | if (cnt % 8 == 0) | ||
1793 | qla_uprintf(&uiter, "\n"); | ||
1794 | |||
1795 | qla_uprintf(&uiter, "%08x ", fw->xmt1_dma_reg[cnt]); | ||
1796 | } | ||
1797 | |||
1798 | qla_uprintf(&uiter, "\n\nXMT2 Data DMA Registers"); | ||
1799 | for (cnt = 0; cnt < sizeof(fw->xmt2_dma_reg) / 4; cnt++) { | ||
1800 | if (cnt % 8 == 0) | ||
1801 | qla_uprintf(&uiter, "\n"); | ||
1802 | |||
1803 | qla_uprintf(&uiter, "%08x ", fw->xmt2_dma_reg[cnt]); | ||
1804 | } | ||
1805 | |||
1806 | qla_uprintf(&uiter, "\n\nXMT3 Data DMA Registers"); | ||
1807 | for (cnt = 0; cnt < sizeof(fw->xmt3_dma_reg) / 4; cnt++) { | ||
1808 | if (cnt % 8 == 0) | ||
1809 | qla_uprintf(&uiter, "\n"); | ||
1810 | |||
1811 | qla_uprintf(&uiter, "%08x ", fw->xmt3_dma_reg[cnt]); | ||
1812 | } | ||
1813 | |||
1814 | qla_uprintf(&uiter, "\n\nXMT4 Data DMA Registers"); | ||
1815 | for (cnt = 0; cnt < sizeof(fw->xmt4_dma_reg) / 4; cnt++) { | ||
1816 | if (cnt % 8 == 0) | ||
1817 | qla_uprintf(&uiter, "\n"); | ||
1818 | |||
1819 | qla_uprintf(&uiter, "%08x ", fw->xmt4_dma_reg[cnt]); | ||
1820 | } | ||
1821 | |||
1822 | qla_uprintf(&uiter, "\n\nXMT Data DMA Common Registers"); | ||
1823 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) { | ||
1824 | if (cnt % 8 == 0) | ||
1825 | qla_uprintf(&uiter, "\n"); | ||
1826 | |||
1827 | qla_uprintf(&uiter, "%08x ", fw->xmt_data_dma_reg[cnt]); | ||
1828 | } | ||
1829 | |||
1830 | qla_uprintf(&uiter, "\n\nRCV Thread 0 Data DMA Registers"); | ||
1831 | for (cnt = 0; cnt < sizeof(fw->rcvt0_data_dma_reg) / 4; cnt++) { | ||
1832 | if (cnt % 8 == 0) | ||
1833 | qla_uprintf(&uiter, "\n"); | ||
1834 | |||
1835 | qla_uprintf(&uiter, "%08x ", fw->rcvt0_data_dma_reg[cnt]); | ||
1836 | } | ||
1837 | |||
1838 | qla_uprintf(&uiter, "\n\nRCV Thread 1 Data DMA Registers"); | ||
1839 | for (cnt = 0; cnt < sizeof(fw->rcvt1_data_dma_reg) / 4; cnt++) { | ||
1840 | if (cnt % 8 == 0) | ||
1841 | qla_uprintf(&uiter, "\n"); | ||
1842 | |||
1843 | qla_uprintf(&uiter, "%08x ", fw->rcvt1_data_dma_reg[cnt]); | ||
1844 | } | ||
1845 | |||
1846 | qla_uprintf(&uiter, "\n\nRISC GP Registers"); | ||
1847 | for (cnt = 0; cnt < sizeof(fw->risc_gp_reg) / 4; cnt++) { | ||
1848 | if (cnt % 8 == 0) | ||
1849 | qla_uprintf(&uiter, "\n"); | ||
1850 | |||
1851 | qla_uprintf(&uiter, "%08x ", fw->risc_gp_reg[cnt]); | ||
1852 | } | ||
1853 | |||
1854 | qla_uprintf(&uiter, "\n\nLMC Registers"); | ||
1855 | for (cnt = 0; cnt < sizeof(fw->lmc_reg) / 4; cnt++) { | ||
1856 | if (cnt % 8 == 0) | ||
1857 | qla_uprintf(&uiter, "\n"); | ||
1858 | |||
1859 | qla_uprintf(&uiter, "%08x ", fw->lmc_reg[cnt]); | ||
1860 | } | ||
1861 | |||
1862 | qla_uprintf(&uiter, "\n\nFPM Hardware Registers"); | ||
1863 | for (cnt = 0; cnt < sizeof(fw->fpm_hdw_reg) / 4; cnt++) { | ||
1864 | if (cnt % 8 == 0) | ||
1865 | qla_uprintf(&uiter, "\n"); | ||
1866 | |||
1867 | qla_uprintf(&uiter, "%08x ", fw->fpm_hdw_reg[cnt]); | ||
1868 | } | ||
1869 | |||
1870 | qla_uprintf(&uiter, "\n\nFB Hardware Registers"); | ||
1871 | for (cnt = 0; cnt < sizeof(fw->fb_hdw_reg) / 4; cnt++) { | ||
1872 | if (cnt % 8 == 0) | ||
1873 | qla_uprintf(&uiter, "\n"); | ||
1874 | |||
1875 | qla_uprintf(&uiter, "%08x ", fw->fb_hdw_reg[cnt]); | ||
1876 | } | ||
1877 | |||
1878 | qla_uprintf(&uiter, "\n\nCode RAM"); | ||
1879 | for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) { | ||
1880 | if (cnt % 8 == 0) { | ||
1881 | qla_uprintf(&uiter, "\n%08x: ", cnt + 0x20000); | ||
1882 | } | ||
1883 | qla_uprintf(&uiter, "%08x ", fw->code_ram[cnt]); | ||
1884 | } | ||
1885 | |||
1886 | qla_uprintf(&uiter, "\n\nExternal Memory"); | ||
1887 | ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1; | ||
1888 | for (cnt = 0; cnt < ext_mem_cnt; cnt++) { | ||
1889 | if (cnt % 8 == 0) { | ||
1890 | qla_uprintf(&uiter, "\n%08x: ", cnt + 0x100000); | ||
1891 | } | ||
1892 | qla_uprintf(&uiter, "%08x ", fw->ext_mem[cnt]); | ||
1893 | } | ||
1894 | |||
1895 | qla_uprintf(&uiter, "\n[<==END] ISP Debug Dump"); | ||
1896 | } | ||
1897 | |||
1898 | |||
1899 | /****************************************************************************/ | 1340 | /****************************************************************************/ |
1900 | /* Driver Debug Functions. */ | 1341 | /* Driver Debug Functions. */ |
1901 | /****************************************************************************/ | 1342 | /****************************************************************************/ |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index ab6afeaa2f2c..533425338e05 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -37,134 +37,86 @@ | |||
37 | /* | 37 | /* |
38 | * Macros use for debugging the driver. | 38 | * Macros use for debugging the driver. |
39 | */ | 39 | */ |
40 | #undef ENTER_TRACE | ||
41 | #if defined(ENTER_TRACE) | ||
42 | #define ENTER(x) do { printk("qla2100 : Entering %s()\n", x); } while (0) | ||
43 | #define LEAVE(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0) | ||
44 | #define ENTER_INTR(x) do { printk("qla2100 : Entering %s()\n", x); } while (0) | ||
45 | #define LEAVE_INTR(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0) | ||
46 | #else | ||
47 | #define ENTER(x) do {} while (0) | ||
48 | #define LEAVE(x) do {} while (0) | ||
49 | #define ENTER_INTR(x) do {} while (0) | ||
50 | #define LEAVE_INTR(x) do {} while (0) | ||
51 | #endif | ||
52 | 40 | ||
53 | #if DEBUG_QLA2100 | 41 | #define DEBUG(x) do { if (extended_error_logging) { x; } } while (0) |
54 | #define DEBUG(x) do {x;} while (0); | ||
55 | #else | ||
56 | #define DEBUG(x) do {} while (0); | ||
57 | #endif | ||
58 | 42 | ||
59 | #if defined(QL_DEBUG_LEVEL_1) | 43 | #if defined(QL_DEBUG_LEVEL_1) |
60 | #define DEBUG1(x) do {x;} while (0); | 44 | #define DEBUG1(x) do {x;} while (0) |
61 | #else | 45 | #else |
62 | #define DEBUG1(x) do {} while (0); | 46 | #define DEBUG1(x) do {} while (0) |
63 | #endif | 47 | #endif |
64 | 48 | ||
65 | #if defined(QL_DEBUG_LEVEL_2) | 49 | #define DEBUG2(x) do { if (extended_error_logging) { x; } } while (0) |
66 | #define DEBUG2(x) do {x;} while (0); | 50 | #define DEBUG2_3(x) do { if (extended_error_logging) { x; } } while (0) |
67 | #define DEBUG2_3(x) do {x;} while (0); | 51 | #define DEBUG2_3_11(x) do { if (extended_error_logging) { x; } } while (0) |
68 | #define DEBUG2_3_11(x) do {x;} while (0); | 52 | #define DEBUG2_9_10(x) do { if (extended_error_logging) { x; } } while (0) |
69 | #define DEBUG2_9_10(x) do {x;} while (0); | 53 | #define DEBUG2_11(x) do { if (extended_error_logging) { x; } } while (0) |
70 | #define DEBUG2_11(x) do {x;} while (0); | 54 | #define DEBUG2_13(x) do { if (extended_error_logging) { x; } } while (0) |
71 | #define DEBUG2_13(x) do {x;} while (0); | ||
72 | #else | ||
73 | #define DEBUG2(x) do {} while (0); | ||
74 | #endif | ||
75 | 55 | ||
76 | #if defined(QL_DEBUG_LEVEL_3) | 56 | #if defined(QL_DEBUG_LEVEL_3) |
77 | #define DEBUG3(x) do {x;} while (0); | 57 | #define DEBUG3(x) do {x;} while (0) |
78 | #define DEBUG2_3(x) do {x;} while (0); | 58 | #define DEBUG3_11(x) do {x;} while (0) |
79 | #define DEBUG2_3_11(x) do {x;} while (0); | ||
80 | #define DEBUG3_11(x) do {x;} while (0); | ||
81 | #else | 59 | #else |
82 | #define DEBUG3(x) do {} while (0); | 60 | #define DEBUG3(x) do {} while (0) |
83 | #if !defined(QL_DEBUG_LEVEL_2) | ||
84 | #define DEBUG2_3(x) do {} while (0); | ||
85 | #endif | ||
86 | #endif | 61 | #endif |
87 | 62 | ||
88 | #if defined(QL_DEBUG_LEVEL_4) | 63 | #if defined(QL_DEBUG_LEVEL_4) |
89 | #define DEBUG4(x) do {x;} while (0); | 64 | #define DEBUG4(x) do {x;} while (0) |
90 | #else | 65 | #else |
91 | #define DEBUG4(x) do {} while (0); | 66 | #define DEBUG4(x) do {} while (0) |
92 | #endif | 67 | #endif |
93 | 68 | ||
94 | #if defined(QL_DEBUG_LEVEL_5) | 69 | #if defined(QL_DEBUG_LEVEL_5) |
95 | #define DEBUG5(x) do {x;} while (0); | 70 | #define DEBUG5(x) do {x;} while (0) |
96 | #else | 71 | #else |
97 | #define DEBUG5(x) do {} while (0); | 72 | #define DEBUG5(x) do {} while (0) |
98 | #endif | 73 | #endif |
99 | 74 | ||
100 | #if defined(QL_DEBUG_LEVEL_7) | 75 | #if defined(QL_DEBUG_LEVEL_7) |
101 | #define DEBUG7(x) do {x;} while (0); | 76 | #define DEBUG7(x) do {x;} while (0) |
102 | #else | 77 | #else |
103 | #define DEBUG7(x) do {} while (0); | 78 | #define DEBUG7(x) do {} while (0) |
104 | #endif | 79 | #endif |
105 | 80 | ||
106 | #if defined(QL_DEBUG_LEVEL_9) | 81 | #if defined(QL_DEBUG_LEVEL_9) |
107 | #define DEBUG9(x) do {x;} while (0); | 82 | #define DEBUG9(x) do {x;} while (0) |
108 | #define DEBUG9_10(x) do {x;} while (0); | 83 | #define DEBUG9_10(x) do {x;} while (0) |
109 | #define DEBUG2_9_10(x) do {x;} while (0); | ||
110 | #else | 84 | #else |
111 | #define DEBUG9(x) do {} while (0); | 85 | #define DEBUG9(x) do {} while (0) |
112 | #endif | 86 | #endif |
113 | 87 | ||
114 | #if defined(QL_DEBUG_LEVEL_10) | 88 | #if defined(QL_DEBUG_LEVEL_10) |
115 | #define DEBUG10(x) do {x;} while (0); | 89 | #define DEBUG10(x) do {x;} while (0) |
116 | #define DEBUG2_9_10(x) do {x;} while (0); | 90 | #define DEBUG9_10(x) do {x;} while (0) |
117 | #define DEBUG9_10(x) do {x;} while (0); | ||
118 | #else | 91 | #else |
119 | #define DEBUG10(x) do {} while (0); | 92 | #define DEBUG10(x) do {} while (0) |
120 | #if !defined(DEBUG2_9_10) | ||
121 | #define DEBUG2_9_10(x) do {} while (0); | ||
122 | #endif | ||
123 | #if !defined(DEBUG9_10) | 93 | #if !defined(DEBUG9_10) |
124 | #define DEBUG9_10(x) do {} while (0); | 94 | #define DEBUG9_10(x) do {} while (0) |
125 | #endif | 95 | #endif |
126 | #endif | 96 | #endif |
127 | 97 | ||
128 | #if defined(QL_DEBUG_LEVEL_11) | 98 | #if defined(QL_DEBUG_LEVEL_11) |
129 | #define DEBUG11(x) do{x;} while(0); | 99 | #define DEBUG11(x) do{x;} while(0) |
130 | #if !defined(DEBUG2_11) | ||
131 | #define DEBUG2_11(x) do{x;} while(0); | ||
132 | #endif | ||
133 | #if !defined(DEBUG2_3_11) | ||
134 | #define DEBUG2_3_11(x) do{x;} while(0); | ||
135 | #endif | ||
136 | #if !defined(DEBUG3_11) | 100 | #if !defined(DEBUG3_11) |
137 | #define DEBUG3_11(x) do{x;} while(0); | 101 | #define DEBUG3_11(x) do{x;} while(0) |
138 | #endif | 102 | #endif |
139 | #else | 103 | #else |
140 | #define DEBUG11(x) do{} while(0); | 104 | #define DEBUG11(x) do{} while(0) |
141 | #if !defined(QL_DEBUG_LEVEL_2) | ||
142 | #define DEBUG2_11(x) do{} while(0); | ||
143 | #if !defined(QL_DEBUG_LEVEL_3) | ||
144 | #define DEBUG2_3_11(x) do{} while(0); | ||
145 | #endif | ||
146 | #endif | ||
147 | #if !defined(QL_DEBUG_LEVEL_3) | 105 | #if !defined(QL_DEBUG_LEVEL_3) |
148 | #define DEBUG3_11(x) do{} while(0); | 106 | #define DEBUG3_11(x) do{} while(0) |
149 | #endif | 107 | #endif |
150 | #endif | 108 | #endif |
151 | 109 | ||
152 | #if defined(QL_DEBUG_LEVEL_12) | 110 | #if defined(QL_DEBUG_LEVEL_12) |
153 | #define DEBUG12(x) do {x;} while (0); | 111 | #define DEBUG12(x) do {x;} while (0) |
154 | #else | 112 | #else |
155 | #define DEBUG12(x) do {} while (0); | 113 | #define DEBUG12(x) do {} while (0) |
156 | #endif | 114 | #endif |
157 | 115 | ||
158 | #if defined(QL_DEBUG_LEVEL_13) | 116 | #if defined(QL_DEBUG_LEVEL_13) |
159 | #define DEBUG13(x) do {x;} while (0) | 117 | #define DEBUG13(x) do {x;} while (0) |
160 | #if !defined(DEBUG2_13) | ||
161 | #define DEBUG2_13(x) do {x;} while(0) | ||
162 | #endif | ||
163 | #else | 118 | #else |
164 | #define DEBUG13(x) do {} while (0) | 119 | #define DEBUG13(x) do {} while (0) |
165 | #if !defined(QL_DEBUG_LEVEL_2) | ||
166 | #define DEBUG2_13(x) do {} while(0) | ||
167 | #endif | ||
168 | #endif | 120 | #endif |
169 | 121 | ||
170 | #if defined(QL_DEBUG_LEVEL_14) | 122 | #if defined(QL_DEBUG_LEVEL_14) |
@@ -176,9 +128,6 @@ | |||
176 | /* | 128 | /* |
177 | * Firmware Dump structure definition | 129 | * Firmware Dump structure definition |
178 | */ | 130 | */ |
179 | #define FW_DUMP_SIZE_128K 0xBC000 | ||
180 | #define FW_DUMP_SIZE_512K 0x2FC000 | ||
181 | #define FW_DUMP_SIZE_1M 0x5FC000 | ||
182 | 131 | ||
183 | struct qla2300_fw_dump { | 132 | struct qla2300_fw_dump { |
184 | uint16_t hccr; | 133 | uint16_t hccr; |
@@ -224,8 +173,6 @@ struct qla2100_fw_dump { | |||
224 | uint16_t risc_ram[0xf000]; | 173 | uint16_t risc_ram[0xf000]; |
225 | }; | 174 | }; |
226 | 175 | ||
227 | #define FW_DUMP_SIZE_24XX 0x2B0000 | ||
228 | |||
229 | struct qla24xx_fw_dump { | 176 | struct qla24xx_fw_dump { |
230 | uint32_t host_status; | 177 | uint32_t host_status; |
231 | uint32_t host_reg[32]; | 178 | uint32_t host_reg[32]; |
@@ -257,3 +204,39 @@ struct qla24xx_fw_dump { | |||
257 | uint32_t code_ram[0x2000]; | 204 | uint32_t code_ram[0x2000]; |
258 | uint32_t ext_mem[1]; | 205 | uint32_t ext_mem[1]; |
259 | }; | 206 | }; |
207 | |||
208 | #define EFT_NUM_BUFFERS 4 | ||
209 | #define EFT_BYTES_PER_BUFFER 0x4000 | ||
210 | #define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS)) | ||
211 | |||
212 | struct qla2xxx_fw_dump { | ||
213 | uint8_t signature[4]; | ||
214 | uint32_t version; | ||
215 | |||
216 | uint32_t fw_major_version; | ||
217 | uint32_t fw_minor_version; | ||
218 | uint32_t fw_subminor_version; | ||
219 | uint32_t fw_attributes; | ||
220 | |||
221 | uint32_t vendor; | ||
222 | uint32_t device; | ||
223 | uint32_t subsystem_vendor; | ||
224 | uint32_t subsystem_device; | ||
225 | |||
226 | uint32_t fixed_size; | ||
227 | uint32_t mem_size; | ||
228 | uint32_t req_q_size; | ||
229 | uint32_t rsp_q_size; | ||
230 | |||
231 | uint32_t eft_size; | ||
232 | uint32_t eft_addr_l; | ||
233 | uint32_t eft_addr_h; | ||
234 | |||
235 | uint32_t header_size; | ||
236 | |||
237 | union { | ||
238 | struct qla2100_fw_dump isp21; | ||
239 | struct qla2300_fw_dump isp23; | ||
240 | struct qla24xx_fw_dump isp24; | ||
241 | } isp; | ||
242 | }; | ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6734453ea28a..139ea0e27fd7 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -608,7 +608,9 @@ typedef struct { | |||
608 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ | 608 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ |
609 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ | 609 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ |
610 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ | 610 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ |
611 | #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ | ||
611 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ | 612 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ |
613 | #define MBC_READ_SFP 0x31 /* Read SFP Data. */ | ||
612 | #define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ | 614 | #define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ |
613 | #define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */ | 615 | #define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */ |
614 | #define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */ | 616 | #define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */ |
@@ -618,6 +620,9 @@ typedef struct { | |||
618 | #define MBC_GET_LINK_PRIV_STATS 0x6d /* Get link & private data. */ | 620 | #define MBC_GET_LINK_PRIV_STATS 0x6d /* Get link & private data. */ |
619 | #define MBC_SET_VENDOR_ID 0x76 /* Set Vendor ID. */ | 621 | #define MBC_SET_VENDOR_ID 0x76 /* Set Vendor ID. */ |
620 | 622 | ||
623 | #define TC_ENABLE 4 | ||
624 | #define TC_DISABLE 5 | ||
625 | |||
621 | /* Firmware return data sizes */ | 626 | /* Firmware return data sizes */ |
622 | #define FCAL_MAP_SIZE 128 | 627 | #define FCAL_MAP_SIZE 128 |
623 | 628 | ||
@@ -1997,7 +2002,6 @@ struct isp_operations { | |||
1997 | uint32_t); | 2002 | uint32_t); |
1998 | 2003 | ||
1999 | void (*fw_dump) (struct scsi_qla_host *, int); | 2004 | void (*fw_dump) (struct scsi_qla_host *, int); |
2000 | void (*ascii_fw_dump) (struct scsi_qla_host *); | ||
2001 | 2005 | ||
2002 | int (*beacon_on) (struct scsi_qla_host *); | 2006 | int (*beacon_on) (struct scsi_qla_host *); |
2003 | int (*beacon_off) (struct scsi_qla_host *); | 2007 | int (*beacon_off) (struct scsi_qla_host *); |
@@ -2041,6 +2045,7 @@ typedef struct scsi_qla_host { | |||
2041 | uint32_t enable_led_scheme :1; | 2045 | uint32_t enable_led_scheme :1; |
2042 | uint32_t msi_enabled :1; | 2046 | uint32_t msi_enabled :1; |
2043 | uint32_t msix_enabled :1; | 2047 | uint32_t msix_enabled :1; |
2048 | uint32_t disable_serdes :1; | ||
2044 | } flags; | 2049 | } flags; |
2045 | 2050 | ||
2046 | atomic_t loop_state; | 2051 | atomic_t loop_state; |
@@ -2238,6 +2243,11 @@ typedef struct scsi_qla_host { | |||
2238 | struct sns_cmd_pkt *sns_cmd; | 2243 | struct sns_cmd_pkt *sns_cmd; |
2239 | dma_addr_t sns_cmd_dma; | 2244 | dma_addr_t sns_cmd_dma; |
2240 | 2245 | ||
2246 | #define SFP_DEV_SIZE 256 | ||
2247 | #define SFP_BLOCK_SIZE 64 | ||
2248 | void *sfp_data; | ||
2249 | dma_addr_t sfp_data_dma; | ||
2250 | |||
2241 | struct task_struct *dpc_thread; | 2251 | struct task_struct *dpc_thread; |
2242 | uint8_t dpc_active; /* DPC routine is active */ | 2252 | uint8_t dpc_active; /* DPC routine is active */ |
2243 | 2253 | ||
@@ -2303,11 +2313,12 @@ typedef struct scsi_qla_host { | |||
2303 | uint16_t fw_seriallink_options24[4]; | 2313 | uint16_t fw_seriallink_options24[4]; |
2304 | 2314 | ||
2305 | /* Firmware dump information. */ | 2315 | /* Firmware dump information. */ |
2306 | void *fw_dump; | 2316 | struct qla2xxx_fw_dump *fw_dump; |
2317 | uint32_t fw_dump_len; | ||
2307 | int fw_dumped; | 2318 | int fw_dumped; |
2308 | int fw_dump_reading; | 2319 | int fw_dump_reading; |
2309 | char *fw_dump_buffer; | 2320 | dma_addr_t eft_dma; |
2310 | int fw_dump_buffer_len; | 2321 | void *eft; |
2311 | 2322 | ||
2312 | uint8_t host_str[16]; | 2323 | uint8_t host_str[16]; |
2313 | uint32_t pci_attr; | 2324 | uint32_t pci_attr; |
diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h index a8fc0ffc7fc5..dd435410dfa2 100644 --- a/drivers/scsi/qla2xxx/qla_devtbl.h +++ b/drivers/scsi/qla2xxx/qla_devtbl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | #define QLA_MODEL_NAMES 0x4A | 1 | #define QLA_MODEL_NAMES 0x57 |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Adapter model names and descriptions. | 4 | * Adapter model names and descriptions. |
@@ -76,6 +76,19 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = { | |||
76 | "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ | 76 | "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ |
77 | "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ | 77 | "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ |
78 | "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ | 78 | "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ |
79 | " ", " ", /* 0x148 */ | 79 | "HP AE369A", "PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x148 */ |
80 | "QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */ | 80 | "QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */ |
81 | " ", " ", /* 0x14a */ | ||
82 | " ", " ", /* 0x14b */ | ||
83 | "QMC2432M", "IBM eServer BC 4Gb FC Expansion Card CFFE", /* 0x14c */ | ||
84 | "QMC2422M", "IBM eServer BC 4Gb FC Expansion Card CFFX", /* 0x14d */ | ||
85 | "QLE220", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x14e */ | ||
86 | " ", " ", /* 0x14f */ | ||
87 | " ", " ", /* 0x150 */ | ||
88 | " ", " ", /* 0x151 */ | ||
89 | "QME2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x152 */ | ||
90 | "QMH2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x153 */ | ||
91 | " ", " ", /* 0x154 */ | ||
92 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x155 */ | ||
93 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x156 */ | ||
81 | }; | 94 | }; |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 3af478663be7..a0a722cf4237 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -141,7 +141,7 @@ struct nvram_24xx { | |||
141 | * BIT 2 = Enable Memory Map BIOS | 141 | * BIT 2 = Enable Memory Map BIOS |
142 | * BIT 3 = Enable Selectable Boot | 142 | * BIT 3 = Enable Selectable Boot |
143 | * BIT 4 = Disable RISC code load | 143 | * BIT 4 = Disable RISC code load |
144 | * BIT 5 = | 144 | * BIT 5 = Disable Serdes |
145 | * BIT 6 = | 145 | * BIT 6 = |
146 | * BIT 7 = | 146 | * BIT 7 = |
147 | * | 147 | * |
@@ -278,7 +278,7 @@ struct init_cb_24xx { | |||
278 | uint16_t response_q_length; | 278 | uint16_t response_q_length; |
279 | uint16_t request_q_length; | 279 | uint16_t request_q_length; |
280 | 280 | ||
281 | uint16_t link_down_timeout; /* Milliseconds. */ | 281 | uint16_t link_down_on_nos; /* Milliseconds. */ |
282 | 282 | ||
283 | uint16_t prio_request_q_length; | 283 | uint16_t prio_request_q_length; |
284 | 284 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 164d53ccbfd0..8311ac2b93a8 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -31,13 +31,9 @@ extern void qla2x00_update_fw_options(struct scsi_qla_host *); | |||
31 | extern void qla24xx_update_fw_options(scsi_qla_host_t *); | 31 | extern void qla24xx_update_fw_options(scsi_qla_host_t *); |
32 | extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *); | 32 | extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *); |
33 | extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *); | 33 | extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *); |
34 | extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *); | ||
35 | |||
36 | extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t); | ||
37 | 34 | ||
38 | extern int qla2x00_loop_resync(scsi_qla_host_t *); | 35 | extern int qla2x00_loop_resync(scsi_qla_host_t *); |
39 | 36 | ||
40 | extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *); | ||
41 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); | 37 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); |
42 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); | 38 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); |
43 | 39 | ||
@@ -51,6 +47,8 @@ extern int qla2x00_abort_isp(scsi_qla_host_t *); | |||
51 | extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | 47 | extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); |
52 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); | 48 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); |
53 | 49 | ||
50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); | ||
51 | |||
54 | /* | 52 | /* |
55 | * Global Data in qla_os.c source file. | 53 | * Global Data in qla_os.c source file. |
56 | */ | 54 | */ |
@@ -61,6 +59,8 @@ extern int qlport_down_retry; | |||
61 | extern int ql2xplogiabsentdevice; | 59 | extern int ql2xplogiabsentdevice; |
62 | extern int ql2xloginretrycount; | 60 | extern int ql2xloginretrycount; |
63 | extern int ql2xfdmienable; | 61 | extern int ql2xfdmienable; |
62 | extern int ql2xallocfwdump; | ||
63 | extern int extended_error_logging; | ||
64 | 64 | ||
65 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); | 65 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); |
66 | 66 | ||
@@ -80,8 +80,6 @@ extern void qla2xxx_wake_dpc(scsi_qla_host_t *); | |||
80 | /* | 80 | /* |
81 | * Global Function Prototypes in qla_iocb.c source file. | 81 | * Global Function Prototypes in qla_iocb.c source file. |
82 | */ | 82 | */ |
83 | extern void qla2x00_isp_cmd(scsi_qla_host_t *); | ||
84 | |||
85 | extern uint16_t qla2x00_calc_iocbs_32(uint16_t); | 83 | extern uint16_t qla2x00_calc_iocbs_32(uint16_t); |
86 | extern uint16_t qla2x00_calc_iocbs_64(uint16_t); | 84 | extern uint16_t qla2x00_calc_iocbs_64(uint16_t); |
87 | extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); | 85 | extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); |
@@ -204,6 +202,12 @@ qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | |||
204 | extern int | 202 | extern int |
205 | qla2x00_stop_firmware(scsi_qla_host_t *); | 203 | qla2x00_stop_firmware(scsi_qla_host_t *); |
206 | 204 | ||
205 | extern int | ||
206 | qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); | ||
207 | |||
208 | extern int | ||
209 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | ||
210 | |||
207 | /* | 211 | /* |
208 | * Global Function Prototypes in qla_isr.c source file. | 212 | * Global Function Prototypes in qla_isr.c source file. |
209 | */ | 213 | */ |
@@ -254,9 +258,6 @@ extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, | |||
254 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); | 258 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); |
255 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); | 259 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); |
256 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | 260 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); |
257 | extern void qla2100_ascii_fw_dump(scsi_qla_host_t *); | ||
258 | extern void qla2300_ascii_fw_dump(scsi_qla_host_t *); | ||
259 | extern void qla24xx_ascii_fw_dump(scsi_qla_host_t *); | ||
260 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 261 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
261 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 262 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
262 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); | 263 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); |
@@ -280,13 +281,6 @@ extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); | |||
280 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); | 281 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); |
281 | 282 | ||
282 | /* | 283 | /* |
283 | * Global Function Prototypes in qla_xioctl.c source file. | ||
284 | */ | ||
285 | #define qla2x00_enqueue_aen(ha, cmd, mode) do { } while (0) | ||
286 | #define qla2x00_alloc_ioctl_mem(ha) (0) | ||
287 | #define qla2x00_free_ioctl_mem(ha) do { } while (0) | ||
288 | |||
289 | /* | ||
290 | * Global Function Prototypes in qla_attr.c source file. | 284 | * Global Function Prototypes in qla_attr.c source file. |
291 | */ | 285 | */ |
292 | struct class_device_attribute; | 286 | struct class_device_attribute; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 3d4487eac9b7..9758dba95542 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -39,6 +39,8 @@ static int qla2x00_fabric_dev_login(scsi_qla_host_t *, fc_port_t *, | |||
39 | 39 | ||
40 | static int qla2x00_restart_isp(scsi_qla_host_t *); | 40 | static int qla2x00_restart_isp(scsi_qla_host_t *); |
41 | 41 | ||
42 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); | ||
43 | |||
42 | /****************************************************************************/ | 44 | /****************************************************************************/ |
43 | /* QLogic ISP2x00 Hardware Support Functions. */ | 45 | /* QLogic ISP2x00 Hardware Support Functions. */ |
44 | /****************************************************************************/ | 46 | /****************************************************************************/ |
@@ -89,6 +91,17 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
89 | 91 | ||
90 | ha->isp_ops.nvram_config(ha); | 92 | ha->isp_ops.nvram_config(ha); |
91 | 93 | ||
94 | if (ha->flags.disable_serdes) { | ||
95 | /* Mask HBA via NVRAM settings? */ | ||
96 | qla_printk(KERN_INFO, ha, "Masking HBA WWPN " | ||
97 | "%02x%02x%02x%02x%02x%02x%02x%02x (via NVRAM).\n", | ||
98 | ha->port_name[0], ha->port_name[1], | ||
99 | ha->port_name[2], ha->port_name[3], | ||
100 | ha->port_name[4], ha->port_name[5], | ||
101 | ha->port_name[6], ha->port_name[7]); | ||
102 | return QLA_FUNCTION_FAILED; | ||
103 | } | ||
104 | |||
92 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); | 105 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); |
93 | 106 | ||
94 | retry = 10; | 107 | retry = 10; |
@@ -770,29 +783,104 @@ qla24xx_chip_diag(scsi_qla_host_t *ha) | |||
770 | return rval; | 783 | return rval; |
771 | } | 784 | } |
772 | 785 | ||
773 | static void | 786 | void |
774 | qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | 787 | qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) |
775 | { | 788 | { |
776 | uint32_t dump_size = 0; | 789 | int rval; |
790 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, | ||
791 | eft_size; | ||
792 | dma_addr_t eft_dma; | ||
793 | void *eft; | ||
794 | |||
795 | if (ha->fw_dump) { | ||
796 | qla_printk(KERN_WARNING, ha, | ||
797 | "Firmware dump previously allocated.\n"); | ||
798 | return; | ||
799 | } | ||
777 | 800 | ||
778 | ha->fw_dumped = 0; | 801 | ha->fw_dumped = 0; |
802 | fixed_size = mem_size = eft_size = 0; | ||
779 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 803 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
780 | dump_size = sizeof(struct qla2100_fw_dump); | 804 | fixed_size = sizeof(struct qla2100_fw_dump); |
781 | } else if (IS_QLA23XX(ha)) { | 805 | } else if (IS_QLA23XX(ha)) { |
782 | dump_size = sizeof(struct qla2300_fw_dump); | 806 | fixed_size = offsetof(struct qla2300_fw_dump, data_ram); |
783 | dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t); | 807 | mem_size = (ha->fw_memory_size - 0x11000 + 1) * |
784 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 808 | sizeof(uint16_t); |
785 | dump_size = sizeof(struct qla24xx_fw_dump); | 809 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
786 | dump_size += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t); | 810 | fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); |
811 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | ||
812 | sizeof(uint32_t); | ||
813 | |||
814 | /* Allocate memory for Extended Trace Buffer. */ | ||
815 | eft = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &eft_dma, | ||
816 | GFP_KERNEL); | ||
817 | if (!eft) { | ||
818 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | ||
819 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); | ||
820 | goto cont_alloc; | ||
821 | } | ||
822 | |||
823 | rval = qla2x00_trace_control(ha, TC_ENABLE, eft_dma, | ||
824 | EFT_NUM_BUFFERS); | ||
825 | if (rval) { | ||
826 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | ||
827 | "EFT (%d).\n", rval); | ||
828 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, eft, | ||
829 | eft_dma); | ||
830 | goto cont_alloc; | ||
831 | } | ||
832 | |||
833 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", | ||
834 | EFT_SIZE / 1024); | ||
835 | |||
836 | eft_size = EFT_SIZE; | ||
837 | memset(eft, 0, eft_size); | ||
838 | ha->eft_dma = eft_dma; | ||
839 | ha->eft = eft; | ||
787 | } | 840 | } |
841 | cont_alloc: | ||
842 | req_q_size = ha->request_q_length * sizeof(request_t); | ||
843 | rsp_q_size = ha->response_q_length * sizeof(response_t); | ||
844 | |||
845 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); | ||
846 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + | ||
847 | eft_size; | ||
788 | 848 | ||
789 | ha->fw_dump = vmalloc(dump_size); | 849 | ha->fw_dump = vmalloc(dump_size); |
790 | if (ha->fw_dump) | 850 | if (!ha->fw_dump) { |
791 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware " | ||
792 | "dump...\n", dump_size / 1024); | ||
793 | else | ||
794 | qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " | 851 | qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " |
795 | "firmware dump!!!\n", dump_size / 1024); | 852 | "firmware dump!!!\n", dump_size / 1024); |
853 | |||
854 | if (ha->eft) { | ||
855 | dma_free_coherent(&ha->pdev->dev, eft_size, ha->eft, | ||
856 | ha->eft_dma); | ||
857 | ha->eft = NULL; | ||
858 | ha->eft_dma = 0; | ||
859 | } | ||
860 | return; | ||
861 | } | ||
862 | |||
863 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware dump...\n", | ||
864 | dump_size / 1024); | ||
865 | |||
866 | ha->fw_dump_len = dump_size; | ||
867 | ha->fw_dump->signature[0] = 'Q'; | ||
868 | ha->fw_dump->signature[1] = 'L'; | ||
869 | ha->fw_dump->signature[2] = 'G'; | ||
870 | ha->fw_dump->signature[3] = 'C'; | ||
871 | ha->fw_dump->version = __constant_htonl(1); | ||
872 | |||
873 | ha->fw_dump->fixed_size = htonl(fixed_size); | ||
874 | ha->fw_dump->mem_size = htonl(mem_size); | ||
875 | ha->fw_dump->req_q_size = htonl(req_q_size); | ||
876 | ha->fw_dump->rsp_q_size = htonl(rsp_q_size); | ||
877 | |||
878 | ha->fw_dump->eft_size = htonl(eft_size); | ||
879 | ha->fw_dump->eft_addr_l = htonl(LSD(ha->eft_dma)); | ||
880 | ha->fw_dump->eft_addr_h = htonl(MSD(ha->eft_dma)); | ||
881 | |||
882 | ha->fw_dump->header_size = | ||
883 | htonl(offsetof(struct qla2xxx_fw_dump, isp)); | ||
796 | } | 884 | } |
797 | 885 | ||
798 | /** | 886 | /** |
@@ -810,8 +898,6 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha) | |||
810 | dma_addr_t request_dma; | 898 | dma_addr_t request_dma; |
811 | request_t *request_ring; | 899 | request_t *request_ring; |
812 | 900 | ||
813 | qla2x00_alloc_fw_dump(ha); | ||
814 | |||
815 | /* Valid only on recent ISPs. */ | 901 | /* Valid only on recent ISPs. */ |
816 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 902 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
817 | return; | 903 | return; |
@@ -883,6 +969,9 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) | |||
883 | &ha->fw_subminor_version, | 969 | &ha->fw_subminor_version, |
884 | &ha->fw_attributes, &ha->fw_memory_size); | 970 | &ha->fw_attributes, &ha->fw_memory_size); |
885 | qla2x00_resize_request_q(ha); | 971 | qla2x00_resize_request_q(ha); |
972 | |||
973 | if (ql2xallocfwdump) | ||
974 | qla2x00_alloc_fw_dump(ha); | ||
886 | } | 975 | } |
887 | } else { | 976 | } else { |
888 | DEBUG2(printk(KERN_INFO | 977 | DEBUG2(printk(KERN_INFO |
@@ -1186,8 +1275,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1186 | rval = QLA_FUNCTION_FAILED; | 1275 | rval = QLA_FUNCTION_FAILED; |
1187 | 1276 | ||
1188 | if (atomic_read(&ha->loop_down_timer) && | 1277 | if (atomic_read(&ha->loop_down_timer) && |
1189 | (fw_state >= FSTATE_LOSS_OF_SYNC || | 1278 | fw_state != FSTATE_READY) { |
1190 | fw_state == FSTATE_WAIT_AL_PA)) { | ||
1191 | /* Loop down. Timeout on min_wait for states | 1279 | /* Loop down. Timeout on min_wait for states |
1192 | * other than Wait for Login. | 1280 | * other than Wait for Login. |
1193 | */ | 1281 | */ |
@@ -1555,6 +1643,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1555 | /* | 1643 | /* |
1556 | * Set host adapter parameters. | 1644 | * Set host adapter parameters. |
1557 | */ | 1645 | */ |
1646 | if (nv->host_p[0] & BIT_7) | ||
1647 | extended_error_logging = 1; | ||
1558 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); | 1648 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); |
1559 | /* Always load RISC code on non ISP2[12]00 chips. */ | 1649 | /* Always load RISC code on non ISP2[12]00 chips. */ |
1560 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) | 1650 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) |
@@ -1563,6 +1653,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1563 | ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0); | 1653 | ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0); |
1564 | ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0); | 1654 | ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0); |
1565 | ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0; | 1655 | ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0; |
1656 | ha->flags.disable_serdes = 0; | ||
1566 | 1657 | ||
1567 | ha->operating_mode = | 1658 | ha->operating_mode = |
1568 | (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; | 1659 | (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; |
@@ -1701,7 +1792,7 @@ qla2x00_rport_del(void *data) | |||
1701 | * | 1792 | * |
1702 | * Returns a pointer to the allocated fcport, or NULL, if none available. | 1793 | * Returns a pointer to the allocated fcport, or NULL, if none available. |
1703 | */ | 1794 | */ |
1704 | fc_port_t * | 1795 | static fc_port_t * |
1705 | qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | 1796 | qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) |
1706 | { | 1797 | { |
1707 | fc_port_t *fcport; | 1798 | fc_port_t *fcport; |
@@ -2497,7 +2588,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2497 | * Context: | 2588 | * Context: |
2498 | * Kernel context. | 2589 | * Kernel context. |
2499 | */ | 2590 | */ |
2500 | int | 2591 | static int |
2501 | qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev) | 2592 | qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev) |
2502 | { | 2593 | { |
2503 | int rval; | 2594 | int rval; |
@@ -3048,14 +3139,14 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3048 | ha->isp_abort_cnt--; | 3139 | ha->isp_abort_cnt--; |
3049 | DEBUG(printk("qla%ld: ISP abort - " | 3140 | DEBUG(printk("qla%ld: ISP abort - " |
3050 | "retry remaining %d\n", | 3141 | "retry remaining %d\n", |
3051 | ha->host_no, ha->isp_abort_cnt);) | 3142 | ha->host_no, ha->isp_abort_cnt)); |
3052 | status = 1; | 3143 | status = 1; |
3053 | } | 3144 | } |
3054 | } else { | 3145 | } else { |
3055 | ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT; | 3146 | ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT; |
3056 | DEBUG(printk("qla2x00(%ld): ISP error recovery " | 3147 | DEBUG(printk("qla2x00(%ld): ISP error recovery " |
3057 | "- retrying (%d) more times\n", | 3148 | "- retrying (%d) more times\n", |
3058 | ha->host_no, ha->isp_abort_cnt);) | 3149 | ha->host_no, ha->isp_abort_cnt)); |
3059 | set_bit(ISP_ABORT_RETRY, &ha->dpc_flags); | 3150 | set_bit(ISP_ABORT_RETRY, &ha->dpc_flags); |
3060 | status = 1; | 3151 | status = 1; |
3061 | } | 3152 | } |
@@ -3069,7 +3160,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3069 | } else { | 3160 | } else { |
3070 | DEBUG(printk(KERN_INFO | 3161 | DEBUG(printk(KERN_INFO |
3071 | "qla2x00_abort_isp(%ld): exiting.\n", | 3162 | "qla2x00_abort_isp(%ld): exiting.\n", |
3072 | ha->host_no);) | 3163 | ha->host_no)); |
3073 | } | 3164 | } |
3074 | 3165 | ||
3075 | return(status); | 3166 | return(status); |
@@ -3145,7 +3236,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) | |||
3145 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 3236 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
3146 | if (!(status = qla2x00_fw_ready(ha))) { | 3237 | if (!(status = qla2x00_fw_ready(ha))) { |
3147 | DEBUG(printk("%s(): Start configure loop, " | 3238 | DEBUG(printk("%s(): Start configure loop, " |
3148 | "status = %d\n", __func__, status);) | 3239 | "status = %d\n", __func__, status)); |
3149 | 3240 | ||
3150 | /* Issue a marker after FW becomes ready. */ | 3241 | /* Issue a marker after FW becomes ready. */ |
3151 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | 3242 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); |
@@ -3169,7 +3260,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) | |||
3169 | 3260 | ||
3170 | DEBUG(printk("%s(): Configure loop done, status = 0x%x\n", | 3261 | DEBUG(printk("%s(): Configure loop done, status = 0x%x\n", |
3171 | __func__, | 3262 | __func__, |
3172 | status);) | 3263 | status)); |
3173 | } | 3264 | } |
3174 | return (status); | 3265 | return (status); |
3175 | } | 3266 | } |
@@ -3289,7 +3380,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3289 | nv->node_name[6] = 0x55; | 3380 | nv->node_name[6] = 0x55; |
3290 | nv->node_name[7] = 0x86; | 3381 | nv->node_name[7] = 0x86; |
3291 | nv->login_retry_count = __constant_cpu_to_le16(8); | 3382 | nv->login_retry_count = __constant_cpu_to_le16(8); |
3292 | nv->link_down_timeout = __constant_cpu_to_le16(200); | ||
3293 | nv->interrupt_delay_timer = __constant_cpu_to_le16(0); | 3383 | nv->interrupt_delay_timer = __constant_cpu_to_le16(0); |
3294 | nv->login_timeout = __constant_cpu_to_le16(0); | 3384 | nv->login_timeout = __constant_cpu_to_le16(0); |
3295 | nv->firmware_options_1 = | 3385 | nv->firmware_options_1 = |
@@ -3318,7 +3408,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3318 | *dptr1++ = *dptr2++; | 3408 | *dptr1++ = *dptr2++; |
3319 | 3409 | ||
3320 | icb->login_retry_count = nv->login_retry_count; | 3410 | icb->login_retry_count = nv->login_retry_count; |
3321 | icb->link_down_timeout = nv->link_down_timeout; | 3411 | icb->link_down_on_nos = nv->link_down_on_nos; |
3322 | 3412 | ||
3323 | /* Copy 2nd segment. */ | 3413 | /* Copy 2nd segment. */ |
3324 | dptr1 = (uint8_t *)&icb->interrupt_delay_timer; | 3414 | dptr1 = (uint8_t *)&icb->interrupt_delay_timer; |
@@ -3373,6 +3463,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3373 | ha->flags.enable_lip_full_login = 1; | 3463 | ha->flags.enable_lip_full_login = 1; |
3374 | ha->flags.enable_target_reset = 1; | 3464 | ha->flags.enable_target_reset = 1; |
3375 | ha->flags.enable_led_scheme = 0; | 3465 | ha->flags.enable_led_scheme = 0; |
3466 | ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0; | ||
3376 | 3467 | ||
3377 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & | 3468 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & |
3378 | (BIT_6 | BIT_5 | BIT_4)) >> 4; | 3469 | (BIT_6 | BIT_5 | BIT_4)) >> 4; |
@@ -3472,7 +3563,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3472 | return (rval); | 3563 | return (rval); |
3473 | } | 3564 | } |
3474 | 3565 | ||
3475 | int | 3566 | static int |
3476 | qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) | 3567 | qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) |
3477 | { | 3568 | { |
3478 | int rval; | 3569 | int rval; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 8c769cfaa14c..2b60a27eff0b 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -15,6 +15,7 @@ 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 *); | 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 *); | 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); | 17 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); |
18 | static void qla2x00_isp_cmd(scsi_qla_host_t *ha); | ||
18 | 19 | ||
19 | /** | 20 | /** |
20 | * qla2x00_get_cmd_direction() - Determine control_flag data direction. | 21 | * qla2x00_get_cmd_direction() - Determine control_flag data direction. |
@@ -574,7 +575,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha) | |||
574 | * | 575 | * |
575 | * Note: The caller must hold the hardware lock before calling this routine. | 576 | * Note: The caller must hold the hardware lock before calling this routine. |
576 | */ | 577 | */ |
577 | void | 578 | static void |
578 | qla2x00_isp_cmd(scsi_qla_host_t *ha) | 579 | qla2x00_isp_cmd(scsi_qla_host_t *ha) |
579 | { | 580 | { |
580 | device_reg_t __iomem *reg = ha->iobase; | 581 | device_reg_t __iomem *reg = ha->iobase; |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index b28ac0a27e25..795bf15b1b8f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -395,10 +395,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
395 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | 395 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); |
396 | 396 | ||
397 | ha->flags.management_server_logged_in = 0; | 397 | ha->flags.management_server_logged_in = 0; |
398 | |||
399 | /* Update AEN queue. */ | ||
400 | qla2x00_enqueue_aen(ha, MBA_LIP_OCCURRED, NULL); | ||
401 | |||
402 | break; | 398 | break; |
403 | 399 | ||
404 | case MBA_LOOP_UP: /* Loop Up Event */ | 400 | case MBA_LOOP_UP: /* Loop Up Event */ |
@@ -418,9 +414,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
418 | link_speed); | 414 | link_speed); |
419 | 415 | ||
420 | ha->flags.management_server_logged_in = 0; | 416 | ha->flags.management_server_logged_in = 0; |
421 | |||
422 | /* Update AEN queue. */ | ||
423 | qla2x00_enqueue_aen(ha, MBA_LOOP_UP, NULL); | ||
424 | break; | 417 | break; |
425 | 418 | ||
426 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 419 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
@@ -439,9 +432,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
439 | ha->link_data_rate = LDR_UNKNOWN; | 432 | ha->link_data_rate = LDR_UNKNOWN; |
440 | if (ql2xfdmienable) | 433 | if (ql2xfdmienable) |
441 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 434 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
442 | |||
443 | /* Update AEN queue. */ | ||
444 | qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL); | ||
445 | break; | 435 | break; |
446 | 436 | ||
447 | case MBA_LIP_RESET: /* LIP reset occurred */ | 437 | case MBA_LIP_RESET: /* LIP reset occurred */ |
@@ -460,10 +450,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
460 | 450 | ||
461 | ha->operating_mode = LOOP; | 451 | ha->operating_mode = LOOP; |
462 | ha->flags.management_server_logged_in = 0; | 452 | ha->flags.management_server_logged_in = 0; |
463 | |||
464 | /* Update AEN queue. */ | ||
465 | qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL); | ||
466 | |||
467 | break; | 453 | break; |
468 | 454 | ||
469 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 455 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
@@ -545,9 +531,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
545 | 531 | ||
546 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 532 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
547 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 533 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
548 | |||
549 | /* Update AEN queue. */ | ||
550 | qla2x00_enqueue_aen(ha, MBA_PORT_UPDATE, NULL); | ||
551 | break; | 534 | break; |
552 | 535 | ||
553 | case MBA_RSCN_UPDATE: /* State Change Registration */ | 536 | case MBA_RSCN_UPDATE: /* State Change Registration */ |
@@ -584,9 +567,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
584 | 567 | ||
585 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 568 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
586 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 569 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
587 | |||
588 | /* Update AEN queue. */ | ||
589 | qla2x00_enqueue_aen(ha, MBA_RSCN_UPDATE, &mb[0]); | ||
590 | break; | 570 | break; |
591 | 571 | ||
592 | /* case MBA_RIO_RESPONSE: */ | 572 | /* case MBA_RIO_RESPONSE: */ |
@@ -1452,8 +1432,8 @@ qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt) | |||
1452 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | 1432 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", |
1453 | __func__, ha->host_no, pkt, pkt->handle)); | 1433 | __func__, ha->host_no, pkt, pkt->handle)); |
1454 | 1434 | ||
1455 | DEBUG9(printk("%s: ct pkt dump:\n", __func__);) | 1435 | DEBUG9(printk("%s: ct pkt dump:\n", __func__)); |
1456 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx));) | 1436 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx))); |
1457 | 1437 | ||
1458 | /* Validate handle. */ | 1438 | /* Validate handle. */ |
1459 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) | 1439 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index d6cb3bd1a29a..879f281e2ea2 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -13,13 +13,13 @@ qla2x00_mbx_sem_timeout(unsigned long data) | |||
13 | { | 13 | { |
14 | struct semaphore *sem_ptr = (struct semaphore *)data; | 14 | struct semaphore *sem_ptr = (struct semaphore *)data; |
15 | 15 | ||
16 | DEBUG11(printk("qla2x00_sem_timeout: entered.\n");) | 16 | DEBUG11(printk("qla2x00_sem_timeout: entered.\n")); |
17 | 17 | ||
18 | if (sem_ptr != NULL) { | 18 | if (sem_ptr != NULL) { |
19 | up(sem_ptr); | 19 | up(sem_ptr); |
20 | } | 20 | } |
21 | 21 | ||
22 | DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n");) | 22 | DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n")); |
23 | } | 23 | } |
24 | 24 | ||
25 | /* | 25 | /* |
@@ -61,7 +61,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
61 | rval = QLA_SUCCESS; | 61 | rval = QLA_SUCCESS; |
62 | abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 62 | abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); |
63 | 63 | ||
64 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 64 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Wait for active mailbox commands to finish by waiting at most tov | 67 | * Wait for active mailbox commands to finish by waiting at most tov |
@@ -72,7 +72,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
72 | if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) { | 72 | if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) { |
73 | /* Timeout occurred. Return error. */ | 73 | /* Timeout occurred. Return error. */ |
74 | DEBUG2_3_11(printk("%s(%ld): cmd access timeout. " | 74 | DEBUG2_3_11(printk("%s(%ld): cmd access timeout. " |
75 | "Exiting.\n", __func__, ha->host_no);) | 75 | "Exiting.\n", __func__, ha->host_no)); |
76 | return QLA_FUNCTION_TIMEOUT; | 76 | return QLA_FUNCTION_TIMEOUT; |
77 | } | 77 | } |
78 | } | 78 | } |
@@ -86,7 +86,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
86 | spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); | 86 | spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); |
87 | 87 | ||
88 | DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n", | 88 | DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n", |
89 | ha->host_no, mcp->mb[0]);) | 89 | ha->host_no, mcp->mb[0])); |
90 | 90 | ||
91 | spin_lock_irqsave(&ha->hardware_lock, flags); | 91 | spin_lock_irqsave(&ha->hardware_lock, flags); |
92 | 92 | ||
@@ -131,14 +131,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
131 | 131 | ||
132 | /* Unlock mbx registers and wait for interrupt */ | 132 | /* Unlock mbx registers and wait for interrupt */ |
133 | DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. " | 133 | DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. " |
134 | "jiffies=%lx.\n", __func__, ha->host_no, jiffies);) | 134 | "jiffies=%lx.\n", __func__, ha->host_no, jiffies)); |
135 | 135 | ||
136 | /* Wait for mbx cmd completion until timeout */ | 136 | /* Wait for mbx cmd completion until timeout */ |
137 | 137 | ||
138 | if (!abort_active && io_lock_on) { | 138 | if (!abort_active && io_lock_on) { |
139 | /* sleep on completion semaphore */ | 139 | /* sleep on completion semaphore */ |
140 | DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n", | 140 | DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n", |
141 | __func__, ha->host_no);) | 141 | __func__, ha->host_no)); |
142 | 142 | ||
143 | init_timer(&tmp_intr_timer); | 143 | init_timer(&tmp_intr_timer); |
144 | tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem; | 144 | tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem; |
@@ -147,11 +147,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
147 | (void (*)(unsigned long))qla2x00_mbx_sem_timeout; | 147 | (void (*)(unsigned long))qla2x00_mbx_sem_timeout; |
148 | 148 | ||
149 | DEBUG11(printk("%s(%ld): Adding timer.\n", __func__, | 149 | DEBUG11(printk("%s(%ld): Adding timer.\n", __func__, |
150 | ha->host_no);) | 150 | ha->host_no)); |
151 | add_timer(&tmp_intr_timer); | 151 | add_timer(&tmp_intr_timer); |
152 | 152 | ||
153 | DEBUG11(printk("%s(%ld): going to unlock & sleep. " | 153 | DEBUG11(printk("%s(%ld): going to unlock & sleep. " |
154 | "time=0x%lx.\n", __func__, ha->host_no, jiffies);) | 154 | "time=0x%lx.\n", __func__, ha->host_no, jiffies)); |
155 | 155 | ||
156 | set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | 156 | set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
157 | 157 | ||
@@ -170,14 +170,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
170 | down(&ha->mbx_intr_sem); | 170 | down(&ha->mbx_intr_sem); |
171 | 171 | ||
172 | DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__, | 172 | DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__, |
173 | ha->host_no, jiffies);) | 173 | ha->host_no, jiffies)); |
174 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | 174 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
175 | 175 | ||
176 | /* delete the timer */ | 176 | /* delete the timer */ |
177 | del_timer(&tmp_intr_timer); | 177 | del_timer(&tmp_intr_timer); |
178 | } else { | 178 | } else { |
179 | DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, | 179 | DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, |
180 | ha->host_no, command);) | 180 | ha->host_no, command)); |
181 | 181 | ||
182 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 182 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) |
183 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); | 183 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); |
@@ -209,7 +209,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
209 | uint16_t *iptr2; | 209 | uint16_t *iptr2; |
210 | 210 | ||
211 | DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__, | 211 | DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__, |
212 | ha->host_no, command);) | 212 | ha->host_no, command)); |
213 | 213 | ||
214 | /* Got interrupt. Clear the flag. */ | 214 | /* Got interrupt. Clear the flag. */ |
215 | ha->flags.mbox_int = 0; | 215 | ha->flags.mbox_int = 0; |
@@ -266,7 +266,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
266 | 266 | ||
267 | if (!abort_active) { | 267 | if (!abort_active) { |
268 | DEBUG11(printk("%s(%ld): checking for additional resp " | 268 | DEBUG11(printk("%s(%ld): checking for additional resp " |
269 | "interrupt.\n", __func__, ha->host_no);) | 269 | "interrupt.\n", __func__, ha->host_no)); |
270 | 270 | ||
271 | /* polling mode for non isp_abort commands. */ | 271 | /* polling mode for non isp_abort commands. */ |
272 | qla2x00_poll(ha); | 272 | qla2x00_poll(ha); |
@@ -277,9 +277,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
277 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { | 277 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { |
278 | /* not in dpc. schedule it for dpc to take over. */ | 278 | /* not in dpc. schedule it for dpc to take over. */ |
279 | DEBUG(printk("%s(%ld): timeout schedule " | 279 | DEBUG(printk("%s(%ld): timeout schedule " |
280 | "isp_abort_needed.\n", __func__, ha->host_no);) | 280 | "isp_abort_needed.\n", __func__, ha->host_no)); |
281 | DEBUG2_3_11(printk("%s(%ld): timeout schedule " | 281 | DEBUG2_3_11(printk("%s(%ld): timeout schedule " |
282 | "isp_abort_needed.\n", __func__, ha->host_no);) | 282 | "isp_abort_needed.\n", __func__, ha->host_no)); |
283 | qla_printk(KERN_WARNING, ha, | 283 | qla_printk(KERN_WARNING, ha, |
284 | "Mailbox command timeout occured. Scheduling ISP " | 284 | "Mailbox command timeout occured. Scheduling ISP " |
285 | "abort.\n"); | 285 | "abort.\n"); |
@@ -288,9 +288,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
288 | } else if (!abort_active) { | 288 | } else if (!abort_active) { |
289 | /* call abort directly since we are in the DPC thread */ | 289 | /* call abort directly since we are in the DPC thread */ |
290 | DEBUG(printk("%s(%ld): timeout calling abort_isp\n", | 290 | DEBUG(printk("%s(%ld): timeout calling abort_isp\n", |
291 | __func__, ha->host_no);) | 291 | __func__, ha->host_no)); |
292 | DEBUG2_3_11(printk("%s(%ld): timeout calling " | 292 | DEBUG2_3_11(printk("%s(%ld): timeout calling " |
293 | "abort_isp\n", __func__, ha->host_no);) | 293 | "abort_isp\n", __func__, ha->host_no)); |
294 | qla_printk(KERN_WARNING, ha, | 294 | qla_printk(KERN_WARNING, ha, |
295 | "Mailbox command timeout occured. Issuing ISP " | 295 | "Mailbox command timeout occured. Issuing ISP " |
296 | "abort.\n"); | 296 | "abort.\n"); |
@@ -303,9 +303,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
303 | } | 303 | } |
304 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 304 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); |
305 | DEBUG(printk("%s(%ld): finished abort_isp\n", __func__, | 305 | DEBUG(printk("%s(%ld): finished abort_isp\n", __func__, |
306 | ha->host_no);) | 306 | ha->host_no)); |
307 | DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n", | 307 | DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n", |
308 | __func__, ha->host_no);) | 308 | __func__, ha->host_no)); |
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
@@ -316,9 +316,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
316 | if (rval) { | 316 | if (rval) { |
317 | DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, " | 317 | DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, " |
318 | "mbx2=%x, cmd=%x ****\n", __func__, ha->host_no, | 318 | "mbx2=%x, cmd=%x ****\n", __func__, ha->host_no, |
319 | mcp->mb[0], mcp->mb[1], mcp->mb[2], command);) | 319 | mcp->mb[0], mcp->mb[1], mcp->mb[2], command)); |
320 | } else { | 320 | } else { |
321 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 321 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
322 | } | 322 | } |
323 | 323 | ||
324 | return rval; | 324 | return rval; |
@@ -394,7 +394,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
394 | mbx_cmd_t mc; | 394 | mbx_cmd_t mc; |
395 | mbx_cmd_t *mcp = &mc; | 395 | mbx_cmd_t *mcp = &mc; |
396 | 396 | ||
397 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 397 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
398 | 398 | ||
399 | mcp->mb[0] = MBC_EXECUTE_FIRMWARE; | 399 | mcp->mb[0] = MBC_EXECUTE_FIRMWARE; |
400 | mcp->out_mb = MBX_0; | 400 | mcp->out_mb = MBX_0; |
@@ -424,10 +424,10 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
424 | } else { | 424 | } else { |
425 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 425 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
426 | DEBUG11(printk("%s(%ld): done exchanges=%x.\n", | 426 | DEBUG11(printk("%s(%ld): done exchanges=%x.\n", |
427 | __func__, ha->host_no, mcp->mb[1]);) | 427 | __func__, ha->host_no, mcp->mb[1])); |
428 | } else { | 428 | } else { |
429 | DEBUG11(printk("%s(%ld): done.\n", __func__, | 429 | DEBUG11(printk("%s(%ld): done.\n", __func__, |
430 | ha->host_no);) | 430 | ha->host_no)); |
431 | } | 431 | } |
432 | } | 432 | } |
433 | 433 | ||
@@ -611,7 +611,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
611 | mbx_cmd_t mc; | 611 | mbx_cmd_t mc; |
612 | mbx_cmd_t *mcp = &mc; | 612 | mbx_cmd_t *mcp = &mc; |
613 | 613 | ||
614 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no);) | 614 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no)); |
615 | 615 | ||
616 | mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; | 616 | mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; |
617 | mcp->mb[1] = 0xAAAA; | 617 | mcp->mb[1] = 0xAAAA; |
@@ -639,11 +639,11 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
639 | if (rval != QLA_SUCCESS) { | 639 | if (rval != QLA_SUCCESS) { |
640 | /*EMPTY*/ | 640 | /*EMPTY*/ |
641 | DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n", | 641 | DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n", |
642 | ha->host_no, rval);) | 642 | ha->host_no, rval)); |
643 | } else { | 643 | } else { |
644 | /*EMPTY*/ | 644 | /*EMPTY*/ |
645 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n", | 645 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n", |
646 | ha->host_no);) | 646 | ha->host_no)); |
647 | } | 647 | } |
648 | 648 | ||
649 | return rval; | 649 | return rval; |
@@ -671,7 +671,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
671 | mbx_cmd_t mc; | 671 | mbx_cmd_t mc; |
672 | mbx_cmd_t *mcp = &mc; | 672 | mbx_cmd_t *mcp = &mc; |
673 | 673 | ||
674 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 674 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
675 | 675 | ||
676 | mcp->mb[0] = MBC_VERIFY_CHECKSUM; | 676 | mcp->mb[0] = MBC_VERIFY_CHECKSUM; |
677 | mcp->out_mb = MBX_0; | 677 | mcp->out_mb = MBX_0; |
@@ -694,9 +694,9 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
694 | if (rval != QLA_SUCCESS) { | 694 | if (rval != QLA_SUCCESS) { |
695 | DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, | 695 | DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, |
696 | ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? | 696 | ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? |
697 | (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));) | 697 | (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]))); |
698 | } else { | 698 | } else { |
699 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 699 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
700 | } | 700 | } |
701 | 701 | ||
702 | return rval; | 702 | return rval; |
@@ -743,9 +743,9 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
743 | if (rval != QLA_SUCCESS) { | 743 | if (rval != QLA_SUCCESS) { |
744 | /*EMPTY*/ | 744 | /*EMPTY*/ |
745 | DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", | 745 | DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", |
746 | ha->host_no, rval);) | 746 | ha->host_no, rval)); |
747 | DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", | 747 | DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", |
748 | ha->host_no, rval);) | 748 | ha->host_no, rval)); |
749 | } else { | 749 | } else { |
750 | sts_entry_t *sts_entry = (sts_entry_t *) buffer; | 750 | sts_entry_t *sts_entry = (sts_entry_t *) buffer; |
751 | 751 | ||
@@ -781,7 +781,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
781 | mbx_cmd_t mc; | 781 | mbx_cmd_t mc; |
782 | mbx_cmd_t *mcp = &mc; | 782 | mbx_cmd_t *mcp = &mc; |
783 | 783 | ||
784 | DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);) | 784 | DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no)); |
785 | 785 | ||
786 | fcport = sp->fcport; | 786 | fcport = sp->fcport; |
787 | 787 | ||
@@ -813,11 +813,11 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
813 | 813 | ||
814 | if (rval != QLA_SUCCESS) { | 814 | if (rval != QLA_SUCCESS) { |
815 | DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n", | 815 | DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n", |
816 | ha->host_no, rval);) | 816 | ha->host_no, rval)); |
817 | } else { | 817 | } else { |
818 | sp->flags |= SRB_ABORT_PENDING; | 818 | sp->flags |= SRB_ABORT_PENDING; |
819 | DEBUG11(printk("qla2x00_abort_command(%ld): done.\n", | 819 | DEBUG11(printk("qla2x00_abort_command(%ld): done.\n", |
820 | ha->host_no);) | 820 | ha->host_no)); |
821 | } | 821 | } |
822 | 822 | ||
823 | return rval; | 823 | return rval; |
@@ -848,7 +848,7 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
848 | if (fcport == NULL) | 848 | if (fcport == NULL) |
849 | return 0; | 849 | return 0; |
850 | 850 | ||
851 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);) | 851 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
852 | 852 | ||
853 | ha = fcport->ha; | 853 | ha = fcport->ha; |
854 | mcp->mb[0] = MBC_ABORT_TARGET; | 854 | mcp->mb[0] = MBC_ABORT_TARGET; |
@@ -872,11 +872,11 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
872 | 872 | ||
873 | if (rval != QLA_SUCCESS) { | 873 | if (rval != QLA_SUCCESS) { |
874 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", | 874 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", |
875 | ha->host_no, rval);) | 875 | ha->host_no, rval)); |
876 | } else { | 876 | } else { |
877 | /*EMPTY*/ | 877 | /*EMPTY*/ |
878 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", | 878 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", |
879 | ha->host_no);) | 879 | ha->host_no)); |
880 | } | 880 | } |
881 | 881 | ||
882 | return rval; | 882 | return rval; |
@@ -912,7 +912,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
912 | mbx_cmd_t *mcp = &mc; | 912 | mbx_cmd_t *mcp = &mc; |
913 | 913 | ||
914 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n", | 914 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n", |
915 | ha->host_no);) | 915 | ha->host_no)); |
916 | 916 | ||
917 | mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; | 917 | mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; |
918 | mcp->out_mb = MBX_0; | 918 | mcp->out_mb = MBX_0; |
@@ -933,11 +933,11 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
933 | if (rval != QLA_SUCCESS) { | 933 | if (rval != QLA_SUCCESS) { |
934 | /*EMPTY*/ | 934 | /*EMPTY*/ |
935 | DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n", | 935 | DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n", |
936 | ha->host_no, rval);) | 936 | ha->host_no, rval)); |
937 | } else { | 937 | } else { |
938 | /*EMPTY*/ | 938 | /*EMPTY*/ |
939 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n", | 939 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n", |
940 | ha->host_no);) | 940 | ha->host_no)); |
941 | } | 941 | } |
942 | 942 | ||
943 | return rval; | 943 | return rval; |
@@ -968,7 +968,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
968 | mbx_cmd_t *mcp = &mc; | 968 | mbx_cmd_t *mcp = &mc; |
969 | 969 | ||
970 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n", | 970 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n", |
971 | ha->host_no);) | 971 | ha->host_no)); |
972 | 972 | ||
973 | mcp->mb[0] = MBC_GET_RETRY_COUNT; | 973 | mcp->mb[0] = MBC_GET_RETRY_COUNT; |
974 | mcp->out_mb = MBX_0; | 974 | mcp->out_mb = MBX_0; |
@@ -980,7 +980,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
980 | if (rval != QLA_SUCCESS) { | 980 | if (rval != QLA_SUCCESS) { |
981 | /*EMPTY*/ | 981 | /*EMPTY*/ |
982 | DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n", | 982 | DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n", |
983 | ha->host_no, mcp->mb[0]);) | 983 | ha->host_no, mcp->mb[0])); |
984 | } else { | 984 | } else { |
985 | /* Convert returned data and check our values. */ | 985 | /* Convert returned data and check our values. */ |
986 | *r_a_tov = mcp->mb[3] / 2; | 986 | *r_a_tov = mcp->mb[3] / 2; |
@@ -992,7 +992,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
992 | } | 992 | } |
993 | 993 | ||
994 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d " | 994 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d " |
995 | "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov);) | 995 | "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov)); |
996 | } | 996 | } |
997 | 997 | ||
998 | return rval; | 998 | return rval; |
@@ -1023,7 +1023,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) | |||
1023 | mbx_cmd_t *mcp = &mc; | 1023 | mbx_cmd_t *mcp = &mc; |
1024 | 1024 | ||
1025 | DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n", | 1025 | DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n", |
1026 | ha->host_no);) | 1026 | ha->host_no)); |
1027 | 1027 | ||
1028 | mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; | 1028 | mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; |
1029 | mcp->mb[2] = MSW(ha->init_cb_dma); | 1029 | mcp->mb[2] = MSW(ha->init_cb_dma); |
@@ -1043,11 +1043,11 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) | |||
1043 | /*EMPTY*/ | 1043 | /*EMPTY*/ |
1044 | DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x " | 1044 | DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x " |
1045 | "mb0=%x.\n", | 1045 | "mb0=%x.\n", |
1046 | ha->host_no, rval, mcp->mb[0]);) | 1046 | ha->host_no, rval, mcp->mb[0])); |
1047 | } else { | 1047 | } else { |
1048 | /*EMPTY*/ | 1048 | /*EMPTY*/ |
1049 | DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n", | 1049 | DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n", |
1050 | ha->host_no);) | 1050 | ha->host_no)); |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | return rval; | 1053 | return rval; |
@@ -1079,7 +1079,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) | |||
1079 | struct port_database_24xx *pd24; | 1079 | struct port_database_24xx *pd24; |
1080 | dma_addr_t pd_dma; | 1080 | dma_addr_t pd_dma; |
1081 | 1081 | ||
1082 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1082 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1083 | 1083 | ||
1084 | pd24 = NULL; | 1084 | pd24 = NULL; |
1085 | pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); | 1085 | pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); |
@@ -1220,7 +1220,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1220 | mbx_cmd_t *mcp = &mc; | 1220 | mbx_cmd_t *mcp = &mc; |
1221 | 1221 | ||
1222 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n", | 1222 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n", |
1223 | ha->host_no);) | 1223 | ha->host_no)); |
1224 | 1224 | ||
1225 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; | 1225 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; |
1226 | mcp->out_mb = MBX_0; | 1226 | mcp->out_mb = MBX_0; |
@@ -1235,11 +1235,11 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1235 | if (rval != QLA_SUCCESS) { | 1235 | if (rval != QLA_SUCCESS) { |
1236 | /*EMPTY*/ | 1236 | /*EMPTY*/ |
1237 | DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): " | 1237 | DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): " |
1238 | "failed=%x.\n", ha->host_no, rval);) | 1238 | "failed=%x.\n", ha->host_no, rval)); |
1239 | } else { | 1239 | } else { |
1240 | /*EMPTY*/ | 1240 | /*EMPTY*/ |
1241 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n", | 1241 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n", |
1242 | ha->host_no);) | 1242 | ha->host_no)); |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | return rval; | 1245 | return rval; |
@@ -1272,7 +1272,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1272 | mbx_cmd_t *mcp = &mc; | 1272 | mbx_cmd_t *mcp = &mc; |
1273 | 1273 | ||
1274 | DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n", | 1274 | DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n", |
1275 | ha->host_no);) | 1275 | ha->host_no)); |
1276 | 1276 | ||
1277 | mcp->mb[0] = MBC_GET_PORT_NAME; | 1277 | mcp->mb[0] = MBC_GET_PORT_NAME; |
1278 | mcp->out_mb = MBX_1|MBX_0; | 1278 | mcp->out_mb = MBX_1|MBX_0; |
@@ -1292,7 +1292,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1292 | if (rval != QLA_SUCCESS) { | 1292 | if (rval != QLA_SUCCESS) { |
1293 | /*EMPTY*/ | 1293 | /*EMPTY*/ |
1294 | DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n", | 1294 | DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n", |
1295 | ha->host_no, rval);) | 1295 | ha->host_no, rval)); |
1296 | } else { | 1296 | } else { |
1297 | if (name != NULL) { | 1297 | if (name != NULL) { |
1298 | /* This function returns name in big endian. */ | 1298 | /* This function returns name in big endian. */ |
@@ -1307,7 +1307,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", | 1309 | DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", |
1310 | ha->host_no);) | 1310 | ha->host_no)); |
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | return rval; | 1313 | return rval; |
@@ -1335,7 +1335,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1335 | mbx_cmd_t mc; | 1335 | mbx_cmd_t mc; |
1336 | mbx_cmd_t *mcp = &mc; | 1336 | mbx_cmd_t *mcp = &mc; |
1337 | 1337 | ||
1338 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1338 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1339 | 1339 | ||
1340 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1340 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
1341 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; | 1341 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; |
@@ -1364,10 +1364,10 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1364 | if (rval != QLA_SUCCESS) { | 1364 | if (rval != QLA_SUCCESS) { |
1365 | /*EMPTY*/ | 1365 | /*EMPTY*/ |
1366 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", | 1366 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", |
1367 | __func__, ha->host_no, rval);) | 1367 | __func__, ha->host_no, rval)); |
1368 | } else { | 1368 | } else { |
1369 | /*EMPTY*/ | 1369 | /*EMPTY*/ |
1370 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1370 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1371 | } | 1371 | } |
1372 | 1372 | ||
1373 | return rval; | 1373 | return rval; |
@@ -1400,10 +1400,10 @@ qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address, | |||
1400 | mbx_cmd_t *mcp = &mc; | 1400 | mbx_cmd_t *mcp = &mc; |
1401 | 1401 | ||
1402 | DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n", | 1402 | DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n", |
1403 | ha->host_no);) | 1403 | ha->host_no)); |
1404 | 1404 | ||
1405 | DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total " | 1405 | DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total " |
1406 | "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov);) | 1406 | "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov)); |
1407 | 1407 | ||
1408 | mcp->mb[0] = MBC_SEND_SNS_COMMAND; | 1408 | mcp->mb[0] = MBC_SEND_SNS_COMMAND; |
1409 | mcp->mb[1] = cmd_size; | 1409 | mcp->mb[1] = cmd_size; |
@@ -1421,12 +1421,12 @@ qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address, | |||
1421 | if (rval != QLA_SUCCESS) { | 1421 | if (rval != QLA_SUCCESS) { |
1422 | /*EMPTY*/ | 1422 | /*EMPTY*/ |
1423 | DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " | 1423 | DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " |
1424 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);) | 1424 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1])); |
1425 | DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " | 1425 | DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " |
1426 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);) | 1426 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1])); |
1427 | } else { | 1427 | } else { |
1428 | /*EMPTY*/ | 1428 | /*EMPTY*/ |
1429 | DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no);) | 1429 | DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no)); |
1430 | } | 1430 | } |
1431 | 1431 | ||
1432 | return rval; | 1432 | return rval; |
@@ -1442,7 +1442,7 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1442 | dma_addr_t lg_dma; | 1442 | dma_addr_t lg_dma; |
1443 | uint32_t iop[2]; | 1443 | uint32_t iop[2]; |
1444 | 1444 | ||
1445 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1445 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1446 | 1446 | ||
1447 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); | 1447 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); |
1448 | if (lg == NULL) { | 1448 | if (lg == NULL) { |
@@ -1458,13 +1458,15 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1458 | lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI); | 1458 | lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI); |
1459 | if (opt & BIT_0) | 1459 | if (opt & BIT_0) |
1460 | lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI); | 1460 | lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI); |
1461 | if (opt & BIT_1) | ||
1462 | lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI); | ||
1461 | lg->port_id[0] = al_pa; | 1463 | lg->port_id[0] = al_pa; |
1462 | lg->port_id[1] = area; | 1464 | lg->port_id[1] = area; |
1463 | lg->port_id[2] = domain; | 1465 | lg->port_id[2] = domain; |
1464 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); | 1466 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); |
1465 | if (rval != QLA_SUCCESS) { | 1467 | if (rval != QLA_SUCCESS) { |
1466 | DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB " | 1468 | DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB " |
1467 | "(%x).\n", __func__, ha->host_no, rval);) | 1469 | "(%x).\n", __func__, ha->host_no, rval)); |
1468 | } else if (lg->entry_status != 0) { | 1470 | } else if (lg->entry_status != 0) { |
1469 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 1471 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
1470 | "-- error status (%x).\n", __func__, ha->host_no, | 1472 | "-- error status (%x).\n", __func__, ha->host_no, |
@@ -1505,7 +1507,7 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1505 | break; | 1507 | break; |
1506 | } | 1508 | } |
1507 | } else { | 1509 | } else { |
1508 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1510 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1509 | 1511 | ||
1510 | iop[0] = le32_to_cpu(lg->io_parameter[0]); | 1512 | iop[0] = le32_to_cpu(lg->io_parameter[0]); |
1511 | 1513 | ||
@@ -1559,7 +1561,7 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1559 | mbx_cmd_t mc; | 1561 | mbx_cmd_t mc; |
1560 | mbx_cmd_t *mcp = &mc; | 1562 | mbx_cmd_t *mcp = &mc; |
1561 | 1563 | ||
1562 | DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no);) | 1564 | DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no)); |
1563 | 1565 | ||
1564 | mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; | 1566 | mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; |
1565 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 1567 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
@@ -1604,11 +1606,11 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1604 | /*EMPTY*/ | 1606 | /*EMPTY*/ |
1605 | DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x " | 1607 | DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x " |
1606 | "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval, | 1608 | "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval, |
1607 | mcp->mb[0], mcp->mb[1], mcp->mb[2]);) | 1609 | mcp->mb[0], mcp->mb[1], mcp->mb[2])); |
1608 | } else { | 1610 | } else { |
1609 | /*EMPTY*/ | 1611 | /*EMPTY*/ |
1610 | DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n", | 1612 | DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n", |
1611 | ha->host_no);) | 1613 | ha->host_no)); |
1612 | } | 1614 | } |
1613 | 1615 | ||
1614 | return rval; | 1616 | return rval; |
@@ -1643,7 +1645,7 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
1643 | fcport->d_id.b.domain, fcport->d_id.b.area, | 1645 | fcport->d_id.b.domain, fcport->d_id.b.area, |
1644 | fcport->d_id.b.al_pa, mb_ret, opt); | 1646 | fcport->d_id.b.al_pa, mb_ret, opt); |
1645 | 1647 | ||
1646 | DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1648 | DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1647 | 1649 | ||
1648 | mcp->mb[0] = MBC_LOGIN_LOOP_PORT; | 1650 | mcp->mb[0] = MBC_LOGIN_LOOP_PORT; |
1649 | if (HAS_EXTENDED_IDS(ha)) | 1651 | if (HAS_EXTENDED_IDS(ha)) |
@@ -1677,13 +1679,13 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
1677 | 1679 | ||
1678 | DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " | 1680 | DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " |
1679 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, | 1681 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, |
1680 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);) | 1682 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7])); |
1681 | DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " | 1683 | DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " |
1682 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, | 1684 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, |
1683 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);) | 1685 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7])); |
1684 | } else { | 1686 | } else { |
1685 | /*EMPTY*/ | 1687 | /*EMPTY*/ |
1686 | DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1688 | DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1687 | } | 1689 | } |
1688 | 1690 | ||
1689 | return (rval); | 1691 | return (rval); |
@@ -1697,7 +1699,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1697 | struct logio_entry_24xx *lg; | 1699 | struct logio_entry_24xx *lg; |
1698 | dma_addr_t lg_dma; | 1700 | dma_addr_t lg_dma; |
1699 | 1701 | ||
1700 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1702 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1701 | 1703 | ||
1702 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); | 1704 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); |
1703 | if (lg == NULL) { | 1705 | if (lg == NULL) { |
@@ -1718,7 +1720,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1718 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); | 1720 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); |
1719 | if (rval != QLA_SUCCESS) { | 1721 | if (rval != QLA_SUCCESS) { |
1720 | DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB " | 1722 | DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB " |
1721 | "(%x).\n", __func__, ha->host_no, rval);) | 1723 | "(%x).\n", __func__, ha->host_no, rval)); |
1722 | } else if (lg->entry_status != 0) { | 1724 | } else if (lg->entry_status != 0) { |
1723 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 1725 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
1724 | "-- error status (%x).\n", __func__, ha->host_no, | 1726 | "-- error status (%x).\n", __func__, ha->host_no, |
@@ -1729,10 +1731,10 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1729 | "-- completion status (%x) ioparam=%x/%x.\n", __func__, | 1731 | "-- completion status (%x) ioparam=%x/%x.\n", __func__, |
1730 | ha->host_no, le16_to_cpu(lg->comp_status), | 1732 | ha->host_no, le16_to_cpu(lg->comp_status), |
1731 | le32_to_cpu(lg->io_parameter[0]), | 1733 | le32_to_cpu(lg->io_parameter[0]), |
1732 | le32_to_cpu(lg->io_parameter[1]));) | 1734 | le32_to_cpu(lg->io_parameter[1]))); |
1733 | } else { | 1735 | } else { |
1734 | /*EMPTY*/ | 1736 | /*EMPTY*/ |
1735 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1737 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1736 | } | 1738 | } |
1737 | 1739 | ||
1738 | dma_pool_free(ha->s_dma_pool, lg, lg_dma); | 1740 | dma_pool_free(ha->s_dma_pool, lg, lg_dma); |
@@ -1765,7 +1767,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1765 | mbx_cmd_t *mcp = &mc; | 1767 | mbx_cmd_t *mcp = &mc; |
1766 | 1768 | ||
1767 | DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n", | 1769 | DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n", |
1768 | ha->host_no);) | 1770 | ha->host_no)); |
1769 | 1771 | ||
1770 | mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; | 1772 | mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; |
1771 | mcp->out_mb = MBX_1|MBX_0; | 1773 | mcp->out_mb = MBX_1|MBX_0; |
@@ -1785,11 +1787,11 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1785 | if (rval != QLA_SUCCESS) { | 1787 | if (rval != QLA_SUCCESS) { |
1786 | /*EMPTY*/ | 1788 | /*EMPTY*/ |
1787 | DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x " | 1789 | DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x " |
1788 | "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]);) | 1790 | "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1])); |
1789 | } else { | 1791 | } else { |
1790 | /*EMPTY*/ | 1792 | /*EMPTY*/ |
1791 | DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n", | 1793 | DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n", |
1792 | ha->host_no);) | 1794 | ha->host_no)); |
1793 | } | 1795 | } |
1794 | 1796 | ||
1795 | return rval; | 1797 | return rval; |
@@ -1818,7 +1820,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1818 | mbx_cmd_t *mcp = &mc; | 1820 | mbx_cmd_t *mcp = &mc; |
1819 | 1821 | ||
1820 | DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n", | 1822 | DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n", |
1821 | ha->host_no);) | 1823 | ha->host_no)); |
1822 | 1824 | ||
1823 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; | 1825 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; |
1824 | mcp->mb[1] = 0; | 1826 | mcp->mb[1] = 0; |
@@ -1833,11 +1835,11 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1833 | if (rval != QLA_SUCCESS) { | 1835 | if (rval != QLA_SUCCESS) { |
1834 | /*EMPTY*/ | 1836 | /*EMPTY*/ |
1835 | DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n", | 1837 | DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n", |
1836 | ha->host_no, rval);) | 1838 | ha->host_no, rval)); |
1837 | } else { | 1839 | } else { |
1838 | /*EMPTY*/ | 1840 | /*EMPTY*/ |
1839 | DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n", | 1841 | DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n", |
1840 | ha->host_no);) | 1842 | ha->host_no)); |
1841 | } | 1843 | } |
1842 | 1844 | ||
1843 | return rval; | 1845 | return rval; |
@@ -1864,7 +1866,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1864 | mbx_cmd_t *mcp = &mc; | 1866 | mbx_cmd_t *mcp = &mc; |
1865 | 1867 | ||
1866 | DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n", | 1868 | DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n", |
1867 | ha->host_no);) | 1869 | ha->host_no)); |
1868 | 1870 | ||
1869 | if (id_list == NULL) | 1871 | if (id_list == NULL) |
1870 | return QLA_FUNCTION_FAILED; | 1872 | return QLA_FUNCTION_FAILED; |
@@ -1893,11 +1895,11 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1893 | if (rval != QLA_SUCCESS) { | 1895 | if (rval != QLA_SUCCESS) { |
1894 | /*EMPTY*/ | 1896 | /*EMPTY*/ |
1895 | DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n", | 1897 | DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n", |
1896 | ha->host_no, rval);) | 1898 | ha->host_no, rval)); |
1897 | } else { | 1899 | } else { |
1898 | *entries = mcp->mb[1]; | 1900 | *entries = mcp->mb[1]; |
1899 | DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n", | 1901 | DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n", |
1900 | ha->host_no);) | 1902 | ha->host_no)); |
1901 | } | 1903 | } |
1902 | 1904 | ||
1903 | return rval; | 1905 | return rval; |
@@ -1936,7 +1938,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
1936 | if (rval != QLA_SUCCESS) { | 1938 | if (rval != QLA_SUCCESS) { |
1937 | /*EMPTY*/ | 1939 | /*EMPTY*/ |
1938 | DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__, | 1940 | DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__, |
1939 | ha->host_no, mcp->mb[0]);) | 1941 | ha->host_no, mcp->mb[0])); |
1940 | } else { | 1942 | } else { |
1941 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " | 1943 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " |
1942 | "mb7=%x mb10=%x.\n", __func__, ha->host_no, | 1944 | "mb7=%x mb10=%x.\n", __func__, ha->host_no, |
@@ -2045,7 +2047,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2045 | link_stat_t *stat_buf; | 2047 | link_stat_t *stat_buf; |
2046 | dma_addr_t stat_buf_dma; | 2048 | dma_addr_t stat_buf_dma; |
2047 | 2049 | ||
2048 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 2050 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2049 | 2051 | ||
2050 | stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma); | 2052 | stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma); |
2051 | if (stat_buf == NULL) { | 2053 | if (stat_buf == NULL) { |
@@ -2083,7 +2085,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2083 | if (rval == QLA_SUCCESS) { | 2085 | if (rval == QLA_SUCCESS) { |
2084 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { | 2086 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { |
2085 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", | 2087 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", |
2086 | __func__, ha->host_no, mcp->mb[0]);) | 2088 | __func__, ha->host_no, mcp->mb[0])); |
2087 | status[0] = mcp->mb[0]; | 2089 | status[0] = mcp->mb[0]; |
2088 | rval = BIT_1; | 2090 | rval = BIT_1; |
2089 | } else { | 2091 | } else { |
@@ -2108,12 +2110,12 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2108 | stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt, | 2110 | stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt, |
2109 | stat_buf->prim_seq_err_cnt, | 2111 | stat_buf->prim_seq_err_cnt, |
2110 | stat_buf->inval_xmit_word_cnt, | 2112 | stat_buf->inval_xmit_word_cnt, |
2111 | stat_buf->inval_crc_cnt);) | 2113 | stat_buf->inval_crc_cnt)); |
2112 | } | 2114 | } |
2113 | } else { | 2115 | } else { |
2114 | /* Failed. */ | 2116 | /* Failed. */ |
2115 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | 2117 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, |
2116 | ha->host_no, rval);) | 2118 | ha->host_no, rval)); |
2117 | rval = BIT_1; | 2119 | rval = BIT_1; |
2118 | } | 2120 | } |
2119 | 2121 | ||
@@ -2132,7 +2134,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, | |||
2132 | uint32_t *sbuf, *siter; | 2134 | uint32_t *sbuf, *siter; |
2133 | dma_addr_t sbuf_dma; | 2135 | dma_addr_t sbuf_dma; |
2134 | 2136 | ||
2135 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 2137 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2136 | 2138 | ||
2137 | if (dwords > (DMA_POOL_SIZE / 4)) { | 2139 | if (dwords > (DMA_POOL_SIZE / 4)) { |
2138 | DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs " | 2140 | DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs " |
@@ -2196,7 +2198,7 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2196 | dma_addr_t abt_dma; | 2198 | dma_addr_t abt_dma; |
2197 | uint32_t handle; | 2199 | uint32_t handle; |
2198 | 2200 | ||
2199 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 2201 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2200 | 2202 | ||
2201 | fcport = sp->fcport; | 2203 | fcport = sp->fcport; |
2202 | 2204 | ||
@@ -2229,7 +2231,7 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2229 | rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0); | 2231 | rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0); |
2230 | if (rval != QLA_SUCCESS) { | 2232 | if (rval != QLA_SUCCESS) { |
2231 | DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", | 2233 | DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", |
2232 | __func__, ha->host_no, rval);) | 2234 | __func__, ha->host_no, rval)); |
2233 | } else if (abt->entry_status != 0) { | 2235 | } else if (abt->entry_status != 0) { |
2234 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2236 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2235 | "-- error status (%x).\n", __func__, ha->host_no, | 2237 | "-- error status (%x).\n", __func__, ha->host_no, |
@@ -2238,10 +2240,10 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2238 | } else if (abt->nport_handle != __constant_cpu_to_le16(0)) { | 2240 | } else if (abt->nport_handle != __constant_cpu_to_le16(0)) { |
2239 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2241 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2240 | "-- completion status (%x).\n", __func__, ha->host_no, | 2242 | "-- completion status (%x).\n", __func__, ha->host_no, |
2241 | le16_to_cpu(abt->nport_handle));) | 2243 | le16_to_cpu(abt->nport_handle))); |
2242 | rval = QLA_FUNCTION_FAILED; | 2244 | rval = QLA_FUNCTION_FAILED; |
2243 | } else { | 2245 | } else { |
2244 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 2246 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2245 | sp->flags |= SRB_ABORT_PENDING; | 2247 | sp->flags |= SRB_ABORT_PENDING; |
2246 | } | 2248 | } |
2247 | 2249 | ||
@@ -2268,7 +2270,7 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2268 | if (fcport == NULL) | 2270 | if (fcport == NULL) |
2269 | return 0; | 2271 | return 0; |
2270 | 2272 | ||
2271 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);) | 2273 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
2272 | 2274 | ||
2273 | ha = fcport->ha; | 2275 | ha = fcport->ha; |
2274 | tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); | 2276 | tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); |
@@ -2290,7 +2292,7 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2290 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); | 2292 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); |
2291 | if (rval != QLA_SUCCESS) { | 2293 | if (rval != QLA_SUCCESS) { |
2292 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " | 2294 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " |
2293 | "(%x).\n", __func__, ha->host_no, rval);) | 2295 | "(%x).\n", __func__, ha->host_no, rval)); |
2294 | goto atarget_done; | 2296 | goto atarget_done; |
2295 | } else if (tsk->p.sts.entry_status != 0) { | 2297 | } else if (tsk->p.sts.entry_status != 0) { |
2296 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2298 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
@@ -2302,7 +2304,7 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2302 | __constant_cpu_to_le16(CS_COMPLETE)) { | 2304 | __constant_cpu_to_le16(CS_COMPLETE)) { |
2303 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2305 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2304 | "-- completion status (%x).\n", __func__, | 2306 | "-- completion status (%x).\n", __func__, |
2305 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status));) | 2307 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); |
2306 | rval = QLA_FUNCTION_FAILED; | 2308 | rval = QLA_FUNCTION_FAILED; |
2307 | goto atarget_done; | 2309 | goto atarget_done; |
2308 | } | 2310 | } |
@@ -2311,9 +2313,9 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2311 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); | 2313 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); |
2312 | if (rval != QLA_SUCCESS) { | 2314 | if (rval != QLA_SUCCESS) { |
2313 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | 2315 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " |
2314 | "(%x).\n", __func__, ha->host_no, rval);) | 2316 | "(%x).\n", __func__, ha->host_no, rval)); |
2315 | } else { | 2317 | } else { |
2316 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 2318 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2317 | } | 2319 | } |
2318 | 2320 | ||
2319 | atarget_done: | 2321 | atarget_done: |
@@ -2460,3 +2462,81 @@ qla2x00_stop_firmware(scsi_qla_host_t *ha) | |||
2460 | 2462 | ||
2461 | return rval; | 2463 | return rval; |
2462 | } | 2464 | } |
2465 | |||
2466 | int | ||
2467 | qla2x00_trace_control(scsi_qla_host_t *ha, uint16_t ctrl, dma_addr_t eft_dma, | ||
2468 | uint16_t buffers) | ||
2469 | { | ||
2470 | int rval; | ||
2471 | mbx_cmd_t mc; | ||
2472 | mbx_cmd_t *mcp = &mc; | ||
2473 | |||
2474 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
2475 | return QLA_FUNCTION_FAILED; | ||
2476 | |||
2477 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2478 | |||
2479 | mcp->mb[0] = MBC_TRACE_CONTROL; | ||
2480 | mcp->mb[1] = ctrl; | ||
2481 | mcp->out_mb = MBX_1|MBX_0; | ||
2482 | mcp->in_mb = MBX_1|MBX_0; | ||
2483 | if (ctrl == TC_ENABLE) { | ||
2484 | mcp->mb[2] = LSW(eft_dma); | ||
2485 | mcp->mb[3] = MSW(eft_dma); | ||
2486 | mcp->mb[4] = LSW(MSD(eft_dma)); | ||
2487 | mcp->mb[5] = MSW(MSD(eft_dma)); | ||
2488 | mcp->mb[6] = buffers; | ||
2489 | mcp->mb[7] = buffers; | ||
2490 | mcp->out_mb |= MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2; | ||
2491 | } | ||
2492 | mcp->tov = 30; | ||
2493 | mcp->flags = 0; | ||
2494 | rval = qla2x00_mailbox_command(ha, mcp); | ||
2495 | |||
2496 | if (rval != QLA_SUCCESS) { | ||
2497 | DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n", | ||
2498 | __func__, ha->host_no, rval, mcp->mb[0], mcp->mb[1])); | ||
2499 | } else { | ||
2500 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
2501 | } | ||
2502 | |||
2503 | return rval; | ||
2504 | } | ||
2505 | |||
2506 | int | ||
2507 | qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | ||
2508 | uint16_t off, uint16_t count) | ||
2509 | { | ||
2510 | int rval; | ||
2511 | mbx_cmd_t mc; | ||
2512 | mbx_cmd_t *mcp = &mc; | ||
2513 | |||
2514 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
2515 | return QLA_FUNCTION_FAILED; | ||
2516 | |||
2517 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2518 | |||
2519 | mcp->mb[0] = MBC_READ_SFP; | ||
2520 | mcp->mb[1] = addr; | ||
2521 | mcp->mb[2] = MSW(sfp_dma); | ||
2522 | mcp->mb[3] = LSW(sfp_dma); | ||
2523 | mcp->mb[6] = MSW(MSD(sfp_dma)); | ||
2524 | mcp->mb[7] = LSW(MSD(sfp_dma)); | ||
2525 | mcp->mb[8] = count; | ||
2526 | mcp->mb[9] = off; | ||
2527 | mcp->mb[10] = 0; | ||
2528 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | ||
2529 | mcp->in_mb = MBX_0; | ||
2530 | mcp->tov = 30; | ||
2531 | mcp->flags = 0; | ||
2532 | rval = qla2x00_mailbox_command(ha, mcp); | ||
2533 | |||
2534 | if (rval != QLA_SUCCESS) { | ||
2535 | DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, | ||
2536 | ha->host_no, rval, mcp->mb[0])); | ||
2537 | } else { | ||
2538 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
2539 | } | ||
2540 | |||
2541 | return rval; | ||
2542 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 93062593ebe7..ec7ebb6037e6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -39,14 +39,14 @@ MODULE_PARM_DESC(ql2xlogintimeout, | |||
39 | int qlport_down_retry = 30; | 39 | int qlport_down_retry = 30; |
40 | module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR); | 40 | module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR); |
41 | MODULE_PARM_DESC(qlport_down_retry, | 41 | MODULE_PARM_DESC(qlport_down_retry, |
42 | "Maximum number of command retries to a port that returns" | 42 | "Maximum number of command retries to a port that returns " |
43 | "a PORT-DOWN status."); | 43 | "a PORT-DOWN status."); |
44 | 44 | ||
45 | int ql2xplogiabsentdevice; | 45 | int ql2xplogiabsentdevice; |
46 | module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR); | 46 | module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR); |
47 | MODULE_PARM_DESC(ql2xplogiabsentdevice, | 47 | MODULE_PARM_DESC(ql2xplogiabsentdevice, |
48 | "Option to enable PLOGI to devices that are not present after " | 48 | "Option to enable PLOGI to devices that are not present after " |
49 | "a Fabric scan. This is needed for several broken switches." | 49 | "a Fabric scan. This is needed for several broken switches. " |
50 | "Default is 0 - no PLOGI. 1 - perfom PLOGI."); | 50 | "Default is 0 - no PLOGI. 1 - perfom PLOGI."); |
51 | 51 | ||
52 | int ql2xloginretrycount = 0; | 52 | int ql2xloginretrycount = 0; |
@@ -54,6 +54,19 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR); | |||
54 | MODULE_PARM_DESC(ql2xloginretrycount, | 54 | MODULE_PARM_DESC(ql2xloginretrycount, |
55 | "Specify an alternate value for the NVRAM login retry count."); | 55 | "Specify an alternate value for the NVRAM login retry count."); |
56 | 56 | ||
57 | int ql2xallocfwdump = 1; | ||
58 | module_param(ql2xallocfwdump, int, S_IRUGO|S_IRUSR); | ||
59 | MODULE_PARM_DESC(ql2xallocfwdump, | ||
60 | "Option to enable allocation of memory for a firmware dump " | ||
61 | "during HBA initialization. Memory allocation requirements " | ||
62 | "vary by ISP type. Default is 1 - allocate memory."); | ||
63 | |||
64 | int extended_error_logging; | ||
65 | module_param(extended_error_logging, int, S_IRUGO|S_IRUSR); | ||
66 | MODULE_PARM_DESC(extended_error_logging, | ||
67 | "Option to enable extended error logging, " | ||
68 | "Default is 0 - no logging. 1 - log errors."); | ||
69 | |||
57 | static void qla2x00_free_device(scsi_qla_host_t *); | 70 | static void qla2x00_free_device(scsi_qla_host_t *); |
58 | 71 | ||
59 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); | 72 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); |
@@ -624,7 +637,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
624 | 637 | ||
625 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", | 638 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", |
626 | __func__, ha->host_no, sp, serial)); | 639 | __func__, ha->host_no, sp, serial)); |
627 | DEBUG3(qla2x00_print_scsi_cmd(cmd);) | 640 | DEBUG3(qla2x00_print_scsi_cmd(cmd)); |
628 | 641 | ||
629 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 642 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
630 | if (ha->isp_ops.abort_command(ha, sp)) { | 643 | if (ha->isp_ops.abort_command(ha, sp)) { |
@@ -766,7 +779,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
766 | #endif | 779 | #endif |
767 | } else { | 780 | } else { |
768 | DEBUG2(printk(KERN_INFO | 781 | DEBUG2(printk(KERN_INFO |
769 | "%s failed: loop not ready\n",__func__);) | 782 | "%s failed: loop not ready\n",__func__)); |
770 | } | 783 | } |
771 | 784 | ||
772 | if (ret == FAILED) { | 785 | if (ret == FAILED) { |
@@ -1021,12 +1034,12 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1021 | /* Empty */ | 1034 | /* Empty */ |
1022 | DEBUG2_3(printk("%s(%ld): **** FAILED ****\n", | 1035 | DEBUG2_3(printk("%s(%ld): **** FAILED ****\n", |
1023 | __func__, | 1036 | __func__, |
1024 | ha->host_no);) | 1037 | ha->host_no)); |
1025 | } else { | 1038 | } else { |
1026 | /* Empty */ | 1039 | /* Empty */ |
1027 | DEBUG3(printk("%s(%ld): exiting normally.\n", | 1040 | DEBUG3(printk("%s(%ld): exiting normally.\n", |
1028 | __func__, | 1041 | __func__, |
1029 | ha->host_no);) | 1042 | ha->host_no)); |
1030 | } | 1043 | } |
1031 | 1044 | ||
1032 | return(status); | 1045 | return(status); |
@@ -1324,7 +1337,8 @@ qla24xx_disable_intrs(scsi_qla_host_t *ha) | |||
1324 | /* | 1337 | /* |
1325 | * PCI driver interface | 1338 | * PCI driver interface |
1326 | */ | 1339 | */ |
1327 | static int qla2x00_probe_one(struct pci_dev *pdev) | 1340 | static int __devinit |
1341 | qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
1328 | { | 1342 | { |
1329 | int ret = -ENODEV; | 1343 | int ret = -ENODEV; |
1330 | device_reg_t __iomem *reg; | 1344 | device_reg_t __iomem *reg; |
@@ -1405,7 +1419,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev) | |||
1405 | ha->isp_ops.read_nvram = qla2x00_read_nvram_data; | 1419 | ha->isp_ops.read_nvram = qla2x00_read_nvram_data; |
1406 | ha->isp_ops.write_nvram = qla2x00_write_nvram_data; | 1420 | ha->isp_ops.write_nvram = qla2x00_write_nvram_data; |
1407 | ha->isp_ops.fw_dump = qla2100_fw_dump; | 1421 | ha->isp_ops.fw_dump = qla2100_fw_dump; |
1408 | ha->isp_ops.ascii_fw_dump = qla2100_ascii_fw_dump; | ||
1409 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; | 1422 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; |
1410 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; | 1423 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; |
1411 | if (IS_QLA2100(ha)) { | 1424 | if (IS_QLA2100(ha)) { |
@@ -1432,7 +1445,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev) | |||
1432 | ha->isp_ops.pci_config = qla2300_pci_config; | 1445 | ha->isp_ops.pci_config = qla2300_pci_config; |
1433 | ha->isp_ops.intr_handler = qla2300_intr_handler; | 1446 | ha->isp_ops.intr_handler = qla2300_intr_handler; |
1434 | ha->isp_ops.fw_dump = qla2300_fw_dump; | 1447 | ha->isp_ops.fw_dump = qla2300_fw_dump; |
1435 | ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump; | ||
1436 | ha->isp_ops.beacon_on = qla2x00_beacon_on; | 1448 | ha->isp_ops.beacon_on = qla2x00_beacon_on; |
1437 | ha->isp_ops.beacon_off = qla2x00_beacon_off; | 1449 | ha->isp_ops.beacon_off = qla2x00_beacon_off; |
1438 | ha->isp_ops.beacon_blink = qla2x00_beacon_blink; | 1450 | ha->isp_ops.beacon_blink = qla2x00_beacon_blink; |
@@ -1469,7 +1481,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev) | |||
1469 | ha->isp_ops.read_nvram = qla24xx_read_nvram_data; | 1481 | ha->isp_ops.read_nvram = qla24xx_read_nvram_data; |
1470 | ha->isp_ops.write_nvram = qla24xx_write_nvram_data; | 1482 | ha->isp_ops.write_nvram = qla24xx_write_nvram_data; |
1471 | ha->isp_ops.fw_dump = qla24xx_fw_dump; | 1483 | ha->isp_ops.fw_dump = qla24xx_fw_dump; |
1472 | ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump; | ||
1473 | ha->isp_ops.read_optrom = qla24xx_read_optrom_data; | 1484 | ha->isp_ops.read_optrom = qla24xx_read_optrom_data; |
1474 | ha->isp_ops.write_optrom = qla24xx_write_optrom_data; | 1485 | ha->isp_ops.write_optrom = qla24xx_write_optrom_data; |
1475 | ha->isp_ops.beacon_on = qla24xx_beacon_on; | 1486 | ha->isp_ops.beacon_on = qla24xx_beacon_on; |
@@ -1640,7 +1651,8 @@ probe_out: | |||
1640 | return ret; | 1651 | return ret; |
1641 | } | 1652 | } |
1642 | 1653 | ||
1643 | static void qla2x00_remove_one(struct pci_dev *pdev) | 1654 | static void __devexit |
1655 | qla2x00_remove_one(struct pci_dev *pdev) | ||
1644 | { | 1656 | { |
1645 | scsi_qla_host_t *ha; | 1657 | scsi_qla_host_t *ha; |
1646 | 1658 | ||
@@ -1678,6 +1690,9 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1678 | kthread_stop(t); | 1690 | kthread_stop(t); |
1679 | } | 1691 | } |
1680 | 1692 | ||
1693 | if (ha->eft) | ||
1694 | qla2x00_trace_control(ha, TC_DISABLE, 0, 0); | ||
1695 | |||
1681 | /* Stop currently executing firmware. */ | 1696 | /* Stop currently executing firmware. */ |
1682 | qla2x00_stop_firmware(ha); | 1697 | qla2x00_stop_firmware(ha); |
1683 | 1698 | ||
@@ -1899,17 +1914,6 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) | |||
1899 | } | 1914 | } |
1900 | memset(ha->init_cb, 0, ha->init_cb_size); | 1915 | memset(ha->init_cb, 0, ha->init_cb_size); |
1901 | 1916 | ||
1902 | /* Allocate ioctl related memory. */ | ||
1903 | if (qla2x00_alloc_ioctl_mem(ha)) { | ||
1904 | qla_printk(KERN_WARNING, ha, | ||
1905 | "Memory Allocation failed - ioctl_mem\n"); | ||
1906 | |||
1907 | qla2x00_mem_free(ha); | ||
1908 | msleep(100); | ||
1909 | |||
1910 | continue; | ||
1911 | } | ||
1912 | |||
1913 | if (qla2x00_allocate_sp_pool(ha)) { | 1917 | if (qla2x00_allocate_sp_pool(ha)) { |
1914 | qla_printk(KERN_WARNING, ha, | 1918 | qla_printk(KERN_WARNING, ha, |
1915 | "Memory Allocation failed - " | 1919 | "Memory Allocation failed - " |
@@ -1972,6 +1976,26 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) | |||
1972 | continue; | 1976 | continue; |
1973 | } | 1977 | } |
1974 | memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); | 1978 | memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); |
1979 | |||
1980 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | ||
1981 | /* | ||
1982 | * Get consistent memory allocated for SFP | ||
1983 | * block. | ||
1984 | */ | ||
1985 | ha->sfp_data = dma_pool_alloc(ha->s_dma_pool, | ||
1986 | GFP_KERNEL, &ha->sfp_data_dma); | ||
1987 | if (ha->sfp_data == NULL) { | ||
1988 | qla_printk(KERN_WARNING, ha, | ||
1989 | "Memory Allocation failed - " | ||
1990 | "sfp_data\n"); | ||
1991 | |||
1992 | qla2x00_mem_free(ha); | ||
1993 | msleep(100); | ||
1994 | |||
1995 | continue; | ||
1996 | } | ||
1997 | memset(ha->sfp_data, 0, SFP_BLOCK_SIZE); | ||
1998 | } | ||
1975 | } | 1999 | } |
1976 | 2000 | ||
1977 | /* Done all allocations without any error. */ | 2001 | /* Done all allocations without any error. */ |
@@ -2006,12 +2030,16 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2006 | return; | 2030 | return; |
2007 | } | 2031 | } |
2008 | 2032 | ||
2009 | /* free ioctl memory */ | ||
2010 | qla2x00_free_ioctl_mem(ha); | ||
2011 | |||
2012 | /* free sp pool */ | 2033 | /* free sp pool */ |
2013 | qla2x00_free_sp_pool(ha); | 2034 | qla2x00_free_sp_pool(ha); |
2014 | 2035 | ||
2036 | if (ha->fw_dump) { | ||
2037 | if (ha->eft) | ||
2038 | dma_free_coherent(&ha->pdev->dev, | ||
2039 | ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma); | ||
2040 | vfree(ha->fw_dump); | ||
2041 | } | ||
2042 | |||
2015 | if (ha->sns_cmd) | 2043 | if (ha->sns_cmd) |
2016 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), | 2044 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), |
2017 | ha->sns_cmd, ha->sns_cmd_dma); | 2045 | ha->sns_cmd, ha->sns_cmd_dma); |
@@ -2020,6 +2048,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2020 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), | 2048 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), |
2021 | ha->ct_sns, ha->ct_sns_dma); | 2049 | ha->ct_sns, ha->ct_sns_dma); |
2022 | 2050 | ||
2051 | if (ha->sfp_data) | ||
2052 | dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); | ||
2053 | |||
2023 | if (ha->ms_iocb) | 2054 | if (ha->ms_iocb) |
2024 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); | 2055 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); |
2025 | 2056 | ||
@@ -2043,6 +2074,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2043 | (ha->request_q_length + 1) * sizeof(request_t), | 2074 | (ha->request_q_length + 1) * sizeof(request_t), |
2044 | ha->request_ring, ha->request_dma); | 2075 | ha->request_ring, ha->request_dma); |
2045 | 2076 | ||
2077 | ha->eft = NULL; | ||
2078 | ha->eft_dma = 0; | ||
2046 | ha->sns_cmd = NULL; | 2079 | ha->sns_cmd = NULL; |
2047 | ha->sns_cmd_dma = 0; | 2080 | ha->sns_cmd_dma = 0; |
2048 | ha->ct_sns = NULL; | 2081 | ha->ct_sns = NULL; |
@@ -2071,13 +2104,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2071 | } | 2104 | } |
2072 | INIT_LIST_HEAD(&ha->fcports); | 2105 | INIT_LIST_HEAD(&ha->fcports); |
2073 | 2106 | ||
2074 | vfree(ha->fw_dump); | ||
2075 | vfree(ha->fw_dump_buffer); | ||
2076 | |||
2077 | ha->fw_dump = NULL; | 2107 | ha->fw_dump = NULL; |
2078 | ha->fw_dumped = 0; | 2108 | ha->fw_dumped = 0; |
2079 | ha->fw_dump_reading = 0; | 2109 | ha->fw_dump_reading = 0; |
2080 | ha->fw_dump_buffer = NULL; | ||
2081 | 2110 | ||
2082 | vfree(ha->optrom_buffer); | 2111 | vfree(ha->optrom_buffer); |
2083 | } | 2112 | } |
@@ -2617,40 +2646,16 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
2617 | }; | 2646 | }; |
2618 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); | 2647 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |
2619 | 2648 | ||
2620 | static int __devinit | ||
2621 | qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
2622 | { | ||
2623 | return qla2x00_probe_one(pdev); | ||
2624 | } | ||
2625 | |||
2626 | static void __devexit | ||
2627 | qla2xxx_remove_one(struct pci_dev *pdev) | ||
2628 | { | ||
2629 | qla2x00_remove_one(pdev); | ||
2630 | } | ||
2631 | |||
2632 | static struct pci_driver qla2xxx_pci_driver = { | 2649 | static struct pci_driver qla2xxx_pci_driver = { |
2633 | .name = QLA2XXX_DRIVER_NAME, | 2650 | .name = QLA2XXX_DRIVER_NAME, |
2634 | .driver = { | 2651 | .driver = { |
2635 | .owner = THIS_MODULE, | 2652 | .owner = THIS_MODULE, |
2636 | }, | 2653 | }, |
2637 | .id_table = qla2xxx_pci_tbl, | 2654 | .id_table = qla2xxx_pci_tbl, |
2638 | .probe = qla2xxx_probe_one, | 2655 | .probe = qla2x00_probe_one, |
2639 | .remove = __devexit_p(qla2xxx_remove_one), | 2656 | .remove = __devexit_p(qla2x00_remove_one), |
2640 | }; | 2657 | }; |
2641 | 2658 | ||
2642 | static inline int | ||
2643 | qla2x00_pci_module_init(void) | ||
2644 | { | ||
2645 | return pci_module_init(&qla2xxx_pci_driver); | ||
2646 | } | ||
2647 | |||
2648 | static inline void | ||
2649 | qla2x00_pci_module_exit(void) | ||
2650 | { | ||
2651 | pci_unregister_driver(&qla2xxx_pci_driver); | ||
2652 | } | ||
2653 | |||
2654 | /** | 2659 | /** |
2655 | * qla2x00_module_init - Module initialization. | 2660 | * qla2x00_module_init - Module initialization. |
2656 | **/ | 2661 | **/ |
@@ -2670,16 +2675,16 @@ qla2x00_module_init(void) | |||
2670 | 2675 | ||
2671 | /* Derive version string. */ | 2676 | /* Derive version string. */ |
2672 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); | 2677 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); |
2673 | #if DEBUG_QLA2100 | 2678 | if (extended_error_logging) |
2674 | strcat(qla2x00_version_str, "-debug"); | 2679 | strcat(qla2x00_version_str, "-debug"); |
2675 | #endif | 2680 | |
2676 | qla2xxx_transport_template = | 2681 | qla2xxx_transport_template = |
2677 | fc_attach_transport(&qla2xxx_transport_functions); | 2682 | fc_attach_transport(&qla2xxx_transport_functions); |
2678 | if (!qla2xxx_transport_template) | 2683 | if (!qla2xxx_transport_template) |
2679 | return -ENODEV; | 2684 | return -ENODEV; |
2680 | 2685 | ||
2681 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); | 2686 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); |
2682 | ret = qla2x00_pci_module_init(); | 2687 | ret = pci_register_driver(&qla2xxx_pci_driver); |
2683 | if (ret) { | 2688 | if (ret) { |
2684 | kmem_cache_destroy(srb_cachep); | 2689 | kmem_cache_destroy(srb_cachep); |
2685 | fc_release_transport(qla2xxx_transport_template); | 2690 | fc_release_transport(qla2xxx_transport_template); |
@@ -2693,7 +2698,7 @@ qla2x00_module_init(void) | |||
2693 | static void __exit | 2698 | static void __exit |
2694 | qla2x00_module_exit(void) | 2699 | qla2x00_module_exit(void) |
2695 | { | 2700 | { |
2696 | qla2x00_pci_module_exit(); | 2701 | pci_unregister_driver(&qla2xxx_pci_driver); |
2697 | qla2x00_release_firmware(); | 2702 | qla2x00_release_firmware(); |
2698 | kmem_cache_destroy(srb_cachep); | 2703 | kmem_cache_destroy(srb_cachep); |
2699 | fc_release_transport(qla2xxx_transport_template); | 2704 | fc_release_transport(qla2xxx_transport_template); |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 6b315521bd89..d2d683440659 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.01.05-k2" | 10 | #define QLA2XXX_VERSION "8.01.05-k3" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 1 | 13 | #define QLA_DRIVER_MINOR_VER 1 |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index e1168860045c..9c63b00773c4 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -50,18 +50,22 @@ | |||
50 | #include "scsi_logging.h" | 50 | #include "scsi_logging.h" |
51 | #include "scsi_debug.h" | 51 | #include "scsi_debug.h" |
52 | 52 | ||
53 | #define SCSI_DEBUG_VERSION "1.75" | 53 | #define SCSI_DEBUG_VERSION "1.79" |
54 | static const char * scsi_debug_version_date = "20050113"; | 54 | static const char * scsi_debug_version_date = "20060604"; |
55 | 55 | ||
56 | /* Additional Sense Code (ASC) used */ | 56 | /* Additional Sense Code (ASC) used */ |
57 | #define NO_ADDED_SENSE 0x0 | 57 | #define NO_ADDITIONAL_SENSE 0x0 |
58 | #define LOGICAL_UNIT_NOT_READY 0x4 | ||
58 | #define UNRECOVERED_READ_ERR 0x11 | 59 | #define UNRECOVERED_READ_ERR 0x11 |
60 | #define PARAMETER_LIST_LENGTH_ERR 0x1a | ||
59 | #define INVALID_OPCODE 0x20 | 61 | #define INVALID_OPCODE 0x20 |
60 | #define ADDR_OUT_OF_RANGE 0x21 | 62 | #define ADDR_OUT_OF_RANGE 0x21 |
61 | #define INVALID_FIELD_IN_CDB 0x24 | 63 | #define INVALID_FIELD_IN_CDB 0x24 |
64 | #define INVALID_FIELD_IN_PARAM_LIST 0x26 | ||
62 | #define POWERON_RESET 0x29 | 65 | #define POWERON_RESET 0x29 |
63 | #define SAVING_PARAMS_UNSUP 0x39 | 66 | #define SAVING_PARAMS_UNSUP 0x39 |
64 | #define THRESHHOLD_EXCEEDED 0x5d | 67 | #define THRESHOLD_EXCEEDED 0x5d |
68 | #define LOW_POWER_COND_ON 0x5e | ||
65 | 69 | ||
66 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ | 70 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ |
67 | 71 | ||
@@ -80,6 +84,8 @@ static const char * scsi_debug_version_date = "20050113"; | |||
80 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ | 84 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ |
81 | #define DEF_PTYPE 0 | 85 | #define DEF_PTYPE 0 |
82 | #define DEF_D_SENSE 0 | 86 | #define DEF_D_SENSE 0 |
87 | #define DEF_NO_LUN_0 0 | ||
88 | #define DEF_VIRTUAL_GB 0 | ||
83 | 89 | ||
84 | /* bit mask values for scsi_debug_opts */ | 90 | /* bit mask values for scsi_debug_opts */ |
85 | #define SCSI_DEBUG_OPT_NOISE 1 | 91 | #define SCSI_DEBUG_OPT_NOISE 1 |
@@ -106,6 +112,7 @@ static const char * scsi_debug_version_date = "20050113"; | |||
106 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) | 112 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) |
107 | * or "peripheral device" addressing (value 0) */ | 113 | * or "peripheral device" addressing (value 0) */ |
108 | #define SAM2_LUN_ADDRESS_METHOD 0 | 114 | #define SAM2_LUN_ADDRESS_METHOD 0 |
115 | #define SAM2_WLUN_REPORT_LUNS 0xc101 | ||
109 | 116 | ||
110 | static int scsi_debug_add_host = DEF_NUM_HOST; | 117 | static int scsi_debug_add_host = DEF_NUM_HOST; |
111 | static int scsi_debug_delay = DEF_DELAY; | 118 | static int scsi_debug_delay = DEF_DELAY; |
@@ -118,13 +125,16 @@ static int scsi_debug_opts = DEF_OPTS; | |||
118 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; | 125 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; |
119 | static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */ | 126 | static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */ |
120 | static int scsi_debug_dsense = DEF_D_SENSE; | 127 | static int scsi_debug_dsense = DEF_D_SENSE; |
128 | static int scsi_debug_no_lun_0 = DEF_NO_LUN_0; | ||
129 | static int scsi_debug_virtual_gb = DEF_VIRTUAL_GB; | ||
121 | 130 | ||
122 | static int scsi_debug_cmnd_count = 0; | 131 | static int scsi_debug_cmnd_count = 0; |
123 | 132 | ||
124 | #define DEV_READONLY(TGT) (0) | 133 | #define DEV_READONLY(TGT) (0) |
125 | #define DEV_REMOVEABLE(TGT) (0) | 134 | #define DEV_REMOVEABLE(TGT) (0) |
126 | 135 | ||
127 | static unsigned long sdebug_store_size; /* in bytes */ | 136 | static unsigned int sdebug_store_size; /* in bytes */ |
137 | static unsigned int sdebug_store_sectors; | ||
128 | static sector_t sdebug_capacity; /* in sectors */ | 138 | static sector_t sdebug_capacity; /* in sectors */ |
129 | 139 | ||
130 | /* old BIOS stuff, kernel may get rid of them but some mode sense pages | 140 | /* old BIOS stuff, kernel may get rid of them but some mode sense pages |
@@ -149,7 +159,9 @@ struct sdebug_dev_info { | |||
149 | unsigned int target; | 159 | unsigned int target; |
150 | unsigned int lun; | 160 | unsigned int lun; |
151 | struct sdebug_host_info *sdbg_host; | 161 | struct sdebug_host_info *sdbg_host; |
162 | unsigned int wlun; | ||
152 | char reset; | 163 | char reset; |
164 | char stopped; | ||
153 | char used; | 165 | char used; |
154 | }; | 166 | }; |
155 | 167 | ||
@@ -193,11 +205,11 @@ static struct scsi_host_template sdebug_driver_template = { | |||
193 | .bios_param = scsi_debug_biosparam, | 205 | .bios_param = scsi_debug_biosparam, |
194 | .can_queue = SCSI_DEBUG_CANQUEUE, | 206 | .can_queue = SCSI_DEBUG_CANQUEUE, |
195 | .this_id = 7, | 207 | .this_id = 7, |
196 | .sg_tablesize = 64, | 208 | .sg_tablesize = 256, |
197 | .cmd_per_lun = 3, | 209 | .cmd_per_lun = 16, |
198 | .max_sectors = 4096, | 210 | .max_sectors = 0xffff, |
199 | .unchecked_isa_dma = 0, | 211 | .unchecked_isa_dma = 0, |
200 | .use_clustering = DISABLE_CLUSTERING, | 212 | .use_clustering = ENABLE_CLUSTERING, |
201 | .module = THIS_MODULE, | 213 | .module = THIS_MODULE, |
202 | }; | 214 | }; |
203 | 215 | ||
@@ -225,19 +237,32 @@ static struct device_driver sdebug_driverfs_driver = { | |||
225 | static const int check_condition_result = | 237 | static const int check_condition_result = |
226 | (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | 238 | (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; |
227 | 239 | ||
240 | static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | ||
241 | 0, 0, 0x2, 0x4b}; | ||
242 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | ||
243 | 0, 0, 0x0, 0x0}; | ||
244 | |||
228 | /* function declarations */ | 245 | /* function declarations */ |
229 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, | 246 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, |
230 | struct sdebug_dev_info * devip); | 247 | struct sdebug_dev_info * devip); |
231 | static int resp_requests(struct scsi_cmnd * SCpnt, | 248 | static int resp_requests(struct scsi_cmnd * SCpnt, |
232 | struct sdebug_dev_info * devip); | 249 | struct sdebug_dev_info * devip); |
250 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
251 | struct sdebug_dev_info * devip); | ||
233 | static int resp_readcap(struct scsi_cmnd * SCpnt, | 252 | static int resp_readcap(struct scsi_cmnd * SCpnt, |
234 | struct sdebug_dev_info * devip); | 253 | struct sdebug_dev_info * devip); |
235 | static int resp_mode_sense(struct scsi_cmnd * SCpnt, int target, | 254 | static int resp_readcap16(struct scsi_cmnd * SCpnt, |
255 | struct sdebug_dev_info * devip); | ||
256 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | ||
236 | struct sdebug_dev_info * devip); | 257 | struct sdebug_dev_info * devip); |
237 | static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 258 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, |
238 | int num, struct sdebug_dev_info * devip); | 259 | struct sdebug_dev_info * devip); |
239 | static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 260 | static int resp_log_sense(struct scsi_cmnd * scp, |
240 | int num, struct sdebug_dev_info * devip); | 261 | struct sdebug_dev_info * devip); |
262 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
263 | unsigned int num, struct sdebug_dev_info * devip); | ||
264 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
265 | unsigned int num, struct sdebug_dev_info * devip); | ||
241 | static int resp_report_luns(struct scsi_cmnd * SCpnt, | 266 | static int resp_report_luns(struct scsi_cmnd * SCpnt, |
242 | struct sdebug_dev_info * devip); | 267 | struct sdebug_dev_info * devip); |
243 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 268 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, |
@@ -248,8 +273,8 @@ static void timer_intr_handler(unsigned long); | |||
248 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); | 273 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); |
249 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, | 274 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, |
250 | int asc, int asq); | 275 | int asc, int asq); |
251 | static int check_reset(struct scsi_cmnd * SCpnt, | 276 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, |
252 | struct sdebug_dev_info * devip); | 277 | struct sdebug_dev_info * devip); |
253 | static int schedule_resp(struct scsi_cmnd * cmnd, | 278 | static int schedule_resp(struct scsi_cmnd * cmnd, |
254 | struct sdebug_dev_info * devip, | 279 | struct sdebug_dev_info * devip, |
255 | done_funct_t done, int scsi_result, int delta_jiff); | 280 | done_funct_t done, int scsi_result, int delta_jiff); |
@@ -257,8 +282,10 @@ static void __init sdebug_build_parts(unsigned char * ramp); | |||
257 | static void __init init_all_queued(void); | 282 | static void __init init_all_queued(void); |
258 | static void stop_all_queued(void); | 283 | static void stop_all_queued(void); |
259 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); | 284 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); |
260 | static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | 285 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, |
261 | const char * dev_id_str, int dev_id_str_len); | 286 | int dev_id_num, const char * dev_id_str, |
287 | int dev_id_str_len); | ||
288 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); | ||
262 | static void do_create_driverfs_files(void); | 289 | static void do_create_driverfs_files(void); |
263 | static void do_remove_driverfs_files(void); | 290 | static void do_remove_driverfs_files(void); |
264 | 291 | ||
@@ -274,18 +301,22 @@ static | |||
274 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | 301 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) |
275 | { | 302 | { |
276 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | 303 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; |
277 | int block, upper_blk, num, k; | 304 | int len, k, j; |
305 | unsigned int num; | ||
306 | unsigned long long lba; | ||
278 | int errsts = 0; | 307 | int errsts = 0; |
279 | int target = scmd_id(SCpnt); | 308 | int target = SCpnt->device->id; |
280 | struct sdebug_dev_info * devip = NULL; | 309 | struct sdebug_dev_info * devip = NULL; |
281 | int inj_recovered = 0; | 310 | int inj_recovered = 0; |
311 | int delay_override = 0; | ||
282 | 312 | ||
283 | if (done == NULL) | 313 | if (done == NULL) |
284 | return 0; /* assume mid level reprocessing command */ | 314 | return 0; /* assume mid level reprocessing command */ |
285 | 315 | ||
316 | SCpnt->resid = 0; | ||
286 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { | 317 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { |
287 | printk(KERN_INFO "scsi_debug: cmd "); | 318 | printk(KERN_INFO "scsi_debug: cmd "); |
288 | for (k = 0, num = SCpnt->cmd_len; k < num; ++k) | 319 | for (k = 0, len = SCpnt->cmd_len; k < len; ++k) |
289 | printk("%02x ", (int)cmd[k]); | 320 | printk("%02x ", (int)cmd[k]); |
290 | printk("\n"); | 321 | printk("\n"); |
291 | } | 322 | } |
@@ -296,7 +327,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
296 | DID_NO_CONNECT << 16, 0); | 327 | DID_NO_CONNECT << 16, 0); |
297 | } | 328 | } |
298 | 329 | ||
299 | if (SCpnt->device->lun >= scsi_debug_max_luns) | 330 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && |
331 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) | ||
300 | return schedule_resp(SCpnt, NULL, done, | 332 | return schedule_resp(SCpnt, NULL, done, |
301 | DID_NO_CONNECT << 16, 0); | 333 | DID_NO_CONNECT << 16, 0); |
302 | devip = devInfoReg(SCpnt->device); | 334 | devip = devInfoReg(SCpnt->device); |
@@ -315,118 +347,150 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
315 | inj_recovered = 1; /* to reads and writes below */ | 347 | inj_recovered = 1; /* to reads and writes below */ |
316 | } | 348 | } |
317 | 349 | ||
350 | if (devip->wlun) { | ||
351 | switch (*cmd) { | ||
352 | case INQUIRY: | ||
353 | case REQUEST_SENSE: | ||
354 | case TEST_UNIT_READY: | ||
355 | case REPORT_LUNS: | ||
356 | break; /* only allowable wlun commands */ | ||
357 | default: | ||
358 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
359 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " | ||
360 | "not supported for wlun\n", *cmd); | ||
361 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
362 | INVALID_OPCODE, 0); | ||
363 | errsts = check_condition_result; | ||
364 | return schedule_resp(SCpnt, devip, done, errsts, | ||
365 | 0); | ||
366 | } | ||
367 | } | ||
368 | |||
318 | switch (*cmd) { | 369 | switch (*cmd) { |
319 | case INQUIRY: /* mandatory, ignore unit attention */ | 370 | case INQUIRY: /* mandatory, ignore unit attention */ |
371 | delay_override = 1; | ||
320 | errsts = resp_inquiry(SCpnt, target, devip); | 372 | errsts = resp_inquiry(SCpnt, target, devip); |
321 | break; | 373 | break; |
322 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ | 374 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ |
375 | delay_override = 1; | ||
323 | errsts = resp_requests(SCpnt, devip); | 376 | errsts = resp_requests(SCpnt, devip); |
324 | break; | 377 | break; |
325 | case REZERO_UNIT: /* actually this is REWIND for SSC */ | 378 | case REZERO_UNIT: /* actually this is REWIND for SSC */ |
326 | case START_STOP: | 379 | case START_STOP: |
327 | errsts = check_reset(SCpnt, devip); | 380 | errsts = resp_start_stop(SCpnt, devip); |
328 | break; | 381 | break; |
329 | case ALLOW_MEDIUM_REMOVAL: | 382 | case ALLOW_MEDIUM_REMOVAL: |
330 | if ((errsts = check_reset(SCpnt, devip))) | 383 | if ((errsts = check_readiness(SCpnt, 1, devip))) |
331 | break; | 384 | break; |
332 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 385 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
333 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", | 386 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", |
334 | cmd[4] ? "inhibited" : "enabled"); | 387 | cmd[4] ? "inhibited" : "enabled"); |
335 | break; | 388 | break; |
336 | case SEND_DIAGNOSTIC: /* mandatory */ | 389 | case SEND_DIAGNOSTIC: /* mandatory */ |
337 | errsts = check_reset(SCpnt, devip); | 390 | errsts = check_readiness(SCpnt, 1, devip); |
338 | break; | 391 | break; |
339 | case TEST_UNIT_READY: /* mandatory */ | 392 | case TEST_UNIT_READY: /* mandatory */ |
340 | errsts = check_reset(SCpnt, devip); | 393 | delay_override = 1; |
394 | errsts = check_readiness(SCpnt, 0, devip); | ||
341 | break; | 395 | break; |
342 | case RESERVE: | 396 | case RESERVE: |
343 | errsts = check_reset(SCpnt, devip); | 397 | errsts = check_readiness(SCpnt, 1, devip); |
344 | break; | 398 | break; |
345 | case RESERVE_10: | 399 | case RESERVE_10: |
346 | errsts = check_reset(SCpnt, devip); | 400 | errsts = check_readiness(SCpnt, 1, devip); |
347 | break; | 401 | break; |
348 | case RELEASE: | 402 | case RELEASE: |
349 | errsts = check_reset(SCpnt, devip); | 403 | errsts = check_readiness(SCpnt, 1, devip); |
350 | break; | 404 | break; |
351 | case RELEASE_10: | 405 | case RELEASE_10: |
352 | errsts = check_reset(SCpnt, devip); | 406 | errsts = check_readiness(SCpnt, 1, devip); |
353 | break; | 407 | break; |
354 | case READ_CAPACITY: | 408 | case READ_CAPACITY: |
355 | errsts = resp_readcap(SCpnt, devip); | 409 | errsts = resp_readcap(SCpnt, devip); |
356 | break; | 410 | break; |
411 | case SERVICE_ACTION_IN: | ||
412 | if (SAI_READ_CAPACITY_16 != cmd[1]) { | ||
413 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
414 | INVALID_OPCODE, 0); | ||
415 | errsts = check_condition_result; | ||
416 | break; | ||
417 | } | ||
418 | errsts = resp_readcap16(SCpnt, devip); | ||
419 | break; | ||
357 | case READ_16: | 420 | case READ_16: |
358 | case READ_12: | 421 | case READ_12: |
359 | case READ_10: | 422 | case READ_10: |
360 | case READ_6: | 423 | case READ_6: |
361 | if ((errsts = check_reset(SCpnt, devip))) | 424 | if ((errsts = check_readiness(SCpnt, 0, devip))) |
362 | break; | 425 | break; |
363 | upper_blk = 0; | ||
364 | if ((*cmd) == READ_16) { | 426 | if ((*cmd) == READ_16) { |
365 | upper_blk = cmd[5] + (cmd[4] << 8) + | 427 | for (lba = 0, j = 0; j < 8; ++j) { |
366 | (cmd[3] << 16) + (cmd[2] << 24); | 428 | if (j > 0) |
367 | block = cmd[9] + (cmd[8] << 8) + | 429 | lba <<= 8; |
368 | (cmd[7] << 16) + (cmd[6] << 24); | 430 | lba += cmd[2 + j]; |
431 | } | ||
369 | num = cmd[13] + (cmd[12] << 8) + | 432 | num = cmd[13] + (cmd[12] << 8) + |
370 | (cmd[11] << 16) + (cmd[10] << 24); | 433 | (cmd[11] << 16) + (cmd[10] << 24); |
371 | } else if ((*cmd) == READ_12) { | 434 | } else if ((*cmd) == READ_12) { |
372 | block = cmd[5] + (cmd[4] << 8) + | 435 | lba = cmd[5] + (cmd[4] << 8) + |
373 | (cmd[3] << 16) + (cmd[2] << 24); | 436 | (cmd[3] << 16) + (cmd[2] << 24); |
374 | num = cmd[9] + (cmd[8] << 8) + | 437 | num = cmd[9] + (cmd[8] << 8) + |
375 | (cmd[7] << 16) + (cmd[6] << 24); | 438 | (cmd[7] << 16) + (cmd[6] << 24); |
376 | } else if ((*cmd) == READ_10) { | 439 | } else if ((*cmd) == READ_10) { |
377 | block = cmd[5] + (cmd[4] << 8) + | 440 | lba = cmd[5] + (cmd[4] << 8) + |
378 | (cmd[3] << 16) + (cmd[2] << 24); | 441 | (cmd[3] << 16) + (cmd[2] << 24); |
379 | num = cmd[8] + (cmd[7] << 8); | 442 | num = cmd[8] + (cmd[7] << 8); |
380 | } else { | 443 | } else { /* READ (6) */ |
381 | block = cmd[3] + (cmd[2] << 8) + | 444 | lba = cmd[3] + (cmd[2] << 8) + |
382 | ((cmd[1] & 0x1f) << 16); | 445 | ((cmd[1] & 0x1f) << 16); |
383 | num = cmd[4]; | 446 | num = (0 == cmd[4]) ? 256 : cmd[4]; |
384 | } | 447 | } |
385 | errsts = resp_read(SCpnt, upper_blk, block, num, devip); | 448 | errsts = resp_read(SCpnt, lba, num, devip); |
386 | if (inj_recovered && (0 == errsts)) { | 449 | if (inj_recovered && (0 == errsts)) { |
387 | mk_sense_buffer(devip, RECOVERED_ERROR, | 450 | mk_sense_buffer(devip, RECOVERED_ERROR, |
388 | THRESHHOLD_EXCEEDED, 0); | 451 | THRESHOLD_EXCEEDED, 0); |
389 | errsts = check_condition_result; | 452 | errsts = check_condition_result; |
390 | } | 453 | } |
391 | break; | 454 | break; |
392 | case REPORT_LUNS: /* mandatory, ignore unit attention */ | 455 | case REPORT_LUNS: /* mandatory, ignore unit attention */ |
456 | delay_override = 1; | ||
393 | errsts = resp_report_luns(SCpnt, devip); | 457 | errsts = resp_report_luns(SCpnt, devip); |
394 | break; | 458 | break; |
395 | case VERIFY: /* 10 byte SBC-2 command */ | 459 | case VERIFY: /* 10 byte SBC-2 command */ |
396 | errsts = check_reset(SCpnt, devip); | 460 | errsts = check_readiness(SCpnt, 0, devip); |
397 | break; | 461 | break; |
398 | case WRITE_16: | 462 | case WRITE_16: |
399 | case WRITE_12: | 463 | case WRITE_12: |
400 | case WRITE_10: | 464 | case WRITE_10: |
401 | case WRITE_6: | 465 | case WRITE_6: |
402 | if ((errsts = check_reset(SCpnt, devip))) | 466 | if ((errsts = check_readiness(SCpnt, 0, devip))) |
403 | break; | 467 | break; |
404 | upper_blk = 0; | ||
405 | if ((*cmd) == WRITE_16) { | 468 | if ((*cmd) == WRITE_16) { |
406 | upper_blk = cmd[5] + (cmd[4] << 8) + | 469 | for (lba = 0, j = 0; j < 8; ++j) { |
407 | (cmd[3] << 16) + (cmd[2] << 24); | 470 | if (j > 0) |
408 | block = cmd[9] + (cmd[8] << 8) + | 471 | lba <<= 8; |
409 | (cmd[7] << 16) + (cmd[6] << 24); | 472 | lba += cmd[2 + j]; |
473 | } | ||
410 | num = cmd[13] + (cmd[12] << 8) + | 474 | num = cmd[13] + (cmd[12] << 8) + |
411 | (cmd[11] << 16) + (cmd[10] << 24); | 475 | (cmd[11] << 16) + (cmd[10] << 24); |
412 | } else if ((*cmd) == WRITE_12) { | 476 | } else if ((*cmd) == WRITE_12) { |
413 | block = cmd[5] + (cmd[4] << 8) + | 477 | lba = cmd[5] + (cmd[4] << 8) + |
414 | (cmd[3] << 16) + (cmd[2] << 24); | 478 | (cmd[3] << 16) + (cmd[2] << 24); |
415 | num = cmd[9] + (cmd[8] << 8) + | 479 | num = cmd[9] + (cmd[8] << 8) + |
416 | (cmd[7] << 16) + (cmd[6] << 24); | 480 | (cmd[7] << 16) + (cmd[6] << 24); |
417 | } else if ((*cmd) == WRITE_10) { | 481 | } else if ((*cmd) == WRITE_10) { |
418 | block = cmd[5] + (cmd[4] << 8) + | 482 | lba = cmd[5] + (cmd[4] << 8) + |
419 | (cmd[3] << 16) + (cmd[2] << 24); | 483 | (cmd[3] << 16) + (cmd[2] << 24); |
420 | num = cmd[8] + (cmd[7] << 8); | 484 | num = cmd[8] + (cmd[7] << 8); |
421 | } else { | 485 | } else { /* WRITE (6) */ |
422 | block = cmd[3] + (cmd[2] << 8) + | 486 | lba = cmd[3] + (cmd[2] << 8) + |
423 | ((cmd[1] & 0x1f) << 16); | 487 | ((cmd[1] & 0x1f) << 16); |
424 | num = cmd[4]; | 488 | num = (0 == cmd[4]) ? 256 : cmd[4]; |
425 | } | 489 | } |
426 | errsts = resp_write(SCpnt, upper_blk, block, num, devip); | 490 | errsts = resp_write(SCpnt, lba, num, devip); |
427 | if (inj_recovered && (0 == errsts)) { | 491 | if (inj_recovered && (0 == errsts)) { |
428 | mk_sense_buffer(devip, RECOVERED_ERROR, | 492 | mk_sense_buffer(devip, RECOVERED_ERROR, |
429 | THRESHHOLD_EXCEEDED, 0); | 493 | THRESHOLD_EXCEEDED, 0); |
430 | errsts = check_condition_result; | 494 | errsts = check_condition_result; |
431 | } | 495 | } |
432 | break; | 496 | break; |
@@ -434,20 +498,31 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
434 | case MODE_SENSE_10: | 498 | case MODE_SENSE_10: |
435 | errsts = resp_mode_sense(SCpnt, target, devip); | 499 | errsts = resp_mode_sense(SCpnt, target, devip); |
436 | break; | 500 | break; |
501 | case MODE_SELECT: | ||
502 | errsts = resp_mode_select(SCpnt, 1, devip); | ||
503 | break; | ||
504 | case MODE_SELECT_10: | ||
505 | errsts = resp_mode_select(SCpnt, 0, devip); | ||
506 | break; | ||
507 | case LOG_SENSE: | ||
508 | errsts = resp_log_sense(SCpnt, devip); | ||
509 | break; | ||
437 | case SYNCHRONIZE_CACHE: | 510 | case SYNCHRONIZE_CACHE: |
438 | errsts = check_reset(SCpnt, devip); | 511 | delay_override = 1; |
512 | errsts = check_readiness(SCpnt, 0, devip); | ||
439 | break; | 513 | break; |
440 | default: | 514 | default: |
441 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 515 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
442 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | 516 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " |
443 | "supported\n", *cmd); | 517 | "supported\n", *cmd); |
444 | if ((errsts = check_reset(SCpnt, devip))) | 518 | if ((errsts = check_readiness(SCpnt, 1, devip))) |
445 | break; /* Unit attention takes precedence */ | 519 | break; /* Unit attention takes precedence */ |
446 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); | 520 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); |
447 | errsts = check_condition_result; | 521 | errsts = check_condition_result; |
448 | break; | 522 | break; |
449 | } | 523 | } |
450 | return schedule_resp(SCpnt, devip, done, errsts, scsi_debug_delay); | 524 | return schedule_resp(SCpnt, devip, done, errsts, |
525 | (delay_override ? 0 : scsi_debug_delay)); | ||
451 | } | 526 | } |
452 | 527 | ||
453 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | 528 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) |
@@ -459,7 +534,8 @@ static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | |||
459 | /* return -ENOTTY; // correct return but upsets fdisk */ | 534 | /* return -ENOTTY; // correct return but upsets fdisk */ |
460 | } | 535 | } |
461 | 536 | ||
462 | static int check_reset(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip) | 537 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, |
538 | struct sdebug_dev_info * devip) | ||
463 | { | 539 | { |
464 | if (devip->reset) { | 540 | if (devip->reset) { |
465 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 541 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
@@ -469,6 +545,14 @@ static int check_reset(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip) | |||
469 | mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0); | 545 | mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0); |
470 | return check_condition_result; | 546 | return check_condition_result; |
471 | } | 547 | } |
548 | if ((0 == reset_only) && devip->stopped) { | ||
549 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
550 | printk(KERN_INFO "scsi_debug: Reporting Not " | ||
551 | "ready: initializing command required\n"); | ||
552 | mk_sense_buffer(devip, NOT_READY, LOGICAL_UNIT_NOT_READY, | ||
553 | 0x2); | ||
554 | return check_condition_result; | ||
555 | } | ||
472 | return 0; | 556 | return 0; |
473 | } | 557 | } |
474 | 558 | ||
@@ -492,7 +576,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | |||
492 | req_len = scp->request_bufflen; | 576 | req_len = scp->request_bufflen; |
493 | act_len = (req_len < arr_len) ? req_len : arr_len; | 577 | act_len = (req_len < arr_len) ? req_len : arr_len; |
494 | memcpy(scp->request_buffer, arr, act_len); | 578 | memcpy(scp->request_buffer, arr, act_len); |
495 | scp->resid = req_len - act_len; | 579 | if (scp->resid) |
580 | scp->resid -= act_len; | ||
581 | else | ||
582 | scp->resid = req_len - act_len; | ||
496 | return 0; | 583 | return 0; |
497 | } | 584 | } |
498 | sgpnt = (struct scatterlist *)scp->request_buffer; | 585 | sgpnt = (struct scatterlist *)scp->request_buffer; |
@@ -515,7 +602,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | |||
515 | } | 602 | } |
516 | req_len += sgpnt->length; | 603 | req_len += sgpnt->length; |
517 | } | 604 | } |
518 | scp->resid = req_len - act_len; | 605 | if (scp->resid) |
606 | scp->resid -= act_len; | ||
607 | else | ||
608 | scp->resid = req_len - act_len; | ||
519 | return 0; | 609 | return 0; |
520 | } | 610 | } |
521 | 611 | ||
@@ -566,12 +656,14 @@ static const char * inq_vendor_id = "Linux "; | |||
566 | static const char * inq_product_id = "scsi_debug "; | 656 | static const char * inq_product_id = "scsi_debug "; |
567 | static const char * inq_product_rev = "0004"; | 657 | static const char * inq_product_rev = "0004"; |
568 | 658 | ||
569 | static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | 659 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, |
570 | const char * dev_id_str, int dev_id_str_len) | 660 | int dev_id_num, const char * dev_id_str, |
661 | int dev_id_str_len) | ||
571 | { | 662 | { |
572 | int num; | 663 | int num, port_a; |
664 | char b[32]; | ||
573 | 665 | ||
574 | /* Two identification descriptors: */ | 666 | port_a = target_dev_id + 1; |
575 | /* T10 vendor identifier field format (faked) */ | 667 | /* T10 vendor identifier field format (faked) */ |
576 | arr[0] = 0x2; /* ASCII */ | 668 | arr[0] = 0x2; /* ASCII */ |
577 | arr[1] = 0x1; | 669 | arr[1] = 0x1; |
@@ -582,25 +674,246 @@ static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | |||
582 | num = 8 + 16 + dev_id_str_len; | 674 | num = 8 + 16 + dev_id_str_len; |
583 | arr[3] = num; | 675 | arr[3] = num; |
584 | num += 4; | 676 | num += 4; |
585 | /* NAA IEEE registered identifier (faked) */ | 677 | if (dev_id_num >= 0) { |
586 | arr[num] = 0x1; /* binary */ | 678 | /* NAA-5, Logical unit identifier (binary) */ |
587 | arr[num + 1] = 0x3; | 679 | arr[num++] = 0x1; /* binary (not necessarily sas) */ |
588 | arr[num + 2] = 0x0; | 680 | arr[num++] = 0x3; /* PIV=0, lu, naa */ |
589 | arr[num + 3] = 0x8; | 681 | arr[num++] = 0x0; |
590 | arr[num + 4] = 0x51; /* ieee company id=0x123456 (faked) */ | 682 | arr[num++] = 0x8; |
591 | arr[num + 5] = 0x23; | 683 | arr[num++] = 0x53; /* naa-5 ieee company id=0x333333 (fake) */ |
592 | arr[num + 6] = 0x45; | 684 | arr[num++] = 0x33; |
593 | arr[num + 7] = 0x60; | 685 | arr[num++] = 0x33; |
594 | arr[num + 8] = (dev_id_num >> 24); | 686 | arr[num++] = 0x30; |
595 | arr[num + 9] = (dev_id_num >> 16) & 0xff; | 687 | arr[num++] = (dev_id_num >> 24); |
596 | arr[num + 10] = (dev_id_num >> 8) & 0xff; | 688 | arr[num++] = (dev_id_num >> 16) & 0xff; |
597 | arr[num + 11] = dev_id_num & 0xff; | 689 | arr[num++] = (dev_id_num >> 8) & 0xff; |
598 | return num + 12; | 690 | arr[num++] = dev_id_num & 0xff; |
691 | /* Target relative port number */ | ||
692 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
693 | arr[num++] = 0x94; /* PIV=1, target port, rel port */ | ||
694 | arr[num++] = 0x0; /* reserved */ | ||
695 | arr[num++] = 0x4; /* length */ | ||
696 | arr[num++] = 0x0; /* reserved */ | ||
697 | arr[num++] = 0x0; /* reserved */ | ||
698 | arr[num++] = 0x0; | ||
699 | arr[num++] = 0x1; /* relative port A */ | ||
700 | } | ||
701 | /* NAA-5, Target port identifier */ | ||
702 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
703 | arr[num++] = 0x93; /* piv=1, target port, naa */ | ||
704 | arr[num++] = 0x0; | ||
705 | arr[num++] = 0x8; | ||
706 | arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */ | ||
707 | arr[num++] = 0x22; | ||
708 | arr[num++] = 0x22; | ||
709 | arr[num++] = 0x20; | ||
710 | arr[num++] = (port_a >> 24); | ||
711 | arr[num++] = (port_a >> 16) & 0xff; | ||
712 | arr[num++] = (port_a >> 8) & 0xff; | ||
713 | arr[num++] = port_a & 0xff; | ||
714 | /* NAA-5, Target device identifier */ | ||
715 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
716 | arr[num++] = 0xa3; /* piv=1, target device, naa */ | ||
717 | arr[num++] = 0x0; | ||
718 | arr[num++] = 0x8; | ||
719 | arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */ | ||
720 | arr[num++] = 0x22; | ||
721 | arr[num++] = 0x22; | ||
722 | arr[num++] = 0x20; | ||
723 | arr[num++] = (target_dev_id >> 24); | ||
724 | arr[num++] = (target_dev_id >> 16) & 0xff; | ||
725 | arr[num++] = (target_dev_id >> 8) & 0xff; | ||
726 | arr[num++] = target_dev_id & 0xff; | ||
727 | /* SCSI name string: Target device identifier */ | ||
728 | arr[num++] = 0x63; /* proto=sas, UTF-8 */ | ||
729 | arr[num++] = 0xa8; /* piv=1, target device, SCSI name string */ | ||
730 | arr[num++] = 0x0; | ||
731 | arr[num++] = 24; | ||
732 | memcpy(arr + num, "naa.52222220", 12); | ||
733 | num += 12; | ||
734 | snprintf(b, sizeof(b), "%08X", target_dev_id); | ||
735 | memcpy(arr + num, b, 8); | ||
736 | num += 8; | ||
737 | memset(arr + num, 0, 4); | ||
738 | num += 4; | ||
739 | return num; | ||
740 | } | ||
741 | |||
742 | |||
743 | static unsigned char vpd84_data[] = { | ||
744 | /* from 4th byte */ 0x22,0x22,0x22,0x0,0xbb,0x0, | ||
745 | 0x22,0x22,0x22,0x0,0xbb,0x1, | ||
746 | 0x22,0x22,0x22,0x0,0xbb,0x2, | ||
747 | }; | ||
748 | |||
749 | static int inquiry_evpd_84(unsigned char * arr) | ||
750 | { | ||
751 | memcpy(arr, vpd84_data, sizeof(vpd84_data)); | ||
752 | return sizeof(vpd84_data); | ||
753 | } | ||
754 | |||
755 | static int inquiry_evpd_85(unsigned char * arr) | ||
756 | { | ||
757 | int num = 0; | ||
758 | const char * na1 = "https://www.kernel.org/config"; | ||
759 | const char * na2 = "http://www.kernel.org/log"; | ||
760 | int plen, olen; | ||
761 | |||
762 | arr[num++] = 0x1; /* lu, storage config */ | ||
763 | arr[num++] = 0x0; /* reserved */ | ||
764 | arr[num++] = 0x0; | ||
765 | olen = strlen(na1); | ||
766 | plen = olen + 1; | ||
767 | if (plen % 4) | ||
768 | plen = ((plen / 4) + 1) * 4; | ||
769 | arr[num++] = plen; /* length, null termianted, padded */ | ||
770 | memcpy(arr + num, na1, olen); | ||
771 | memset(arr + num + olen, 0, plen - olen); | ||
772 | num += plen; | ||
773 | |||
774 | arr[num++] = 0x4; /* lu, logging */ | ||
775 | arr[num++] = 0x0; /* reserved */ | ||
776 | arr[num++] = 0x0; | ||
777 | olen = strlen(na2); | ||
778 | plen = olen + 1; | ||
779 | if (plen % 4) | ||
780 | plen = ((plen / 4) + 1) * 4; | ||
781 | arr[num++] = plen; /* length, null terminated, padded */ | ||
782 | memcpy(arr + num, na2, olen); | ||
783 | memset(arr + num + olen, 0, plen - olen); | ||
784 | num += plen; | ||
785 | |||
786 | return num; | ||
787 | } | ||
788 | |||
789 | /* SCSI ports VPD page */ | ||
790 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id) | ||
791 | { | ||
792 | int num = 0; | ||
793 | int port_a, port_b; | ||
794 | |||
795 | port_a = target_dev_id + 1; | ||
796 | port_b = port_a + 1; | ||
797 | arr[num++] = 0x0; /* reserved */ | ||
798 | arr[num++] = 0x0; /* reserved */ | ||
799 | arr[num++] = 0x0; | ||
800 | arr[num++] = 0x1; /* relative port 1 (primary) */ | ||
801 | memset(arr + num, 0, 6); | ||
802 | num += 6; | ||
803 | arr[num++] = 0x0; | ||
804 | arr[num++] = 12; /* length tp descriptor */ | ||
805 | /* naa-5 target port identifier (A) */ | ||
806 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
807 | arr[num++] = 0x93; /* PIV=1, target port, NAA */ | ||
808 | arr[num++] = 0x0; /* reserved */ | ||
809 | arr[num++] = 0x8; /* length */ | ||
810 | arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */ | ||
811 | arr[num++] = 0x22; | ||
812 | arr[num++] = 0x22; | ||
813 | arr[num++] = 0x20; | ||
814 | arr[num++] = (port_a >> 24); | ||
815 | arr[num++] = (port_a >> 16) & 0xff; | ||
816 | arr[num++] = (port_a >> 8) & 0xff; | ||
817 | arr[num++] = port_a & 0xff; | ||
818 | |||
819 | arr[num++] = 0x0; /* reserved */ | ||
820 | arr[num++] = 0x0; /* reserved */ | ||
821 | arr[num++] = 0x0; | ||
822 | arr[num++] = 0x2; /* relative port 2 (secondary) */ | ||
823 | memset(arr + num, 0, 6); | ||
824 | num += 6; | ||
825 | arr[num++] = 0x0; | ||
826 | arr[num++] = 12; /* length tp descriptor */ | ||
827 | /* naa-5 target port identifier (B) */ | ||
828 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
829 | arr[num++] = 0x93; /* PIV=1, target port, NAA */ | ||
830 | arr[num++] = 0x0; /* reserved */ | ||
831 | arr[num++] = 0x8; /* length */ | ||
832 | arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */ | ||
833 | arr[num++] = 0x22; | ||
834 | arr[num++] = 0x22; | ||
835 | arr[num++] = 0x20; | ||
836 | arr[num++] = (port_b >> 24); | ||
837 | arr[num++] = (port_b >> 16) & 0xff; | ||
838 | arr[num++] = (port_b >> 8) & 0xff; | ||
839 | arr[num++] = port_b & 0xff; | ||
840 | |||
841 | return num; | ||
842 | } | ||
843 | |||
844 | |||
845 | static unsigned char vpd89_data[] = { | ||
846 | /* from 4th byte */ 0,0,0,0, | ||
847 | 'l','i','n','u','x',' ',' ',' ', | ||
848 | 'S','A','T',' ','s','c','s','i','_','d','e','b','u','g',' ',' ', | ||
849 | '1','2','3','4', | ||
850 | 0x34,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, | ||
851 | 0xec,0,0,0, | ||
852 | 0x5a,0xc,0xff,0x3f,0x37,0xc8,0x10,0,0,0,0,0,0x3f,0,0,0, | ||
853 | 0,0,0,0,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x20,0x20,0x20,0x20, | ||
854 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0,0,0,0x40,0x4,0,0x2e,0x33, | ||
855 | 0x38,0x31,0x20,0x20,0x20,0x20,0x54,0x53,0x38,0x33,0x30,0x30,0x33,0x31, | ||
856 | 0x53,0x41, | ||
857 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | ||
858 | 0x20,0x20, | ||
859 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | ||
860 | 0x10,0x80, | ||
861 | 0,0,0,0x2f,0,0,0,0x2,0,0x2,0x7,0,0xff,0xff,0x1,0, | ||
862 | 0x3f,0,0xc1,0xff,0x3e,0,0x10,0x1,0xb0,0xf8,0x50,0x9,0,0,0x7,0, | ||
863 | 0x3,0,0x78,0,0x78,0,0xf0,0,0x78,0,0,0,0,0,0,0, | ||
864 | 0,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0,0, | ||
865 | 0x7e,0,0x1b,0,0x6b,0x34,0x1,0x7d,0x3,0x40,0x69,0x34,0x1,0x3c,0x3,0x40, | ||
866 | 0x7f,0x40,0,0,0,0,0xfe,0xfe,0,0,0,0,0,0xfe,0,0, | ||
867 | 0,0,0,0,0,0,0,0,0xb0,0xf8,0x50,0x9,0,0,0,0, | ||
868 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
869 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
870 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
871 | 0x1,0,0xb0,0xf8,0x50,0x9,0xb0,0xf8,0x50,0x9,0x20,0x20,0x2,0,0xb6,0x42, | ||
872 | 0,0x80,0x8a,0,0x6,0x3c,0xa,0x3c,0xff,0xff,0xc6,0x7,0,0x1,0,0x8, | ||
873 | 0xf0,0xf,0,0x10,0x2,0,0x30,0,0,0,0,0,0,0,0x6,0xfe, | ||
874 | 0,0,0x2,0,0x50,0,0x8a,0,0x4f,0x95,0,0,0x21,0,0xb,0, | ||
875 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
876 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
877 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
878 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
879 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
880 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
881 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
882 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
883 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
884 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
885 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
886 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa5,0x51, | ||
887 | }; | ||
888 | |||
889 | static int inquiry_evpd_89(unsigned char * arr) | ||
890 | { | ||
891 | memcpy(arr, vpd89_data, sizeof(vpd89_data)); | ||
892 | return sizeof(vpd89_data); | ||
893 | } | ||
894 | |||
895 | |||
896 | static unsigned char vpdb0_data[] = { | ||
897 | /* from 4th byte */ 0,0,0,4, | ||
898 | 0,0,0x4,0, | ||
899 | 0,0,0,64, | ||
900 | }; | ||
901 | |||
902 | static int inquiry_evpd_b0(unsigned char * arr) | ||
903 | { | ||
904 | memcpy(arr, vpdb0_data, sizeof(vpdb0_data)); | ||
905 | if (sdebug_store_sectors > 0x400) { | ||
906 | arr[4] = (sdebug_store_sectors >> 24) & 0xff; | ||
907 | arr[5] = (sdebug_store_sectors >> 16) & 0xff; | ||
908 | arr[6] = (sdebug_store_sectors >> 8) & 0xff; | ||
909 | arr[7] = sdebug_store_sectors & 0xff; | ||
910 | } | ||
911 | return sizeof(vpdb0_data); | ||
599 | } | 912 | } |
600 | 913 | ||
601 | 914 | ||
602 | #define SDEBUG_LONG_INQ_SZ 96 | 915 | #define SDEBUG_LONG_INQ_SZ 96 |
603 | #define SDEBUG_MAX_INQ_ARR_SZ 128 | 916 | #define SDEBUG_MAX_INQ_ARR_SZ 584 |
604 | 917 | ||
605 | static int resp_inquiry(struct scsi_cmnd * scp, int target, | 918 | static int resp_inquiry(struct scsi_cmnd * scp, int target, |
606 | struct sdebug_dev_info * devip) | 919 | struct sdebug_dev_info * devip) |
@@ -608,64 +921,113 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
608 | unsigned char pq_pdt; | 921 | unsigned char pq_pdt; |
609 | unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; | 922 | unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; |
610 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 923 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
611 | int alloc_len; | 924 | int alloc_len, n; |
612 | 925 | ||
613 | alloc_len = (cmd[3] << 8) + cmd[4]; | 926 | alloc_len = (cmd[3] << 8) + cmd[4]; |
614 | memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); | 927 | memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); |
615 | pq_pdt = (scsi_debug_ptype & 0x1f); | 928 | if (devip->wlun) |
929 | pq_pdt = 0x1e; /* present, wlun */ | ||
930 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) | ||
931 | pq_pdt = 0x7f; /* not present, no device type */ | ||
932 | else | ||
933 | pq_pdt = (scsi_debug_ptype & 0x1f); | ||
616 | arr[0] = pq_pdt; | 934 | arr[0] = pq_pdt; |
617 | if (0x2 & cmd[1]) { /* CMDDT bit set */ | 935 | if (0x2 & cmd[1]) { /* CMDDT bit set */ |
618 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 936 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
619 | 0); | 937 | 0); |
620 | return check_condition_result; | 938 | return check_condition_result; |
621 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ | 939 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ |
622 | int dev_id_num, len; | 940 | int lu_id_num, target_dev_id, len; |
623 | char dev_id_str[6]; | 941 | char lu_id_str[6]; |
942 | int host_no = devip->sdbg_host->shost->host_no; | ||
624 | 943 | ||
625 | dev_id_num = ((devip->sdbg_host->shost->host_no + 1) * 2000) + | 944 | lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) + |
626 | (devip->target * 1000) + devip->lun; | 945 | (devip->target * 1000) + devip->lun); |
627 | len = scnprintf(dev_id_str, 6, "%d", dev_id_num); | 946 | target_dev_id = ((host_no + 1) * 2000) + |
947 | (devip->target * 1000) - 3; | ||
948 | len = scnprintf(lu_id_str, 6, "%d", lu_id_num); | ||
628 | if (0 == cmd[2]) { /* supported vital product data pages */ | 949 | if (0 == cmd[2]) { /* supported vital product data pages */ |
629 | arr[3] = 3; | 950 | arr[1] = cmd[2]; /*sanity */ |
630 | arr[4] = 0x0; /* this page */ | 951 | n = 4; |
631 | arr[5] = 0x80; /* unit serial number */ | 952 | arr[n++] = 0x0; /* this page */ |
632 | arr[6] = 0x83; /* device identification */ | 953 | arr[n++] = 0x80; /* unit serial number */ |
954 | arr[n++] = 0x83; /* device identification */ | ||
955 | arr[n++] = 0x84; /* software interface ident. */ | ||
956 | arr[n++] = 0x85; /* management network addresses */ | ||
957 | arr[n++] = 0x86; /* extended inquiry */ | ||
958 | arr[n++] = 0x87; /* mode page policy */ | ||
959 | arr[n++] = 0x88; /* SCSI ports */ | ||
960 | arr[n++] = 0x89; /* ATA information */ | ||
961 | arr[n++] = 0xb0; /* Block limits (SBC) */ | ||
962 | arr[3] = n - 4; /* number of supported VPD pages */ | ||
633 | } else if (0x80 == cmd[2]) { /* unit serial number */ | 963 | } else if (0x80 == cmd[2]) { /* unit serial number */ |
634 | arr[1] = 0x80; | 964 | arr[1] = cmd[2]; /*sanity */ |
635 | arr[3] = len; | 965 | arr[3] = len; |
636 | memcpy(&arr[4], dev_id_str, len); | 966 | memcpy(&arr[4], lu_id_str, len); |
637 | } else if (0x83 == cmd[2]) { /* device identification */ | 967 | } else if (0x83 == cmd[2]) { /* device identification */ |
638 | arr[1] = 0x83; | 968 | arr[1] = cmd[2]; /*sanity */ |
639 | arr[3] = inquiry_evpd_83(&arr[4], dev_id_num, | 969 | arr[3] = inquiry_evpd_83(&arr[4], target_dev_id, |
640 | dev_id_str, len); | 970 | lu_id_num, lu_id_str, len); |
971 | } else if (0x84 == cmd[2]) { /* Software interface ident. */ | ||
972 | arr[1] = cmd[2]; /*sanity */ | ||
973 | arr[3] = inquiry_evpd_84(&arr[4]); | ||
974 | } else if (0x85 == cmd[2]) { /* Management network addresses */ | ||
975 | arr[1] = cmd[2]; /*sanity */ | ||
976 | arr[3] = inquiry_evpd_85(&arr[4]); | ||
977 | } else if (0x86 == cmd[2]) { /* extended inquiry */ | ||
978 | arr[1] = cmd[2]; /*sanity */ | ||
979 | arr[3] = 0x3c; /* number of following entries */ | ||
980 | arr[4] = 0x0; /* no protection stuff */ | ||
981 | arr[5] = 0x7; /* head of q, ordered + simple q's */ | ||
982 | } else if (0x87 == cmd[2]) { /* mode page policy */ | ||
983 | arr[1] = cmd[2]; /*sanity */ | ||
984 | arr[3] = 0x8; /* number of following entries */ | ||
985 | arr[4] = 0x2; /* disconnect-reconnect mp */ | ||
986 | arr[6] = 0x80; /* mlus, shared */ | ||
987 | arr[8] = 0x18; /* protocol specific lu */ | ||
988 | arr[10] = 0x82; /* mlus, per initiator port */ | ||
989 | } else if (0x88 == cmd[2]) { /* SCSI Ports */ | ||
990 | arr[1] = cmd[2]; /*sanity */ | ||
991 | arr[3] = inquiry_evpd_88(&arr[4], target_dev_id); | ||
992 | } else if (0x89 == cmd[2]) { /* ATA information */ | ||
993 | arr[1] = cmd[2]; /*sanity */ | ||
994 | n = inquiry_evpd_89(&arr[4]); | ||
995 | arr[2] = (n >> 8); | ||
996 | arr[3] = (n & 0xff); | ||
997 | } else if (0xb0 == cmd[2]) { /* Block limits (SBC) */ | ||
998 | arr[1] = cmd[2]; /*sanity */ | ||
999 | arr[3] = inquiry_evpd_b0(&arr[4]); | ||
641 | } else { | 1000 | } else { |
642 | /* Illegal request, invalid field in cdb */ | 1001 | /* Illegal request, invalid field in cdb */ |
643 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1002 | mk_sense_buffer(devip, ILLEGAL_REQUEST, |
644 | INVALID_FIELD_IN_CDB, 0); | 1003 | INVALID_FIELD_IN_CDB, 0); |
645 | return check_condition_result; | 1004 | return check_condition_result; |
646 | } | 1005 | } |
1006 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); | ||
647 | return fill_from_dev_buffer(scp, arr, | 1007 | return fill_from_dev_buffer(scp, arr, |
648 | min(alloc_len, SDEBUG_MAX_INQ_ARR_SZ)); | 1008 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); |
649 | } | 1009 | } |
650 | /* drops through here for a standard inquiry */ | 1010 | /* drops through here for a standard inquiry */ |
651 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ | 1011 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ |
652 | arr[2] = scsi_debug_scsi_level; | 1012 | arr[2] = scsi_debug_scsi_level; |
653 | arr[3] = 2; /* response_data_format==2 */ | 1013 | arr[3] = 2; /* response_data_format==2 */ |
654 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; | 1014 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; |
655 | arr[6] = 0x1; /* claim: ADDR16 */ | 1015 | arr[6] = 0x10; /* claim: MultiP */ |
656 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ | 1016 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ |
657 | arr[7] = 0x3a; /* claim: WBUS16, SYNC, LINKED + CMDQUE */ | 1017 | arr[7] = 0xa; /* claim: LINKED + CMDQUE */ |
658 | memcpy(&arr[8], inq_vendor_id, 8); | 1018 | memcpy(&arr[8], inq_vendor_id, 8); |
659 | memcpy(&arr[16], inq_product_id, 16); | 1019 | memcpy(&arr[16], inq_product_id, 16); |
660 | memcpy(&arr[32], inq_product_rev, 4); | 1020 | memcpy(&arr[32], inq_product_rev, 4); |
661 | /* version descriptors (2 bytes each) follow */ | 1021 | /* version descriptors (2 bytes each) follow */ |
662 | arr[58] = 0x0; arr[59] = 0x40; /* SAM-2 */ | 1022 | arr[58] = 0x0; arr[59] = 0x77; /* SAM-3 ANSI */ |
663 | arr[60] = 0x3; arr[61] = 0x0; /* SPC-3 */ | 1023 | arr[60] = 0x3; arr[61] = 0x14; /* SPC-3 ANSI */ |
1024 | n = 62; | ||
664 | if (scsi_debug_ptype == 0) { | 1025 | if (scsi_debug_ptype == 0) { |
665 | arr[62] = 0x1; arr[63] = 0x80; /* SBC */ | 1026 | arr[n++] = 0x3; arr[n++] = 0x3d; /* SBC-2 ANSI */ |
666 | } else if (scsi_debug_ptype == 1) { | 1027 | } else if (scsi_debug_ptype == 1) { |
667 | arr[62] = 0x2; arr[63] = 0x00; /* SSC */ | 1028 | arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */ |
668 | } | 1029 | } |
1030 | arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */ | ||
669 | return fill_from_dev_buffer(scp, arr, | 1031 | return fill_from_dev_buffer(scp, arr, |
670 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); | 1032 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); |
671 | } | 1033 | } |
@@ -676,46 +1038,141 @@ static int resp_requests(struct scsi_cmnd * scp, | |||
676 | unsigned char * sbuff; | 1038 | unsigned char * sbuff; |
677 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1039 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
678 | unsigned char arr[SDEBUG_SENSE_LEN]; | 1040 | unsigned char arr[SDEBUG_SENSE_LEN]; |
1041 | int want_dsense; | ||
679 | int len = 18; | 1042 | int len = 18; |
680 | 1043 | ||
681 | memset(arr, 0, SDEBUG_SENSE_LEN); | 1044 | memset(arr, 0, sizeof(arr)); |
682 | if (devip->reset == 1) | 1045 | if (devip->reset == 1) |
683 | mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0); | 1046 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); |
1047 | want_dsense = !!(cmd[1] & 1) || scsi_debug_dsense; | ||
684 | sbuff = devip->sense_buff; | 1048 | sbuff = devip->sense_buff; |
685 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { | 1049 | if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { |
686 | /* DESC bit set and sense_buff in fixed format */ | 1050 | if (want_dsense) { |
687 | arr[0] = 0x72; | 1051 | arr[0] = 0x72; |
688 | arr[1] = sbuff[2]; /* sense key */ | 1052 | arr[1] = 0x0; /* NO_SENSE in sense_key */ |
689 | arr[2] = sbuff[12]; /* asc */ | 1053 | arr[2] = THRESHOLD_EXCEEDED; |
690 | arr[3] = sbuff[13]; /* ascq */ | 1054 | arr[3] = 0xff; /* TEST set and MRIE==6 */ |
691 | len = 8; | 1055 | } else { |
692 | } else | 1056 | arr[0] = 0x70; |
1057 | arr[2] = 0x0; /* NO_SENSE in sense_key */ | ||
1058 | arr[7] = 0xa; /* 18 byte sense buffer */ | ||
1059 | arr[12] = THRESHOLD_EXCEEDED; | ||
1060 | arr[13] = 0xff; /* TEST set and MRIE==6 */ | ||
1061 | } | ||
1062 | } else if (devip->stopped) { | ||
1063 | if (want_dsense) { | ||
1064 | arr[0] = 0x72; | ||
1065 | arr[1] = 0x0; /* NO_SENSE in sense_key */ | ||
1066 | arr[2] = LOW_POWER_COND_ON; | ||
1067 | arr[3] = 0x0; /* TEST set and MRIE==6 */ | ||
1068 | } else { | ||
1069 | arr[0] = 0x70; | ||
1070 | arr[2] = 0x0; /* NO_SENSE in sense_key */ | ||
1071 | arr[7] = 0xa; /* 18 byte sense buffer */ | ||
1072 | arr[12] = LOW_POWER_COND_ON; | ||
1073 | arr[13] = 0x0; /* TEST set and MRIE==6 */ | ||
1074 | } | ||
1075 | } else { | ||
693 | memcpy(arr, sbuff, SDEBUG_SENSE_LEN); | 1076 | memcpy(arr, sbuff, SDEBUG_SENSE_LEN); |
694 | mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0); | 1077 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { |
1078 | /* DESC bit set and sense_buff in fixed format */ | ||
1079 | memset(arr, 0, sizeof(arr)); | ||
1080 | arr[0] = 0x72; | ||
1081 | arr[1] = sbuff[2]; /* sense key */ | ||
1082 | arr[2] = sbuff[12]; /* asc */ | ||
1083 | arr[3] = sbuff[13]; /* ascq */ | ||
1084 | len = 8; | ||
1085 | } | ||
1086 | } | ||
1087 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); | ||
695 | return fill_from_dev_buffer(scp, arr, len); | 1088 | return fill_from_dev_buffer(scp, arr, len); |
696 | } | 1089 | } |
697 | 1090 | ||
1091 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
1092 | struct sdebug_dev_info * devip) | ||
1093 | { | ||
1094 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1095 | int power_cond, errsts, start; | ||
1096 | |||
1097 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1098 | return errsts; | ||
1099 | power_cond = (cmd[4] & 0xf0) >> 4; | ||
1100 | if (power_cond) { | ||
1101 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1102 | 0); | ||
1103 | return check_condition_result; | ||
1104 | } | ||
1105 | start = cmd[4] & 1; | ||
1106 | if (start == devip->stopped) | ||
1107 | devip->stopped = !start; | ||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
698 | #define SDEBUG_READCAP_ARR_SZ 8 | 1111 | #define SDEBUG_READCAP_ARR_SZ 8 |
699 | static int resp_readcap(struct scsi_cmnd * scp, | 1112 | static int resp_readcap(struct scsi_cmnd * scp, |
700 | struct sdebug_dev_info * devip) | 1113 | struct sdebug_dev_info * devip) |
701 | { | 1114 | { |
702 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; | 1115 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; |
703 | unsigned long capac; | 1116 | unsigned int capac; |
704 | int errsts; | 1117 | int errsts; |
705 | 1118 | ||
706 | if ((errsts = check_reset(scp, devip))) | 1119 | if ((errsts = check_readiness(scp, 1, devip))) |
707 | return errsts; | 1120 | return errsts; |
1121 | /* following just in case virtual_gb changed */ | ||
1122 | if (scsi_debug_virtual_gb > 0) { | ||
1123 | sdebug_capacity = 2048 * 1024; | ||
1124 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1125 | } else | ||
1126 | sdebug_capacity = sdebug_store_sectors; | ||
708 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); | 1127 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); |
709 | capac = (unsigned long)sdebug_capacity - 1; | 1128 | if (sdebug_capacity < 0xffffffff) { |
710 | arr[0] = (capac >> 24); | 1129 | capac = (unsigned int)sdebug_capacity - 1; |
711 | arr[1] = (capac >> 16) & 0xff; | 1130 | arr[0] = (capac >> 24); |
712 | arr[2] = (capac >> 8) & 0xff; | 1131 | arr[1] = (capac >> 16) & 0xff; |
713 | arr[3] = capac & 0xff; | 1132 | arr[2] = (capac >> 8) & 0xff; |
1133 | arr[3] = capac & 0xff; | ||
1134 | } else { | ||
1135 | arr[0] = 0xff; | ||
1136 | arr[1] = 0xff; | ||
1137 | arr[2] = 0xff; | ||
1138 | arr[3] = 0xff; | ||
1139 | } | ||
714 | arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; | 1140 | arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; |
715 | arr[7] = SECT_SIZE_PER(target) & 0xff; | 1141 | arr[7] = SECT_SIZE_PER(target) & 0xff; |
716 | return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ); | 1142 | return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ); |
717 | } | 1143 | } |
718 | 1144 | ||
1145 | #define SDEBUG_READCAP16_ARR_SZ 32 | ||
1146 | static int resp_readcap16(struct scsi_cmnd * scp, | ||
1147 | struct sdebug_dev_info * devip) | ||
1148 | { | ||
1149 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1150 | unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; | ||
1151 | unsigned long long capac; | ||
1152 | int errsts, k, alloc_len; | ||
1153 | |||
1154 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1155 | return errsts; | ||
1156 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) | ||
1157 | + cmd[13]); | ||
1158 | /* following just in case virtual_gb changed */ | ||
1159 | if (scsi_debug_virtual_gb > 0) { | ||
1160 | sdebug_capacity = 2048 * 1024; | ||
1161 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1162 | } else | ||
1163 | sdebug_capacity = sdebug_store_sectors; | ||
1164 | memset(arr, 0, SDEBUG_READCAP16_ARR_SZ); | ||
1165 | capac = sdebug_capacity - 1; | ||
1166 | for (k = 0; k < 8; ++k, capac >>= 8) | ||
1167 | arr[7 - k] = capac & 0xff; | ||
1168 | arr[8] = (SECT_SIZE_PER(target) >> 24) & 0xff; | ||
1169 | arr[9] = (SECT_SIZE_PER(target) >> 16) & 0xff; | ||
1170 | arr[10] = (SECT_SIZE_PER(target) >> 8) & 0xff; | ||
1171 | arr[11] = SECT_SIZE_PER(target) & 0xff; | ||
1172 | return fill_from_dev_buffer(scp, arr, | ||
1173 | min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); | ||
1174 | } | ||
1175 | |||
719 | /* <<Following mode page info copied from ST318451LW>> */ | 1176 | /* <<Following mode page info copied from ST318451LW>> */ |
720 | 1177 | ||
721 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) | 1178 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) |
@@ -771,27 +1228,98 @@ static int resp_caching_pg(unsigned char * p, int pcontrol, int target) | |||
771 | 1228 | ||
772 | static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) | 1229 | static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) |
773 | { /* Control mode page for mode_sense */ | 1230 | { /* Control mode page for mode_sense */ |
774 | unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | 1231 | unsigned char ch_ctrl_m_pg[] = {/* 0xa, 10, */ 0x6, 0, 0, 0, 0, 0, |
1232 | 0, 0, 0, 0}; | ||
1233 | unsigned char d_ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | ||
775 | 0, 0, 0x2, 0x4b}; | 1234 | 0, 0, 0x2, 0x4b}; |
776 | 1235 | ||
777 | if (scsi_debug_dsense) | 1236 | if (scsi_debug_dsense) |
778 | ctrl_m_pg[2] |= 0x4; | 1237 | ctrl_m_pg[2] |= 0x4; |
1238 | else | ||
1239 | ctrl_m_pg[2] &= ~0x4; | ||
779 | memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); | 1240 | memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); |
780 | if (1 == pcontrol) | 1241 | if (1 == pcontrol) |
781 | memset(p + 2, 0, sizeof(ctrl_m_pg) - 2); | 1242 | memcpy(p + 2, ch_ctrl_m_pg, sizeof(ch_ctrl_m_pg)); |
1243 | else if (2 == pcontrol) | ||
1244 | memcpy(p, d_ctrl_m_pg, sizeof(d_ctrl_m_pg)); | ||
782 | return sizeof(ctrl_m_pg); | 1245 | return sizeof(ctrl_m_pg); |
783 | } | 1246 | } |
784 | 1247 | ||
1248 | |||
785 | static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) | 1249 | static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) |
786 | { /* Informational Exceptions control mode page for mode_sense */ | 1250 | { /* Informational Exceptions control mode page for mode_sense */ |
787 | unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | 1251 | unsigned char ch_iec_m_pg[] = {/* 0x1c, 0xa, */ 0x4, 0xf, 0, 0, 0, 0, |
788 | 0, 0, 0x0, 0x0}; | 1252 | 0, 0, 0x0, 0x0}; |
1253 | unsigned char d_iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | ||
1254 | 0, 0, 0x0, 0x0}; | ||
1255 | |||
789 | memcpy(p, iec_m_pg, sizeof(iec_m_pg)); | 1256 | memcpy(p, iec_m_pg, sizeof(iec_m_pg)); |
790 | if (1 == pcontrol) | 1257 | if (1 == pcontrol) |
791 | memset(p + 2, 0, sizeof(iec_m_pg) - 2); | 1258 | memcpy(p + 2, ch_iec_m_pg, sizeof(ch_iec_m_pg)); |
1259 | else if (2 == pcontrol) | ||
1260 | memcpy(p, d_iec_m_pg, sizeof(d_iec_m_pg)); | ||
792 | return sizeof(iec_m_pg); | 1261 | return sizeof(iec_m_pg); |
793 | } | 1262 | } |
794 | 1263 | ||
1264 | static int resp_sas_sf_m_pg(unsigned char * p, int pcontrol, int target) | ||
1265 | { /* SAS SSP mode page - short format for mode_sense */ | ||
1266 | unsigned char sas_sf_m_pg[] = {0x19, 0x6, | ||
1267 | 0x6, 0x0, 0x7, 0xd0, 0x0, 0x0}; | ||
1268 | |||
1269 | memcpy(p, sas_sf_m_pg, sizeof(sas_sf_m_pg)); | ||
1270 | if (1 == pcontrol) | ||
1271 | memset(p + 2, 0, sizeof(sas_sf_m_pg) - 2); | ||
1272 | return sizeof(sas_sf_m_pg); | ||
1273 | } | ||
1274 | |||
1275 | |||
1276 | static int resp_sas_pcd_m_spg(unsigned char * p, int pcontrol, int target, | ||
1277 | int target_dev_id) | ||
1278 | { /* SAS phy control and discover mode page for mode_sense */ | ||
1279 | unsigned char sas_pcd_m_pg[] = {0x59, 0x1, 0, 0x64, 0, 0x6, 0, 2, | ||
1280 | 0, 0, 0, 0, 0x10, 0x9, 0x8, 0x0, | ||
1281 | 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0, | ||
1282 | 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1, | ||
1283 | 0x2, 0, 0, 0, 0, 0, 0, 0, | ||
1284 | 0x88, 0x99, 0, 0, 0, 0, 0, 0, | ||
1285 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
1286 | 0, 1, 0, 0, 0x10, 0x9, 0x8, 0x0, | ||
1287 | 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0, | ||
1288 | 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1, | ||
1289 | 0x3, 0, 0, 0, 0, 0, 0, 0, | ||
1290 | 0x88, 0x99, 0, 0, 0, 0, 0, 0, | ||
1291 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
1292 | }; | ||
1293 | int port_a, port_b; | ||
1294 | |||
1295 | port_a = target_dev_id + 1; | ||
1296 | port_b = port_a + 1; | ||
1297 | memcpy(p, sas_pcd_m_pg, sizeof(sas_pcd_m_pg)); | ||
1298 | p[20] = (port_a >> 24); | ||
1299 | p[21] = (port_a >> 16) & 0xff; | ||
1300 | p[22] = (port_a >> 8) & 0xff; | ||
1301 | p[23] = port_a & 0xff; | ||
1302 | p[48 + 20] = (port_b >> 24); | ||
1303 | p[48 + 21] = (port_b >> 16) & 0xff; | ||
1304 | p[48 + 22] = (port_b >> 8) & 0xff; | ||
1305 | p[48 + 23] = port_b & 0xff; | ||
1306 | if (1 == pcontrol) | ||
1307 | memset(p + 4, 0, sizeof(sas_pcd_m_pg) - 4); | ||
1308 | return sizeof(sas_pcd_m_pg); | ||
1309 | } | ||
1310 | |||
1311 | static int resp_sas_sha_m_spg(unsigned char * p, int pcontrol) | ||
1312 | { /* SAS SSP shared protocol specific port mode subpage */ | ||
1313 | unsigned char sas_sha_m_pg[] = {0x59, 0x2, 0, 0xc, 0, 0x6, 0x10, 0, | ||
1314 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
1315 | }; | ||
1316 | |||
1317 | memcpy(p, sas_sha_m_pg, sizeof(sas_sha_m_pg)); | ||
1318 | if (1 == pcontrol) | ||
1319 | memset(p + 4, 0, sizeof(sas_sha_m_pg) - 4); | ||
1320 | return sizeof(sas_sha_m_pg); | ||
1321 | } | ||
1322 | |||
795 | #define SDEBUG_MAX_MSENSE_SZ 256 | 1323 | #define SDEBUG_MAX_MSENSE_SZ 256 |
796 | 1324 | ||
797 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | 1325 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, |
@@ -800,12 +1328,12 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
800 | unsigned char dbd; | 1328 | unsigned char dbd; |
801 | int pcontrol, pcode, subpcode; | 1329 | int pcontrol, pcode, subpcode; |
802 | unsigned char dev_spec; | 1330 | unsigned char dev_spec; |
803 | int alloc_len, msense_6, offset, len, errsts; | 1331 | int alloc_len, msense_6, offset, len, errsts, target_dev_id; |
804 | unsigned char * ap; | 1332 | unsigned char * ap; |
805 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; | 1333 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; |
806 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1334 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
807 | 1335 | ||
808 | if ((errsts = check_reset(scp, devip))) | 1336 | if ((errsts = check_readiness(scp, 1, devip))) |
809 | return errsts; | 1337 | return errsts; |
810 | dbd = cmd[1] & 0x8; | 1338 | dbd = cmd[1] & 0x8; |
811 | pcontrol = (cmd[2] & 0xc0) >> 6; | 1339 | pcontrol = (cmd[2] & 0xc0) >> 6; |
@@ -819,6 +1347,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
819 | 0); | 1347 | 0); |
820 | return check_condition_result; | 1348 | return check_condition_result; |
821 | } | 1349 | } |
1350 | target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) + | ||
1351 | (devip->target * 1000) - 3; | ||
822 | dev_spec = DEV_READONLY(target) ? 0x80 : 0x0; | 1352 | dev_spec = DEV_READONLY(target) ? 0x80 : 0x0; |
823 | if (msense_6) { | 1353 | if (msense_6) { |
824 | arr[2] = dev_spec; | 1354 | arr[2] = dev_spec; |
@@ -829,7 +1359,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
829 | } | 1359 | } |
830 | ap = arr + offset; | 1360 | ap = arr + offset; |
831 | 1361 | ||
832 | if (0 != subpcode) { /* TODO: Control Extension page */ | 1362 | if ((subpcode > 0x0) && (subpcode < 0xff) && (0x19 != pcode)) { |
1363 | /* TODO: Control Extension page */ | ||
833 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1364 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
834 | 0); | 1365 | 0); |
835 | return check_condition_result; | 1366 | return check_condition_result; |
@@ -855,17 +1386,45 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
855 | len = resp_ctrl_m_pg(ap, pcontrol, target); | 1386 | len = resp_ctrl_m_pg(ap, pcontrol, target); |
856 | offset += len; | 1387 | offset += len; |
857 | break; | 1388 | break; |
1389 | case 0x19: /* if spc==1 then sas phy, control+discover */ | ||
1390 | if ((subpcode > 0x2) && (subpcode < 0xff)) { | ||
1391 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1392 | INVALID_FIELD_IN_CDB, 0); | ||
1393 | return check_condition_result; | ||
1394 | } | ||
1395 | len = 0; | ||
1396 | if ((0x0 == subpcode) || (0xff == subpcode)) | ||
1397 | len += resp_sas_sf_m_pg(ap + len, pcontrol, target); | ||
1398 | if ((0x1 == subpcode) || (0xff == subpcode)) | ||
1399 | len += resp_sas_pcd_m_spg(ap + len, pcontrol, target, | ||
1400 | target_dev_id); | ||
1401 | if ((0x2 == subpcode) || (0xff == subpcode)) | ||
1402 | len += resp_sas_sha_m_spg(ap + len, pcontrol); | ||
1403 | offset += len; | ||
1404 | break; | ||
858 | case 0x1c: /* Informational Exceptions Mode page, all devices */ | 1405 | case 0x1c: /* Informational Exceptions Mode page, all devices */ |
859 | len = resp_iec_m_pg(ap, pcontrol, target); | 1406 | len = resp_iec_m_pg(ap, pcontrol, target); |
860 | offset += len; | 1407 | offset += len; |
861 | break; | 1408 | break; |
862 | case 0x3f: /* Read all Mode pages */ | 1409 | case 0x3f: /* Read all Mode pages */ |
863 | len = resp_err_recov_pg(ap, pcontrol, target); | 1410 | if ((0 == subpcode) || (0xff == subpcode)) { |
864 | len += resp_disconnect_pg(ap + len, pcontrol, target); | 1411 | len = resp_err_recov_pg(ap, pcontrol, target); |
865 | len += resp_format_pg(ap + len, pcontrol, target); | 1412 | len += resp_disconnect_pg(ap + len, pcontrol, target); |
866 | len += resp_caching_pg(ap + len, pcontrol, target); | 1413 | len += resp_format_pg(ap + len, pcontrol, target); |
867 | len += resp_ctrl_m_pg(ap + len, pcontrol, target); | 1414 | len += resp_caching_pg(ap + len, pcontrol, target); |
868 | len += resp_iec_m_pg(ap + len, pcontrol, target); | 1415 | len += resp_ctrl_m_pg(ap + len, pcontrol, target); |
1416 | len += resp_sas_sf_m_pg(ap + len, pcontrol, target); | ||
1417 | if (0xff == subpcode) { | ||
1418 | len += resp_sas_pcd_m_spg(ap + len, pcontrol, | ||
1419 | target, target_dev_id); | ||
1420 | len += resp_sas_sha_m_spg(ap + len, pcontrol); | ||
1421 | } | ||
1422 | len += resp_iec_m_pg(ap + len, pcontrol, target); | ||
1423 | } else { | ||
1424 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1425 | INVALID_FIELD_IN_CDB, 0); | ||
1426 | return check_condition_result; | ||
1427 | } | ||
869 | offset += len; | 1428 | offset += len; |
870 | break; | 1429 | break; |
871 | default: | 1430 | default: |
@@ -882,71 +1441,274 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
882 | return fill_from_dev_buffer(scp, arr, min(alloc_len, offset)); | 1441 | return fill_from_dev_buffer(scp, arr, min(alloc_len, offset)); |
883 | } | 1442 | } |
884 | 1443 | ||
885 | static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 1444 | #define SDEBUG_MAX_MSELECT_SZ 512 |
886 | int num, struct sdebug_dev_info * devip) | 1445 | |
1446 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | ||
1447 | struct sdebug_dev_info * devip) | ||
1448 | { | ||
1449 | int pf, sp, ps, md_len, bd_len, off, spf, pg_len; | ||
1450 | int param_len, res, errsts, mpage; | ||
1451 | unsigned char arr[SDEBUG_MAX_MSELECT_SZ]; | ||
1452 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1453 | |||
1454 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1455 | return errsts; | ||
1456 | memset(arr, 0, sizeof(arr)); | ||
1457 | pf = cmd[1] & 0x10; | ||
1458 | sp = cmd[1] & 0x1; | ||
1459 | param_len = mselect6 ? cmd[4] : ((cmd[7] << 8) + cmd[8]); | ||
1460 | if ((0 == pf) || sp || (param_len > SDEBUG_MAX_MSELECT_SZ)) { | ||
1461 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1462 | INVALID_FIELD_IN_CDB, 0); | ||
1463 | return check_condition_result; | ||
1464 | } | ||
1465 | res = fetch_to_dev_buffer(scp, arr, param_len); | ||
1466 | if (-1 == res) | ||
1467 | return (DID_ERROR << 16); | ||
1468 | else if ((res < param_len) && | ||
1469 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | ||
1470 | printk(KERN_INFO "scsi_debug: mode_select: cdb indicated=%d, " | ||
1471 | " IO sent=%d bytes\n", param_len, res); | ||
1472 | md_len = mselect6 ? (arr[0] + 1) : ((arr[0] << 8) + arr[1] + 2); | ||
1473 | bd_len = mselect6 ? arr[3] : ((arr[6] << 8) + arr[7]); | ||
1474 | if ((md_len > 2) || (0 != bd_len)) { | ||
1475 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1476 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
1477 | return check_condition_result; | ||
1478 | } | ||
1479 | off = bd_len + (mselect6 ? 4 : 8); | ||
1480 | mpage = arr[off] & 0x3f; | ||
1481 | ps = !!(arr[off] & 0x80); | ||
1482 | if (ps) { | ||
1483 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1484 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
1485 | return check_condition_result; | ||
1486 | } | ||
1487 | spf = !!(arr[off] & 0x40); | ||
1488 | pg_len = spf ? ((arr[off + 2] << 8) + arr[off + 3] + 4) : | ||
1489 | (arr[off + 1] + 2); | ||
1490 | if ((pg_len + off) > param_len) { | ||
1491 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1492 | PARAMETER_LIST_LENGTH_ERR, 0); | ||
1493 | return check_condition_result; | ||
1494 | } | ||
1495 | switch (mpage) { | ||
1496 | case 0xa: /* Control Mode page */ | ||
1497 | if (ctrl_m_pg[1] == arr[off + 1]) { | ||
1498 | memcpy(ctrl_m_pg + 2, arr + off + 2, | ||
1499 | sizeof(ctrl_m_pg) - 2); | ||
1500 | scsi_debug_dsense = !!(ctrl_m_pg[2] & 0x4); | ||
1501 | return 0; | ||
1502 | } | ||
1503 | break; | ||
1504 | case 0x1c: /* Informational Exceptions Mode page */ | ||
1505 | if (iec_m_pg[1] == arr[off + 1]) { | ||
1506 | memcpy(iec_m_pg + 2, arr + off + 2, | ||
1507 | sizeof(iec_m_pg) - 2); | ||
1508 | return 0; | ||
1509 | } | ||
1510 | break; | ||
1511 | default: | ||
1512 | break; | ||
1513 | } | ||
1514 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1515 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
1516 | return check_condition_result; | ||
1517 | } | ||
1518 | |||
1519 | static int resp_temp_l_pg(unsigned char * arr) | ||
1520 | { | ||
1521 | unsigned char temp_l_pg[] = {0x0, 0x0, 0x3, 0x2, 0x0, 38, | ||
1522 | 0x0, 0x1, 0x3, 0x2, 0x0, 65, | ||
1523 | }; | ||
1524 | |||
1525 | memcpy(arr, temp_l_pg, sizeof(temp_l_pg)); | ||
1526 | return sizeof(temp_l_pg); | ||
1527 | } | ||
1528 | |||
1529 | static int resp_ie_l_pg(unsigned char * arr) | ||
1530 | { | ||
1531 | unsigned char ie_l_pg[] = {0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 38, | ||
1532 | }; | ||
1533 | |||
1534 | memcpy(arr, ie_l_pg, sizeof(ie_l_pg)); | ||
1535 | if (iec_m_pg[2] & 0x4) { /* TEST bit set */ | ||
1536 | arr[4] = THRESHOLD_EXCEEDED; | ||
1537 | arr[5] = 0xff; | ||
1538 | } | ||
1539 | return sizeof(ie_l_pg); | ||
1540 | } | ||
1541 | |||
1542 | #define SDEBUG_MAX_LSENSE_SZ 512 | ||
1543 | |||
1544 | static int resp_log_sense(struct scsi_cmnd * scp, | ||
1545 | struct sdebug_dev_info * devip) | ||
1546 | { | ||
1547 | int ppc, sp, pcontrol, pcode, alloc_len, errsts, len, n; | ||
1548 | unsigned char arr[SDEBUG_MAX_LSENSE_SZ]; | ||
1549 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1550 | |||
1551 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1552 | return errsts; | ||
1553 | memset(arr, 0, sizeof(arr)); | ||
1554 | ppc = cmd[1] & 0x2; | ||
1555 | sp = cmd[1] & 0x1; | ||
1556 | if (ppc || sp) { | ||
1557 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1558 | INVALID_FIELD_IN_CDB, 0); | ||
1559 | return check_condition_result; | ||
1560 | } | ||
1561 | pcontrol = (cmd[2] & 0xc0) >> 6; | ||
1562 | pcode = cmd[2] & 0x3f; | ||
1563 | alloc_len = (cmd[7] << 8) + cmd[8]; | ||
1564 | arr[0] = pcode; | ||
1565 | switch (pcode) { | ||
1566 | case 0x0: /* Supported log pages log page */ | ||
1567 | n = 4; | ||
1568 | arr[n++] = 0x0; /* this page */ | ||
1569 | arr[n++] = 0xd; /* Temperature */ | ||
1570 | arr[n++] = 0x2f; /* Informational exceptions */ | ||
1571 | arr[3] = n - 4; | ||
1572 | break; | ||
1573 | case 0xd: /* Temperature log page */ | ||
1574 | arr[3] = resp_temp_l_pg(arr + 4); | ||
1575 | break; | ||
1576 | case 0x2f: /* Informational exceptions log page */ | ||
1577 | arr[3] = resp_ie_l_pg(arr + 4); | ||
1578 | break; | ||
1579 | default: | ||
1580 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1581 | INVALID_FIELD_IN_CDB, 0); | ||
1582 | return check_condition_result; | ||
1583 | } | ||
1584 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); | ||
1585 | return fill_from_dev_buffer(scp, arr, | ||
1586 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); | ||
1587 | } | ||
1588 | |||
1589 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
1590 | unsigned int num, struct sdebug_dev_info * devip) | ||
887 | { | 1591 | { |
888 | unsigned long iflags; | 1592 | unsigned long iflags; |
1593 | unsigned int block, from_bottom; | ||
1594 | unsigned long long u; | ||
889 | int ret; | 1595 | int ret; |
890 | 1596 | ||
891 | if (upper_blk || (block + num > sdebug_capacity)) { | 1597 | if (lba + num > sdebug_capacity) { |
892 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1598 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, |
893 | 0); | 1599 | 0); |
894 | return check_condition_result; | 1600 | return check_condition_result; |
895 | } | 1601 | } |
1602 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
1603 | if (num > sdebug_store_sectors) { | ||
1604 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1605 | 0); | ||
1606 | return check_condition_result; | ||
1607 | } | ||
896 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && | 1608 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && |
897 | (block <= OPT_MEDIUM_ERR_ADDR) && | 1609 | (lba <= OPT_MEDIUM_ERR_ADDR) && |
898 | ((block + num) > OPT_MEDIUM_ERR_ADDR)) { | 1610 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { |
1611 | /* claim unrecoverable read error */ | ||
899 | mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, | 1612 | mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, |
900 | 0); | 1613 | 0); |
901 | /* claim unrecoverable read error */ | 1614 | /* set info field and valid bit for fixed descriptor */ |
1615 | if (0x70 == (devip->sense_buff[0] & 0x7f)) { | ||
1616 | devip->sense_buff[0] |= 0x80; /* Valid bit */ | ||
1617 | ret = OPT_MEDIUM_ERR_ADDR; | ||
1618 | devip->sense_buff[3] = (ret >> 24) & 0xff; | ||
1619 | devip->sense_buff[4] = (ret >> 16) & 0xff; | ||
1620 | devip->sense_buff[5] = (ret >> 8) & 0xff; | ||
1621 | devip->sense_buff[6] = ret & 0xff; | ||
1622 | } | ||
902 | return check_condition_result; | 1623 | return check_condition_result; |
903 | } | 1624 | } |
904 | read_lock_irqsave(&atomic_rw, iflags); | 1625 | read_lock_irqsave(&atomic_rw, iflags); |
905 | ret = fill_from_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE), | 1626 | if ((lba + num) <= sdebug_store_sectors) |
906 | num * SECT_SIZE); | 1627 | ret = fill_from_dev_buffer(SCpnt, |
1628 | fake_storep + (lba * SECT_SIZE), | ||
1629 | num * SECT_SIZE); | ||
1630 | else { | ||
1631 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1632 | u = lba; | ||
1633 | block = do_div(u, sdebug_store_sectors); | ||
1634 | from_bottom = 0; | ||
1635 | if ((block + num) > sdebug_store_sectors) | ||
1636 | from_bottom = (block + num) - sdebug_store_sectors; | ||
1637 | ret = fill_from_dev_buffer(SCpnt, | ||
1638 | fake_storep + (block * SECT_SIZE), | ||
1639 | (num - from_bottom) * SECT_SIZE); | ||
1640 | if ((0 == ret) && (from_bottom > 0)) | ||
1641 | ret = fill_from_dev_buffer(SCpnt, fake_storep, | ||
1642 | from_bottom * SECT_SIZE); | ||
1643 | } | ||
907 | read_unlock_irqrestore(&atomic_rw, iflags); | 1644 | read_unlock_irqrestore(&atomic_rw, iflags); |
908 | return ret; | 1645 | return ret; |
909 | } | 1646 | } |
910 | 1647 | ||
911 | static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 1648 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, |
912 | int num, struct sdebug_dev_info * devip) | 1649 | unsigned int num, struct sdebug_dev_info * devip) |
913 | { | 1650 | { |
914 | unsigned long iflags; | 1651 | unsigned long iflags; |
1652 | unsigned int block, to_bottom; | ||
1653 | unsigned long long u; | ||
915 | int res; | 1654 | int res; |
916 | 1655 | ||
917 | if (upper_blk || (block + num > sdebug_capacity)) { | 1656 | if (lba + num > sdebug_capacity) { |
918 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1657 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, |
919 | 0); | 1658 | 0); |
920 | return check_condition_result; | 1659 | return check_condition_result; |
921 | } | 1660 | } |
1661 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
1662 | if (num > sdebug_store_sectors) { | ||
1663 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1664 | 0); | ||
1665 | return check_condition_result; | ||
1666 | } | ||
922 | 1667 | ||
923 | write_lock_irqsave(&atomic_rw, iflags); | 1668 | write_lock_irqsave(&atomic_rw, iflags); |
924 | res = fetch_to_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE), | 1669 | if ((lba + num) <= sdebug_store_sectors) |
925 | num * SECT_SIZE); | 1670 | res = fetch_to_dev_buffer(SCpnt, |
1671 | fake_storep + (lba * SECT_SIZE), | ||
1672 | num * SECT_SIZE); | ||
1673 | else { | ||
1674 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1675 | u = lba; | ||
1676 | block = do_div(u, sdebug_store_sectors); | ||
1677 | to_bottom = 0; | ||
1678 | if ((block + num) > sdebug_store_sectors) | ||
1679 | to_bottom = (block + num) - sdebug_store_sectors; | ||
1680 | res = fetch_to_dev_buffer(SCpnt, | ||
1681 | fake_storep + (block * SECT_SIZE), | ||
1682 | (num - to_bottom) * SECT_SIZE); | ||
1683 | if ((0 == res) && (to_bottom > 0)) | ||
1684 | res = fetch_to_dev_buffer(SCpnt, fake_storep, | ||
1685 | to_bottom * SECT_SIZE); | ||
1686 | } | ||
926 | write_unlock_irqrestore(&atomic_rw, iflags); | 1687 | write_unlock_irqrestore(&atomic_rw, iflags); |
927 | if (-1 == res) | 1688 | if (-1 == res) |
928 | return (DID_ERROR << 16); | 1689 | return (DID_ERROR << 16); |
929 | else if ((res < (num * SECT_SIZE)) && | 1690 | else if ((res < (num * SECT_SIZE)) && |
930 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 1691 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
931 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%d, " | 1692 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " |
932 | " IO sent=%d bytes\n", num * SECT_SIZE, res); | 1693 | " IO sent=%d bytes\n", num * SECT_SIZE, res); |
933 | return 0; | 1694 | return 0; |
934 | } | 1695 | } |
935 | 1696 | ||
936 | #define SDEBUG_RLUN_ARR_SZ 128 | 1697 | #define SDEBUG_RLUN_ARR_SZ 256 |
937 | 1698 | ||
938 | static int resp_report_luns(struct scsi_cmnd * scp, | 1699 | static int resp_report_luns(struct scsi_cmnd * scp, |
939 | struct sdebug_dev_info * devip) | 1700 | struct sdebug_dev_info * devip) |
940 | { | 1701 | { |
941 | unsigned int alloc_len; | 1702 | unsigned int alloc_len; |
942 | int lun_cnt, i, upper; | 1703 | int lun_cnt, i, upper, num, n, wlun, lun; |
943 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1704 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
944 | int select_report = (int)cmd[2]; | 1705 | int select_report = (int)cmd[2]; |
945 | struct scsi_lun *one_lun; | 1706 | struct scsi_lun *one_lun; |
946 | unsigned char arr[SDEBUG_RLUN_ARR_SZ]; | 1707 | unsigned char arr[SDEBUG_RLUN_ARR_SZ]; |
1708 | unsigned char * max_addr; | ||
947 | 1709 | ||
948 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); | 1710 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); |
949 | if ((alloc_len < 16) || (select_report > 2)) { | 1711 | if ((alloc_len < 4) || (select_report > 2)) { |
950 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1712 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
951 | 0); | 1713 | 0); |
952 | return check_condition_result; | 1714 | return check_condition_result; |
@@ -954,18 +1716,37 @@ static int resp_report_luns(struct scsi_cmnd * scp, | |||
954 | /* can produce response with up to 16k luns (lun 0 to lun 16383) */ | 1716 | /* can produce response with up to 16k luns (lun 0 to lun 16383) */ |
955 | memset(arr, 0, SDEBUG_RLUN_ARR_SZ); | 1717 | memset(arr, 0, SDEBUG_RLUN_ARR_SZ); |
956 | lun_cnt = scsi_debug_max_luns; | 1718 | lun_cnt = scsi_debug_max_luns; |
957 | arr[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff; | 1719 | if (1 == select_report) |
958 | arr[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff; | 1720 | lun_cnt = 0; |
959 | lun_cnt = min((int)((SDEBUG_RLUN_ARR_SZ - 8) / | 1721 | else if (scsi_debug_no_lun_0 && (lun_cnt > 0)) |
960 | sizeof(struct scsi_lun)), lun_cnt); | 1722 | --lun_cnt; |
1723 | wlun = (select_report > 0) ? 1 : 0; | ||
1724 | num = lun_cnt + wlun; | ||
1725 | arr[2] = ((sizeof(struct scsi_lun) * num) >> 8) & 0xff; | ||
1726 | arr[3] = (sizeof(struct scsi_lun) * num) & 0xff; | ||
1727 | n = min((int)((SDEBUG_RLUN_ARR_SZ - 8) / | ||
1728 | sizeof(struct scsi_lun)), num); | ||
1729 | if (n < num) { | ||
1730 | wlun = 0; | ||
1731 | lun_cnt = n; | ||
1732 | } | ||
961 | one_lun = (struct scsi_lun *) &arr[8]; | 1733 | one_lun = (struct scsi_lun *) &arr[8]; |
962 | for (i = 0; i < lun_cnt; i++) { | 1734 | max_addr = arr + SDEBUG_RLUN_ARR_SZ; |
963 | upper = (i >> 8) & 0x3f; | 1735 | for (i = 0, lun = (scsi_debug_no_lun_0 ? 1 : 0); |
1736 | ((i < lun_cnt) && ((unsigned char *)(one_lun + i) < max_addr)); | ||
1737 | i++, lun++) { | ||
1738 | upper = (lun >> 8) & 0x3f; | ||
964 | if (upper) | 1739 | if (upper) |
965 | one_lun[i].scsi_lun[0] = | 1740 | one_lun[i].scsi_lun[0] = |
966 | (upper | (SAM2_LUN_ADDRESS_METHOD << 6)); | 1741 | (upper | (SAM2_LUN_ADDRESS_METHOD << 6)); |
967 | one_lun[i].scsi_lun[1] = i & 0xff; | 1742 | one_lun[i].scsi_lun[1] = lun & 0xff; |
1743 | } | ||
1744 | if (wlun) { | ||
1745 | one_lun[i].scsi_lun[0] = (SAM2_WLUN_REPORT_LUNS >> 8) & 0xff; | ||
1746 | one_lun[i].scsi_lun[1] = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
1747 | i++; | ||
968 | } | 1748 | } |
1749 | alloc_len = (unsigned char *)(one_lun + i) - arr; | ||
969 | return fill_from_dev_buffer(scp, arr, | 1750 | return fill_from_dev_buffer(scp, arr, |
970 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); | 1751 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); |
971 | } | 1752 | } |
@@ -1001,7 +1782,8 @@ static void timer_intr_handler(unsigned long indx) | |||
1001 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) | 1782 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) |
1002 | { | 1783 | { |
1003 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1784 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1004 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_alloc\n"); | 1785 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", |
1786 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
1005 | return 0; | 1787 | return 0; |
1006 | } | 1788 | } |
1007 | 1789 | ||
@@ -1010,7 +1792,8 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
1010 | struct sdebug_dev_info * devip; | 1792 | struct sdebug_dev_info * devip; |
1011 | 1793 | ||
1012 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1794 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1013 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_configure\n"); | 1795 | printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", |
1796 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
1014 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) | 1797 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) |
1015 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; | 1798 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; |
1016 | devip = devInfoReg(sdp); | 1799 | devip = devInfoReg(sdp); |
@@ -1018,6 +1801,7 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
1018 | if (sdp->host->cmd_per_lun) | 1801 | if (sdp->host->cmd_per_lun) |
1019 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, | 1802 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, |
1020 | sdp->host->cmd_per_lun); | 1803 | sdp->host->cmd_per_lun); |
1804 | blk_queue_max_segment_size(sdp->request_queue, 256 * 1024); | ||
1021 | return 0; | 1805 | return 0; |
1022 | } | 1806 | } |
1023 | 1807 | ||
@@ -1027,7 +1811,8 @@ static void scsi_debug_slave_destroy(struct scsi_device * sdp) | |||
1027 | (struct sdebug_dev_info *)sdp->hostdata; | 1811 | (struct sdebug_dev_info *)sdp->hostdata; |
1028 | 1812 | ||
1029 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1813 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1030 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_destroy\n"); | 1814 | printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", |
1815 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
1031 | if (devip) { | 1816 | if (devip) { |
1032 | /* make this slot avaliable for re-use */ | 1817 | /* make this slot avaliable for re-use */ |
1033 | devip->used = 0; | 1818 | devip->used = 0; |
@@ -1084,6 +1869,8 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
1084 | open_devip->sense_buff[0] = 0x70; | 1869 | open_devip->sense_buff[0] = 0x70; |
1085 | open_devip->sense_buff[7] = 0xa; | 1870 | open_devip->sense_buff[7] = 0xa; |
1086 | } | 1871 | } |
1872 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) | ||
1873 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
1087 | return open_devip; | 1874 | return open_devip; |
1088 | } | 1875 | } |
1089 | return NULL; | 1876 | return NULL; |
@@ -1272,7 +2059,7 @@ static void __init sdebug_build_parts(unsigned char * ramp) | |||
1272 | printk(KERN_WARNING "scsi_debug:build_parts: reducing " | 2059 | printk(KERN_WARNING "scsi_debug:build_parts: reducing " |
1273 | "partitions to %d\n", SDEBUG_MAX_PARTS); | 2060 | "partitions to %d\n", SDEBUG_MAX_PARTS); |
1274 | } | 2061 | } |
1275 | num_sectors = (int)(sdebug_store_size / SECT_SIZE); | 2062 | num_sectors = (int)sdebug_store_sectors; |
1276 | sectors_per_part = (num_sectors - sdebug_sectors_per) | 2063 | sectors_per_part = (num_sectors - sdebug_sectors_per) |
1277 | / scsi_debug_num_parts; | 2064 | / scsi_debug_num_parts; |
1278 | heads_by_sects = sdebug_heads * sdebug_sectors_per; | 2065 | heads_by_sects = sdebug_heads * sdebug_sectors_per; |
@@ -1315,9 +2102,9 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
1315 | if (scsi_result) { | 2102 | if (scsi_result) { |
1316 | struct scsi_device * sdp = cmnd->device; | 2103 | struct scsi_device * sdp = cmnd->device; |
1317 | 2104 | ||
1318 | sdev_printk(KERN_INFO, sdp, | 2105 | printk(KERN_INFO "scsi_debug: <%u %u %u %u> " |
1319 | "non-zero result=0x%x\n", | 2106 | "non-zero result=0x%x\n", sdp->host->host_no, |
1320 | scsi_result); | 2107 | sdp->channel, sdp->id, sdp->lun, scsi_result); |
1321 | } | 2108 | } |
1322 | } | 2109 | } |
1323 | if (cmnd && devip) { | 2110 | if (cmnd && devip) { |
@@ -1364,21 +2151,19 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
1364 | } | 2151 | } |
1365 | } | 2152 | } |
1366 | 2153 | ||
1367 | /* Set 'perm' (4th argument) to 0 to disable module_param's definition | 2154 | module_param_named(add_host, scsi_debug_add_host, int, S_IRUGO | S_IWUSR); |
1368 | * of sysfs parameters (which module_param doesn't yet support). | 2155 | module_param_named(delay, scsi_debug_delay, int, S_IRUGO | S_IWUSR); |
1369 | * Sysfs parameters defined explicitly below. | 2156 | module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, S_IRUGO); |
1370 | */ | 2157 | module_param_named(dsense, scsi_debug_dsense, int, S_IRUGO | S_IWUSR); |
1371 | module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */ | 2158 | module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR); |
1372 | module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */ | 2159 | module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR); |
1373 | module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, 0); | 2160 | module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR); |
1374 | module_param_named(dsense, scsi_debug_dsense, int, 0); | 2161 | module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO); |
1375 | module_param_named(every_nth, scsi_debug_every_nth, int, 0); | 2162 | module_param_named(num_tgts, scsi_debug_num_tgts, int, S_IRUGO | S_IWUSR); |
1376 | module_param_named(max_luns, scsi_debug_max_luns, int, 0); | 2163 | module_param_named(opts, scsi_debug_opts, int, S_IRUGO | S_IWUSR); |
1377 | module_param_named(num_parts, scsi_debug_num_parts, int, 0); | 2164 | module_param_named(ptype, scsi_debug_ptype, int, S_IRUGO | S_IWUSR); |
1378 | module_param_named(num_tgts, scsi_debug_num_tgts, int, 0); | 2165 | module_param_named(scsi_level, scsi_debug_scsi_level, int, S_IRUGO); |
1379 | module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */ | 2166 | module_param_named(virtual_gb, scsi_debug_virtual_gb, int, S_IRUGO | S_IWUSR); |
1380 | module_param_named(ptype, scsi_debug_ptype, int, 0); | ||
1381 | module_param_named(scsi_level, scsi_debug_scsi_level, int, 0); | ||
1382 | 2167 | ||
1383 | MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); | 2168 | MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); |
1384 | MODULE_DESCRIPTION("SCSI debug adapter driver"); | 2169 | MODULE_DESCRIPTION("SCSI debug adapter driver"); |
@@ -1387,15 +2172,17 @@ MODULE_VERSION(SCSI_DEBUG_VERSION); | |||
1387 | 2172 | ||
1388 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); | 2173 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); |
1389 | MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); | 2174 | MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); |
1390 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs"); | 2175 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)"); |
1391 | MODULE_PARM_DESC(dsense, "use descriptor sense format(def: fixed)"); | 2176 | MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)"); |
1392 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)"); | 2177 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)"); |
1393 | MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate"); | 2178 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); |
2179 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); | ||
1394 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); | 2180 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); |
1395 | MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate"); | 2181 | MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); |
1396 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->..."); | 2182 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->... (def=0)"); |
1397 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); | 2183 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); |
1398 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); | 2184 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); |
2185 | MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); | ||
1399 | 2186 | ||
1400 | 2187 | ||
1401 | static char sdebug_info[256]; | 2188 | static char sdebug_info[256]; |
@@ -1547,6 +2334,24 @@ static ssize_t sdebug_dsense_store(struct device_driver * ddp, | |||
1547 | DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show, | 2334 | DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show, |
1548 | sdebug_dsense_store); | 2335 | sdebug_dsense_store); |
1549 | 2336 | ||
2337 | static ssize_t sdebug_no_lun_0_show(struct device_driver * ddp, char * buf) | ||
2338 | { | ||
2339 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_no_lun_0); | ||
2340 | } | ||
2341 | static ssize_t sdebug_no_lun_0_store(struct device_driver * ddp, | ||
2342 | const char * buf, size_t count) | ||
2343 | { | ||
2344 | int n; | ||
2345 | |||
2346 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | ||
2347 | scsi_debug_no_lun_0 = n; | ||
2348 | return count; | ||
2349 | } | ||
2350 | return -EINVAL; | ||
2351 | } | ||
2352 | DRIVER_ATTR(no_lun_0, S_IRUGO | S_IWUSR, sdebug_no_lun_0_show, | ||
2353 | sdebug_no_lun_0_store); | ||
2354 | |||
1550 | static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) | 2355 | static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) |
1551 | { | 2356 | { |
1552 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts); | 2357 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts); |
@@ -1622,6 +2427,29 @@ static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf) | |||
1622 | } | 2427 | } |
1623 | DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL); | 2428 | DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL); |
1624 | 2429 | ||
2430 | static ssize_t sdebug_virtual_gb_show(struct device_driver * ddp, char * buf) | ||
2431 | { | ||
2432 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_virtual_gb); | ||
2433 | } | ||
2434 | static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp, | ||
2435 | const char * buf, size_t count) | ||
2436 | { | ||
2437 | int n; | ||
2438 | |||
2439 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | ||
2440 | scsi_debug_virtual_gb = n; | ||
2441 | if (scsi_debug_virtual_gb > 0) { | ||
2442 | sdebug_capacity = 2048 * 1024; | ||
2443 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
2444 | } else | ||
2445 | sdebug_capacity = sdebug_store_sectors; | ||
2446 | return count; | ||
2447 | } | ||
2448 | return -EINVAL; | ||
2449 | } | ||
2450 | DRIVER_ATTR(virtual_gb, S_IRUGO | S_IWUSR, sdebug_virtual_gb_show, | ||
2451 | sdebug_virtual_gb_store); | ||
2452 | |||
1625 | static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) | 2453 | static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) |
1626 | { | 2454 | { |
1627 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host); | 2455 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host); |
@@ -1691,14 +2519,19 @@ static void do_remove_driverfs_files(void) | |||
1691 | 2519 | ||
1692 | static int __init scsi_debug_init(void) | 2520 | static int __init scsi_debug_init(void) |
1693 | { | 2521 | { |
1694 | unsigned long sz; | 2522 | unsigned int sz; |
1695 | int host_to_add; | 2523 | int host_to_add; |
1696 | int k; | 2524 | int k; |
1697 | 2525 | ||
1698 | if (scsi_debug_dev_size_mb < 1) | 2526 | if (scsi_debug_dev_size_mb < 1) |
1699 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ | 2527 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ |
1700 | sdebug_store_size = (unsigned long)scsi_debug_dev_size_mb * 1048576; | 2528 | sdebug_store_size = (unsigned int)scsi_debug_dev_size_mb * 1048576; |
1701 | sdebug_capacity = sdebug_store_size / SECT_SIZE; | 2529 | sdebug_store_sectors = sdebug_store_size / SECT_SIZE; |
2530 | if (scsi_debug_virtual_gb > 0) { | ||
2531 | sdebug_capacity = 2048 * 1024; | ||
2532 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
2533 | } else | ||
2534 | sdebug_capacity = sdebug_store_sectors; | ||
1702 | 2535 | ||
1703 | /* play around with geometry, don't waste too much on track 0 */ | 2536 | /* play around with geometry, don't waste too much on track 0 */ |
1704 | sdebug_heads = 8; | 2537 | sdebug_heads = 8; |
@@ -1812,7 +2645,7 @@ static int sdebug_add_adapter(void) | |||
1812 | struct sdebug_dev_info *sdbg_devinfo; | 2645 | struct sdebug_dev_info *sdbg_devinfo; |
1813 | struct list_head *lh, *lh_sf; | 2646 | struct list_head *lh, *lh_sf; |
1814 | 2647 | ||
1815 | sdbg_host = kzalloc(sizeof(*sdbg_host), GFP_KERNEL); | 2648 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); |
1816 | 2649 | ||
1817 | if (NULL == sdbg_host) { | 2650 | if (NULL == sdbg_host) { |
1818 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2651 | printk(KERN_ERR "%s: out of memory at line %d\n", |
@@ -1824,7 +2657,7 @@ static int sdebug_add_adapter(void) | |||
1824 | 2657 | ||
1825 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; | 2658 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; |
1826 | for (k = 0; k < devs_per_host; k++) { | 2659 | for (k = 0; k < devs_per_host; k++) { |
1827 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo), GFP_KERNEL); | 2660 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo),GFP_KERNEL); |
1828 | if (NULL == sdbg_devinfo) { | 2661 | if (NULL == sdbg_devinfo) { |
1829 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2662 | printk(KERN_ERR "%s: out of memory at line %d\n", |
1830 | __FUNCTION__, __LINE__); | 2663 | __FUNCTION__, __LINE__); |
@@ -1905,7 +2738,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
1905 | hpnt->max_id = scsi_debug_num_tgts + 1; | 2738 | hpnt->max_id = scsi_debug_num_tgts + 1; |
1906 | else | 2739 | else |
1907 | hpnt->max_id = scsi_debug_num_tgts; | 2740 | hpnt->max_id = scsi_debug_num_tgts; |
1908 | hpnt->max_lun = scsi_debug_max_luns; | 2741 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* = scsi_debug_max_luns; */ |
1909 | 2742 | ||
1910 | error = scsi_add_host(hpnt, &sdbg_host->dev); | 2743 | error = scsi_add_host(hpnt, &sdbg_host->dev); |
1911 | if (error) { | 2744 | if (error) { |
@@ -1959,7 +2792,7 @@ static void sdebug_max_tgts_luns(void) | |||
1959 | hpnt->max_id = scsi_debug_num_tgts + 1; | 2792 | hpnt->max_id = scsi_debug_num_tgts + 1; |
1960 | else | 2793 | else |
1961 | hpnt->max_id = scsi_debug_num_tgts; | 2794 | hpnt->max_id = scsi_debug_num_tgts; |
1962 | hpnt->max_lun = scsi_debug_max_luns; | 2795 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* scsi_debug_max_luns; */ |
1963 | } | 2796 | } |
1964 | spin_unlock(&sdebug_host_list_lock); | 2797 | spin_unlock(&sdebug_host_list_lock); |
1965 | } | 2798 | } |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index fb5cb4c9ac65..3d0429bc14ab 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -162,7 +162,7 @@ static struct { | |||
162 | {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, | 162 | {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, |
163 | {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, | 163 | {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, |
164 | {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ | 164 | {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ |
165 | {"HP", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP XP Arrays */ | 165 | {"HP", "OPEN-", "*", BLIST_REPORTLUN2}, /* HP XP Arrays */ |
166 | {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, | 166 | {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, |
167 | {"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, | 167 | {"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, |
168 | {"HP", "C1557A", NULL, BLIST_FORCELUN}, | 168 | {"HP", "C1557A", NULL, BLIST_FORCELUN}, |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 6a7a60fc0a4e..6683d596234a 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1672,7 +1672,9 @@ int | |||
1672 | scsi_reset_provider(struct scsi_device *dev, int flag) | 1672 | scsi_reset_provider(struct scsi_device *dev, int flag) |
1673 | { | 1673 | { |
1674 | struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL); | 1674 | struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL); |
1675 | struct Scsi_Host *shost = dev->host; | ||
1675 | struct request req; | 1676 | struct request req; |
1677 | unsigned long flags; | ||
1676 | int rtn; | 1678 | int rtn; |
1677 | 1679 | ||
1678 | scmd->request = &req; | 1680 | scmd->request = &req; |
@@ -1699,6 +1701,10 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1699 | */ | 1701 | */ |
1700 | scmd->pid = 0; | 1702 | scmd->pid = 0; |
1701 | 1703 | ||
1704 | spin_lock_irqsave(shost->host_lock, flags); | ||
1705 | shost->tmf_in_progress = 1; | ||
1706 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1707 | |||
1702 | switch (flag) { | 1708 | switch (flag) { |
1703 | case SCSI_TRY_RESET_DEVICE: | 1709 | case SCSI_TRY_RESET_DEVICE: |
1704 | rtn = scsi_try_bus_device_reset(scmd); | 1710 | rtn = scsi_try_bus_device_reset(scmd); |
@@ -1717,6 +1723,22 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1717 | rtn = FAILED; | 1723 | rtn = FAILED; |
1718 | } | 1724 | } |
1719 | 1725 | ||
1726 | spin_lock_irqsave(shost->host_lock, flags); | ||
1727 | shost->tmf_in_progress = 0; | ||
1728 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1729 | |||
1730 | /* | ||
1731 | * be sure to wake up anyone who was sleeping or had their queue | ||
1732 | * suspended while we performed the TMF. | ||
1733 | */ | ||
1734 | SCSI_LOG_ERROR_RECOVERY(3, | ||
1735 | printk("%s: waking up host to restart after TMF\n", | ||
1736 | __FUNCTION__)); | ||
1737 | |||
1738 | wake_up(&shost->host_wait); | ||
1739 | |||
1740 | scsi_run_host_queues(shost); | ||
1741 | |||
1720 | scsi_next_command(scmd); | 1742 | scsi_next_command(scmd); |
1721 | return rtn; | 1743 | return rtn; |
1722 | } | 1744 | } |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3d04a9f386ac..08af9aae7df3 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -855,8 +855,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd) | |||
855 | * b) We can just use scsi_requeue_command() here. This would | 855 | * b) We can just use scsi_requeue_command() here. This would |
856 | * be used if we just wanted to retry, for example. | 856 | * be used if we just wanted to retry, for example. |
857 | */ | 857 | */ |
858 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | 858 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) |
859 | unsigned int block_bytes) | ||
860 | { | 859 | { |
861 | int result = cmd->result; | 860 | int result = cmd->result; |
862 | int this_count = cmd->bufflen; | 861 | int this_count = cmd->bufflen; |
@@ -921,87 +920,70 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
921 | * Next deal with any sectors which we were able to correctly | 920 | * Next deal with any sectors which we were able to correctly |
922 | * handle. | 921 | * handle. |
923 | */ | 922 | */ |
924 | if (good_bytes >= 0) { | 923 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, " |
925 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d bytes done.\n", | 924 | "%d bytes done.\n", |
926 | req->nr_sectors, good_bytes)); | 925 | req->nr_sectors, good_bytes)); |
927 | SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg)); | 926 | SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg)); |
928 | 927 | ||
929 | if (clear_errors) | 928 | if (clear_errors) |
930 | req->errors = 0; | 929 | req->errors = 0; |
931 | /* | ||
932 | * If multiple sectors are requested in one buffer, then | ||
933 | * they will have been finished off by the first command. | ||
934 | * If not, then we have a multi-buffer command. | ||
935 | * | ||
936 | * If block_bytes != 0, it means we had a medium error | ||
937 | * of some sort, and that we want to mark some number of | ||
938 | * sectors as not uptodate. Thus we want to inhibit | ||
939 | * requeueing right here - we will requeue down below | ||
940 | * when we handle the bad sectors. | ||
941 | */ | ||
942 | 930 | ||
943 | /* | 931 | /* A number of bytes were successfully read. If there |
944 | * If the command completed without error, then either | 932 | * are leftovers and there is some kind of error |
945 | * finish off the rest of the command, or start a new one. | 933 | * (result != 0), retry the rest. |
946 | */ | 934 | */ |
947 | if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL) | 935 | if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL) |
948 | return; | 936 | return; |
949 | } | 937 | |
950 | /* | 938 | /* good_bytes = 0, or (inclusive) there were leftovers and |
951 | * Now, if we were good little boys and girls, Santa left us a request | 939 | * result = 0, so scsi_end_request couldn't retry. |
952 | * sense buffer. We can extract information from this, so we | ||
953 | * can choose a block to remap, etc. | ||
954 | */ | 940 | */ |
955 | if (sense_valid && !sense_deferred) { | 941 | if (sense_valid && !sense_deferred) { |
956 | switch (sshdr.sense_key) { | 942 | switch (sshdr.sense_key) { |
957 | case UNIT_ATTENTION: | 943 | case UNIT_ATTENTION: |
958 | if (cmd->device->removable) { | 944 | if (cmd->device->removable) { |
959 | /* detected disc change. set a bit | 945 | /* Detected disc change. Set a bit |
960 | * and quietly refuse further access. | 946 | * and quietly refuse further access. |
961 | */ | 947 | */ |
962 | cmd->device->changed = 1; | 948 | cmd->device->changed = 1; |
963 | scsi_end_request(cmd, 0, | 949 | scsi_end_request(cmd, 0, this_count, 1); |
964 | this_count, 1); | ||
965 | return; | 950 | return; |
966 | } else { | 951 | } else { |
967 | /* | 952 | /* Must have been a power glitch, or a |
968 | * Must have been a power glitch, or a | 953 | * bus reset. Could not have been a |
969 | * bus reset. Could not have been a | 954 | * media change, so we just retry the |
970 | * media change, so we just retry the | 955 | * request and see what happens. |
971 | * request and see what happens. | 956 | */ |
972 | */ | ||
973 | scsi_requeue_command(q, cmd); | 957 | scsi_requeue_command(q, cmd); |
974 | return; | 958 | return; |
975 | } | 959 | } |
976 | break; | 960 | break; |
977 | case ILLEGAL_REQUEST: | 961 | case ILLEGAL_REQUEST: |
978 | /* | 962 | /* If we had an ILLEGAL REQUEST returned, then |
979 | * If we had an ILLEGAL REQUEST returned, then we may | 963 | * we may have performed an unsupported |
980 | * have performed an unsupported command. The only | 964 | * command. The only thing this should be |
981 | * thing this should be would be a ten byte read where | 965 | * would be a ten byte read where only a six |
982 | * only a six byte read was supported. Also, on a | 966 | * byte read was supported. Also, on a system |
983 | * system where READ CAPACITY failed, we may have read | 967 | * where READ CAPACITY failed, we may have |
984 | * past the end of the disk. | 968 | * read past the end of the disk. |
985 | */ | 969 | */ |
986 | if ((cmd->device->use_10_for_rw && | 970 | if ((cmd->device->use_10_for_rw && |
987 | sshdr.asc == 0x20 && sshdr.ascq == 0x00) && | 971 | sshdr.asc == 0x20 && sshdr.ascq == 0x00) && |
988 | (cmd->cmnd[0] == READ_10 || | 972 | (cmd->cmnd[0] == READ_10 || |
989 | cmd->cmnd[0] == WRITE_10)) { | 973 | cmd->cmnd[0] == WRITE_10)) { |
990 | cmd->device->use_10_for_rw = 0; | 974 | cmd->device->use_10_for_rw = 0; |
991 | /* | 975 | /* This will cause a retry with a |
992 | * This will cause a retry with a 6-byte | 976 | * 6-byte command. |
993 | * command. | ||
994 | */ | 977 | */ |
995 | scsi_requeue_command(q, cmd); | 978 | scsi_requeue_command(q, cmd); |
996 | result = 0; | 979 | return; |
997 | } else { | 980 | } else { |
998 | scsi_end_request(cmd, 0, this_count, 1); | 981 | scsi_end_request(cmd, 0, this_count, 1); |
999 | return; | 982 | return; |
1000 | } | 983 | } |
1001 | break; | 984 | break; |
1002 | case NOT_READY: | 985 | case NOT_READY: |
1003 | /* | 986 | /* If the device is in the process of becoming |
1004 | * If the device is in the process of becoming | ||
1005 | * ready, or has a temporary blockage, retry. | 987 | * ready, or has a temporary blockage, retry. |
1006 | */ | 988 | */ |
1007 | if (sshdr.asc == 0x04) { | 989 | if (sshdr.asc == 0x04) { |
@@ -1021,7 +1003,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
1021 | } | 1003 | } |
1022 | if (!(req->flags & REQ_QUIET)) { | 1004 | if (!(req->flags & REQ_QUIET)) { |
1023 | scmd_printk(KERN_INFO, cmd, | 1005 | scmd_printk(KERN_INFO, cmd, |
1024 | "Device not ready: "); | 1006 | "Device not ready: "); |
1025 | scsi_print_sense_hdr("", &sshdr); | 1007 | scsi_print_sense_hdr("", &sshdr); |
1026 | } | 1008 | } |
1027 | scsi_end_request(cmd, 0, this_count, 1); | 1009 | scsi_end_request(cmd, 0, this_count, 1); |
@@ -1029,21 +1011,21 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
1029 | case VOLUME_OVERFLOW: | 1011 | case VOLUME_OVERFLOW: |
1030 | if (!(req->flags & REQ_QUIET)) { | 1012 | if (!(req->flags & REQ_QUIET)) { |
1031 | scmd_printk(KERN_INFO, cmd, | 1013 | scmd_printk(KERN_INFO, cmd, |
1032 | "Volume overflow, CDB: "); | 1014 | "Volume overflow, CDB: "); |
1033 | __scsi_print_command(cmd->data_cmnd); | 1015 | __scsi_print_command(cmd->data_cmnd); |
1034 | scsi_print_sense("", cmd); | 1016 | scsi_print_sense("", cmd); |
1035 | } | 1017 | } |
1036 | scsi_end_request(cmd, 0, block_bytes, 1); | 1018 | /* See SSC3rXX or current. */ |
1019 | scsi_end_request(cmd, 0, this_count, 1); | ||
1037 | return; | 1020 | return; |
1038 | default: | 1021 | default: |
1039 | break; | 1022 | break; |
1040 | } | 1023 | } |
1041 | } /* driver byte != 0 */ | 1024 | } |
1042 | if (host_byte(result) == DID_RESET) { | 1025 | if (host_byte(result) == DID_RESET) { |
1043 | /* | 1026 | /* Third party bus reset or reset for error recovery |
1044 | * Third party bus reset or reset for error | 1027 | * reasons. Just retry the request and see what |
1045 | * recovery reasons. Just retry the request | 1028 | * happens. |
1046 | * and see what happens. | ||
1047 | */ | 1029 | */ |
1048 | scsi_requeue_command(q, cmd); | 1030 | scsi_requeue_command(q, cmd); |
1049 | return; | 1031 | return; |
@@ -1051,21 +1033,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
1051 | if (result) { | 1033 | if (result) { |
1052 | if (!(req->flags & REQ_QUIET)) { | 1034 | if (!(req->flags & REQ_QUIET)) { |
1053 | scmd_printk(KERN_INFO, cmd, | 1035 | scmd_printk(KERN_INFO, cmd, |
1054 | "SCSI error: return code = 0x%x\n", result); | 1036 | "SCSI error: return code = 0x%08x\n", |
1055 | 1037 | result); | |
1056 | if (driver_byte(result) & DRIVER_SENSE) | 1038 | if (driver_byte(result) & DRIVER_SENSE) |
1057 | scsi_print_sense("", cmd); | 1039 | scsi_print_sense("", cmd); |
1058 | } | 1040 | } |
1059 | /* | ||
1060 | * Mark a single buffer as not uptodate. Queue the remainder. | ||
1061 | * We sometimes get this cruft in the event that a medium error | ||
1062 | * isn't properly reported. | ||
1063 | */ | ||
1064 | block_bytes = req->hard_cur_sectors << 9; | ||
1065 | if (!block_bytes) | ||
1066 | block_bytes = req->data_len; | ||
1067 | scsi_end_request(cmd, 0, block_bytes, 1); | ||
1068 | } | 1041 | } |
1042 | scsi_end_request(cmd, 0, this_count, !result); | ||
1069 | } | 1043 | } |
1070 | EXPORT_SYMBOL(scsi_io_completion); | 1044 | EXPORT_SYMBOL(scsi_io_completion); |
1071 | 1045 | ||
@@ -1169,7 +1143,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | |||
1169 | * successfully. Since this is a REQ_BLOCK_PC command the | 1143 | * successfully. Since this is a REQ_BLOCK_PC command the |
1170 | * caller should check the request's errors value | 1144 | * caller should check the request's errors value |
1171 | */ | 1145 | */ |
1172 | scsi_io_completion(cmd, cmd->bufflen, 0); | 1146 | scsi_io_completion(cmd, cmd->bufflen); |
1173 | } | 1147 | } |
1174 | 1148 | ||
1175 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | 1149 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) |
@@ -2050,6 +2024,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
2050 | switch (oldstate) { | 2024 | switch (oldstate) { |
2051 | case SDEV_CREATED: | 2025 | case SDEV_CREATED: |
2052 | case SDEV_RUNNING: | 2026 | case SDEV_RUNNING: |
2027 | case SDEV_QUIESCE: | ||
2053 | case SDEV_OFFLINE: | 2028 | case SDEV_OFFLINE: |
2054 | case SDEV_BLOCK: | 2029 | case SDEV_BLOCK: |
2055 | break; | 2030 | break; |
@@ -2060,6 +2035,9 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
2060 | 2035 | ||
2061 | case SDEV_DEL: | 2036 | case SDEV_DEL: |
2062 | switch (oldstate) { | 2037 | switch (oldstate) { |
2038 | case SDEV_CREATED: | ||
2039 | case SDEV_RUNNING: | ||
2040 | case SDEV_OFFLINE: | ||
2063 | case SDEV_CANCEL: | 2041 | case SDEV_CANCEL: |
2064 | break; | 2042 | break; |
2065 | default: | 2043 | default: |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 015c90cf3abc..e2fbe9a9d5a9 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -116,7 +116,7 @@ extern struct bus_type scsi_bus_type; | |||
116 | * classes. | 116 | * classes. |
117 | */ | 117 | */ |
118 | 118 | ||
119 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT (HZ*60) | 119 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT 600 /* units in seconds */ |
120 | extern int scsi_internal_device_block(struct scsi_device *sdev); | 120 | extern int scsi_internal_device_block(struct scsi_device *sdev); |
121 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); | 121 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); |
122 | 122 | ||
diff --git a/drivers/scsi/scsi_sas_internal.h b/drivers/scsi/scsi_sas_internal.h index d76e6e3d8ca5..e1edab45a37b 100644 --- a/drivers/scsi/scsi_sas_internal.h +++ b/drivers/scsi/scsi_sas_internal.h | |||
@@ -2,7 +2,8 @@ | |||
2 | #define _SCSI_SAS_INTERNAL_H | 2 | #define _SCSI_SAS_INTERNAL_H |
3 | 3 | ||
4 | #define SAS_HOST_ATTRS 0 | 4 | #define SAS_HOST_ATTRS 0 |
5 | #define SAS_PORT_ATTRS 17 | 5 | #define SAS_PHY_ATTRS 17 |
6 | #define SAS_PORT_ATTRS 1 | ||
6 | #define SAS_RPORT_ATTRS 7 | 7 | #define SAS_RPORT_ATTRS 7 |
7 | #define SAS_END_DEV_ATTRS 3 | 8 | #define SAS_END_DEV_ATTRS 3 |
8 | #define SAS_EXPANDER_ATTRS 7 | 9 | #define SAS_EXPANDER_ATTRS 7 |
@@ -13,12 +14,14 @@ struct sas_internal { | |||
13 | struct sas_domain_function_template *dft; | 14 | struct sas_domain_function_template *dft; |
14 | 15 | ||
15 | struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS]; | 16 | struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS]; |
16 | struct class_device_attribute private_phy_attrs[SAS_PORT_ATTRS]; | 17 | struct class_device_attribute private_phy_attrs[SAS_PHY_ATTRS]; |
18 | struct class_device_attribute private_port_attrs[SAS_PORT_ATTRS]; | ||
17 | struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS]; | 19 | struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS]; |
18 | struct class_device_attribute private_end_dev_attrs[SAS_END_DEV_ATTRS]; | 20 | struct class_device_attribute private_end_dev_attrs[SAS_END_DEV_ATTRS]; |
19 | struct class_device_attribute private_expander_attrs[SAS_EXPANDER_ATTRS]; | 21 | struct class_device_attribute private_expander_attrs[SAS_EXPANDER_ATTRS]; |
20 | 22 | ||
21 | struct transport_container phy_attr_cont; | 23 | struct transport_container phy_attr_cont; |
24 | struct transport_container port_attr_cont; | ||
22 | struct transport_container rphy_attr_cont; | 25 | struct transport_container rphy_attr_cont; |
23 | struct transport_container end_dev_attr_cont; | 26 | struct transport_container end_dev_attr_cont; |
24 | struct transport_container expander_attr_cont; | 27 | struct transport_container expander_attr_cont; |
@@ -28,7 +31,8 @@ struct sas_internal { | |||
28 | * needed by scsi_sysfs.c | 31 | * needed by scsi_sysfs.c |
29 | */ | 32 | */ |
30 | struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1]; | 33 | struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1]; |
31 | struct class_device_attribute *phy_attrs[SAS_PORT_ATTRS + 1]; | 34 | struct class_device_attribute *phy_attrs[SAS_PHY_ATTRS + 1]; |
35 | struct class_device_attribute *port_attrs[SAS_PORT_ATTRS + 1]; | ||
32 | struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1]; | 36 | struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1]; |
33 | struct class_device_attribute *end_dev_attrs[SAS_END_DEV_ATTRS + 1]; | 37 | struct class_device_attribute *end_dev_attrs[SAS_END_DEV_ATTRS + 1]; |
34 | struct class_device_attribute *expander_attrs[SAS_EXPANDER_ATTRS + 1]; | 38 | struct class_device_attribute *expander_attrs[SAS_EXPANDER_ATTRS + 1]; |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 1341608e9e3b..1bd92b9b46d9 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -809,6 +809,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) | |||
809 | 809 | ||
810 | static inline void scsi_destroy_sdev(struct scsi_device *sdev) | 810 | static inline void scsi_destroy_sdev(struct scsi_device *sdev) |
811 | { | 811 | { |
812 | scsi_device_set_state(sdev, SDEV_DEL); | ||
812 | if (sdev->host->hostt->slave_destroy) | 813 | if (sdev->host->hostt->slave_destroy) |
813 | sdev->host->hostt->slave_destroy(sdev); | 814 | sdev->host->hostt->slave_destroy(sdev); |
814 | transport_destroy_device(&sdev->sdev_gendev); | 815 | transport_destroy_device(&sdev->sdev_gendev); |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index f2db7a41cf1d..b03aa85108e5 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -368,7 +368,7 @@ static DECLARE_TRANSPORT_CLASS(fc_rport_class, | |||
368 | * should insulate the loss of a remote port. | 368 | * should insulate the loss of a remote port. |
369 | * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. | 369 | * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. |
370 | */ | 370 | */ |
371 | static unsigned int fc_dev_loss_tmo = SCSI_DEVICE_BLOCK_MAX_TIMEOUT; | 371 | static unsigned int fc_dev_loss_tmo = 60; /* seconds */ |
372 | 372 | ||
373 | module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); | 373 | module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); |
374 | MODULE_PARM_DESC(dev_loss_tmo, | 374 | MODULE_PARM_DESC(dev_loss_tmo, |
@@ -1284,7 +1284,9 @@ EXPORT_SYMBOL(fc_release_transport); | |||
1284 | * @work: Work to queue for execution. | 1284 | * @work: Work to queue for execution. |
1285 | * | 1285 | * |
1286 | * Return value: | 1286 | * Return value: |
1287 | * 0 on success / != 0 for error | 1287 | * 1 - work queued for execution |
1288 | * 0 - work is already queued | ||
1289 | * -EINVAL - work queue doesn't exist | ||
1288 | **/ | 1290 | **/ |
1289 | static int | 1291 | static int |
1290 | fc_queue_work(struct Scsi_Host *shost, struct work_struct *work) | 1292 | fc_queue_work(struct Scsi_Host *shost, struct work_struct *work) |
@@ -1434,8 +1436,6 @@ fc_starget_delete(void *data) | |||
1434 | struct Scsi_Host *shost = rport_to_shost(rport); | 1436 | struct Scsi_Host *shost = rport_to_shost(rport); |
1435 | unsigned long flags; | 1437 | unsigned long flags; |
1436 | 1438 | ||
1437 | scsi_target_unblock(&rport->dev); | ||
1438 | |||
1439 | spin_lock_irqsave(shost->host_lock, flags); | 1439 | spin_lock_irqsave(shost->host_lock, flags); |
1440 | if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { | 1440 | if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { |
1441 | spin_unlock_irqrestore(shost->host_lock, flags); | 1441 | spin_unlock_irqrestore(shost->host_lock, flags); |
@@ -1476,7 +1476,8 @@ fc_rport_final_delete(void *data) | |||
1476 | transport_remove_device(dev); | 1476 | transport_remove_device(dev); |
1477 | device_del(dev); | 1477 | device_del(dev); |
1478 | transport_destroy_device(dev); | 1478 | transport_destroy_device(dev); |
1479 | put_device(&shost->shost_gendev); | 1479 | put_device(&shost->shost_gendev); /* for fc_host->rport list */ |
1480 | put_device(dev); /* for self-reference */ | ||
1480 | } | 1481 | } |
1481 | 1482 | ||
1482 | 1483 | ||
@@ -1537,13 +1538,13 @@ fc_rport_create(struct Scsi_Host *shost, int channel, | |||
1537 | else | 1538 | else |
1538 | rport->scsi_target_id = -1; | 1539 | rport->scsi_target_id = -1; |
1539 | list_add_tail(&rport->peers, &fc_host->rports); | 1540 | list_add_tail(&rport->peers, &fc_host->rports); |
1540 | get_device(&shost->shost_gendev); | 1541 | get_device(&shost->shost_gendev); /* for fc_host->rport list */ |
1541 | 1542 | ||
1542 | spin_unlock_irqrestore(shost->host_lock, flags); | 1543 | spin_unlock_irqrestore(shost->host_lock, flags); |
1543 | 1544 | ||
1544 | dev = &rport->dev; | 1545 | dev = &rport->dev; |
1545 | device_initialize(dev); | 1546 | device_initialize(dev); /* takes self reference */ |
1546 | dev->parent = get_device(&shost->shost_gendev); | 1547 | dev->parent = get_device(&shost->shost_gendev); /* parent reference */ |
1547 | dev->release = fc_rport_dev_release; | 1548 | dev->release = fc_rport_dev_release; |
1548 | sprintf(dev->bus_id, "rport-%d:%d-%d", | 1549 | sprintf(dev->bus_id, "rport-%d:%d-%d", |
1549 | shost->host_no, channel, rport->number); | 1550 | shost->host_no, channel, rport->number); |
@@ -1567,10 +1568,9 @@ fc_rport_create(struct Scsi_Host *shost, int channel, | |||
1567 | 1568 | ||
1568 | delete_rport: | 1569 | delete_rport: |
1569 | transport_destroy_device(dev); | 1570 | transport_destroy_device(dev); |
1570 | put_device(dev->parent); | ||
1571 | spin_lock_irqsave(shost->host_lock, flags); | 1571 | spin_lock_irqsave(shost->host_lock, flags); |
1572 | list_del(&rport->peers); | 1572 | list_del(&rport->peers); |
1573 | put_device(&shost->shost_gendev); | 1573 | put_device(&shost->shost_gendev); /* for fc_host->rport list */ |
1574 | spin_unlock_irqrestore(shost->host_lock, flags); | 1574 | spin_unlock_irqrestore(shost->host_lock, flags); |
1575 | put_device(dev->parent); | 1575 | put_device(dev->parent); |
1576 | kfree(rport); | 1576 | kfree(rport); |
@@ -1707,6 +1707,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, | |||
1707 | 1707 | ||
1708 | spin_unlock_irqrestore(shost->host_lock, flags); | 1708 | spin_unlock_irqrestore(shost->host_lock, flags); |
1709 | 1709 | ||
1710 | scsi_target_unblock(&rport->dev); | ||
1711 | |||
1710 | return rport; | 1712 | return rport; |
1711 | } | 1713 | } |
1712 | } | 1714 | } |
@@ -1762,9 +1764,10 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, | |||
1762 | /* initiate a scan of the target */ | 1764 | /* initiate a scan of the target */ |
1763 | rport->flags |= FC_RPORT_SCAN_PENDING; | 1765 | rport->flags |= FC_RPORT_SCAN_PENDING; |
1764 | scsi_queue_work(shost, &rport->scan_work); | 1766 | scsi_queue_work(shost, &rport->scan_work); |
1765 | } | 1767 | spin_unlock_irqrestore(shost->host_lock, flags); |
1766 | 1768 | scsi_target_unblock(&rport->dev); | |
1767 | spin_unlock_irqrestore(shost->host_lock, flags); | 1769 | } else |
1770 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1768 | 1771 | ||
1769 | return rport; | 1772 | return rport; |
1770 | } | 1773 | } |
@@ -1938,6 +1941,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) | |||
1938 | rport->flags |= FC_RPORT_SCAN_PENDING; | 1941 | rport->flags |= FC_RPORT_SCAN_PENDING; |
1939 | scsi_queue_work(shost, &rport->scan_work); | 1942 | scsi_queue_work(shost, &rport->scan_work); |
1940 | spin_unlock_irqrestore(shost->host_lock, flags); | 1943 | spin_unlock_irqrestore(shost->host_lock, flags); |
1944 | scsi_target_unblock(&rport->dev); | ||
1941 | } | 1945 | } |
1942 | } | 1946 | } |
1943 | EXPORT_SYMBOL(fc_remote_port_rolechg); | 1947 | EXPORT_SYMBOL(fc_remote_port_rolechg); |
@@ -1970,8 +1974,9 @@ fc_timeout_deleted_rport(void *data) | |||
1970 | dev_printk(KERN_ERR, &rport->dev, | 1974 | dev_printk(KERN_ERR, &rport->dev, |
1971 | "blocked FC remote port time out: no longer" | 1975 | "blocked FC remote port time out: no longer" |
1972 | " a FCP target, removing starget\n"); | 1976 | " a FCP target, removing starget\n"); |
1973 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
1974 | spin_unlock_irqrestore(shost->host_lock, flags); | 1977 | spin_unlock_irqrestore(shost->host_lock, flags); |
1978 | scsi_target_unblock(&rport->dev); | ||
1979 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
1975 | return; | 1980 | return; |
1976 | } | 1981 | } |
1977 | 1982 | ||
@@ -2035,17 +2040,15 @@ fc_timeout_deleted_rport(void *data) | |||
2035 | * went away and didn't come back - we'll remove | 2040 | * went away and didn't come back - we'll remove |
2036 | * all attached scsi devices. | 2041 | * all attached scsi devices. |
2037 | */ | 2042 | */ |
2038 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
2039 | |||
2040 | spin_unlock_irqrestore(shost->host_lock, flags); | 2043 | spin_unlock_irqrestore(shost->host_lock, flags); |
2044 | |||
2045 | scsi_target_unblock(&rport->dev); | ||
2046 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
2041 | } | 2047 | } |
2042 | 2048 | ||
2043 | /** | 2049 | /** |
2044 | * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. | 2050 | * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. |
2045 | * | 2051 | * |
2046 | * Will unblock the target (in case it went away and has now come back), | ||
2047 | * then invoke a scan. | ||
2048 | * | ||
2049 | * @data: remote port to be scanned. | 2052 | * @data: remote port to be scanned. |
2050 | **/ | 2053 | **/ |
2051 | static void | 2054 | static void |
@@ -2057,7 +2060,6 @@ fc_scsi_scan_rport(void *data) | |||
2057 | 2060 | ||
2058 | if ((rport->port_state == FC_PORTSTATE_ONLINE) && | 2061 | if ((rport->port_state == FC_PORTSTATE_ONLINE) && |
2059 | (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { | 2062 | (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { |
2060 | scsi_target_unblock(&rport->dev); | ||
2061 | scsi_scan_target(&rport->dev, rport->channel, | 2063 | scsi_scan_target(&rport->dev, rport->channel, |
2062 | rport->scsi_target_id, SCAN_WILD_CARD, 1); | 2064 | rport->scsi_target_id, SCAN_WILD_CARD, 1); |
2063 | } | 2065 | } |
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 5569fdcfd621..7b9e8fa1a4e0 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -228,14 +228,11 @@ static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid) | |||
228 | static void iscsi_session_release(struct device *dev) | 228 | static void iscsi_session_release(struct device *dev) |
229 | { | 229 | { |
230 | struct iscsi_cls_session *session = iscsi_dev_to_session(dev); | 230 | struct iscsi_cls_session *session = iscsi_dev_to_session(dev); |
231 | struct iscsi_transport *transport = session->transport; | ||
232 | struct Scsi_Host *shost; | 231 | struct Scsi_Host *shost; |
233 | 232 | ||
234 | shost = iscsi_session_to_shost(session); | 233 | shost = iscsi_session_to_shost(session); |
235 | scsi_host_put(shost); | 234 | scsi_host_put(shost); |
236 | kfree(session->targetname); | ||
237 | kfree(session); | 235 | kfree(session); |
238 | module_put(transport->owner); | ||
239 | } | 236 | } |
240 | 237 | ||
241 | static int iscsi_is_session_dev(const struct device *dev) | 238 | static int iscsi_is_session_dev(const struct device *dev) |
@@ -251,10 +248,9 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, | |||
251 | 248 | ||
252 | mutex_lock(&ihost->mutex); | 249 | mutex_lock(&ihost->mutex); |
253 | list_for_each_entry(session, &ihost->sessions, host_list) { | 250 | list_for_each_entry(session, &ihost->sessions, host_list) { |
254 | if ((channel == SCAN_WILD_CARD || | 251 | if ((channel == SCAN_WILD_CARD || channel == 0) && |
255 | channel == session->channel) && | ||
256 | (id == SCAN_WILD_CARD || id == session->target_id)) | 252 | (id == SCAN_WILD_CARD || id == session->target_id)) |
257 | scsi_scan_target(&session->dev, session->channel, | 253 | scsi_scan_target(&session->dev, 0, |
258 | session->target_id, lun, 1); | 254 | session->target_id, lun, 1); |
259 | } | 255 | } |
260 | mutex_unlock(&ihost->mutex); | 256 | mutex_unlock(&ihost->mutex); |
@@ -291,80 +287,92 @@ void iscsi_block_session(struct iscsi_cls_session *session) | |||
291 | } | 287 | } |
292 | EXPORT_SYMBOL_GPL(iscsi_block_session); | 288 | EXPORT_SYMBOL_GPL(iscsi_block_session); |
293 | 289 | ||
294 | /** | ||
295 | * iscsi_create_session - create iscsi class session | ||
296 | * @shost: scsi host | ||
297 | * @transport: iscsi transport | ||
298 | * | ||
299 | * This can be called from a LLD or iscsi_transport. | ||
300 | **/ | ||
301 | struct iscsi_cls_session * | 290 | struct iscsi_cls_session * |
302 | iscsi_create_session(struct Scsi_Host *shost, | 291 | iscsi_alloc_session(struct Scsi_Host *shost, |
303 | struct iscsi_transport *transport, int channel) | 292 | struct iscsi_transport *transport) |
304 | { | 293 | { |
305 | struct iscsi_host *ihost; | ||
306 | struct iscsi_cls_session *session; | 294 | struct iscsi_cls_session *session; |
307 | int err; | ||
308 | |||
309 | if (!try_module_get(transport->owner)) | ||
310 | return NULL; | ||
311 | 295 | ||
312 | session = kzalloc(sizeof(*session) + transport->sessiondata_size, | 296 | session = kzalloc(sizeof(*session) + transport->sessiondata_size, |
313 | GFP_KERNEL); | 297 | GFP_KERNEL); |
314 | if (!session) | 298 | if (!session) |
315 | goto module_put; | 299 | return NULL; |
300 | |||
316 | session->transport = transport; | 301 | session->transport = transport; |
317 | session->recovery_tmo = 120; | 302 | session->recovery_tmo = 120; |
318 | INIT_WORK(&session->recovery_work, session_recovery_timedout, session); | 303 | INIT_WORK(&session->recovery_work, session_recovery_timedout, session); |
319 | INIT_LIST_HEAD(&session->host_list); | 304 | INIT_LIST_HEAD(&session->host_list); |
320 | INIT_LIST_HEAD(&session->sess_list); | 305 | INIT_LIST_HEAD(&session->sess_list); |
321 | 306 | ||
307 | /* this is released in the dev's release function */ | ||
308 | scsi_host_get(shost); | ||
309 | session->dev.parent = &shost->shost_gendev; | ||
310 | session->dev.release = iscsi_session_release; | ||
311 | device_initialize(&session->dev); | ||
322 | if (transport->sessiondata_size) | 312 | if (transport->sessiondata_size) |
323 | session->dd_data = &session[1]; | 313 | session->dd_data = &session[1]; |
314 | return session; | ||
315 | } | ||
316 | EXPORT_SYMBOL_GPL(iscsi_alloc_session); | ||
324 | 317 | ||
325 | /* this is released in the dev's release function */ | 318 | int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) |
326 | scsi_host_get(shost); | 319 | { |
327 | ihost = shost->shost_data; | 320 | struct Scsi_Host *shost = iscsi_session_to_shost(session); |
321 | struct iscsi_host *ihost; | ||
322 | int err; | ||
328 | 323 | ||
324 | ihost = shost->shost_data; | ||
329 | session->sid = iscsi_session_nr++; | 325 | session->sid = iscsi_session_nr++; |
330 | session->channel = channel; | 326 | session->target_id = target_id; |
331 | session->target_id = ihost->next_target_id++; | ||
332 | 327 | ||
333 | snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", | 328 | snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", |
334 | session->sid); | 329 | session->sid); |
335 | session->dev.parent = &shost->shost_gendev; | 330 | err = device_add(&session->dev); |
336 | session->dev.release = iscsi_session_release; | ||
337 | err = device_register(&session->dev); | ||
338 | if (err) { | 331 | if (err) { |
339 | dev_printk(KERN_ERR, &session->dev, "iscsi: could not " | 332 | dev_printk(KERN_ERR, &session->dev, "iscsi: could not " |
340 | "register session's dev\n"); | 333 | "register session's dev\n"); |
341 | goto free_session; | 334 | goto release_host; |
342 | } | 335 | } |
343 | transport_register_device(&session->dev); | 336 | transport_register_device(&session->dev); |
344 | 337 | ||
345 | mutex_lock(&ihost->mutex); | 338 | mutex_lock(&ihost->mutex); |
346 | list_add(&session->host_list, &ihost->sessions); | 339 | list_add(&session->host_list, &ihost->sessions); |
347 | mutex_unlock(&ihost->mutex); | 340 | mutex_unlock(&ihost->mutex); |
341 | return 0; | ||
348 | 342 | ||
349 | return session; | 343 | release_host: |
350 | 344 | scsi_host_put(shost); | |
351 | free_session: | 345 | return err; |
352 | kfree(session); | ||
353 | module_put: | ||
354 | module_put(transport->owner); | ||
355 | return NULL; | ||
356 | } | 346 | } |
357 | 347 | EXPORT_SYMBOL_GPL(iscsi_add_session); | |
358 | EXPORT_SYMBOL_GPL(iscsi_create_session); | ||
359 | 348 | ||
360 | /** | 349 | /** |
361 | * iscsi_destroy_session - destroy iscsi session | 350 | * iscsi_create_session - create iscsi class session |
362 | * @session: iscsi_session | 351 | * @shost: scsi host |
352 | * @transport: iscsi transport | ||
363 | * | 353 | * |
364 | * Can be called by a LLD or iscsi_transport. There must not be | 354 | * This can be called from a LLD or iscsi_transport. |
365 | * any running connections. | ||
366 | **/ | 355 | **/ |
367 | int iscsi_destroy_session(struct iscsi_cls_session *session) | 356 | struct iscsi_cls_session * |
357 | iscsi_create_session(struct Scsi_Host *shost, | ||
358 | struct iscsi_transport *transport, | ||
359 | unsigned int target_id) | ||
360 | { | ||
361 | struct iscsi_cls_session *session; | ||
362 | |||
363 | session = iscsi_alloc_session(shost, transport); | ||
364 | if (!session) | ||
365 | return NULL; | ||
366 | |||
367 | if (iscsi_add_session(session, target_id)) { | ||
368 | iscsi_free_session(session); | ||
369 | return NULL; | ||
370 | } | ||
371 | return session; | ||
372 | } | ||
373 | EXPORT_SYMBOL_GPL(iscsi_create_session); | ||
374 | |||
375 | void iscsi_remove_session(struct iscsi_cls_session *session) | ||
368 | { | 376 | { |
369 | struct Scsi_Host *shost = iscsi_session_to_shost(session); | 377 | struct Scsi_Host *shost = iscsi_session_to_shost(session); |
370 | struct iscsi_host *ihost = shost->shost_data; | 378 | struct iscsi_host *ihost = shost->shost_data; |
@@ -376,19 +384,88 @@ int iscsi_destroy_session(struct iscsi_cls_session *session) | |||
376 | list_del(&session->host_list); | 384 | list_del(&session->host_list); |
377 | mutex_unlock(&ihost->mutex); | 385 | mutex_unlock(&ihost->mutex); |
378 | 386 | ||
387 | scsi_remove_target(&session->dev); | ||
388 | |||
379 | transport_unregister_device(&session->dev); | 389 | transport_unregister_device(&session->dev); |
380 | device_unregister(&session->dev); | 390 | device_del(&session->dev); |
381 | return 0; | 391 | } |
392 | EXPORT_SYMBOL_GPL(iscsi_remove_session); | ||
393 | |||
394 | void iscsi_free_session(struct iscsi_cls_session *session) | ||
395 | { | ||
396 | put_device(&session->dev); | ||
382 | } | 397 | } |
383 | 398 | ||
399 | EXPORT_SYMBOL_GPL(iscsi_free_session); | ||
400 | |||
401 | /** | ||
402 | * iscsi_destroy_session - destroy iscsi session | ||
403 | * @session: iscsi_session | ||
404 | * | ||
405 | * Can be called by a LLD or iscsi_transport. There must not be | ||
406 | * any running connections. | ||
407 | **/ | ||
408 | int iscsi_destroy_session(struct iscsi_cls_session *session) | ||
409 | { | ||
410 | iscsi_remove_session(session); | ||
411 | iscsi_free_session(session); | ||
412 | return 0; | ||
413 | } | ||
384 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); | 414 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); |
385 | 415 | ||
416 | static void mempool_zone_destroy(struct mempool_zone *zp) | ||
417 | { | ||
418 | mempool_destroy(zp->pool); | ||
419 | kfree(zp); | ||
420 | } | ||
421 | |||
422 | static void* | ||
423 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) | ||
424 | { | ||
425 | struct mempool_zone *zone = pool_data; | ||
426 | |||
427 | return alloc_skb(zone->size, gfp_mask); | ||
428 | } | ||
429 | |||
430 | static void | ||
431 | mempool_zone_free_skb(void *element, void *pool_data) | ||
432 | { | ||
433 | kfree_skb(element); | ||
434 | } | ||
435 | |||
436 | static struct mempool_zone * | ||
437 | mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) | ||
438 | { | ||
439 | struct mempool_zone *zp; | ||
440 | |||
441 | zp = kzalloc(sizeof(*zp), GFP_KERNEL); | ||
442 | if (!zp) | ||
443 | return NULL; | ||
444 | |||
445 | zp->size = size; | ||
446 | zp->hiwat = hiwat; | ||
447 | INIT_LIST_HEAD(&zp->freequeue); | ||
448 | spin_lock_init(&zp->freelock); | ||
449 | atomic_set(&zp->allocated, 0); | ||
450 | |||
451 | zp->pool = mempool_create(max, mempool_zone_alloc_skb, | ||
452 | mempool_zone_free_skb, zp); | ||
453 | if (!zp->pool) { | ||
454 | kfree(zp); | ||
455 | return NULL; | ||
456 | } | ||
457 | |||
458 | return zp; | ||
459 | } | ||
460 | |||
386 | static void iscsi_conn_release(struct device *dev) | 461 | static void iscsi_conn_release(struct device *dev) |
387 | { | 462 | { |
388 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); | 463 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); |
389 | struct device *parent = conn->dev.parent; | 464 | struct device *parent = conn->dev.parent; |
390 | 465 | ||
391 | kfree(conn->persistent_address); | 466 | mempool_zone_destroy(conn->z_pdu); |
467 | mempool_zone_destroy(conn->z_error); | ||
468 | |||
392 | kfree(conn); | 469 | kfree(conn); |
393 | put_device(parent); | 470 | put_device(parent); |
394 | } | 471 | } |
@@ -398,6 +475,31 @@ static int iscsi_is_conn_dev(const struct device *dev) | |||
398 | return dev->release == iscsi_conn_release; | 475 | return dev->release == iscsi_conn_release; |
399 | } | 476 | } |
400 | 477 | ||
478 | static int iscsi_create_event_pools(struct iscsi_cls_conn *conn) | ||
479 | { | ||
480 | conn->z_pdu = mempool_zone_init(Z_MAX_PDU, | ||
481 | NLMSG_SPACE(sizeof(struct iscsi_uevent) + | ||
482 | sizeof(struct iscsi_hdr) + | ||
483 | DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), | ||
484 | Z_HIWAT_PDU); | ||
485 | if (!conn->z_pdu) { | ||
486 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
487 | "pdu zone for new conn\n"); | ||
488 | return -ENOMEM; | ||
489 | } | ||
490 | |||
491 | conn->z_error = mempool_zone_init(Z_MAX_ERROR, | ||
492 | NLMSG_SPACE(sizeof(struct iscsi_uevent)), | ||
493 | Z_HIWAT_ERROR); | ||
494 | if (!conn->z_error) { | ||
495 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
496 | "error zone for new conn\n"); | ||
497 | mempool_zone_destroy(conn->z_pdu); | ||
498 | return -ENOMEM; | ||
499 | } | ||
500 | return 0; | ||
501 | } | ||
502 | |||
401 | /** | 503 | /** |
402 | * iscsi_create_conn - create iscsi class connection | 504 | * iscsi_create_conn - create iscsi class connection |
403 | * @session: iscsi cls session | 505 | * @session: iscsi cls session |
@@ -430,9 +532,12 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) | |||
430 | conn->transport = transport; | 532 | conn->transport = transport; |
431 | conn->cid = cid; | 533 | conn->cid = cid; |
432 | 534 | ||
535 | if (iscsi_create_event_pools(conn)) | ||
536 | goto free_conn; | ||
537 | |||
433 | /* this is released in the dev's release function */ | 538 | /* this is released in the dev's release function */ |
434 | if (!get_device(&session->dev)) | 539 | if (!get_device(&session->dev)) |
435 | goto free_conn; | 540 | goto free_conn_pools; |
436 | 541 | ||
437 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", | 542 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", |
438 | session->sid, cid); | 543 | session->sid, cid); |
@@ -449,6 +554,8 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) | |||
449 | 554 | ||
450 | release_parent_ref: | 555 | release_parent_ref: |
451 | put_device(&session->dev); | 556 | put_device(&session->dev); |
557 | free_conn_pools: | ||
558 | |||
452 | free_conn: | 559 | free_conn: |
453 | kfree(conn); | 560 | kfree(conn); |
454 | return NULL; | 561 | return NULL; |
@@ -496,20 +603,6 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) | |||
496 | return (struct list_head *)&skb->cb; | 603 | return (struct list_head *)&skb->cb; |
497 | } | 604 | } |
498 | 605 | ||
499 | static void* | ||
500 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) | ||
501 | { | ||
502 | struct mempool_zone *zone = pool_data; | ||
503 | |||
504 | return alloc_skb(zone->size, gfp_mask); | ||
505 | } | ||
506 | |||
507 | static void | ||
508 | mempool_zone_free_skb(void *element, void *pool_data) | ||
509 | { | ||
510 | kfree_skb(element); | ||
511 | } | ||
512 | |||
513 | static void | 606 | static void |
514 | mempool_zone_complete(struct mempool_zone *zone) | 607 | mempool_zone_complete(struct mempool_zone *zone) |
515 | { | 608 | { |
@@ -529,37 +622,6 @@ mempool_zone_complete(struct mempool_zone *zone) | |||
529 | spin_unlock_irqrestore(&zone->freelock, flags); | 622 | spin_unlock_irqrestore(&zone->freelock, flags); |
530 | } | 623 | } |
531 | 624 | ||
532 | static struct mempool_zone * | ||
533 | mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) | ||
534 | { | ||
535 | struct mempool_zone *zp; | ||
536 | |||
537 | zp = kzalloc(sizeof(*zp), GFP_KERNEL); | ||
538 | if (!zp) | ||
539 | return NULL; | ||
540 | |||
541 | zp->size = size; | ||
542 | zp->hiwat = hiwat; | ||
543 | INIT_LIST_HEAD(&zp->freequeue); | ||
544 | spin_lock_init(&zp->freelock); | ||
545 | atomic_set(&zp->allocated, 0); | ||
546 | |||
547 | zp->pool = mempool_create(max, mempool_zone_alloc_skb, | ||
548 | mempool_zone_free_skb, zp); | ||
549 | if (!zp->pool) { | ||
550 | kfree(zp); | ||
551 | return NULL; | ||
552 | } | ||
553 | |||
554 | return zp; | ||
555 | } | ||
556 | |||
557 | static void mempool_zone_destroy(struct mempool_zone *zp) | ||
558 | { | ||
559 | mempool_destroy(zp->pool); | ||
560 | kfree(zp); | ||
561 | } | ||
562 | |||
563 | static struct sk_buff* | 625 | static struct sk_buff* |
564 | mempool_zone_get_skb(struct mempool_zone *zone) | 626 | mempool_zone_get_skb(struct mempool_zone *zone) |
565 | { | 627 | { |
@@ -572,6 +634,27 @@ mempool_zone_get_skb(struct mempool_zone *zone) | |||
572 | } | 634 | } |
573 | 635 | ||
574 | static int | 636 | static int |
637 | iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb) | ||
638 | { | ||
639 | unsigned long flags; | ||
640 | int rc; | ||
641 | |||
642 | skb_get(skb); | ||
643 | rc = netlink_broadcast(nls, skb, 0, 1, GFP_KERNEL); | ||
644 | if (rc < 0) { | ||
645 | mempool_free(skb, zone->pool); | ||
646 | printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc); | ||
647 | return rc; | ||
648 | } | ||
649 | |||
650 | spin_lock_irqsave(&zone->freelock, flags); | ||
651 | INIT_LIST_HEAD(skb_to_lh(skb)); | ||
652 | list_add(skb_to_lh(skb), &zone->freequeue); | ||
653 | spin_unlock_irqrestore(&zone->freelock, flags); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | static int | ||
575 | iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) | 658 | iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) |
576 | { | 659 | { |
577 | unsigned long flags; | 660 | unsigned long flags; |
@@ -666,7 +749,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) | |||
666 | ev->r.connerror.cid = conn->cid; | 749 | ev->r.connerror.cid = conn->cid; |
667 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); | 750 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); |
668 | 751 | ||
669 | iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid); | 752 | iscsi_broadcast_skb(conn->z_error, skb); |
670 | 753 | ||
671 | dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", | 754 | dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", |
672 | error); | 755 | error); |
@@ -767,6 +850,131 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
767 | return err; | 850 | return err; |
768 | } | 851 | } |
769 | 852 | ||
853 | /** | ||
854 | * iscsi_if_destroy_session_done - send session destr. completion event | ||
855 | * @conn: last connection for session | ||
856 | * | ||
857 | * This is called by HW iscsi LLDs to notify userpsace that its HW has | ||
858 | * removed a session. | ||
859 | **/ | ||
860 | int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) | ||
861 | { | ||
862 | struct iscsi_internal *priv; | ||
863 | struct iscsi_cls_session *session; | ||
864 | struct Scsi_Host *shost; | ||
865 | struct iscsi_uevent *ev; | ||
866 | struct sk_buff *skb; | ||
867 | struct nlmsghdr *nlh; | ||
868 | unsigned long flags; | ||
869 | int rc, len = NLMSG_SPACE(sizeof(*ev)); | ||
870 | |||
871 | priv = iscsi_if_transport_lookup(conn->transport); | ||
872 | if (!priv) | ||
873 | return -EINVAL; | ||
874 | |||
875 | session = iscsi_dev_to_session(conn->dev.parent); | ||
876 | shost = iscsi_session_to_shost(session); | ||
877 | |||
878 | mempool_zone_complete(conn->z_pdu); | ||
879 | |||
880 | skb = mempool_zone_get_skb(conn->z_pdu); | ||
881 | if (!skb) { | ||
882 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
883 | "session creation event\n"); | ||
884 | return -ENOMEM; | ||
885 | } | ||
886 | |||
887 | nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); | ||
888 | ev = NLMSG_DATA(nlh); | ||
889 | ev->transport_handle = iscsi_handle(conn->transport); | ||
890 | ev->type = ISCSI_KEVENT_DESTROY_SESSION; | ||
891 | ev->r.d_session.host_no = shost->host_no; | ||
892 | ev->r.d_session.sid = session->sid; | ||
893 | |||
894 | /* | ||
895 | * this will occur if the daemon is not up, so we just warn | ||
896 | * the user and when the daemon is restarted it will handle it | ||
897 | */ | ||
898 | rc = iscsi_broadcast_skb(conn->z_pdu, skb); | ||
899 | if (rc < 0) | ||
900 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
901 | "session destruction event. Check iscsi daemon\n"); | ||
902 | |||
903 | spin_lock_irqsave(&sesslock, flags); | ||
904 | list_del(&session->sess_list); | ||
905 | spin_unlock_irqrestore(&sesslock, flags); | ||
906 | |||
907 | spin_lock_irqsave(&connlock, flags); | ||
908 | conn->active = 0; | ||
909 | list_del(&conn->conn_list); | ||
910 | spin_unlock_irqrestore(&connlock, flags); | ||
911 | |||
912 | return rc; | ||
913 | } | ||
914 | EXPORT_SYMBOL_GPL(iscsi_if_destroy_session_done); | ||
915 | |||
916 | /** | ||
917 | * iscsi_if_create_session_done - send session creation completion event | ||
918 | * @conn: leading connection for session | ||
919 | * | ||
920 | * This is called by HW iscsi LLDs to notify userpsace that its HW has | ||
921 | * created a session or a existing session is back in the logged in state. | ||
922 | **/ | ||
923 | int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) | ||
924 | { | ||
925 | struct iscsi_internal *priv; | ||
926 | struct iscsi_cls_session *session; | ||
927 | struct Scsi_Host *shost; | ||
928 | struct iscsi_uevent *ev; | ||
929 | struct sk_buff *skb; | ||
930 | struct nlmsghdr *nlh; | ||
931 | unsigned long flags; | ||
932 | int rc, len = NLMSG_SPACE(sizeof(*ev)); | ||
933 | |||
934 | priv = iscsi_if_transport_lookup(conn->transport); | ||
935 | if (!priv) | ||
936 | return -EINVAL; | ||
937 | |||
938 | session = iscsi_dev_to_session(conn->dev.parent); | ||
939 | shost = iscsi_session_to_shost(session); | ||
940 | |||
941 | mempool_zone_complete(conn->z_pdu); | ||
942 | |||
943 | skb = mempool_zone_get_skb(conn->z_pdu); | ||
944 | if (!skb) { | ||
945 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
946 | "session creation event\n"); | ||
947 | return -ENOMEM; | ||
948 | } | ||
949 | |||
950 | nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); | ||
951 | ev = NLMSG_DATA(nlh); | ||
952 | ev->transport_handle = iscsi_handle(conn->transport); | ||
953 | ev->type = ISCSI_UEVENT_CREATE_SESSION; | ||
954 | ev->r.c_session_ret.host_no = shost->host_no; | ||
955 | ev->r.c_session_ret.sid = session->sid; | ||
956 | |||
957 | /* | ||
958 | * this will occur if the daemon is not up, so we just warn | ||
959 | * the user and when the daemon is restarted it will handle it | ||
960 | */ | ||
961 | rc = iscsi_broadcast_skb(conn->z_pdu, skb); | ||
962 | if (rc < 0) | ||
963 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
964 | "session creation event. Check iscsi daemon\n"); | ||
965 | |||
966 | spin_lock_irqsave(&sesslock, flags); | ||
967 | list_add(&session->sess_list, &sesslist); | ||
968 | spin_unlock_irqrestore(&sesslock, flags); | ||
969 | |||
970 | spin_lock_irqsave(&connlock, flags); | ||
971 | list_add(&conn->conn_list, &connlist); | ||
972 | conn->active = 1; | ||
973 | spin_unlock_irqrestore(&connlock, flags); | ||
974 | return rc; | ||
975 | } | ||
976 | EXPORT_SYMBOL_GPL(iscsi_if_create_session_done); | ||
977 | |||
770 | static int | 978 | static int |
771 | iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) | 979 | iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) |
772 | { | 980 | { |
@@ -812,26 +1020,6 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
812 | return -ENOMEM; | 1020 | return -ENOMEM; |
813 | } | 1021 | } |
814 | 1022 | ||
815 | conn->z_pdu = mempool_zone_init(Z_MAX_PDU, | ||
816 | NLMSG_SPACE(sizeof(struct iscsi_uevent) + | ||
817 | sizeof(struct iscsi_hdr) + | ||
818 | DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), | ||
819 | Z_HIWAT_PDU); | ||
820 | if (!conn->z_pdu) { | ||
821 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
822 | "pdu zone for new conn\n"); | ||
823 | goto destroy_conn; | ||
824 | } | ||
825 | |||
826 | conn->z_error = mempool_zone_init(Z_MAX_ERROR, | ||
827 | NLMSG_SPACE(sizeof(struct iscsi_uevent)), | ||
828 | Z_HIWAT_ERROR); | ||
829 | if (!conn->z_error) { | ||
830 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
831 | "error zone for new conn\n"); | ||
832 | goto free_pdu_pool; | ||
833 | } | ||
834 | |||
835 | ev->r.c_conn_ret.sid = session->sid; | 1023 | ev->r.c_conn_ret.sid = session->sid; |
836 | ev->r.c_conn_ret.cid = conn->cid; | 1024 | ev->r.c_conn_ret.cid = conn->cid; |
837 | 1025 | ||
@@ -841,13 +1029,6 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
841 | spin_unlock_irqrestore(&connlock, flags); | 1029 | spin_unlock_irqrestore(&connlock, flags); |
842 | 1030 | ||
843 | return 0; | 1031 | return 0; |
844 | |||
845 | free_pdu_pool: | ||
846 | mempool_zone_destroy(conn->z_pdu); | ||
847 | destroy_conn: | ||
848 | if (transport->destroy_conn) | ||
849 | transport->destroy_conn(conn->dd_data); | ||
850 | return -ENOMEM; | ||
851 | } | 1032 | } |
852 | 1033 | ||
853 | static int | 1034 | static int |
@@ -855,7 +1036,6 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev | |||
855 | { | 1036 | { |
856 | unsigned long flags; | 1037 | unsigned long flags; |
857 | struct iscsi_cls_conn *conn; | 1038 | struct iscsi_cls_conn *conn; |
858 | struct mempool_zone *z_error, *z_pdu; | ||
859 | 1039 | ||
860 | conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); | 1040 | conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); |
861 | if (!conn) | 1041 | if (!conn) |
@@ -865,35 +1045,18 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev | |||
865 | list_del(&conn->conn_list); | 1045 | list_del(&conn->conn_list); |
866 | spin_unlock_irqrestore(&connlock, flags); | 1046 | spin_unlock_irqrestore(&connlock, flags); |
867 | 1047 | ||
868 | z_pdu = conn->z_pdu; | ||
869 | z_error = conn->z_error; | ||
870 | |||
871 | if (transport->destroy_conn) | 1048 | if (transport->destroy_conn) |
872 | transport->destroy_conn(conn); | 1049 | transport->destroy_conn(conn); |
873 | |||
874 | mempool_zone_destroy(z_pdu); | ||
875 | mempool_zone_destroy(z_error); | ||
876 | |||
877 | return 0; | 1050 | return 0; |
878 | } | 1051 | } |
879 | 1052 | ||
880 | static void | ||
881 | iscsi_copy_param(struct iscsi_uevent *ev, uint32_t *value, char *data) | ||
882 | { | ||
883 | if (ev->u.set_param.len != sizeof(uint32_t)) | ||
884 | BUG(); | ||
885 | memcpy(value, data, min_t(uint32_t, sizeof(uint32_t), | ||
886 | ev->u.set_param.len)); | ||
887 | } | ||
888 | |||
889 | static int | 1053 | static int |
890 | iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) | 1054 | iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) |
891 | { | 1055 | { |
892 | char *data = (char*)ev + sizeof(*ev); | 1056 | char *data = (char*)ev + sizeof(*ev); |
893 | struct iscsi_cls_conn *conn; | 1057 | struct iscsi_cls_conn *conn; |
894 | struct iscsi_cls_session *session; | 1058 | struct iscsi_cls_session *session; |
895 | int err = 0; | 1059 | int err = 0, value = 0; |
896 | uint32_t value = 0; | ||
897 | 1060 | ||
898 | session = iscsi_session_lookup(ev->u.set_param.sid); | 1061 | session = iscsi_session_lookup(ev->u.set_param.sid); |
899 | conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); | 1062 | conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); |
@@ -902,42 +1065,13 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
902 | 1065 | ||
903 | switch (ev->u.set_param.param) { | 1066 | switch (ev->u.set_param.param) { |
904 | case ISCSI_PARAM_SESS_RECOVERY_TMO: | 1067 | case ISCSI_PARAM_SESS_RECOVERY_TMO: |
905 | iscsi_copy_param(ev, &value, data); | 1068 | sscanf(data, "%d", &value); |
906 | if (value != 0) | 1069 | if (value != 0) |
907 | session->recovery_tmo = value; | 1070 | session->recovery_tmo = value; |
908 | break; | 1071 | break; |
909 | case ISCSI_PARAM_TARGET_NAME: | ||
910 | /* this should not change between logins */ | ||
911 | if (session->targetname) | ||
912 | return 0; | ||
913 | |||
914 | session->targetname = kstrdup(data, GFP_KERNEL); | ||
915 | if (!session->targetname) | ||
916 | return -ENOMEM; | ||
917 | break; | ||
918 | case ISCSI_PARAM_TPGT: | ||
919 | iscsi_copy_param(ev, &value, data); | ||
920 | session->tpgt = value; | ||
921 | break; | ||
922 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
923 | iscsi_copy_param(ev, &value, data); | ||
924 | conn->persistent_port = value; | ||
925 | break; | ||
926 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
927 | /* | ||
928 | * this is the address returned in discovery so it should | ||
929 | * not change between logins. | ||
930 | */ | ||
931 | if (conn->persistent_address) | ||
932 | return 0; | ||
933 | |||
934 | conn->persistent_address = kstrdup(data, GFP_KERNEL); | ||
935 | if (!conn->persistent_address) | ||
936 | return -ENOMEM; | ||
937 | break; | ||
938 | default: | 1072 | default: |
939 | iscsi_copy_param(ev, &value, data); | 1073 | err = transport->set_param(conn, ev->u.set_param.param, |
940 | err = transport->set_param(conn, ev->u.set_param.param, value); | 1074 | data, ev->u.set_param.len); |
941 | } | 1075 | } |
942 | 1076 | ||
943 | return err; | 1077 | return err; |
@@ -978,6 +1112,21 @@ iscsi_if_transport_ep(struct iscsi_transport *transport, | |||
978 | } | 1112 | } |
979 | 1113 | ||
980 | static int | 1114 | static int |
1115 | iscsi_tgt_dscvr(struct iscsi_transport *transport, | ||
1116 | struct iscsi_uevent *ev) | ||
1117 | { | ||
1118 | struct sockaddr *dst_addr; | ||
1119 | |||
1120 | if (!transport->tgt_dscvr) | ||
1121 | return -EINVAL; | ||
1122 | |||
1123 | dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); | ||
1124 | return transport->tgt_dscvr(ev->u.tgt_dscvr.type, | ||
1125 | ev->u.tgt_dscvr.host_no, | ||
1126 | ev->u.tgt_dscvr.enable, dst_addr); | ||
1127 | } | ||
1128 | |||
1129 | static int | ||
981 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 1130 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
982 | { | 1131 | { |
983 | int err = 0; | 1132 | int err = 0; |
@@ -1065,6 +1214,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1065 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: | 1214 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: |
1066 | err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); | 1215 | err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); |
1067 | break; | 1216 | break; |
1217 | case ISCSI_UEVENT_TGT_DSCVR: | ||
1218 | err = iscsi_tgt_dscvr(transport, ev); | ||
1219 | break; | ||
1068 | default: | 1220 | default: |
1069 | err = -EINVAL; | 1221 | err = -EINVAL; |
1070 | break; | 1222 | break; |
@@ -1147,49 +1299,31 @@ struct class_device_attribute class_device_attr_##_prefix##_##_name = \ | |||
1147 | /* | 1299 | /* |
1148 | * iSCSI connection attrs | 1300 | * iSCSI connection attrs |
1149 | */ | 1301 | */ |
1150 | #define iscsi_conn_int_attr_show(param, format) \ | 1302 | #define iscsi_conn_attr_show(param) \ |
1151 | static ssize_t \ | ||
1152 | show_conn_int_param_##param(struct class_device *cdev, char *buf) \ | ||
1153 | { \ | ||
1154 | uint32_t value = 0; \ | ||
1155 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | ||
1156 | struct iscsi_transport *t = conn->transport; \ | ||
1157 | \ | ||
1158 | t->get_conn_param(conn, param, &value); \ | ||
1159 | return snprintf(buf, 20, format"\n", value); \ | ||
1160 | } | ||
1161 | |||
1162 | #define iscsi_conn_int_attr(field, param, format) \ | ||
1163 | iscsi_conn_int_attr_show(param, format) \ | ||
1164 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \ | ||
1165 | NULL); | ||
1166 | |||
1167 | iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); | ||
1168 | iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u"); | ||
1169 | iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d"); | ||
1170 | iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); | ||
1171 | iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); | ||
1172 | iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); | ||
1173 | iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); | ||
1174 | iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); | ||
1175 | iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u"); | ||
1176 | |||
1177 | #define iscsi_conn_str_attr_show(param) \ | ||
1178 | static ssize_t \ | 1303 | static ssize_t \ |
1179 | show_conn_str_param_##param(struct class_device *cdev, char *buf) \ | 1304 | show_conn_param_##param(struct class_device *cdev, char *buf) \ |
1180 | { \ | 1305 | { \ |
1181 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | 1306 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ |
1182 | struct iscsi_transport *t = conn->transport; \ | 1307 | struct iscsi_transport *t = conn->transport; \ |
1183 | return t->get_conn_str_param(conn, param, buf); \ | 1308 | return t->get_conn_param(conn, param, buf); \ |
1184 | } | 1309 | } |
1185 | 1310 | ||
1186 | #define iscsi_conn_str_attr(field, param) \ | 1311 | #define iscsi_conn_attr(field, param) \ |
1187 | iscsi_conn_str_attr_show(param) \ | 1312 | iscsi_conn_attr_show(param) \ |
1188 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \ | 1313 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_param_##param, \ |
1189 | NULL); | 1314 | NULL); |
1190 | 1315 | ||
1191 | iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); | 1316 | iscsi_conn_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH); |
1192 | iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); | 1317 | iscsi_conn_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH); |
1318 | iscsi_conn_attr(header_digest, ISCSI_PARAM_HDRDGST_EN); | ||
1319 | iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN); | ||
1320 | iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN); | ||
1321 | iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN); | ||
1322 | iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT); | ||
1323 | iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT); | ||
1324 | iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN); | ||
1325 | iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); | ||
1326 | iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS); | ||
1193 | 1327 | ||
1194 | #define iscsi_cdev_to_session(_cdev) \ | 1328 | #define iscsi_cdev_to_session(_cdev) \ |
1195 | iscsi_dev_to_session(_cdev->dev) | 1329 | iscsi_dev_to_session(_cdev->dev) |
@@ -1197,61 +1331,36 @@ iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); | |||
1197 | /* | 1331 | /* |
1198 | * iSCSI session attrs | 1332 | * iSCSI session attrs |
1199 | */ | 1333 | */ |
1200 | #define iscsi_session_int_attr_show(param, format) \ | 1334 | #define iscsi_session_attr_show(param) \ |
1201 | static ssize_t \ | ||
1202 | show_session_int_param_##param(struct class_device *cdev, char *buf) \ | ||
1203 | { \ | ||
1204 | uint32_t value = 0; \ | ||
1205 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | ||
1206 | struct iscsi_transport *t = session->transport; \ | ||
1207 | \ | ||
1208 | t->get_session_param(session, param, &value); \ | ||
1209 | return snprintf(buf, 20, format"\n", value); \ | ||
1210 | } | ||
1211 | |||
1212 | #define iscsi_session_int_attr(field, param, format) \ | ||
1213 | iscsi_session_int_attr_show(param, format) \ | ||
1214 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \ | ||
1215 | NULL); | ||
1216 | |||
1217 | iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); | ||
1218 | iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu"); | ||
1219 | iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d"); | ||
1220 | iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u"); | ||
1221 | iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u"); | ||
1222 | iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); | ||
1223 | iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); | ||
1224 | iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); | ||
1225 | iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d"); | ||
1226 | |||
1227 | #define iscsi_session_str_attr_show(param) \ | ||
1228 | static ssize_t \ | 1335 | static ssize_t \ |
1229 | show_session_str_param_##param(struct class_device *cdev, char *buf) \ | 1336 | show_session_param_##param(struct class_device *cdev, char *buf) \ |
1230 | { \ | 1337 | { \ |
1231 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | 1338 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ |
1232 | struct iscsi_transport *t = session->transport; \ | 1339 | struct iscsi_transport *t = session->transport; \ |
1233 | return t->get_session_str_param(session, param, buf); \ | 1340 | return t->get_session_param(session, param, buf); \ |
1234 | } | 1341 | } |
1235 | 1342 | ||
1236 | #define iscsi_session_str_attr(field, param) \ | 1343 | #define iscsi_session_attr(field, param) \ |
1237 | iscsi_session_str_attr_show(param) \ | 1344 | iscsi_session_attr_show(param) \ |
1238 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \ | 1345 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_param_##param, \ |
1239 | NULL); | 1346 | NULL); |
1240 | 1347 | ||
1241 | iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME); | 1348 | iscsi_session_attr(targetname, ISCSI_PARAM_TARGET_NAME); |
1349 | iscsi_session_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN); | ||
1350 | iscsi_session_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T); | ||
1351 | iscsi_session_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN); | ||
1352 | iscsi_session_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST); | ||
1353 | iscsi_session_attr(max_burst_len, ISCSI_PARAM_MAX_BURST); | ||
1354 | iscsi_session_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN); | ||
1355 | iscsi_session_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN); | ||
1356 | iscsi_session_attr(erl, ISCSI_PARAM_ERL); | ||
1357 | iscsi_session_attr(tpgt, ISCSI_PARAM_TPGT); | ||
1242 | 1358 | ||
1243 | /* | ||
1244 | * Private session and conn attrs. userspace uses several iscsi values | ||
1245 | * to identify each session between reboots. Some of these values may not | ||
1246 | * be present in the iscsi_transport/LLD driver becuase userspace handles | ||
1247 | * login (and failback for login redirect) so for these type of drivers | ||
1248 | * the class manages the attrs and values for the iscsi_transport/LLD | ||
1249 | */ | ||
1250 | #define iscsi_priv_session_attr_show(field, format) \ | 1359 | #define iscsi_priv_session_attr_show(field, format) \ |
1251 | static ssize_t \ | 1360 | static ssize_t \ |
1252 | show_priv_session_##field(struct class_device *cdev, char *buf) \ | 1361 | show_priv_session_##field(struct class_device *cdev, char *buf) \ |
1253 | { \ | 1362 | { \ |
1254 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | 1363 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\ |
1255 | return sprintf(buf, format"\n", session->field); \ | 1364 | return sprintf(buf, format"\n", session->field); \ |
1256 | } | 1365 | } |
1257 | 1366 | ||
@@ -1259,31 +1368,15 @@ show_priv_session_##field(struct class_device *cdev, char *buf) \ | |||
1259 | iscsi_priv_session_attr_show(field, format) \ | 1368 | iscsi_priv_session_attr_show(field, format) \ |
1260 | static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ | 1369 | static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ |
1261 | NULL) | 1370 | NULL) |
1262 | iscsi_priv_session_attr(targetname, "%s"); | ||
1263 | iscsi_priv_session_attr(tpgt, "%d"); | ||
1264 | iscsi_priv_session_attr(recovery_tmo, "%d"); | 1371 | iscsi_priv_session_attr(recovery_tmo, "%d"); |
1265 | 1372 | ||
1266 | #define iscsi_priv_conn_attr_show(field, format) \ | ||
1267 | static ssize_t \ | ||
1268 | show_priv_conn_##field(struct class_device *cdev, char *buf) \ | ||
1269 | { \ | ||
1270 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | ||
1271 | return sprintf(buf, format"\n", conn->field); \ | ||
1272 | } | ||
1273 | |||
1274 | #define iscsi_priv_conn_attr(field, format) \ | ||
1275 | iscsi_priv_conn_attr_show(field, format) \ | ||
1276 | static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \ | ||
1277 | NULL) | ||
1278 | iscsi_priv_conn_attr(persistent_address, "%s"); | ||
1279 | iscsi_priv_conn_attr(persistent_port, "%d"); | ||
1280 | |||
1281 | #define SETUP_PRIV_SESSION_RD_ATTR(field) \ | 1373 | #define SETUP_PRIV_SESSION_RD_ATTR(field) \ |
1282 | do { \ | 1374 | do { \ |
1283 | priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ | 1375 | priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ |
1284 | count++; \ | 1376 | count++; \ |
1285 | } while (0) | 1377 | } while (0) |
1286 | 1378 | ||
1379 | |||
1287 | #define SETUP_SESSION_RD_ATTR(field, param_flag) \ | 1380 | #define SETUP_SESSION_RD_ATTR(field, param_flag) \ |
1288 | do { \ | 1381 | do { \ |
1289 | if (tt->param_mask & param_flag) { \ | 1382 | if (tt->param_mask & param_flag) { \ |
@@ -1292,12 +1385,6 @@ do { \ | |||
1292 | } \ | 1385 | } \ |
1293 | } while (0) | 1386 | } while (0) |
1294 | 1387 | ||
1295 | #define SETUP_PRIV_CONN_RD_ATTR(field) \ | ||
1296 | do { \ | ||
1297 | priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \ | ||
1298 | count++; \ | ||
1299 | } while (0) | ||
1300 | |||
1301 | #define SETUP_CONN_RD_ATTR(field, param_flag) \ | 1388 | #define SETUP_CONN_RD_ATTR(field, param_flag) \ |
1302 | do { \ | 1389 | do { \ |
1303 | if (tt->param_mask & param_flag) { \ | 1390 | if (tt->param_mask & param_flag) { \ |
@@ -1388,6 +1475,7 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
1388 | if (!priv) | 1475 | if (!priv) |
1389 | return NULL; | 1476 | return NULL; |
1390 | INIT_LIST_HEAD(&priv->list); | 1477 | INIT_LIST_HEAD(&priv->list); |
1478 | priv->daemon_pid = -1; | ||
1391 | priv->iscsi_transport = tt; | 1479 | priv->iscsi_transport = tt; |
1392 | priv->t.user_scan = iscsi_user_scan; | 1480 | priv->t.user_scan = iscsi_user_scan; |
1393 | 1481 | ||
@@ -1424,16 +1512,8 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
1424 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); | 1512 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); |
1425 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); | 1513 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); |
1426 | SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); | 1514 | SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); |
1427 | 1515 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); | |
1428 | if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS) | 1516 | SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); |
1429 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); | ||
1430 | else | ||
1431 | SETUP_PRIV_CONN_RD_ATTR(persistent_address); | ||
1432 | |||
1433 | if (tt->param_mask & ISCSI_PERSISTENT_PORT) | ||
1434 | SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); | ||
1435 | else | ||
1436 | SETUP_PRIV_CONN_RD_ATTR(persistent_port); | ||
1437 | 1517 | ||
1438 | BUG_ON(count > ISCSI_CONN_ATTRS); | 1518 | BUG_ON(count > ISCSI_CONN_ATTRS); |
1439 | priv->conn_attrs[count] = NULL; | 1519 | priv->conn_attrs[count] = NULL; |
@@ -1453,18 +1533,10 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
1453 | SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); | 1533 | SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); |
1454 | SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); | 1534 | SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); |
1455 | SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); | 1535 | SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); |
1536 | SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); | ||
1537 | SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); | ||
1456 | SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); | 1538 | SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); |
1457 | 1539 | ||
1458 | if (tt->param_mask & ISCSI_TARGET_NAME) | ||
1459 | SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); | ||
1460 | else | ||
1461 | SETUP_PRIV_SESSION_RD_ATTR(targetname); | ||
1462 | |||
1463 | if (tt->param_mask & ISCSI_TPGT) | ||
1464 | SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); | ||
1465 | else | ||
1466 | SETUP_PRIV_SESSION_RD_ATTR(tpgt); | ||
1467 | |||
1468 | BUG_ON(count > ISCSI_SESSION_ATTRS); | 1540 | BUG_ON(count > ISCSI_SESSION_ATTRS); |
1469 | priv->session_attrs[count] = NULL; | 1541 | priv->session_attrs[count] = NULL; |
1470 | 1542 | ||
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 1fe6b2d01853..dd075627e605 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -174,12 +174,29 @@ static int sas_host_match(struct attribute_container *cont, | |||
174 | 174 | ||
175 | static int do_sas_phy_delete(struct device *dev, void *data) | 175 | static int do_sas_phy_delete(struct device *dev, void *data) |
176 | { | 176 | { |
177 | if (scsi_is_sas_phy(dev)) | 177 | int pass = (int)(unsigned long)data; |
178 | |||
179 | if (pass == 0 && scsi_is_sas_port(dev)) | ||
180 | sas_port_delete(dev_to_sas_port(dev)); | ||
181 | else if (pass == 1 && scsi_is_sas_phy(dev)) | ||
178 | sas_phy_delete(dev_to_phy(dev)); | 182 | sas_phy_delete(dev_to_phy(dev)); |
179 | return 0; | 183 | return 0; |
180 | } | 184 | } |
181 | 185 | ||
182 | /** | 186 | /** |
187 | * sas_remove_children -- tear down a devices SAS data structures | ||
188 | * @dev: device belonging to the sas object | ||
189 | * | ||
190 | * Removes all SAS PHYs and remote PHYs for a given object | ||
191 | */ | ||
192 | void sas_remove_children(struct device *dev) | ||
193 | { | ||
194 | device_for_each_child(dev, (void *)0, do_sas_phy_delete); | ||
195 | device_for_each_child(dev, (void *)1, do_sas_phy_delete); | ||
196 | } | ||
197 | EXPORT_SYMBOL(sas_remove_children); | ||
198 | |||
199 | /** | ||
183 | * sas_remove_host -- tear down a Scsi_Host's SAS data structures | 200 | * sas_remove_host -- tear down a Scsi_Host's SAS data structures |
184 | * @shost: Scsi Host that is torn down | 201 | * @shost: Scsi Host that is torn down |
185 | * | 202 | * |
@@ -188,13 +205,13 @@ static int do_sas_phy_delete(struct device *dev, void *data) | |||
188 | */ | 205 | */ |
189 | void sas_remove_host(struct Scsi_Host *shost) | 206 | void sas_remove_host(struct Scsi_Host *shost) |
190 | { | 207 | { |
191 | device_for_each_child(&shost->shost_gendev, NULL, do_sas_phy_delete); | 208 | sas_remove_children(&shost->shost_gendev); |
192 | } | 209 | } |
193 | EXPORT_SYMBOL(sas_remove_host); | 210 | EXPORT_SYMBOL(sas_remove_host); |
194 | 211 | ||
195 | 212 | ||
196 | /* | 213 | /* |
197 | * SAS Port attributes | 214 | * SAS Phy attributes |
198 | */ | 215 | */ |
199 | 216 | ||
200 | #define sas_phy_show_simple(field, name, format_string, cast) \ | 217 | #define sas_phy_show_simple(field, name, format_string, cast) \ |
@@ -310,7 +327,7 @@ sas_phy_protocol_attr(identify.target_port_protocols, | |||
310 | sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", | 327 | sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", |
311 | unsigned long long); | 328 | unsigned long long); |
312 | sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); | 329 | sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); |
313 | sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); | 330 | //sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); |
314 | sas_phy_linkspeed_attr(negotiated_linkrate); | 331 | sas_phy_linkspeed_attr(negotiated_linkrate); |
315 | sas_phy_linkspeed_attr(minimum_linkrate_hw); | 332 | sas_phy_linkspeed_attr(minimum_linkrate_hw); |
316 | sas_phy_linkspeed_attr(minimum_linkrate); | 333 | sas_phy_linkspeed_attr(minimum_linkrate); |
@@ -378,9 +395,10 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number) | |||
378 | device_initialize(&phy->dev); | 395 | device_initialize(&phy->dev); |
379 | phy->dev.parent = get_device(parent); | 396 | phy->dev.parent = get_device(parent); |
380 | phy->dev.release = sas_phy_release; | 397 | phy->dev.release = sas_phy_release; |
398 | INIT_LIST_HEAD(&phy->port_siblings); | ||
381 | if (scsi_is_sas_expander_device(parent)) { | 399 | if (scsi_is_sas_expander_device(parent)) { |
382 | struct sas_rphy *rphy = dev_to_rphy(parent); | 400 | struct sas_rphy *rphy = dev_to_rphy(parent); |
383 | sprintf(phy->dev.bus_id, "phy-%d-%d:%d", shost->host_no, | 401 | sprintf(phy->dev.bus_id, "phy-%d:%d:%d", shost->host_no, |
384 | rphy->scsi_target_id, number); | 402 | rphy->scsi_target_id, number); |
385 | } else | 403 | } else |
386 | sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number); | 404 | sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number); |
@@ -440,8 +458,8 @@ sas_phy_delete(struct sas_phy *phy) | |||
440 | { | 458 | { |
441 | struct device *dev = &phy->dev; | 459 | struct device *dev = &phy->dev; |
442 | 460 | ||
443 | if (phy->rphy) | 461 | /* this happens if the phy is still part of a port when deleted */ |
444 | sas_rphy_delete(phy->rphy); | 462 | BUG_ON(!list_empty(&phy->port_siblings)); |
445 | 463 | ||
446 | transport_remove_device(dev); | 464 | transport_remove_device(dev); |
447 | device_del(dev); | 465 | device_del(dev); |
@@ -464,6 +482,258 @@ int scsi_is_sas_phy(const struct device *dev) | |||
464 | EXPORT_SYMBOL(scsi_is_sas_phy); | 482 | EXPORT_SYMBOL(scsi_is_sas_phy); |
465 | 483 | ||
466 | /* | 484 | /* |
485 | * SAS Port attributes | ||
486 | */ | ||
487 | #define sas_port_show_simple(field, name, format_string, cast) \ | ||
488 | static ssize_t \ | ||
489 | show_sas_port_##name(struct class_device *cdev, char *buf) \ | ||
490 | { \ | ||
491 | struct sas_port *port = transport_class_to_sas_port(cdev); \ | ||
492 | \ | ||
493 | return snprintf(buf, 20, format_string, cast port->field); \ | ||
494 | } | ||
495 | |||
496 | #define sas_port_simple_attr(field, name, format_string, type) \ | ||
497 | sas_port_show_simple(field, name, format_string, (type)) \ | ||
498 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_port_##name, NULL) | ||
499 | |||
500 | sas_port_simple_attr(num_phys, num_phys, "%d\n", int); | ||
501 | |||
502 | static DECLARE_TRANSPORT_CLASS(sas_port_class, | ||
503 | "sas_port", NULL, NULL, NULL); | ||
504 | |||
505 | static int sas_port_match(struct attribute_container *cont, struct device *dev) | ||
506 | { | ||
507 | struct Scsi_Host *shost; | ||
508 | struct sas_internal *i; | ||
509 | |||
510 | if (!scsi_is_sas_port(dev)) | ||
511 | return 0; | ||
512 | shost = dev_to_shost(dev->parent); | ||
513 | |||
514 | if (!shost->transportt) | ||
515 | return 0; | ||
516 | if (shost->transportt->host_attrs.ac.class != | ||
517 | &sas_host_class.class) | ||
518 | return 0; | ||
519 | |||
520 | i = to_sas_internal(shost->transportt); | ||
521 | return &i->port_attr_cont.ac == cont; | ||
522 | } | ||
523 | |||
524 | |||
525 | static void sas_port_release(struct device *dev) | ||
526 | { | ||
527 | struct sas_port *port = dev_to_sas_port(dev); | ||
528 | |||
529 | BUG_ON(!list_empty(&port->phy_list)); | ||
530 | |||
531 | put_device(dev->parent); | ||
532 | kfree(port); | ||
533 | } | ||
534 | |||
535 | static void sas_port_create_link(struct sas_port *port, | ||
536 | struct sas_phy *phy) | ||
537 | { | ||
538 | sysfs_create_link(&port->dev.kobj, &phy->dev.kobj, phy->dev.bus_id); | ||
539 | sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port"); | ||
540 | } | ||
541 | |||
542 | static void sas_port_delete_link(struct sas_port *port, | ||
543 | struct sas_phy *phy) | ||
544 | { | ||
545 | sysfs_remove_link(&port->dev.kobj, phy->dev.bus_id); | ||
546 | sysfs_remove_link(&phy->dev.kobj, "port"); | ||
547 | } | ||
548 | |||
549 | /** sas_port_alloc - allocate and initialize a SAS port structure | ||
550 | * | ||
551 | * @parent: parent device | ||
552 | * @port_id: port number | ||
553 | * | ||
554 | * Allocates a SAS port structure. It will be added to the device tree | ||
555 | * below the device specified by @parent which must be either a Scsi_Host | ||
556 | * or a sas_expander_device. | ||
557 | * | ||
558 | * Returns %NULL on error | ||
559 | */ | ||
560 | struct sas_port *sas_port_alloc(struct device *parent, int port_id) | ||
561 | { | ||
562 | struct Scsi_Host *shost = dev_to_shost(parent); | ||
563 | struct sas_port *port; | ||
564 | |||
565 | port = kzalloc(sizeof(*port), GFP_KERNEL); | ||
566 | if (!port) | ||
567 | return NULL; | ||
568 | |||
569 | port->port_identifier = port_id; | ||
570 | |||
571 | device_initialize(&port->dev); | ||
572 | |||
573 | port->dev.parent = get_device(parent); | ||
574 | port->dev.release = sas_port_release; | ||
575 | |||
576 | mutex_init(&port->phy_list_mutex); | ||
577 | INIT_LIST_HEAD(&port->phy_list); | ||
578 | |||
579 | if (scsi_is_sas_expander_device(parent)) { | ||
580 | struct sas_rphy *rphy = dev_to_rphy(parent); | ||
581 | sprintf(port->dev.bus_id, "port-%d:%d:%d", shost->host_no, | ||
582 | rphy->scsi_target_id, port->port_identifier); | ||
583 | } else | ||
584 | sprintf(port->dev.bus_id, "port-%d:%d", shost->host_no, | ||
585 | port->port_identifier); | ||
586 | |||
587 | transport_setup_device(&port->dev); | ||
588 | |||
589 | return port; | ||
590 | } | ||
591 | EXPORT_SYMBOL(sas_port_alloc); | ||
592 | |||
593 | /** | ||
594 | * sas_port_add - add a SAS port to the device hierarchy | ||
595 | * | ||
596 | * @port: port to be added | ||
597 | * | ||
598 | * publishes a port to the rest of the system | ||
599 | */ | ||
600 | int sas_port_add(struct sas_port *port) | ||
601 | { | ||
602 | int error; | ||
603 | |||
604 | /* No phys should be added until this is made visible */ | ||
605 | BUG_ON(!list_empty(&port->phy_list)); | ||
606 | |||
607 | error = device_add(&port->dev); | ||
608 | |||
609 | if (error) | ||
610 | return error; | ||
611 | |||
612 | transport_add_device(&port->dev); | ||
613 | transport_configure_device(&port->dev); | ||
614 | |||
615 | return 0; | ||
616 | } | ||
617 | EXPORT_SYMBOL(sas_port_add); | ||
618 | |||
619 | /** | ||
620 | * sas_port_free -- free a SAS PORT | ||
621 | * @port: SAS PORT to free | ||
622 | * | ||
623 | * Frees the specified SAS PORT. | ||
624 | * | ||
625 | * Note: | ||
626 | * This function must only be called on a PORT that has not | ||
627 | * sucessfully been added using sas_port_add(). | ||
628 | */ | ||
629 | void sas_port_free(struct sas_port *port) | ||
630 | { | ||
631 | transport_destroy_device(&port->dev); | ||
632 | put_device(&port->dev); | ||
633 | } | ||
634 | EXPORT_SYMBOL(sas_port_free); | ||
635 | |||
636 | /** | ||
637 | * sas_port_delete -- remove SAS PORT | ||
638 | * @port: SAS PORT to remove | ||
639 | * | ||
640 | * Removes the specified SAS PORT. If the SAS PORT has an | ||
641 | * associated phys, unlink them from the port as well. | ||
642 | */ | ||
643 | void sas_port_delete(struct sas_port *port) | ||
644 | { | ||
645 | struct device *dev = &port->dev; | ||
646 | struct sas_phy *phy, *tmp_phy; | ||
647 | |||
648 | if (port->rphy) { | ||
649 | sas_rphy_delete(port->rphy); | ||
650 | port->rphy = NULL; | ||
651 | } | ||
652 | |||
653 | mutex_lock(&port->phy_list_mutex); | ||
654 | list_for_each_entry_safe(phy, tmp_phy, &port->phy_list, | ||
655 | port_siblings) { | ||
656 | sas_port_delete_link(port, phy); | ||
657 | list_del_init(&phy->port_siblings); | ||
658 | } | ||
659 | mutex_unlock(&port->phy_list_mutex); | ||
660 | |||
661 | transport_remove_device(dev); | ||
662 | device_del(dev); | ||
663 | transport_destroy_device(dev); | ||
664 | put_device(dev); | ||
665 | } | ||
666 | EXPORT_SYMBOL(sas_port_delete); | ||
667 | |||
668 | /** | ||
669 | * scsi_is_sas_port -- check if a struct device represents a SAS port | ||
670 | * @dev: device to check | ||
671 | * | ||
672 | * Returns: | ||
673 | * %1 if the device represents a SAS Port, %0 else | ||
674 | */ | ||
675 | int scsi_is_sas_port(const struct device *dev) | ||
676 | { | ||
677 | return dev->release == sas_port_release; | ||
678 | } | ||
679 | EXPORT_SYMBOL(scsi_is_sas_port); | ||
680 | |||
681 | /** | ||
682 | * sas_port_add_phy - add another phy to a port to form a wide port | ||
683 | * @port: port to add the phy to | ||
684 | * @phy: phy to add | ||
685 | * | ||
686 | * When a port is initially created, it is empty (has no phys). All | ||
687 | * ports must have at least one phy to operated, and all wide ports | ||
688 | * must have at least two. The current code makes no difference | ||
689 | * between ports and wide ports, but the only object that can be | ||
690 | * connected to a remote device is a port, so ports must be formed on | ||
691 | * all devices with phys if they're connected to anything. | ||
692 | */ | ||
693 | void sas_port_add_phy(struct sas_port *port, struct sas_phy *phy) | ||
694 | { | ||
695 | mutex_lock(&port->phy_list_mutex); | ||
696 | if (unlikely(!list_empty(&phy->port_siblings))) { | ||
697 | /* make sure we're already on this port */ | ||
698 | struct sas_phy *tmp; | ||
699 | |||
700 | list_for_each_entry(tmp, &port->phy_list, port_siblings) | ||
701 | if (tmp == phy) | ||
702 | break; | ||
703 | /* If this trips, you added a phy that was already | ||
704 | * part of a different port */ | ||
705 | if (unlikely(tmp != phy)) { | ||
706 | dev_printk(KERN_ERR, &port->dev, "trying to add phy %s fails: it's already part of another port\n", phy->dev.bus_id); | ||
707 | BUG(); | ||
708 | } | ||
709 | } else { | ||
710 | sas_port_create_link(port, phy); | ||
711 | list_add_tail(&phy->port_siblings, &port->phy_list); | ||
712 | port->num_phys++; | ||
713 | } | ||
714 | mutex_unlock(&port->phy_list_mutex); | ||
715 | } | ||
716 | EXPORT_SYMBOL(sas_port_add_phy); | ||
717 | |||
718 | /** | ||
719 | * sas_port_delete_phy - remove a phy from a port or wide port | ||
720 | * @port: port to remove the phy from | ||
721 | * @phy: phy to remove | ||
722 | * | ||
723 | * This operation is used for tearing down ports again. It must be | ||
724 | * done to every port or wide port before calling sas_port_delete. | ||
725 | */ | ||
726 | void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy) | ||
727 | { | ||
728 | mutex_lock(&port->phy_list_mutex); | ||
729 | sas_port_delete_link(port, phy); | ||
730 | list_del_init(&phy->port_siblings); | ||
731 | port->num_phys--; | ||
732 | mutex_unlock(&port->phy_list_mutex); | ||
733 | } | ||
734 | EXPORT_SYMBOL(sas_port_delete_phy); | ||
735 | |||
736 | /* | ||
467 | * SAS remote PHY attributes. | 737 | * SAS remote PHY attributes. |
468 | */ | 738 | */ |
469 | 739 | ||
@@ -767,7 +1037,7 @@ static void sas_rphy_initialize(struct sas_rphy *rphy) | |||
767 | * Returns: | 1037 | * Returns: |
768 | * SAS PHY allocated or %NULL if the allocation failed. | 1038 | * SAS PHY allocated or %NULL if the allocation failed. |
769 | */ | 1039 | */ |
770 | struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent) | 1040 | struct sas_rphy *sas_end_device_alloc(struct sas_port *parent) |
771 | { | 1041 | { |
772 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); | 1042 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); |
773 | struct sas_end_device *rdev; | 1043 | struct sas_end_device *rdev; |
@@ -780,8 +1050,13 @@ struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent) | |||
780 | device_initialize(&rdev->rphy.dev); | 1050 | device_initialize(&rdev->rphy.dev); |
781 | rdev->rphy.dev.parent = get_device(&parent->dev); | 1051 | rdev->rphy.dev.parent = get_device(&parent->dev); |
782 | rdev->rphy.dev.release = sas_end_device_release; | 1052 | rdev->rphy.dev.release = sas_end_device_release; |
783 | sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d-%d", | 1053 | if (scsi_is_sas_expander_device(parent->dev.parent)) { |
784 | shost->host_no, parent->port_identifier, parent->number); | 1054 | struct sas_rphy *rphy = dev_to_rphy(parent->dev.parent); |
1055 | sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d:%d", | ||
1056 | shost->host_no, rphy->scsi_target_id, parent->port_identifier); | ||
1057 | } else | ||
1058 | sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d", | ||
1059 | shost->host_no, parent->port_identifier); | ||
785 | rdev->rphy.identify.device_type = SAS_END_DEVICE; | 1060 | rdev->rphy.identify.device_type = SAS_END_DEVICE; |
786 | sas_rphy_initialize(&rdev->rphy); | 1061 | sas_rphy_initialize(&rdev->rphy); |
787 | transport_setup_device(&rdev->rphy.dev); | 1062 | transport_setup_device(&rdev->rphy.dev); |
@@ -798,7 +1073,7 @@ EXPORT_SYMBOL(sas_end_device_alloc); | |||
798 | * Returns: | 1073 | * Returns: |
799 | * SAS PHY allocated or %NULL if the allocation failed. | 1074 | * SAS PHY allocated or %NULL if the allocation failed. |
800 | */ | 1075 | */ |
801 | struct sas_rphy *sas_expander_alloc(struct sas_phy *parent, | 1076 | struct sas_rphy *sas_expander_alloc(struct sas_port *parent, |
802 | enum sas_device_type type) | 1077 | enum sas_device_type type) |
803 | { | 1078 | { |
804 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); | 1079 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); |
@@ -837,7 +1112,7 @@ EXPORT_SYMBOL(sas_expander_alloc); | |||
837 | */ | 1112 | */ |
838 | int sas_rphy_add(struct sas_rphy *rphy) | 1113 | int sas_rphy_add(struct sas_rphy *rphy) |
839 | { | 1114 | { |
840 | struct sas_phy *parent = dev_to_phy(rphy->dev.parent); | 1115 | struct sas_port *parent = dev_to_sas_port(rphy->dev.parent); |
841 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); | 1116 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); |
842 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); | 1117 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); |
843 | struct sas_identify *identify = &rphy->identify; | 1118 | struct sas_identify *identify = &rphy->identify; |
@@ -910,7 +1185,7 @@ void | |||
910 | sas_rphy_delete(struct sas_rphy *rphy) | 1185 | sas_rphy_delete(struct sas_rphy *rphy) |
911 | { | 1186 | { |
912 | struct device *dev = &rphy->dev; | 1187 | struct device *dev = &rphy->dev; |
913 | struct sas_phy *parent = dev_to_phy(dev->parent); | 1188 | struct sas_port *parent = dev_to_sas_port(dev->parent); |
914 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); | 1189 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); |
915 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); | 1190 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); |
916 | 1191 | ||
@@ -920,7 +1195,7 @@ sas_rphy_delete(struct sas_rphy *rphy) | |||
920 | break; | 1195 | break; |
921 | case SAS_EDGE_EXPANDER_DEVICE: | 1196 | case SAS_EDGE_EXPANDER_DEVICE: |
922 | case SAS_FANOUT_EXPANDER_DEVICE: | 1197 | case SAS_FANOUT_EXPANDER_DEVICE: |
923 | device_for_each_child(dev, NULL, do_sas_phy_delete); | 1198 | sas_remove_children(dev); |
924 | break; | 1199 | break; |
925 | default: | 1200 | default: |
926 | break; | 1201 | break; |
@@ -967,7 +1242,7 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
967 | 1242 | ||
968 | mutex_lock(&sas_host->lock); | 1243 | mutex_lock(&sas_host->lock); |
969 | list_for_each_entry(rphy, &sas_host->rphy_list, list) { | 1244 | list_for_each_entry(rphy, &sas_host->rphy_list, list) { |
970 | struct sas_phy *parent = dev_to_phy(rphy->dev.parent); | 1245 | struct sas_port *parent = dev_to_sas_port(rphy->dev.parent); |
971 | 1246 | ||
972 | if (rphy->identify.device_type != SAS_END_DEVICE || | 1247 | if (rphy->identify.device_type != SAS_END_DEVICE || |
973 | rphy->scsi_target_id == -1) | 1248 | rphy->scsi_target_id == -1) |
@@ -1003,16 +1278,19 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
1003 | #define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func) \ | 1278 | #define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func) \ |
1004 | SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func) | 1279 | SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func) |
1005 | 1280 | ||
1006 | #define SETUP_PORT_ATTRIBUTE(field) \ | 1281 | #define SETUP_PHY_ATTRIBUTE(field) \ |
1007 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1) | 1282 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1) |
1008 | 1283 | ||
1009 | #define SETUP_OPTIONAL_PORT_ATTRIBUTE(field, func) \ | 1284 | #define SETUP_PORT_ATTRIBUTE(field) \ |
1285 | SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1) | ||
1286 | |||
1287 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE(field, func) \ | ||
1010 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func) | 1288 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func) |
1011 | 1289 | ||
1012 | #define SETUP_PORT_ATTRIBUTE_WRONLY(field) \ | 1290 | #define SETUP_PHY_ATTRIBUTE_WRONLY(field) \ |
1013 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1) | 1291 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1) |
1014 | 1292 | ||
1015 | #define SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(field, func) \ | 1293 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func) \ |
1016 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func) | 1294 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func) |
1017 | 1295 | ||
1018 | #define SETUP_END_DEV_ATTRIBUTE(field) \ | 1296 | #define SETUP_END_DEV_ATTRIBUTE(field) \ |
@@ -1048,6 +1326,11 @@ sas_attach_transport(struct sas_function_template *ft) | |||
1048 | i->phy_attr_cont.ac.match = sas_phy_match; | 1326 | i->phy_attr_cont.ac.match = sas_phy_match; |
1049 | transport_container_register(&i->phy_attr_cont); | 1327 | transport_container_register(&i->phy_attr_cont); |
1050 | 1328 | ||
1329 | i->port_attr_cont.ac.class = &sas_port_class.class; | ||
1330 | i->port_attr_cont.ac.attrs = &i->port_attrs[0]; | ||
1331 | i->port_attr_cont.ac.match = sas_port_match; | ||
1332 | transport_container_register(&i->port_attr_cont); | ||
1333 | |||
1051 | i->rphy_attr_cont.ac.class = &sas_rphy_class.class; | 1334 | i->rphy_attr_cont.ac.class = &sas_rphy_class.class; |
1052 | i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0]; | 1335 | i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0]; |
1053 | i->rphy_attr_cont.ac.match = sas_rphy_match; | 1336 | i->rphy_attr_cont.ac.match = sas_rphy_match; |
@@ -1066,30 +1349,35 @@ sas_attach_transport(struct sas_function_template *ft) | |||
1066 | i->f = ft; | 1349 | i->f = ft; |
1067 | 1350 | ||
1068 | count = 0; | 1351 | count = 0; |
1352 | SETUP_PORT_ATTRIBUTE(num_phys); | ||
1069 | i->host_attrs[count] = NULL; | 1353 | i->host_attrs[count] = NULL; |
1070 | 1354 | ||
1071 | count = 0; | 1355 | count = 0; |
1072 | SETUP_PORT_ATTRIBUTE(initiator_port_protocols); | 1356 | SETUP_PHY_ATTRIBUTE(initiator_port_protocols); |
1073 | SETUP_PORT_ATTRIBUTE(target_port_protocols); | 1357 | SETUP_PHY_ATTRIBUTE(target_port_protocols); |
1074 | SETUP_PORT_ATTRIBUTE(device_type); | 1358 | SETUP_PHY_ATTRIBUTE(device_type); |
1075 | SETUP_PORT_ATTRIBUTE(sas_address); | 1359 | SETUP_PHY_ATTRIBUTE(sas_address); |
1076 | SETUP_PORT_ATTRIBUTE(phy_identifier); | 1360 | SETUP_PHY_ATTRIBUTE(phy_identifier); |
1077 | SETUP_PORT_ATTRIBUTE(port_identifier); | 1361 | //SETUP_PHY_ATTRIBUTE(port_identifier); |
1078 | SETUP_PORT_ATTRIBUTE(negotiated_linkrate); | 1362 | SETUP_PHY_ATTRIBUTE(negotiated_linkrate); |
1079 | SETUP_PORT_ATTRIBUTE(minimum_linkrate_hw); | 1363 | SETUP_PHY_ATTRIBUTE(minimum_linkrate_hw); |
1080 | SETUP_PORT_ATTRIBUTE(minimum_linkrate); | 1364 | SETUP_PHY_ATTRIBUTE(minimum_linkrate); |
1081 | SETUP_PORT_ATTRIBUTE(maximum_linkrate_hw); | 1365 | SETUP_PHY_ATTRIBUTE(maximum_linkrate_hw); |
1082 | SETUP_PORT_ATTRIBUTE(maximum_linkrate); | 1366 | SETUP_PHY_ATTRIBUTE(maximum_linkrate); |
1083 | 1367 | ||
1084 | SETUP_PORT_ATTRIBUTE(invalid_dword_count); | 1368 | SETUP_PHY_ATTRIBUTE(invalid_dword_count); |
1085 | SETUP_PORT_ATTRIBUTE(running_disparity_error_count); | 1369 | SETUP_PHY_ATTRIBUTE(running_disparity_error_count); |
1086 | SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); | 1370 | SETUP_PHY_ATTRIBUTE(loss_of_dword_sync_count); |
1087 | SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); | 1371 | SETUP_PHY_ATTRIBUTE(phy_reset_problem_count); |
1088 | SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(link_reset, phy_reset); | 1372 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset); |
1089 | SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(hard_reset, phy_reset); | 1373 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset); |
1090 | i->phy_attrs[count] = NULL; | 1374 | i->phy_attrs[count] = NULL; |
1091 | 1375 | ||
1092 | count = 0; | 1376 | count = 0; |
1377 | SETUP_PORT_ATTRIBUTE(num_phys); | ||
1378 | i->port_attrs[count] = NULL; | ||
1379 | |||
1380 | count = 0; | ||
1093 | SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols); | 1381 | SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols); |
1094 | SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols); | 1382 | SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols); |
1095 | SETUP_RPORT_ATTRIBUTE(rphy_device_type); | 1383 | SETUP_RPORT_ATTRIBUTE(rphy_device_type); |
@@ -1131,6 +1419,7 @@ void sas_release_transport(struct scsi_transport_template *t) | |||
1131 | 1419 | ||
1132 | transport_container_unregister(&i->t.host_attrs); | 1420 | transport_container_unregister(&i->t.host_attrs); |
1133 | transport_container_unregister(&i->phy_attr_cont); | 1421 | transport_container_unregister(&i->phy_attr_cont); |
1422 | transport_container_unregister(&i->port_attr_cont); | ||
1134 | transport_container_unregister(&i->rphy_attr_cont); | 1423 | transport_container_unregister(&i->rphy_attr_cont); |
1135 | transport_container_unregister(&i->end_dev_attr_cont); | 1424 | transport_container_unregister(&i->end_dev_attr_cont); |
1136 | transport_container_unregister(&i->expander_attr_cont); | 1425 | transport_container_unregister(&i->expander_attr_cont); |
@@ -1149,9 +1438,12 @@ static __init int sas_transport_init(void) | |||
1149 | error = transport_class_register(&sas_phy_class); | 1438 | error = transport_class_register(&sas_phy_class); |
1150 | if (error) | 1439 | if (error) |
1151 | goto out_unregister_transport; | 1440 | goto out_unregister_transport; |
1152 | error = transport_class_register(&sas_rphy_class); | 1441 | error = transport_class_register(&sas_port_class); |
1153 | if (error) | 1442 | if (error) |
1154 | goto out_unregister_phy; | 1443 | goto out_unregister_phy; |
1444 | error = transport_class_register(&sas_rphy_class); | ||
1445 | if (error) | ||
1446 | goto out_unregister_port; | ||
1155 | error = transport_class_register(&sas_end_dev_class); | 1447 | error = transport_class_register(&sas_end_dev_class); |
1156 | if (error) | 1448 | if (error) |
1157 | goto out_unregister_rphy; | 1449 | goto out_unregister_rphy; |
@@ -1165,6 +1457,8 @@ static __init int sas_transport_init(void) | |||
1165 | transport_class_unregister(&sas_end_dev_class); | 1457 | transport_class_unregister(&sas_end_dev_class); |
1166 | out_unregister_rphy: | 1458 | out_unregister_rphy: |
1167 | transport_class_unregister(&sas_rphy_class); | 1459 | transport_class_unregister(&sas_rphy_class); |
1460 | out_unregister_port: | ||
1461 | transport_class_unregister(&sas_port_class); | ||
1168 | out_unregister_phy: | 1462 | out_unregister_phy: |
1169 | transport_class_unregister(&sas_phy_class); | 1463 | transport_class_unregister(&sas_phy_class); |
1170 | out_unregister_transport: | 1464 | out_unregister_transport: |
@@ -1178,6 +1472,7 @@ static void __exit sas_transport_exit(void) | |||
1178 | { | 1472 | { |
1179 | transport_class_unregister(&sas_host_class); | 1473 | transport_class_unregister(&sas_host_class); |
1180 | transport_class_unregister(&sas_phy_class); | 1474 | transport_class_unregister(&sas_phy_class); |
1475 | transport_class_unregister(&sas_port_class); | ||
1181 | transport_class_unregister(&sas_rphy_class); | 1476 | transport_class_unregister(&sas_rphy_class); |
1182 | transport_class_unregister(&sas_end_dev_class); | 1477 | transport_class_unregister(&sas_end_dev_class); |
1183 | transport_class_unregister(&sas_expander_class); | 1478 | transport_class_unregister(&sas_expander_class); |
diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c index b78354fc4b17..cd68a66c7bb3 100644 --- a/drivers/scsi/scsicam.c +++ b/drivers/scsi/scsicam.c | |||
@@ -57,6 +57,7 @@ EXPORT_SYMBOL(scsi_bios_ptable); | |||
57 | int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip) | 57 | int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip) |
58 | { | 58 | { |
59 | unsigned char *p; | 59 | unsigned char *p; |
60 | u64 capacity64 = capacity; /* Suppress gcc warning */ | ||
60 | int ret; | 61 | int ret; |
61 | 62 | ||
62 | p = scsi_bios_ptable(bdev); | 63 | p = scsi_bios_ptable(bdev); |
@@ -68,7 +69,7 @@ int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip) | |||
68 | (unsigned int *)ip + 0, (unsigned int *)ip + 1); | 69 | (unsigned int *)ip + 0, (unsigned int *)ip + 1); |
69 | kfree(p); | 70 | kfree(p); |
70 | 71 | ||
71 | if (ret == -1) { | 72 | if (ret == -1 && capacity64 < (1ULL << 32)) { |
72 | /* pick some standard mapping with at most 1024 cylinders, | 73 | /* pick some standard mapping with at most 1024 cylinders, |
73 | and at most 62 sectors per track - this works up to | 74 | and at most 62 sectors per track - this works up to |
74 | 7905 MB */ | 75 | 7905 MB */ |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ea38757d12e5..3225d31449e1 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -207,6 +207,23 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, | |||
207 | return count; | 207 | return count; |
208 | } | 208 | } |
209 | 209 | ||
210 | static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf, | ||
211 | size_t count) | ||
212 | { | ||
213 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | ||
214 | struct scsi_device *sdp = sdkp->device; | ||
215 | |||
216 | if (!capable(CAP_SYS_ADMIN)) | ||
217 | return -EACCES; | ||
218 | |||
219 | if (sdp->type != TYPE_DISK) | ||
220 | return -EINVAL; | ||
221 | |||
222 | sdp->allow_restart = simple_strtoul(buf, NULL, 10); | ||
223 | |||
224 | return count; | ||
225 | } | ||
226 | |||
210 | static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) | 227 | static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) |
211 | { | 228 | { |
212 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | 229 | struct scsi_disk *sdkp = to_scsi_disk(cdev); |
@@ -222,10 +239,19 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf) | |||
222 | return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); | 239 | return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); |
223 | } | 240 | } |
224 | 241 | ||
242 | static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf) | ||
243 | { | ||
244 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | ||
245 | |||
246 | return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); | ||
247 | } | ||
248 | |||
225 | static struct class_device_attribute sd_disk_attrs[] = { | 249 | static struct class_device_attribute sd_disk_attrs[] = { |
226 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, | 250 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
227 | sd_store_cache_type), | 251 | sd_store_cache_type), |
228 | __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), | 252 | __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), |
253 | __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, | ||
254 | sd_store_allow_restart), | ||
229 | __ATTR_NULL, | 255 | __ATTR_NULL, |
230 | }; | 256 | }; |
231 | 257 | ||
@@ -890,11 +916,10 @@ static struct block_device_operations sd_fops = { | |||
890 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) | 916 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) |
891 | { | 917 | { |
892 | int result = SCpnt->result; | 918 | int result = SCpnt->result; |
893 | int this_count = SCpnt->request_bufflen; | 919 | unsigned int xfer_size = SCpnt->request_bufflen; |
894 | int good_bytes = (result == 0 ? this_count : 0); | 920 | unsigned int good_bytes = result ? 0 : xfer_size; |
895 | sector_t block_sectors = 1; | 921 | u64 start_lba = SCpnt->request->sector; |
896 | u64 first_err_block; | 922 | u64 bad_lba; |
897 | sector_t error_sector; | ||
898 | struct scsi_sense_hdr sshdr; | 923 | struct scsi_sense_hdr sshdr; |
899 | int sense_valid = 0; | 924 | int sense_valid = 0; |
900 | int sense_deferred = 0; | 925 | int sense_deferred = 0; |
@@ -905,7 +930,6 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
905 | if (sense_valid) | 930 | if (sense_valid) |
906 | sense_deferred = scsi_sense_is_deferred(&sshdr); | 931 | sense_deferred = scsi_sense_is_deferred(&sshdr); |
907 | } | 932 | } |
908 | |||
909 | #ifdef CONFIG_SCSI_LOGGING | 933 | #ifdef CONFIG_SCSI_LOGGING |
910 | SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", | 934 | SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", |
911 | SCpnt->request->rq_disk->disk_name, result)); | 935 | SCpnt->request->rq_disk->disk_name, result)); |
@@ -915,89 +939,72 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
915 | sshdr.sense_key, sshdr.asc, sshdr.ascq)); | 939 | sshdr.sense_key, sshdr.asc, sshdr.ascq)); |
916 | } | 940 | } |
917 | #endif | 941 | #endif |
918 | /* | 942 | if (driver_byte(result) != DRIVER_SENSE && |
919 | Handle MEDIUM ERRORs that indicate partial success. Since this is a | 943 | (!sense_valid || sense_deferred)) |
920 | relatively rare error condition, no care is taken to avoid | 944 | goto out; |
921 | unnecessary additional work such as memcpy's that could be avoided. | ||
922 | */ | ||
923 | if (driver_byte(result) != 0 && | ||
924 | sense_valid && !sense_deferred) { | ||
925 | switch (sshdr.sense_key) { | ||
926 | case MEDIUM_ERROR: | ||
927 | if (!blk_fs_request(SCpnt->request)) | ||
928 | break; | ||
929 | info_valid = scsi_get_sense_info_fld( | ||
930 | SCpnt->sense_buffer, SCSI_SENSE_BUFFERSIZE, | ||
931 | &first_err_block); | ||
932 | /* | ||
933 | * May want to warn and skip if following cast results | ||
934 | * in actual truncation (if sector_t < 64 bits) | ||
935 | */ | ||
936 | error_sector = (sector_t)first_err_block; | ||
937 | if (SCpnt->request->bio != NULL) | ||
938 | block_sectors = bio_sectors(SCpnt->request->bio); | ||
939 | switch (SCpnt->device->sector_size) { | ||
940 | case 1024: | ||
941 | error_sector <<= 1; | ||
942 | if (block_sectors < 2) | ||
943 | block_sectors = 2; | ||
944 | break; | ||
945 | case 2048: | ||
946 | error_sector <<= 2; | ||
947 | if (block_sectors < 4) | ||
948 | block_sectors = 4; | ||
949 | break; | ||
950 | case 4096: | ||
951 | error_sector <<=3; | ||
952 | if (block_sectors < 8) | ||
953 | block_sectors = 8; | ||
954 | break; | ||
955 | case 256: | ||
956 | error_sector >>= 1; | ||
957 | break; | ||
958 | default: | ||
959 | break; | ||
960 | } | ||
961 | 945 | ||
962 | error_sector &= ~(block_sectors - 1); | 946 | switch (sshdr.sense_key) { |
963 | good_bytes = (error_sector - SCpnt->request->sector) << 9; | 947 | case HARDWARE_ERROR: |
964 | if (good_bytes < 0 || good_bytes >= this_count) | 948 | case MEDIUM_ERROR: |
965 | good_bytes = 0; | 949 | if (!blk_fs_request(SCpnt->request)) |
950 | goto out; | ||
951 | info_valid = scsi_get_sense_info_fld(SCpnt->sense_buffer, | ||
952 | SCSI_SENSE_BUFFERSIZE, | ||
953 | &bad_lba); | ||
954 | if (!info_valid) | ||
955 | goto out; | ||
956 | if (xfer_size <= SCpnt->device->sector_size) | ||
957 | goto out; | ||
958 | switch (SCpnt->device->sector_size) { | ||
959 | case 256: | ||
960 | start_lba <<= 1; | ||
966 | break; | 961 | break; |
967 | 962 | case 512: | |
968 | case RECOVERED_ERROR: /* an error occurred, but it recovered */ | ||
969 | case NO_SENSE: /* LLDD got sense data */ | ||
970 | /* | ||
971 | * Inform the user, but make sure that it's not treated | ||
972 | * as a hard error. | ||
973 | */ | ||
974 | scsi_print_sense("sd", SCpnt); | ||
975 | SCpnt->result = 0; | ||
976 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
977 | good_bytes = this_count; | ||
978 | break; | 963 | break; |
979 | 964 | case 1024: | |
980 | case ILLEGAL_REQUEST: | 965 | start_lba >>= 1; |
981 | if (SCpnt->device->use_10_for_rw && | 966 | break; |
982 | (SCpnt->cmnd[0] == READ_10 || | 967 | case 2048: |
983 | SCpnt->cmnd[0] == WRITE_10)) | 968 | start_lba >>= 2; |
984 | SCpnt->device->use_10_for_rw = 0; | 969 | break; |
985 | if (SCpnt->device->use_10_for_ms && | 970 | case 4096: |
986 | (SCpnt->cmnd[0] == MODE_SENSE_10 || | 971 | start_lba >>= 3; |
987 | SCpnt->cmnd[0] == MODE_SELECT_10)) | ||
988 | SCpnt->device->use_10_for_ms = 0; | ||
989 | break; | 972 | break; |
990 | |||
991 | default: | 973 | default: |
974 | /* Print something here with limiting frequency. */ | ||
975 | goto out; | ||
992 | break; | 976 | break; |
993 | } | 977 | } |
978 | /* This computation should always be done in terms of | ||
979 | * the resolution of the device's medium. | ||
980 | */ | ||
981 | good_bytes = (bad_lba - start_lba)*SCpnt->device->sector_size; | ||
982 | break; | ||
983 | case RECOVERED_ERROR: | ||
984 | case NO_SENSE: | ||
985 | /* Inform the user, but make sure that it's not treated | ||
986 | * as a hard error. | ||
987 | */ | ||
988 | scsi_print_sense("sd", SCpnt); | ||
989 | SCpnt->result = 0; | ||
990 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
991 | good_bytes = xfer_size; | ||
992 | break; | ||
993 | case ILLEGAL_REQUEST: | ||
994 | if (SCpnt->device->use_10_for_rw && | ||
995 | (SCpnt->cmnd[0] == READ_10 || | ||
996 | SCpnt->cmnd[0] == WRITE_10)) | ||
997 | SCpnt->device->use_10_for_rw = 0; | ||
998 | if (SCpnt->device->use_10_for_ms && | ||
999 | (SCpnt->cmnd[0] == MODE_SENSE_10 || | ||
1000 | SCpnt->cmnd[0] == MODE_SELECT_10)) | ||
1001 | SCpnt->device->use_10_for_ms = 0; | ||
1002 | break; | ||
1003 | default: | ||
1004 | break; | ||
994 | } | 1005 | } |
995 | /* | 1006 | out: |
996 | * This calls the generic completion function, now that we know | 1007 | scsi_io_completion(SCpnt, good_bytes); |
997 | * how many actual sectors finished, and how many sectors we need | ||
998 | * to say have failed. | ||
999 | */ | ||
1000 | scsi_io_completion(SCpnt, good_bytes, block_sectors << 9); | ||
1001 | } | 1008 | } |
1002 | 1009 | ||
1003 | static int media_not_present(struct scsi_disk *sdkp, | 1010 | static int media_not_present(struct scsi_disk *sdkp, |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 4e607d3065bc..65eef33846bb 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1401,6 +1401,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1401 | Sg_device *sdp = NULL; | 1401 | Sg_device *sdp = NULL; |
1402 | struct cdev * cdev = NULL; | 1402 | struct cdev * cdev = NULL; |
1403 | int error, k; | 1403 | int error, k; |
1404 | unsigned long iflags; | ||
1404 | 1405 | ||
1405 | disk = alloc_disk(1); | 1406 | disk = alloc_disk(1); |
1406 | if (!disk) { | 1407 | if (!disk) { |
@@ -1428,7 +1429,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1428 | 1429 | ||
1429 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); | 1430 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); |
1430 | if (error) | 1431 | if (error) |
1431 | goto out; | 1432 | goto cdev_add_err; |
1432 | 1433 | ||
1433 | sdp->cdev = cdev; | 1434 | sdp->cdev = cdev; |
1434 | if (sg_sysfs_valid) { | 1435 | if (sg_sysfs_valid) { |
@@ -1455,6 +1456,13 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1455 | 1456 | ||
1456 | return 0; | 1457 | return 0; |
1457 | 1458 | ||
1459 | cdev_add_err: | ||
1460 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | ||
1461 | kfree(sg_dev_arr[k]); | ||
1462 | sg_dev_arr[k] = NULL; | ||
1463 | sg_nr_dev--; | ||
1464 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | ||
1465 | |||
1458 | out: | 1466 | out: |
1459 | put_disk(disk); | 1467 | put_disk(disk); |
1460 | if (cdev) | 1468 | if (cdev) |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index ebf6579ed698..fd94408577e5 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -292,7 +292,7 @@ static void rw_intr(struct scsi_cmnd * SCpnt) | |||
292 | * how many actual sectors finished, and how many sectors we need | 292 | * how many actual sectors finished, and how many sectors we need |
293 | * to say have failed. | 293 | * to say have failed. |
294 | */ | 294 | */ |
295 | scsi_io_completion(SCpnt, good_bytes, block_sectors << 9); | 295 | scsi_io_completion(SCpnt, good_bytes); |
296 | } | 296 | } |
297 | 297 | ||
298 | static int sr_init_command(struct scsi_cmnd * SCpnt) | 298 | static int sr_init_command(struct scsi_cmnd * SCpnt) |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index b5218fc0ac86..756ceb93ddc8 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -3599,7 +3599,6 @@ static struct st_buffer * | |||
3599 | tb->use_sg = max_sg; | 3599 | tb->use_sg = max_sg; |
3600 | tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); | 3600 | tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); |
3601 | 3601 | ||
3602 | tb->in_use = 1; | ||
3603 | tb->dma = need_dma; | 3602 | tb->dma = need_dma; |
3604 | tb->buffer_size = got; | 3603 | tb->buffer_size = got; |
3605 | 3604 | ||
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 411209048d74..05a5cae126ec 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h | |||
@@ -31,7 +31,6 @@ struct st_request { | |||
31 | 31 | ||
32 | /* The tape buffer descriptor. */ | 32 | /* The tape buffer descriptor. */ |
33 | struct st_buffer { | 33 | struct st_buffer { |
34 | unsigned char in_use; | ||
35 | unsigned char dma; /* DMA-able buffer */ | 34 | unsigned char dma; /* DMA-able buffer */ |
36 | unsigned char do_dio; /* direct i/o set up? */ | 35 | unsigned char do_dio; /* direct i/o set up? */ |
37 | int buffer_size; | 36 | int buffer_size; |
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 253797c60095..55ebf035e620 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h | |||
@@ -47,10 +47,19 @@ enum iscsi_uevent_e { | |||
47 | ISCSI_UEVENT_TRANSPORT_EP_POLL = UEVENT_BASE + 13, | 47 | ISCSI_UEVENT_TRANSPORT_EP_POLL = UEVENT_BASE + 13, |
48 | ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT = UEVENT_BASE + 14, | 48 | ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT = UEVENT_BASE + 14, |
49 | 49 | ||
50 | ISCSI_UEVENT_TGT_DSCVR = UEVENT_BASE + 15, | ||
51 | |||
50 | /* up events */ | 52 | /* up events */ |
51 | ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, | 53 | ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, |
52 | ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, | 54 | ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, |
53 | ISCSI_KEVENT_IF_ERROR = KEVENT_BASE + 3, | 55 | ISCSI_KEVENT_IF_ERROR = KEVENT_BASE + 3, |
56 | ISCSI_KEVENT_DESTROY_SESSION = KEVENT_BASE + 4, | ||
57 | }; | ||
58 | |||
59 | enum iscsi_tgt_dscvr { | ||
60 | ISCSI_TGT_DSCVR_SEND_TARGETS = 1, | ||
61 | ISCSI_TGT_DSCVR_ISNS = 2, | ||
62 | ISCSI_TGT_DSCVR_SLP = 3, | ||
54 | }; | 63 | }; |
55 | 64 | ||
56 | struct iscsi_uevent { | 65 | struct iscsi_uevent { |
@@ -116,6 +125,17 @@ struct iscsi_uevent { | |||
116 | struct msg_transport_disconnect { | 125 | struct msg_transport_disconnect { |
117 | uint64_t ep_handle; | 126 | uint64_t ep_handle; |
118 | } ep_disconnect; | 127 | } ep_disconnect; |
128 | struct msg_tgt_dscvr { | ||
129 | enum iscsi_tgt_dscvr type; | ||
130 | uint32_t host_no; | ||
131 | /* | ||
132 | * enable = 1 to establish a new connection | ||
133 | * with the server. enable = 0 to disconnect | ||
134 | * from the server. Used primarily to switch | ||
135 | * from one iSNS server to another. | ||
136 | */ | ||
137 | uint32_t enable; | ||
138 | } tgt_dscvr; | ||
119 | } u; | 139 | } u; |
120 | union { | 140 | union { |
121 | /* messages k -> u */ | 141 | /* messages k -> u */ |
@@ -138,6 +158,10 @@ struct iscsi_uevent { | |||
138 | uint32_t cid; | 158 | uint32_t cid; |
139 | uint32_t error; /* enum iscsi_err */ | 159 | uint32_t error; /* enum iscsi_err */ |
140 | } connerror; | 160 | } connerror; |
161 | struct msg_session_destroyed { | ||
162 | uint32_t host_no; | ||
163 | uint32_t sid; | ||
164 | } d_session; | ||
141 | struct msg_transport_connect_ret { | 165 | struct msg_transport_connect_ret { |
142 | uint64_t handle; | 166 | uint64_t handle; |
143 | } ep_connect_ret; | 167 | } ep_connect_ret; |
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index cbf7e58bd6f9..ba2760802ded 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
@@ -157,6 +157,11 @@ struct iscsi_conn { | |||
157 | int max_xmit_dlength; /* target_max_recv_dsl */ | 157 | int max_xmit_dlength; /* target_max_recv_dsl */ |
158 | int hdrdgst_en; | 158 | int hdrdgst_en; |
159 | int datadgst_en; | 159 | int datadgst_en; |
160 | int ifmarker_en; | ||
161 | int ofmarker_en; | ||
162 | /* values userspace uses to id a conn */ | ||
163 | int persistent_port; | ||
164 | char *persistent_address; | ||
160 | 165 | ||
161 | /* MIB-statistics */ | 166 | /* MIB-statistics */ |
162 | uint64_t txdata_octets; | 167 | uint64_t txdata_octets; |
@@ -196,8 +201,8 @@ struct iscsi_session { | |||
196 | int pdu_inorder_en; | 201 | int pdu_inorder_en; |
197 | int dataseq_inorder_en; | 202 | int dataseq_inorder_en; |
198 | int erl; | 203 | int erl; |
199 | int ifmarker_en; | 204 | int tpgt; |
200 | int ofmarker_en; | 205 | char *targetname; |
201 | 206 | ||
202 | /* control data */ | 207 | /* control data */ |
203 | struct iscsi_transport *tt; | 208 | struct iscsi_transport *tt; |
@@ -240,6 +245,10 @@ iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *, | |||
240 | extern void iscsi_session_teardown(struct iscsi_cls_session *); | 245 | extern void iscsi_session_teardown(struct iscsi_cls_session *); |
241 | extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *); | 246 | extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *); |
242 | extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); | 247 | extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); |
248 | extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, | ||
249 | enum iscsi_param param, char *buf, int buflen); | ||
250 | extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, | ||
251 | enum iscsi_param param, char *buf); | ||
243 | 252 | ||
244 | #define session_to_cls(_sess) \ | 253 | #define session_to_cls(_sess) \ |
245 | hostdata_session(_sess->host->hostdata) | 254 | hostdata_session(_sess->host->hostdata) |
@@ -255,6 +264,8 @@ extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); | |||
255 | extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, | 264 | extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, |
256 | int); | 265 | int); |
257 | extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); | 266 | extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); |
267 | extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | ||
268 | enum iscsi_param param, char *buf); | ||
258 | 269 | ||
259 | /* | 270 | /* |
260 | * pdu and task processing | 271 | * pdu and task processing |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index e46cd404bd7d..371f70d9aa92 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -143,7 +143,7 @@ struct scsi_cmnd { | |||
143 | 143 | ||
144 | extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); | 144 | extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); |
145 | extern void scsi_put_command(struct scsi_cmnd *); | 145 | extern void scsi_put_command(struct scsi_cmnd *); |
146 | extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int); | 146 | extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); |
147 | extern void scsi_finish_command(struct scsi_cmnd *cmd); | 147 | extern void scsi_finish_command(struct scsi_cmnd *cmd); |
148 | extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd); | 148 | extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd); |
149 | 149 | ||
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index a42efd6e4be8..b3dd90f3e858 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -542,6 +542,9 @@ struct Scsi_Host { | |||
542 | */ | 542 | */ |
543 | unsigned ordered_tag:1; | 543 | unsigned ordered_tag:1; |
544 | 544 | ||
545 | /* task mgmt function in progress */ | ||
546 | unsigned tmf_in_progress:1; | ||
547 | |||
545 | /* | 548 | /* |
546 | * Optional work queue to be utilized by the transport | 549 | * Optional work queue to be utilized by the transport |
547 | */ | 550 | */ |
@@ -619,7 +622,8 @@ static inline int scsi_host_in_recovery(struct Scsi_Host *shost) | |||
619 | { | 622 | { |
620 | return shost->shost_state == SHOST_RECOVERY || | 623 | return shost->shost_state == SHOST_RECOVERY || |
621 | shost->shost_state == SHOST_CANCEL_RECOVERY || | 624 | shost->shost_state == SHOST_CANCEL_RECOVERY || |
622 | shost->shost_state == SHOST_DEL_RECOVERY; | 625 | shost->shost_state == SHOST_DEL_RECOVERY || |
626 | shost->tmf_in_progress; | ||
623 | } | 627 | } |
624 | 628 | ||
625 | extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *); | 629 | extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *); |
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index b684426a5900..5a3df1d7085f 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h | |||
@@ -34,6 +34,7 @@ struct iscsi_cls_conn; | |||
34 | struct iscsi_conn; | 34 | struct iscsi_conn; |
35 | struct iscsi_cmd_task; | 35 | struct iscsi_cmd_task; |
36 | struct iscsi_mgmt_task; | 36 | struct iscsi_mgmt_task; |
37 | struct sockaddr; | ||
37 | 38 | ||
38 | /** | 39 | /** |
39 | * struct iscsi_transport - iSCSI Transport template | 40 | * struct iscsi_transport - iSCSI Transport template |
@@ -46,7 +47,12 @@ struct iscsi_mgmt_task; | |||
46 | * @bind_conn: associate this connection with existing iSCSI session | 47 | * @bind_conn: associate this connection with existing iSCSI session |
47 | * and specified transport descriptor | 48 | * and specified transport descriptor |
48 | * @destroy_conn: destroy inactive iSCSI connection | 49 | * @destroy_conn: destroy inactive iSCSI connection |
49 | * @set_param: set iSCSI Data-Path operational parameter | 50 | * @set_param: set iSCSI parameter. Return 0 on success, -ENODATA |
51 | * when param is not supported, and a -Exx value on other | ||
52 | * error. | ||
53 | * @get_param get iSCSI parameter. Must return number of bytes | ||
54 | * copied to buffer on success, -ENODATA when param | ||
55 | * is not supported, and a -Exx value on other error | ||
50 | * @start_conn: set connection to be operational | 56 | * @start_conn: set connection to be operational |
51 | * @stop_conn: suspend/recover/terminate connection | 57 | * @stop_conn: suspend/recover/terminate connection |
52 | * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. | 58 | * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. |
@@ -97,15 +103,11 @@ struct iscsi_transport { | |||
97 | void (*stop_conn) (struct iscsi_cls_conn *conn, int flag); | 103 | void (*stop_conn) (struct iscsi_cls_conn *conn, int flag); |
98 | void (*destroy_conn) (struct iscsi_cls_conn *conn); | 104 | void (*destroy_conn) (struct iscsi_cls_conn *conn); |
99 | int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, | 105 | int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, |
100 | uint32_t value); | 106 | char *buf, int buflen); |
101 | int (*get_conn_param) (struct iscsi_cls_conn *conn, | 107 | int (*get_conn_param) (struct iscsi_cls_conn *conn, |
102 | enum iscsi_param param, uint32_t *value); | 108 | enum iscsi_param param, char *buf); |
103 | int (*get_session_param) (struct iscsi_cls_session *session, | 109 | int (*get_session_param) (struct iscsi_cls_session *session, |
104 | enum iscsi_param param, uint32_t *value); | 110 | enum iscsi_param param, char *buf); |
105 | int (*get_conn_str_param) (struct iscsi_cls_conn *conn, | ||
106 | enum iscsi_param param, char *buf); | ||
107 | int (*get_session_str_param) (struct iscsi_cls_session *session, | ||
108 | enum iscsi_param param, char *buf); | ||
109 | int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, | 111 | int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, |
110 | char *data, uint32_t data_size); | 112 | char *data, uint32_t data_size); |
111 | void (*get_stats) (struct iscsi_cls_conn *conn, | 113 | void (*get_stats) (struct iscsi_cls_conn *conn, |
@@ -127,6 +129,8 @@ struct iscsi_transport { | |||
127 | uint64_t *ep_handle); | 129 | uint64_t *ep_handle); |
128 | int (*ep_poll) (uint64_t ep_handle, int timeout_ms); | 130 | int (*ep_poll) (uint64_t ep_handle, int timeout_ms); |
129 | void (*ep_disconnect) (uint64_t ep_handle); | 131 | void (*ep_disconnect) (uint64_t ep_handle); |
132 | int (*tgt_dscvr) (enum iscsi_tgt_dscvr type, uint32_t host_no, | ||
133 | uint32_t enable, struct sockaddr *dst_addr); | ||
130 | }; | 134 | }; |
131 | 135 | ||
132 | /* | 136 | /* |
@@ -155,13 +159,6 @@ struct iscsi_cls_conn { | |||
155 | struct iscsi_transport *transport; | 159 | struct iscsi_transport *transport; |
156 | uint32_t cid; /* connection id */ | 160 | uint32_t cid; /* connection id */ |
157 | 161 | ||
158 | /* portal/group values we got during discovery */ | ||
159 | char *persistent_address; | ||
160 | int persistent_port; | ||
161 | /* portal/group values we are currently using */ | ||
162 | char *address; | ||
163 | int port; | ||
164 | |||
165 | int active; /* must be accessed with the connlock */ | 162 | int active; /* must be accessed with the connlock */ |
166 | struct device dev; /* sysfs transport/container device */ | 163 | struct device dev; /* sysfs transport/container device */ |
167 | struct mempool_zone *z_error; | 164 | struct mempool_zone *z_error; |
@@ -185,16 +182,11 @@ struct iscsi_cls_session { | |||
185 | struct list_head host_list; | 182 | struct list_head host_list; |
186 | struct iscsi_transport *transport; | 183 | struct iscsi_transport *transport; |
187 | 184 | ||
188 | /* iSCSI values used as unique id by userspace. */ | ||
189 | char *targetname; | ||
190 | int tpgt; | ||
191 | |||
192 | /* recovery fields */ | 185 | /* recovery fields */ |
193 | int recovery_tmo; | 186 | int recovery_tmo; |
194 | struct work_struct recovery_work; | 187 | struct work_struct recovery_work; |
195 | 188 | ||
196 | int target_id; | 189 | int target_id; |
197 | int channel; | ||
198 | 190 | ||
199 | int sid; /* session id */ | 191 | int sid; /* session id */ |
200 | void *dd_data; /* LLD private data */ | 192 | void *dd_data; /* LLD private data */ |
@@ -207,8 +199,10 @@ struct iscsi_cls_session { | |||
207 | #define iscsi_session_to_shost(_session) \ | 199 | #define iscsi_session_to_shost(_session) \ |
208 | dev_to_shost(_session->dev.parent) | 200 | dev_to_shost(_session->dev.parent) |
209 | 201 | ||
202 | #define starget_to_session(_stgt) \ | ||
203 | iscsi_dev_to_session(_stgt->dev.parent) | ||
204 | |||
210 | struct iscsi_host { | 205 | struct iscsi_host { |
211 | int next_target_id; | ||
212 | struct list_head sessions; | 206 | struct list_head sessions; |
213 | struct mutex mutex; | 207 | struct mutex mutex; |
214 | }; | 208 | }; |
@@ -216,8 +210,17 @@ struct iscsi_host { | |||
216 | /* | 210 | /* |
217 | * session and connection functions that can be used by HW iSCSI LLDs | 211 | * session and connection functions that can be used by HW iSCSI LLDs |
218 | */ | 212 | */ |
213 | extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost, | ||
214 | struct iscsi_transport *transport); | ||
215 | extern int iscsi_add_session(struct iscsi_cls_session *session, | ||
216 | unsigned int target_id); | ||
217 | extern int iscsi_if_create_session_done(struct iscsi_cls_conn *conn); | ||
218 | extern int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn); | ||
219 | extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, | 219 | extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, |
220 | struct iscsi_transport *t, int channel); | 220 | struct iscsi_transport *t, |
221 | unsigned int target_id); | ||
222 | extern void iscsi_remove_session(struct iscsi_cls_session *session); | ||
223 | extern void iscsi_free_session(struct iscsi_cls_session *session); | ||
221 | extern int iscsi_destroy_session(struct iscsi_cls_session *session); | 224 | extern int iscsi_destroy_session(struct iscsi_cls_session *session); |
222 | extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, | 225 | extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, |
223 | uint32_t cid); | 226 | uint32_t cid); |
@@ -225,4 +228,5 @@ extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); | |||
225 | extern void iscsi_unblock_session(struct iscsi_cls_session *session); | 228 | extern void iscsi_unblock_session(struct iscsi_cls_session *session); |
226 | extern void iscsi_block_session(struct iscsi_cls_session *session); | 229 | extern void iscsi_block_session(struct iscsi_cls_session *session); |
227 | 230 | ||
231 | |||
228 | #endif | 232 | #endif |
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 93cfb4bf4211..e3c503cd175e 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/transport_class.h> | 4 | #include <linux/transport_class.h> |
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <linux/mutex.h> | ||
6 | 7 | ||
7 | struct scsi_transport_template; | 8 | struct scsi_transport_template; |
8 | struct sas_rphy; | 9 | struct sas_rphy; |
@@ -55,7 +56,6 @@ struct sas_phy { | |||
55 | enum sas_linkrate minimum_linkrate; | 56 | enum sas_linkrate minimum_linkrate; |
56 | enum sas_linkrate maximum_linkrate_hw; | 57 | enum sas_linkrate maximum_linkrate_hw; |
57 | enum sas_linkrate maximum_linkrate; | 58 | enum sas_linkrate maximum_linkrate; |
58 | u8 port_identifier; | ||
59 | 59 | ||
60 | /* internal state */ | 60 | /* internal state */ |
61 | unsigned int local_attached : 1; | 61 | unsigned int local_attached : 1; |
@@ -66,8 +66,8 @@ struct sas_phy { | |||
66 | u32 loss_of_dword_sync_count; | 66 | u32 loss_of_dword_sync_count; |
67 | u32 phy_reset_problem_count; | 67 | u32 phy_reset_problem_count; |
68 | 68 | ||
69 | /* the other end of the link */ | 69 | /* for the list of phys belonging to a port */ |
70 | struct sas_rphy *rphy; | 70 | struct list_head port_siblings; |
71 | }; | 71 | }; |
72 | 72 | ||
73 | #define dev_to_phy(d) \ | 73 | #define dev_to_phy(d) \ |
@@ -124,6 +124,24 @@ struct sas_expander_device { | |||
124 | #define rphy_to_expander_device(r) \ | 124 | #define rphy_to_expander_device(r) \ |
125 | container_of((r), struct sas_expander_device, rphy) | 125 | container_of((r), struct sas_expander_device, rphy) |
126 | 126 | ||
127 | struct sas_port { | ||
128 | struct device dev; | ||
129 | |||
130 | u8 port_identifier; | ||
131 | int num_phys; | ||
132 | |||
133 | /* the other end of the link */ | ||
134 | struct sas_rphy *rphy; | ||
135 | |||
136 | struct mutex phy_list_mutex; | ||
137 | struct list_head phy_list; | ||
138 | }; | ||
139 | |||
140 | #define dev_to_sas_port(d) \ | ||
141 | container_of((d), struct sas_port, dev) | ||
142 | #define transport_class_to_sas_port(cdev) \ | ||
143 | dev_to_sas_port((cdev)->dev) | ||
144 | |||
127 | /* The functions by which the transport class and the driver communicate */ | 145 | /* The functions by which the transport class and the driver communicate */ |
128 | struct sas_function_template { | 146 | struct sas_function_template { |
129 | int (*get_linkerrors)(struct sas_phy *); | 147 | int (*get_linkerrors)(struct sas_phy *); |
@@ -133,6 +151,7 @@ struct sas_function_template { | |||
133 | }; | 151 | }; |
134 | 152 | ||
135 | 153 | ||
154 | void sas_remove_children(struct device *); | ||
136 | extern void sas_remove_host(struct Scsi_Host *); | 155 | extern void sas_remove_host(struct Scsi_Host *); |
137 | 156 | ||
138 | extern struct sas_phy *sas_phy_alloc(struct device *, int); | 157 | extern struct sas_phy *sas_phy_alloc(struct device *, int); |
@@ -141,13 +160,21 @@ extern int sas_phy_add(struct sas_phy *); | |||
141 | extern void sas_phy_delete(struct sas_phy *); | 160 | extern void sas_phy_delete(struct sas_phy *); |
142 | extern int scsi_is_sas_phy(const struct device *); | 161 | extern int scsi_is_sas_phy(const struct device *); |
143 | 162 | ||
144 | extern struct sas_rphy *sas_end_device_alloc(struct sas_phy *); | 163 | extern struct sas_rphy *sas_end_device_alloc(struct sas_port *); |
145 | extern struct sas_rphy *sas_expander_alloc(struct sas_phy *, enum sas_device_type); | 164 | extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type); |
146 | void sas_rphy_free(struct sas_rphy *); | 165 | void sas_rphy_free(struct sas_rphy *); |
147 | extern int sas_rphy_add(struct sas_rphy *); | 166 | extern int sas_rphy_add(struct sas_rphy *); |
148 | extern void sas_rphy_delete(struct sas_rphy *); | 167 | extern void sas_rphy_delete(struct sas_rphy *); |
149 | extern int scsi_is_sas_rphy(const struct device *); | 168 | extern int scsi_is_sas_rphy(const struct device *); |
150 | 169 | ||
170 | struct sas_port *sas_port_alloc(struct device *, int); | ||
171 | int sas_port_add(struct sas_port *); | ||
172 | void sas_port_free(struct sas_port *); | ||
173 | void sas_port_delete(struct sas_port *); | ||
174 | void sas_port_add_phy(struct sas_port *, struct sas_phy *); | ||
175 | void sas_port_delete_phy(struct sas_port *, struct sas_phy *); | ||
176 | int scsi_is_sas_port(const struct device *); | ||
177 | |||
151 | extern struct scsi_transport_template * | 178 | extern struct scsi_transport_template * |
152 | sas_attach_transport(struct sas_function_template *); | 179 | sas_attach_transport(struct sas_function_template *); |
153 | extern void sas_release_transport(struct scsi_transport_template *); | 180 | extern void sas_release_transport(struct scsi_transport_template *); |