Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
[SCSI] mpt: fix disable lsi sas to use msi as default
[SCSI] fix ABORTED_COMMAND looping forever problem
[SCSI] sd: revive sd_index_lock
[SCSI] cxgb3i: update the driver version to 1.0.1
[SCSI] cxgb3i: Fix spelling errors in documentation
[SCSI] cxgb3i: added missing include in cxgb3i_ddp.h
[SCSI] cxgb3i: Outgoing pdus need to observe skb's MAX_SKB_FRAGS
[SCSI] cxgb3i: added per-task data to track transmit progress
[SCSI] cxgb3i: transmit work-request fixes
[SCSI] hptiop: Add new PCI device ID

+368 -177
+5 -6
Documentation/scsi/cxgb3i.txt
··· 4 4 ============ 5 5 6 6 The Chelsio T3 ASIC based Adapters (S310, S320, S302, S304, Mezz cards, etc. 7 - series of products) supports iSCSI acceleration and iSCSI Direct Data Placement 7 + series of products) support iSCSI acceleration and iSCSI Direct Data Placement 8 8 (DDP) where the hardware handles the expensive byte touching operations, such 9 9 as CRC computation and verification, and direct DMA to the final host memory 10 10 destination: ··· 31 31 the TCP segments onto the wire. It handles TCP retransmission if 32 32 needed. 33 33 34 - On receving, S3 h/w recovers the iSCSI PDU by reassembling TCP 34 + On receiving, S3 h/w recovers the iSCSI PDU by reassembling TCP 35 35 segments, separating the header and data, calculating and verifying 36 - the digests, then forwards the header to the host. The payload data, 36 + the digests, then forwarding the header to the host. The payload data, 37 37 if possible, will be directly placed into the pre-posted host DDP 38 38 buffer. Otherwise, the payload data will be sent to the host too. 39 39 ··· 68 68 sure the ip address is unique in the network. 69 69 70 70 3. edit /etc/iscsi/iscsid.conf 71 - The default setting for MaxRecvDataSegmentLength (131072) is too big, 72 - replace "node.conn[0].iscsi.MaxRecvDataSegmentLength" to be a value no 73 - bigger than 15360 (for example 8192): 71 + The default setting for MaxRecvDataSegmentLength (131072) is too big; 72 + replace with a value no bigger than 15360 (for example 8192): 74 73 75 74 node.conn[0].iscsi.MaxRecvDataSegmentLength = 8192 76 75
+2 -2
drivers/message/fusion/mptbase.c
··· 91 91 controllers (default=0)"); 92 92 93 93 static int mpt_msi_enable_sas; 94 - module_param(mpt_msi_enable_sas, int, 1); 94 + module_param(mpt_msi_enable_sas, int, 0); 95 95 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \ 96 - controllers (default=1)"); 96 + controllers (default=0)"); 97 97 98 98 99 99 static int mpt_channel_mapping;
+21
drivers/scsi/cxgb3i/cxgb3i.h
··· 20 20 #include <linux/list.h> 21 21 #include <linux/netdevice.h> 22 22 #include <linux/scatterlist.h> 23 + #include <linux/skbuff.h> 23 24 #include <scsi/libiscsi_tcp.h> 24 25 25 26 /* from cxgb3 LLD */ ··· 112 111 struct s3_conn *c3cn; 113 112 struct cxgb3i_hba *hba; 114 113 struct cxgb3i_conn *cconn; 114 + }; 115 + 116 + /** 117 + * struct cxgb3i_task_data - private iscsi task data 118 + * 119 + * @nr_frags: # of coalesced page frags (from scsi sgl) 120 + * @frags: coalesced page frags (from scsi sgl) 121 + * @skb: tx pdu skb 122 + * @offset: data offset for the next pdu 123 + * @count: max. possible pdu payload 124 + * @sgoffset: offset to the first sg entry for a given offset 125 + */ 126 + #define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512) 127 + struct cxgb3i_task_data { 128 + unsigned short nr_frags; 129 + skb_frag_t frags[MAX_PDU_FRAGS]; 130 + struct sk_buff *skb; 131 + unsigned int offset; 132 + unsigned int count; 133 + unsigned int sgoffset; 115 134 }; 116 135 117 136 int cxgb3i_iscsi_init(void);
+11 -8
drivers/scsi/cxgb3i/cxgb3i_ddp.c
··· 639 639 write_unlock(&cxgb3i_ddp_rwlock); 640 640 641 641 ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x " 642 - "pkt %u,%u.\n", 642 + "pkt %u/%u, %u/%u.\n", 643 643 ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits, 644 644 ddp->idx_mask, ddp->rsvd_tag_mask, 645 - ddp->max_txsz, ddp->max_rxsz); 645 + ddp->max_txsz, uinfo.max_txsz, 646 + ddp->max_rxsz, uinfo.max_rxsz); 646 647 return 0; 647 648 648 649 free_ddp_map: ··· 655 654 * cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource 656 655 * @tdev: t3cdev adapter 657 656 * @tformat: tag format 658 - * @txsz: max tx pkt size, filled in by this func. 659 - * @rxsz: max rx pkt size, filled in by this func. 657 + * @txsz: max tx pdu payload size, filled in by this func. 658 + * @rxsz: max rx pdu payload size, filled in by this func. 660 659 * initialize the ddp pagepod manager for a given adapter if needed and 661 660 * setup the tag format for a given iscsi entity 662 661 */ ··· 686 685 tformat->sw_bits, tformat->rsvd_bits, 687 686 tformat->rsvd_shift, tformat->rsvd_mask); 688 687 689 - *txsz = ddp->max_txsz; 690 - *rxsz = ddp->max_rxsz; 691 - ddp_log_info("ddp max pkt size: %u, %u.\n", 692 - ddp->max_txsz, ddp->max_rxsz); 688 + *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, 689 + ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN); 690 + *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, 691 + ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN); 692 + ddp_log_info("max payload size: %u/%u, %u/%u.\n", 693 + *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz); 693 694 return 0; 694 695 } 695 696 EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init);
+4 -1
drivers/scsi/cxgb3i/cxgb3i_ddp.h
··· 13 13 #ifndef __CXGB3I_ULP2_DDP_H__ 14 14 #define __CXGB3I_ULP2_DDP_H__ 15 15 16 + #include <linux/vmalloc.h> 17 + 16 18 /** 17 19 * struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity 18 20 * ··· 87 85 struct sk_buff **gl_skb; 88 86 }; 89 87 88 + #define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8) */ 90 89 #define ULP2_MAX_PKT_SIZE 16224 91 - #define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_MAX) 90 + #define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN) 92 91 #define PPOD_PAGES_MAX 4 93 92 #define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */ 94 93
+2 -2
drivers/scsi/cxgb3i/cxgb3i_init.c
··· 12 12 #include "cxgb3i.h" 13 13 14 14 #define DRV_MODULE_NAME "cxgb3i" 15 - #define DRV_MODULE_VERSION "1.0.0" 16 - #define DRV_MODULE_RELDATE "Jun. 1, 2008" 15 + #define DRV_MODULE_VERSION "1.0.1" 16 + #define DRV_MODULE_RELDATE "Jan. 2009" 17 17 18 18 static char version[] = 19 19 "Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME
+9 -13
drivers/scsi/cxgb3i/cxgb3i_iscsi.c
··· 364 364 365 365 cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost, 366 366 cmds_max, 367 - sizeof(struct iscsi_tcp_task), 367 + sizeof(struct iscsi_tcp_task) + 368 + sizeof(struct cxgb3i_task_data), 368 369 initial_cmdsn, ISCSI_MAX_TARGET); 369 370 if (!cls_session) 370 371 return NULL; ··· 403 402 { 404 403 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 405 404 struct cxgb3i_conn *cconn = tcp_conn->dd_data; 406 - unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, 407 - cconn->hba->snic->tx_max_size - 408 - ISCSI_PDU_NONPAYLOAD_MAX); 405 + unsigned int max = max(512 * MAX_SKB_FRAGS, SKB_TX_HEADROOM); 409 406 407 + max = min(cconn->hba->snic->tx_max_size, max); 410 408 if (conn->max_xmit_dlength) 411 - conn->max_xmit_dlength = min_t(unsigned int, 412 - conn->max_xmit_dlength, max); 409 + conn->max_xmit_dlength = min(conn->max_xmit_dlength, max); 413 410 else 414 411 conn->max_xmit_dlength = max; 415 412 align_pdu_size(conn->max_xmit_dlength); 416 - cxgb3i_log_info("conn 0x%p, max xmit %u.\n", 413 + cxgb3i_api_debug("conn 0x%p, max xmit %u.\n", 417 414 conn, conn->max_xmit_dlength); 418 415 return 0; 419 416 } ··· 426 427 { 427 428 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 428 429 struct cxgb3i_conn *cconn = tcp_conn->dd_data; 429 - unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, 430 - cconn->hba->snic->rx_max_size - 431 - ISCSI_PDU_NONPAYLOAD_MAX); 430 + unsigned int max = cconn->hba->snic->rx_max_size; 432 431 433 432 align_pdu_size(max); 434 433 if (conn->max_recv_dlength) { ··· 436 439 conn->max_recv_dlength, max); 437 440 return -EINVAL; 438 441 } 439 - conn->max_recv_dlength = min_t(unsigned int, 440 - conn->max_recv_dlength, max); 442 + conn->max_recv_dlength = min(conn->max_recv_dlength, max); 441 443 align_pdu_size(conn->max_recv_dlength); 442 444 } else 443 445 conn->max_recv_dlength = max; ··· 840 844 .proc_name = "cxgb3i", 841 845 .queuecommand = iscsi_queuecommand, 842 846 .change_queue_depth = iscsi_change_queue_depth, 843 - .can_queue = 128 * (ISCSI_DEF_XMIT_CMDS_MAX - 1), 847 + .can_queue = CXGB3I_SCSI_QDEPTH_DFLT - 1, 844 848 .sg_tablesize = SG_ALL, 845 849 .max_sectors = 0xFFFF, 846 850 .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
+103 -43
drivers/scsi/cxgb3i/cxgb3i_offload.c
··· 23 23 #include "cxgb3i_ddp.h" 24 24 25 25 #ifdef __DEBUG_C3CN_CONN__ 26 - #define c3cn_conn_debug cxgb3i_log_info 26 + #define c3cn_conn_debug cxgb3i_log_debug 27 27 #else 28 28 #define c3cn_conn_debug(fmt...) 29 29 #endif 30 30 31 31 #ifdef __DEBUG_C3CN_TX__ 32 - #define c3cn_tx_debug cxgb3i_log_debug 32 + #define c3cn_tx_debug cxgb3i_log_debug 33 33 #else 34 34 #define c3cn_tx_debug(fmt...) 35 35 #endif 36 36 37 37 #ifdef __DEBUG_C3CN_RX__ 38 - #define c3cn_rx_debug cxgb3i_log_debug 38 + #define c3cn_rx_debug cxgb3i_log_debug 39 39 #else 40 40 #define c3cn_rx_debug(fmt...) 41 41 #endif ··· 47 47 module_param(cxgb3_rcv_win, int, 0644); 48 48 MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)"); 49 49 50 - static int cxgb3_snd_win = 64 * 1024; 50 + static int cxgb3_snd_win = 128 * 1024; 51 51 module_param(cxgb3_snd_win, int, 0644); 52 - MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=64KB)"); 52 + MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=128KB)"); 53 53 54 54 static int cxgb3_rx_credit_thres = 10 * 1024; 55 55 module_param(cxgb3_rx_credit_thres, int, 0644); ··· 301 301 static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb, 302 302 int flags) 303 303 { 304 - CXGB3_SKB_CB(skb)->seq = c3cn->write_seq; 305 - CXGB3_SKB_CB(skb)->flags = flags; 304 + skb_tcp_seq(skb) = c3cn->write_seq; 305 + skb_flags(skb) = flags; 306 306 __skb_queue_tail(&c3cn->write_queue, skb); 307 307 } 308 308 ··· 457 457 * The number of WRs needed for an skb depends on the number of fragments 458 458 * in the skb and whether it has any payload in its main body. This maps the 459 459 * length of the gather list represented by an skb into the # of necessary WRs. 460 - * 461 - * The max. length of an skb is controlled by the max pdu size which is ~16K. 462 - * Also, assume the min. fragment length is the sector size (512), then add 463 - * extra fragment counts for iscsi bhs and payload padding. 460 + * The extra two fragments are for iscsi bhs and payload padding. 464 461 */ 465 - #define SKB_WR_LIST_SIZE (16384/512 + 3) 462 + #define SKB_WR_LIST_SIZE (MAX_SKB_FRAGS + 2) 466 463 static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly; 467 464 468 465 static void s3_init_wr_tab(unsigned int wr_len) ··· 482 485 483 486 static inline void reset_wr_list(struct s3_conn *c3cn) 484 487 { 485 - c3cn->wr_pending_head = NULL; 488 + c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL; 486 489 } 487 490 488 491 /* ··· 493 496 static inline void enqueue_wr(struct s3_conn *c3cn, 494 497 struct sk_buff *skb) 495 498 { 496 - skb_wr_data(skb) = NULL; 499 + skb_tx_wr_next(skb) = NULL; 497 500 498 501 /* 499 502 * We want to take an extra reference since both us and the driver ··· 506 509 if (!c3cn->wr_pending_head) 507 510 c3cn->wr_pending_head = skb; 508 511 else 509 - skb_wr_data(skb) = skb; 512 + skb_tx_wr_next(c3cn->wr_pending_tail) = skb; 510 513 c3cn->wr_pending_tail = skb; 514 + } 515 + 516 + static int count_pending_wrs(struct s3_conn *c3cn) 517 + { 518 + int n = 0; 519 + const struct sk_buff *skb = c3cn->wr_pending_head; 520 + 521 + while (skb) { 522 + n += skb->csum; 523 + skb = skb_tx_wr_next(skb); 524 + } 525 + return n; 511 526 } 512 527 513 528 static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn) ··· 538 529 539 530 if (likely(skb)) { 540 531 /* Don't bother clearing the tail */ 541 - c3cn->wr_pending_head = skb_wr_data(skb); 542 - skb_wr_data(skb) = NULL; 532 + c3cn->wr_pending_head = skb_tx_wr_next(skb); 533 + skb_tx_wr_next(skb) = NULL; 543 534 } 544 535 return skb; 545 536 } ··· 552 543 } 553 544 554 545 static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb, 555 - int len) 546 + int len, int req_completion) 556 547 { 557 548 struct tx_data_wr *req; 558 549 559 550 skb_reset_transport_header(skb); 560 551 req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req)); 561 - req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); 552 + req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) | 553 + (req_completion ? F_WR_COMPL : 0)); 562 554 req->wr_lo = htonl(V_WR_TID(c3cn->tid)); 563 555 req->sndseq = htonl(c3cn->snd_nxt); 564 556 /* len includes the length of any HW ULP additions */ ··· 602 592 603 593 if (unlikely(c3cn->state == C3CN_STATE_CONNECTING || 604 594 c3cn->state == C3CN_STATE_CLOSE_WAIT_1 || 605 - c3cn->state == C3CN_STATE_ABORTING)) { 595 + c3cn->state >= C3CN_STATE_ABORTING)) { 606 596 c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n", 607 597 c3cn, c3cn->state); 608 598 return 0; ··· 625 615 if (c3cn->wr_avail < wrs_needed) { 626 616 c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, " 627 617 "wr %d < %u.\n", 628 - c3cn, skb->len, skb->datalen, frags, 618 + c3cn, skb->len, skb->data_len, frags, 629 619 wrs_needed, c3cn->wr_avail); 630 620 break; 631 621 } ··· 637 627 c3cn->wr_unacked += wrs_needed; 638 628 enqueue_wr(c3cn, skb); 639 629 640 - if (likely(CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_NEED_HDR)) { 641 - len += ulp_extra_len(skb); 642 - make_tx_data_wr(c3cn, skb, len); 643 - c3cn->snd_nxt += len; 644 - if ((req_completion 645 - && c3cn->wr_unacked == wrs_needed) 646 - || (CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_COMPL) 647 - || c3cn->wr_unacked >= c3cn->wr_max / 2) { 648 - struct work_request_hdr *wr = cplhdr(skb); 630 + c3cn_tx_debug("c3cn 0x%p, enqueue, skb len %u/%u, frag %u, " 631 + "wr %d, left %u, unack %u.\n", 632 + c3cn, skb->len, skb->data_len, frags, 633 + wrs_needed, c3cn->wr_avail, c3cn->wr_unacked); 649 634 650 - wr->wr_hi |= htonl(F_WR_COMPL); 635 + 636 + if (likely(skb_flags(skb) & C3CB_FLAG_NEED_HDR)) { 637 + if ((req_completion && 638 + c3cn->wr_unacked == wrs_needed) || 639 + (skb_flags(skb) & C3CB_FLAG_COMPL) || 640 + c3cn->wr_unacked >= c3cn->wr_max / 2) { 641 + req_completion = 1; 651 642 c3cn->wr_unacked = 0; 652 643 } 653 - CXGB3_SKB_CB(skb)->flags &= ~C3CB_FLAG_NEED_HDR; 644 + len += ulp_extra_len(skb); 645 + make_tx_data_wr(c3cn, skb, len, req_completion); 646 + c3cn->snd_nxt += len; 647 + skb_flags(skb) &= ~C3CB_FLAG_NEED_HDR; 654 648 } 655 649 656 650 total_size += skb->truesize; ··· 749 735 if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED))) 750 736 /* upper layer has requested closing */ 751 737 send_abort_req(c3cn); 752 - else if (c3cn_push_tx_frames(c3cn, 1)) 738 + else { 739 + if (skb_queue_len(&c3cn->write_queue)) 740 + c3cn_push_tx_frames(c3cn, 1); 753 741 cxgb3i_conn_tx_open(c3cn); 742 + } 754 743 } 755 744 756 745 static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb, ··· 1099 1082 return; 1100 1083 } 1101 1084 1102 - CXGB3_SKB_CB(skb)->seq = ntohl(hdr_cpl->seq); 1103 - CXGB3_SKB_CB(skb)->flags = 0; 1085 + skb_tcp_seq(skb) = ntohl(hdr_cpl->seq); 1086 + skb_flags(skb) = 0; 1104 1087 1105 1088 skb_reset_transport_header(skb); 1106 1089 __skb_pull(skb, sizeof(struct cpl_iscsi_hdr)); ··· 1120 1103 goto abort_conn; 1121 1104 1122 1105 skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY; 1123 - skb_ulp_pdulen(skb) = ntohs(ddp_cpl.len); 1124 - skb_ulp_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); 1106 + skb_rx_pdulen(skb) = ntohs(ddp_cpl.len); 1107 + skb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); 1125 1108 status = ntohl(ddp_cpl.ddp_status); 1126 1109 1127 1110 c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n", 1128 - skb, skb->len, skb_ulp_pdulen(skb), status); 1111 + skb, skb->len, skb_rx_pdulen(skb), status); 1129 1112 1130 1113 if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT)) 1131 1114 skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR; ··· 1143 1126 } else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT)) 1144 1127 skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED; 1145 1128 1146 - c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_ulp_pdulen(skb); 1129 + c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_rx_pdulen(skb); 1147 1130 __pskb_trim(skb, len); 1148 1131 __skb_queue_tail(&c3cn->receive_queue, skb); 1149 1132 cxgb3i_conn_pdu_ready(c3cn); ··· 1168 1151 * Process an acknowledgment of WR completion. Advance snd_una and send the 1169 1152 * next batch of work requests from the write queue. 1170 1153 */ 1154 + static void check_wr_invariants(struct s3_conn *c3cn) 1155 + { 1156 + int pending = count_pending_wrs(c3cn); 1157 + 1158 + if (unlikely(c3cn->wr_avail + pending != c3cn->wr_max)) 1159 + cxgb3i_log_error("TID %u: credit imbalance: avail %u, " 1160 + "pending %u, total should be %u\n", 1161 + c3cn->tid, c3cn->wr_avail, pending, 1162 + c3cn->wr_max); 1163 + } 1164 + 1171 1165 static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) 1172 1166 { 1173 1167 struct cpl_wr_ack *hdr = cplhdr(skb); 1174 1168 unsigned int credits = ntohs(hdr->credits); 1175 1169 u32 snd_una = ntohl(hdr->snd_una); 1170 + 1171 + c3cn_tx_debug("%u WR credits, avail %u, unack %u, TID %u, state %u.\n", 1172 + credits, c3cn->wr_avail, c3cn->wr_unacked, 1173 + c3cn->tid, c3cn->state); 1176 1174 1177 1175 c3cn->wr_avail += credits; 1178 1176 if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail) ··· 1203 1171 break; 1204 1172 } 1205 1173 if (unlikely(credits < p->csum)) { 1174 + struct tx_data_wr *w = cplhdr(p); 1175 + cxgb3i_log_error("TID %u got %u WR credits need %u, " 1176 + "len %u, main body %u, frags %u, " 1177 + "seq # %u, ACK una %u, ACK nxt %u, " 1178 + "WR_AVAIL %u, WRs pending %u\n", 1179 + c3cn->tid, credits, p->csum, p->len, 1180 + p->len - p->data_len, 1181 + skb_shinfo(p)->nr_frags, 1182 + ntohl(w->sndseq), snd_una, 1183 + ntohl(hdr->snd_nxt), c3cn->wr_avail, 1184 + count_pending_wrs(c3cn) - credits); 1206 1185 p->csum -= credits; 1207 1186 break; 1208 1187 } else { ··· 1223 1180 } 1224 1181 } 1225 1182 1226 - if (unlikely(before(snd_una, c3cn->snd_una))) 1183 + check_wr_invariants(c3cn); 1184 + 1185 + if (unlikely(before(snd_una, c3cn->snd_una))) { 1186 + cxgb3i_log_error("TID %u, unexpected sequence # %u in WR_ACK " 1187 + "snd_una %u\n", 1188 + c3cn->tid, snd_una, c3cn->snd_una); 1227 1189 goto out_free; 1190 + } 1228 1191 1229 1192 if (c3cn->snd_una != snd_una) { 1230 1193 c3cn->snd_una = snd_una; 1231 1194 dst_confirm(c3cn->dst_cache); 1232 1195 } 1233 1196 1234 - if (skb_queue_len(&c3cn->write_queue) && c3cn_push_tx_frames(c3cn, 0)) 1197 + if (skb_queue_len(&c3cn->write_queue)) { 1198 + if (c3cn_push_tx_frames(c3cn, 0)) 1199 + cxgb3i_conn_tx_open(c3cn); 1200 + } else 1235 1201 cxgb3i_conn_tx_open(c3cn); 1236 1202 out_free: 1237 1203 __kfree_skb(skb); ··· 1504 1452 struct dst_entry *dst) 1505 1453 { 1506 1454 BUG_ON(c3cn->cdev != cdev); 1507 - c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs; 1455 + c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs - 1; 1508 1456 c3cn->wr_unacked = 0; 1509 1457 c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst)); 1510 1458 ··· 1723 1671 goto out_err; 1724 1672 } 1725 1673 1726 - err = -EPIPE; 1727 1674 if (c3cn->err) { 1728 1675 c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err); 1676 + err = -EPIPE; 1677 + goto out_err; 1678 + } 1679 + 1680 + if (c3cn->write_seq - c3cn->snd_una >= cxgb3_snd_win) { 1681 + c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n", 1682 + c3cn, c3cn->write_seq, c3cn->snd_una, 1683 + cxgb3_snd_win); 1684 + err = -EAGAIN; 1729 1685 goto out_err; 1730 1686 } 1731 1687
+19 -10
drivers/scsi/cxgb3i/cxgb3i_offload.h
··· 178 178 * @flag: see C3CB_FLAG_* below 179 179 * @ulp_mode: ULP mode/submode of sk_buff 180 180 * @seq: tcp sequence number 181 - * @ddigest: pdu data digest 182 - * @pdulen: recovered pdu length 183 - * @wr_data: scratch area for tx wr 184 181 */ 182 + struct cxgb3_skb_rx_cb { 183 + __u32 ddigest; /* data digest */ 184 + __u32 pdulen; /* recovered pdu length */ 185 + }; 186 + 187 + struct cxgb3_skb_tx_cb { 188 + struct sk_buff *wr_next; /* next wr */ 189 + }; 190 + 185 191 struct cxgb3_skb_cb { 186 192 __u8 flags; 187 193 __u8 ulp_mode; 188 194 __u32 seq; 189 - __u32 ddigest; 190 - __u32 pdulen; 191 - struct sk_buff *wr_data; 195 + union { 196 + struct cxgb3_skb_rx_cb rx; 197 + struct cxgb3_skb_tx_cb tx; 198 + }; 192 199 }; 193 200 194 201 #define CXGB3_SKB_CB(skb) ((struct cxgb3_skb_cb *)&((skb)->cb[0])) 195 - 202 + #define skb_flags(skb) (CXGB3_SKB_CB(skb)->flags) 196 203 #define skb_ulp_mode(skb) (CXGB3_SKB_CB(skb)->ulp_mode) 197 - #define skb_ulp_ddigest(skb) (CXGB3_SKB_CB(skb)->ddigest) 198 - #define skb_ulp_pdulen(skb) (CXGB3_SKB_CB(skb)->pdulen) 199 - #define skb_wr_data(skb) (CXGB3_SKB_CB(skb)->wr_data) 204 + #define skb_tcp_seq(skb) (CXGB3_SKB_CB(skb)->seq) 205 + #define skb_rx_ddigest(skb) (CXGB3_SKB_CB(skb)->rx.ddigest) 206 + #define skb_rx_pdulen(skb) (CXGB3_SKB_CB(skb)->rx.pdulen) 207 + #define skb_tx_wr_next(skb) (CXGB3_SKB_CB(skb)->tx.wr_next) 200 208 201 209 enum c3cb_flags { 202 210 C3CB_FLAG_NEED_HDR = 1 << 0, /* packet needs a TX_DATA_WR header */ ··· 225 217 /* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */ 226 218 #define TX_HEADER_LEN \ 227 219 (sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr)) 220 + #define SKB_TX_HEADROOM SKB_MAX_HEAD(TX_HEADER_LEN) 228 221 229 222 /* 230 223 * get and set private ip for iscsi traffic
+181 -88
drivers/scsi/cxgb3i/cxgb3i_pdu.c
··· 32 32 #define cxgb3i_tx_debug(fmt...) 33 33 #endif 34 34 35 + /* always allocate rooms for AHS */ 36 + #define SKB_TX_PDU_HEADER_LEN \ 37 + (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE) 38 + static unsigned int skb_extra_headroom; 35 39 static struct page *pad_page; 36 40 37 41 /* ··· 150 146 151 147 void cxgb3i_conn_cleanup_task(struct iscsi_task *task) 152 148 { 153 - struct iscsi_tcp_task *tcp_task = task->dd_data; 149 + struct cxgb3i_task_data *tdata = task->dd_data + 150 + sizeof(struct iscsi_tcp_task); 154 151 155 152 /* never reached the xmit task callout */ 156 - if (tcp_task->dd_data) 157 - kfree_skb(tcp_task->dd_data); 158 - tcp_task->dd_data = NULL; 153 + if (tdata->skb) 154 + __kfree_skb(tdata->skb); 155 + memset(tdata, 0, sizeof(struct cxgb3i_task_data)); 159 156 160 157 /* MNC - Do we need a check in case this is called but 161 158 * cxgb3i_conn_alloc_pdu has never been called on the task */ ··· 164 159 iscsi_tcp_cleanup_task(task); 165 160 } 166 161 167 - /* 168 - * We do not support ahs yet 169 - */ 162 + static int sgl_seek_offset(struct scatterlist *sgl, unsigned int sgcnt, 163 + unsigned int offset, unsigned int *off, 164 + struct scatterlist **sgp) 165 + { 166 + int i; 167 + struct scatterlist *sg; 168 + 169 + for_each_sg(sgl, sg, sgcnt, i) { 170 + if (offset < sg->length) { 171 + *off = offset; 172 + *sgp = sg; 173 + return 0; 174 + } 175 + offset -= sg->length; 176 + } 177 + return -EFAULT; 178 + } 179 + 180 + static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset, 181 + unsigned int dlen, skb_frag_t *frags, 182 + int frag_max) 183 + { 184 + unsigned int datalen = dlen; 185 + unsigned int sglen = sg->length - sgoffset; 186 + struct page *page = sg_page(sg); 187 + int i; 188 + 189 + i = 0; 190 + do { 191 + unsigned int copy; 192 + 193 + if (!sglen) { 194 + sg = sg_next(sg); 195 + if (!sg) { 196 + cxgb3i_log_error("%s, sg NULL, len %u/%u.\n", 197 + __func__, datalen, dlen); 198 + return -EINVAL; 199 + } 200 + sgoffset = 0; 201 + sglen = sg->length; 202 + page = sg_page(sg); 203 + 204 + } 205 + copy = min(datalen, sglen); 206 + if (i && page == frags[i - 1].page && 207 + sgoffset + sg->offset == 208 + frags[i - 1].page_offset + frags[i - 1].size) { 209 + frags[i - 1].size += copy; 210 + } else { 211 + if (i >= frag_max) { 212 + cxgb3i_log_error("%s, too many pages %u, " 213 + "dlen %u.\n", __func__, 214 + frag_max, dlen); 215 + return -EINVAL; 216 + } 217 + 218 + frags[i].page = page; 219 + frags[i].page_offset = sg->offset + sgoffset; 220 + frags[i].size = copy; 221 + i++; 222 + } 223 + datalen -= copy; 224 + sgoffset += copy; 225 + sglen -= copy; 226 + } while (datalen); 227 + 228 + return i; 229 + } 230 + 170 231 int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode) 171 232 { 233 + struct iscsi_conn *conn = task->conn; 172 234 struct iscsi_tcp_task *tcp_task = task->dd_data; 173 - struct sk_buff *skb; 235 + struct cxgb3i_task_data *tdata = task->dd_data + sizeof(*tcp_task); 236 + struct scsi_cmnd *sc = task->sc; 237 + int headroom = SKB_TX_PDU_HEADER_LEN; 174 238 239 + tcp_task->dd_data = tdata; 175 240 task->hdr = NULL; 176 - /* always allocate rooms for AHS */ 177 - skb = alloc_skb(sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE + 178 - TX_HEADER_LEN, GFP_ATOMIC); 179 - if (!skb) 241 + 242 + /* write command, need to send data pdus */ 243 + if (skb_extra_headroom && (opcode == ISCSI_OP_SCSI_DATA_OUT || 244 + (opcode == ISCSI_OP_SCSI_CMD && 245 + (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE)))) 246 + headroom += min(skb_extra_headroom, conn->max_xmit_dlength); 247 + 248 + tdata->skb = alloc_skb(TX_HEADER_LEN + headroom, GFP_ATOMIC); 249 + if (!tdata->skb) 180 250 return -ENOMEM; 251 + skb_reserve(tdata->skb, TX_HEADER_LEN); 181 252 182 253 cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n", 183 - task, opcode, skb); 254 + task, opcode, tdata->skb); 184 255 185 - tcp_task->dd_data = skb; 186 - skb_reserve(skb, TX_HEADER_LEN); 187 - task->hdr = (struct iscsi_hdr *)skb->data; 188 - task->hdr_max = sizeof(struct iscsi_hdr); 256 + task->hdr = (struct iscsi_hdr *)tdata->skb->data; 257 + task->hdr_max = SKB_TX_PDU_HEADER_LEN; 189 258 190 259 /* data_out uses scsi_cmd's itt */ 191 260 if (opcode != ISCSI_OP_SCSI_DATA_OUT) ··· 271 192 int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset, 272 193 unsigned int count) 273 194 { 274 - struct iscsi_tcp_task *tcp_task = task->dd_data; 275 - struct sk_buff *skb = tcp_task->dd_data; 276 195 struct iscsi_conn *conn = task->conn; 277 - struct page *pg; 196 + struct iscsi_tcp_task *tcp_task = task->dd_data; 197 + struct cxgb3i_task_data *tdata = tcp_task->dd_data; 198 + struct sk_buff *skb = tdata->skb; 278 199 unsigned int datalen = count; 279 200 int i, padlen = iscsi_padding(count); 280 - skb_frag_t *frag; 201 + struct page *pg; 281 202 282 203 cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n", 283 204 task, task->sc, offset, count, skb); ··· 288 209 return 0; 289 210 290 211 if (task->sc) { 291 - struct scatterlist *sg; 292 - struct scsi_data_buffer *sdb; 293 - unsigned int sgoffset = offset; 294 - struct page *sgpg; 295 - unsigned int sglen; 212 + struct scsi_data_buffer *sdb = scsi_out(task->sc); 213 + struct scatterlist *sg = NULL; 214 + int err; 296 215 297 - sdb = scsi_out(task->sc); 298 - sg = sdb->table.sgl; 299 - 300 - for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { 301 - cxgb3i_tx_debug("sg %d, page 0x%p, len %u offset %u\n", 302 - i, sg_page(sg), sg->length, sg->offset); 303 - 304 - if (sgoffset < sg->length) 305 - break; 306 - sgoffset -= sg->length; 216 + tdata->offset = offset; 217 + tdata->count = count; 218 + err = sgl_seek_offset(sdb->table.sgl, sdb->table.nents, 219 + tdata->offset, &tdata->sgoffset, &sg); 220 + if (err < 0) { 221 + cxgb3i_log_warn("tpdu, sgl %u, bad offset %u/%u.\n", 222 + sdb->table.nents, tdata->offset, 223 + sdb->length); 224 + return err; 307 225 } 308 - sgpg = sg_page(sg); 309 - sglen = sg->length - sgoffset; 226 + err = sgl_read_to_frags(sg, tdata->sgoffset, tdata->count, 227 + tdata->frags, MAX_PDU_FRAGS); 228 + if (err < 0) { 229 + cxgb3i_log_warn("tpdu, sgl %u, bad offset %u + %u.\n", 230 + sdb->table.nents, tdata->offset, 231 + tdata->count); 232 + return err; 233 + } 234 + tdata->nr_frags = err; 310 235 311 - do { 312 - int j = skb_shinfo(skb)->nr_frags; 313 - unsigned int copy; 236 + if (tdata->nr_frags > MAX_SKB_FRAGS || 237 + (padlen && tdata->nr_frags == MAX_SKB_FRAGS)) { 238 + char *dst = skb->data + task->hdr_len; 239 + skb_frag_t *frag = tdata->frags; 314 240 315 - if (!sglen) { 316 - sg = sg_next(sg); 317 - sgpg = sg_page(sg); 318 - sgoffset = 0; 319 - sglen = sg->length; 320 - ++i; 241 + /* data fits in the skb's headroom */ 242 + for (i = 0; i < tdata->nr_frags; i++, frag++) { 243 + char *src = kmap_atomic(frag->page, 244 + KM_SOFTIRQ0); 245 + 246 + memcpy(dst, src+frag->page_offset, frag->size); 247 + dst += frag->size; 248 + kunmap_atomic(src, KM_SOFTIRQ0); 321 249 } 322 - copy = min(sglen, datalen); 323 - if (j && skb_can_coalesce(skb, j, sgpg, 324 - sg->offset + sgoffset)) { 325 - skb_shinfo(skb)->frags[j - 1].size += copy; 326 - } else { 327 - get_page(sgpg); 328 - skb_fill_page_desc(skb, j, sgpg, 329 - sg->offset + sgoffset, copy); 250 + if (padlen) { 251 + memset(dst, 0, padlen); 252 + padlen = 0; 330 253 } 331 - sgoffset += copy; 332 - sglen -= copy; 333 - datalen -= copy; 334 - } while (datalen); 254 + skb_put(skb, count + padlen); 255 + } else { 256 + /* data fit into frag_list */ 257 + for (i = 0; i < tdata->nr_frags; i++) 258 + get_page(tdata->frags[i].page); 259 + 260 + memcpy(skb_shinfo(skb)->frags, tdata->frags, 261 + sizeof(skb_frag_t) * tdata->nr_frags); 262 + skb_shinfo(skb)->nr_frags = tdata->nr_frags; 263 + skb->len += count; 264 + skb->data_len += count; 265 + skb->truesize += count; 266 + } 267 + 335 268 } else { 336 269 pg = virt_to_page(task->data); 337 270 338 - while (datalen) { 339 - i = skb_shinfo(skb)->nr_frags; 340 - frag = &skb_shinfo(skb)->frags[i]; 341 - 342 - get_page(pg); 343 - frag->page = pg; 344 - frag->page_offset = 0; 345 - frag->size = min((unsigned int)PAGE_SIZE, datalen); 346 - 347 - skb_shinfo(skb)->nr_frags++; 348 - datalen -= frag->size; 349 - pg++; 350 - } 271 + get_page(pg); 272 + skb_fill_page_desc(skb, 0, pg, offset_in_page(task->data), 273 + count); 274 + skb->len += count; 275 + skb->data_len += count; 276 + skb->truesize += count; 351 277 } 352 278 353 279 if (padlen) { 354 280 i = skb_shinfo(skb)->nr_frags; 355 - frag = &skb_shinfo(skb)->frags[i]; 356 - frag->page = pad_page; 357 - frag->page_offset = 0; 358 - frag->size = padlen; 359 - skb_shinfo(skb)->nr_frags++; 281 + get_page(pad_page); 282 + skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, pad_page, 0, 283 + padlen); 284 + 285 + skb->data_len += padlen; 286 + skb->truesize += padlen; 287 + skb->len += padlen; 360 288 } 361 289 362 - datalen = count + padlen; 363 - skb->data_len += datalen; 364 - skb->truesize += datalen; 365 - skb->len += datalen; 366 290 return 0; 367 291 } 368 292 369 293 int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) 370 294 { 371 - struct iscsi_tcp_task *tcp_task = task->dd_data; 372 - struct sk_buff *skb = tcp_task->dd_data; 373 295 struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data; 374 296 struct cxgb3i_conn *cconn = tcp_conn->dd_data; 297 + struct iscsi_tcp_task *tcp_task = task->dd_data; 298 + struct cxgb3i_task_data *tdata = tcp_task->dd_data; 299 + struct sk_buff *skb = tdata->skb; 375 300 unsigned int datalen; 376 301 int err; 377 302 ··· 383 300 return 0; 384 301 385 302 datalen = skb->data_len; 386 - tcp_task->dd_data = NULL; 303 + tdata->skb = NULL; 387 304 err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb); 388 - cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", 389 - task, skb, skb->len, skb->data_len, err); 390 305 if (err > 0) { 391 306 int pdulen = err; 307 + 308 + cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", 309 + task, skb, skb->len, skb->data_len, err); 392 310 393 311 if (task->conn->hdrdgst_en) 394 312 pdulen += ISCSI_DIGEST_SIZE; ··· 409 325 return err; 410 326 } 411 327 /* reset skb to send when we are called again */ 412 - tcp_task->dd_data = skb; 328 + tdata->skb = skb; 413 329 return -EAGAIN; 414 330 } 415 331 416 332 int cxgb3i_pdu_init(void) 417 333 { 334 + if (SKB_TX_HEADROOM > (512 * MAX_SKB_FRAGS)) 335 + skb_extra_headroom = SKB_TX_HEADROOM; 418 336 pad_page = alloc_page(GFP_KERNEL); 419 337 if (!pad_page) 420 338 return -ENOMEM; ··· 452 366 skb = skb_peek(&c3cn->receive_queue); 453 367 while (!err && skb) { 454 368 __skb_unlink(skb, &c3cn->receive_queue); 455 - read += skb_ulp_pdulen(skb); 369 + read += skb_rx_pdulen(skb); 370 + cxgb3i_rx_debug("conn 0x%p, cn 0x%p, rx skb 0x%p, pdulen %u.\n", 371 + conn, c3cn, skb, skb_rx_pdulen(skb)); 456 372 err = cxgb3i_conn_read_pdu_skb(conn, skb); 457 373 __kfree_skb(skb); 458 374 skb = skb_peek(&c3cn->receive_queue); ··· 465 377 cxgb3i_c3cn_rx_credits(c3cn, read); 466 378 } 467 379 conn->rxdata_octets += read; 380 + 381 + if (err) { 382 + cxgb3i_log_info("conn 0x%p rx failed err %d.\n", conn, err); 383 + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 384 + } 468 385 } 469 386 470 387 void cxgb3i_conn_tx_open(struct s3_conn *c3cn)
+1 -1
drivers/scsi/cxgb3i/cxgb3i_pdu.h
··· 53 53 #define ULP2_FLAG_DCRC_ERROR 0x20 54 54 #define ULP2_FLAG_PAD_ERROR 0x40 55 55 56 - void cxgb3i_conn_closing(struct s3_conn *); 56 + void cxgb3i_conn_closing(struct s3_conn *c3cn); 57 57 void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn); 58 58 void cxgb3i_conn_tx_open(struct s3_conn *c3cn); 59 59 #endif
+1
drivers/scsi/hptiop.c
··· 1251 1251 { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops }, 1252 1252 { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops }, 1253 1253 { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops }, 1254 + { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops }, 1254 1255 { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops }, 1255 1256 { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops }, 1256 1257 { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops },
+2 -3
drivers/scsi/scsi_lib.c
··· 1040 1040 action = ACTION_FAIL; 1041 1041 break; 1042 1042 case ABORTED_COMMAND: 1043 + action = ACTION_FAIL; 1043 1044 if (sshdr.asc == 0x10) { /* DIF */ 1044 1045 description = "Target Data Integrity Failure"; 1045 - action = ACTION_FAIL; 1046 1046 error = -EILSEQ; 1047 - } else 1048 - action = ACTION_RETRY; 1047 + } 1049 1048 break; 1050 1049 case NOT_READY: 1051 1050 /* If the device is in the process of becoming
+7
drivers/scsi/sd.c
··· 107 107 static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); 108 108 static void sd_print_result(struct scsi_disk *, int); 109 109 110 + static DEFINE_SPINLOCK(sd_index_lock); 110 111 static DEFINE_IDA(sd_index_ida); 111 112 112 113 /* This semaphore is used to mediate the 0->1 reference get in the ··· 1915 1914 if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) 1916 1915 goto out_put; 1917 1916 1917 + spin_lock(&sd_index_lock); 1918 1918 error = ida_get_new(&sd_index_ida, &index); 1919 + spin_unlock(&sd_index_lock); 1919 1920 } while (error == -EAGAIN); 1920 1921 1921 1922 if (error) ··· 1939 1936 return 0; 1940 1937 1941 1938 out_free_index: 1939 + spin_lock(&sd_index_lock); 1942 1940 ida_remove(&sd_index_ida, index); 1941 + spin_unlock(&sd_index_lock); 1943 1942 out_put: 1944 1943 put_disk(gd); 1945 1944 out_free: ··· 1991 1986 struct scsi_disk *sdkp = to_scsi_disk(dev); 1992 1987 struct gendisk *disk = sdkp->disk; 1993 1988 1989 + spin_lock(&sd_index_lock); 1994 1990 ida_remove(&sd_index_ida, sdkp->index); 1991 + spin_unlock(&sd_index_lock); 1995 1992 1996 1993 disk->private_data = NULL; 1997 1994 put_disk(disk);