aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/tcm_fc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 15:38:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 15:38:04 -0400
commit1ab142d499294b844ecc81e8004db4ce029b0b61 (patch)
tree9db85a456d0cba3de8b9bd6671b1b52fa939770c /drivers/target/tcm_fc
parent267d7b23dd62f6ec55e0fba777e456495c308fc7 (diff)
parent187e70a554e0f0717a65998bc9199945cbbd4692 (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger: "This contains the usual set of updates and bugfixes to target-core + existing fabric module code, along with a handful of the patches destined for v3.3 stable. It also contains the necessary target-core infrastructure pieces required to run using tcm_qla2xxx.ko WWPNs with the new Qlogic Fibre Channel fabric module currently queued in target-pending/for-next-merge, and coming for round 2. The highlights for this series include: - Add target_submit_tmr() helper function for fabric task management (andy) - Convert tcm_fc to use target_submit_tmr() (andy) - Replace target core various cmd flags with a transport state (hch) - Convert loopback to use workqueue submission (hch) - Convert target core to use array_zalloc for tpg_lun_list (joern) - Convert target core to use array_zalloc for device_list (joern) - Add target core support for TMR_ABORT_TASK (nab) - Add target core se_sess->sess_kref + get/put helpers (nab) - Add target core se_node_acl->acl_kref for ->acl_free_comp usage (nab) - Convert iscsi-target to use target_put_session + sess_kref (nab) - Fix tcm_fc fc_exch memory leak in ft_send_resp_status (nab) - Fix ib_srpt srpt_handle_cmd send_ioctx->ioctx_kref leak on exception (nab) - Fix target core up handling of short INQUIRY buffers (roland) - Untangle target-core front-end and back-end meanings of max_sectors attribute (roland) - Set loopback residual field for SCSI commands (roland) - Fix target-core 16-bit target ports for SET TARGET PORT GROUPS emulation (roland) Thanks again to Andy, Christoph, Joern, Roland, and everyone who has contributed this round!" * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (64 commits) ib_srpt: Fix srpt_handle_cmd send_ioctx->ioctx_kref leak on exception loopback: Fix transport_generic_allocate_tasks error handling iscsi-target: remove improper externs iscsi-target: Remove unused variables in iscsi_target_parameters.c target: remove obvious warnings target: Use array_zalloc for device_list target: Use array_zalloc for tpg_lun_list target: Fix sense code for unsupported SERVICE ACTION IN target: Remove hack to make READ CAPACITY(10) lie if thin provisioning is enabled target: Bump core version to v4.1.0-rc2-ml + fabric versions tcm_fc: Fix fc_exch memory leak in ft_send_resp_status target: Drop unused legacy target_core_fabric_ops API callers iscsi-target: Convert to use target_put_session + sess_kref target: Convert se_node_acl->acl_group removal to use ->acl_kref target: Add se_node_acl->acl_kref for ->acl_free_comp usage target: Add se_node_acl->acl_free_comp for NodeACL release path target: Add se_sess->sess_kref + get/put helpers target: Convert session_lock to irqsave target: Fix typo in drivers/target iscsi-target: Fix dynamic -> explict NodeACL pointer reference ...
Diffstat (limited to 'drivers/target/tcm_fc')
-rw-r--r--drivers/target/tcm_fc/tcm_fc.h8
-rw-r--r--drivers/target/tcm_fc/tfc_cmd.c147
-rw-r--r--drivers/target/tcm_fc/tfc_conf.c4
-rw-r--r--drivers/target/tcm_fc/tfc_sess.c21
4 files changed, 46 insertions, 134 deletions
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h
index e05c55100ec6..830657908db8 100644
--- a/drivers/target/tcm_fc/tcm_fc.h
+++ b/drivers/target/tcm_fc/tcm_fc.h
@@ -17,7 +17,7 @@
17#ifndef __TCM_FC_H__ 17#ifndef __TCM_FC_H__
18#define __TCM_FC_H__ 18#define __TCM_FC_H__
19 19
20#define FT_VERSION "0.3" 20#define FT_VERSION "0.4"
21 21
22#define FT_NAMELEN 32 /* length of ASCII WWPNs including pad */ 22#define FT_NAMELEN 32 /* length of ASCII WWPNs including pad */
23#define FT_TPG_NAMELEN 32 /* max length of TPG name */ 23#define FT_TPG_NAMELEN 32 /* max length of TPG name */
@@ -113,12 +113,10 @@ struct ft_lport_acl {
113 * Commands 113 * Commands
114 */ 114 */
115struct ft_cmd { 115struct ft_cmd {
116 u32 lun; /* LUN from request */
117 struct ft_sess *sess; /* session held for cmd */ 116 struct ft_sess *sess; /* session held for cmd */
118 struct fc_seq *seq; /* sequence in exchange mgr */ 117 struct fc_seq *seq; /* sequence in exchange mgr */
119 struct se_cmd se_cmd; /* Local TCM I/O descriptor */ 118 struct se_cmd se_cmd; /* Local TCM I/O descriptor */
120 struct fc_frame *req_frame; 119 struct fc_frame *req_frame;
121 unsigned char *cdb; /* pointer to CDB inside frame */
122 u32 write_data_len; /* data received on writes */ 120 u32 write_data_len; /* data received on writes */
123 struct work_struct work; 121 struct work_struct work;
124 /* Local sense buffer */ 122 /* Local sense buffer */
@@ -143,11 +141,8 @@ extern struct target_fabric_configfs *ft_configfs;
143void ft_sess_put(struct ft_sess *); 141void ft_sess_put(struct ft_sess *);
144int ft_sess_shutdown(struct se_session *); 142int ft_sess_shutdown(struct se_session *);
145void ft_sess_close(struct se_session *); 143void ft_sess_close(struct se_session *);
146void ft_sess_stop(struct se_session *, int, int);
147int ft_sess_logged_in(struct se_session *);
148u32 ft_sess_get_index(struct se_session *); 144u32 ft_sess_get_index(struct se_session *);
149u32 ft_sess_get_port_name(struct se_session *, unsigned char *, u32); 145u32 ft_sess_get_port_name(struct se_session *, unsigned char *, u32);
150void ft_sess_set_erl0(struct se_session *);
151 146
152void ft_lport_add(struct fc_lport *, void *); 147void ft_lport_add(struct fc_lport *, void *);
153void ft_lport_del(struct fc_lport *, void *); 148void ft_lport_del(struct fc_lport *, void *);
@@ -165,7 +160,6 @@ int ft_write_pending_status(struct se_cmd *);
165u32 ft_get_task_tag(struct se_cmd *); 160u32 ft_get_task_tag(struct se_cmd *);
166int ft_get_cmd_state(struct se_cmd *); 161int ft_get_cmd_state(struct se_cmd *);
167int ft_queue_tm_resp(struct se_cmd *); 162int ft_queue_tm_resp(struct se_cmd *);
168int ft_is_state_remove(struct se_cmd *);
169 163
170/* 164/*
171 * other internal functions. 165 * other internal functions.
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 9e7e26c74c79..62dec9715ce5 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -59,9 +59,6 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
59 se_cmd = &cmd->se_cmd; 59 se_cmd = &cmd->se_cmd;
60 pr_debug("%s: cmd %p sess %p seq %p se_cmd %p\n", 60 pr_debug("%s: cmd %p sess %p seq %p se_cmd %p\n",
61 caller, cmd, cmd->sess, cmd->seq, se_cmd); 61 caller, cmd, cmd->sess, cmd->seq, se_cmd);
62 pr_debug("%s: cmd %p cdb %p\n",
63 caller, cmd, cmd->cdb);
64 pr_debug("%s: cmd %p lun %d\n", caller, cmd, cmd->lun);
65 62
66 pr_debug("%s: cmd %p data_nents %u len %u se_cmd_flags <0x%x>\n", 63 pr_debug("%s: cmd %p data_nents %u len %u se_cmd_flags <0x%x>\n",
67 caller, cmd, se_cmd->t_data_nents, 64 caller, cmd, se_cmd->t_data_nents,
@@ -81,8 +78,6 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
81 caller, cmd, ep->sid, ep->did, ep->oxid, ep->rxid, 78 caller, cmd, ep->sid, ep->did, ep->oxid, ep->rxid,
82 sp->id, ep->esb_stat); 79 sp->id, ep->esb_stat);
83 } 80 }
84 print_hex_dump(KERN_INFO, "ft_dump_cmd ", DUMP_PREFIX_NONE,
85 16, 4, cmd->cdb, MAX_COMMAND_SIZE, 0);
86} 81}
87 82
88static void ft_free_cmd(struct ft_cmd *cmd) 83static void ft_free_cmd(struct ft_cmd *cmd)
@@ -249,11 +244,6 @@ int ft_get_cmd_state(struct se_cmd *se_cmd)
249 return 0; 244 return 0;
250} 245}
251 246
252int ft_is_state_remove(struct se_cmd *se_cmd)
253{
254 return 0; /* XXX TBD */
255}
256
257/* 247/*
258 * FC sequence response handler for follow-on sequences (data) and aborts. 248 * FC sequence response handler for follow-on sequences (data) and aborts.
259 */ 249 */
@@ -325,10 +315,12 @@ static void ft_send_resp_status(struct fc_lport *lport,
325 315
326 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_DD_CMD_STATUS, 0); 316 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_DD_CMD_STATUS, 0);
327 sp = fr_seq(fp); 317 sp = fr_seq(fp);
328 if (sp) 318 if (sp) {
329 lport->tt.seq_send(lport, sp, fp); 319 lport->tt.seq_send(lport, sp, fp);
330 else 320 lport->tt.exch_done(sp);
321 } else {
331 lport->tt.frame_send(lport, fp); 322 lport->tt.frame_send(lport, fp);
323 }
332} 324}
333 325
334/* 326/*
@@ -358,16 +350,10 @@ static void ft_send_resp_code_and_free(struct ft_cmd *cmd,
358 */ 350 */
359static void ft_send_tm(struct ft_cmd *cmd) 351static void ft_send_tm(struct ft_cmd *cmd)
360{ 352{
361 struct se_tmr_req *tmr;
362 struct fcp_cmnd *fcp; 353 struct fcp_cmnd *fcp;
363 struct ft_sess *sess; 354 int rc;
364 u8 tm_func; 355 u8 tm_func;
365 356
366 transport_init_se_cmd(&cmd->se_cmd, &ft_configfs->tf_ops,
367 cmd->sess->se_sess, 0, DMA_NONE, 0,
368 &cmd->ft_sense_buffer[0]);
369 target_get_sess_cmd(cmd->sess->se_sess, &cmd->se_cmd, false);
370
371 fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp)); 357 fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
372 358
373 switch (fcp->fc_tm_flags) { 359 switch (fcp->fc_tm_flags) {
@@ -396,44 +382,12 @@ static void ft_send_tm(struct ft_cmd *cmd)
396 return; 382 return;
397 } 383 }
398 384
399 pr_debug("alloc tm cmd fn %d\n", tm_func); 385 /* FIXME: Add referenced task tag for ABORT_TASK */
400 tmr = core_tmr_alloc_req(&cmd->se_cmd, cmd, tm_func, GFP_KERNEL); 386 rc = target_submit_tmr(&cmd->se_cmd, cmd->sess->se_sess,
401 if (!tmr) { 387 &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun),
402 pr_debug("alloc failed\n"); 388 cmd, tm_func, GFP_KERNEL, 0, 0);
389 if (rc < 0)
403 ft_send_resp_code_and_free(cmd, FCP_TMF_FAILED); 390 ft_send_resp_code_and_free(cmd, FCP_TMF_FAILED);
404 return;
405 }
406 cmd->se_cmd.se_tmr_req = tmr;
407
408 switch (fcp->fc_tm_flags) {
409 case FCP_TMF_LUN_RESET:
410 cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
411 if (transport_lookup_tmr_lun(&cmd->se_cmd, cmd->lun) < 0) {
412 /*
413 * Make sure to clean up newly allocated TMR request
414 * since "unable to handle TMR request because failed
415 * to get to LUN"
416 */
417 pr_debug("Failed to get LUN for TMR func %d, "
418 "se_cmd %p, unpacked_lun %d\n",
419 tm_func, &cmd->se_cmd, cmd->lun);
420 ft_dump_cmd(cmd, __func__);
421 sess = cmd->sess;
422 transport_send_check_condition_and_sense(&cmd->se_cmd,
423 cmd->se_cmd.scsi_sense_reason, 0);
424 ft_sess_put(sess);
425 return;
426 }
427 break;
428 case FCP_TMF_TGT_RESET:
429 case FCP_TMF_CLR_TASK_SET:
430 case FCP_TMF_ABT_TASK_SET:
431 case FCP_TMF_CLR_ACA:
432 break;
433 default:
434 return;
435 }
436 transport_generic_handle_tmr(&cmd->se_cmd);
437} 391}
438 392
439/* 393/*
@@ -538,7 +492,6 @@ static void ft_send_work(struct work_struct *work)
538 struct fc_frame_header *fh = fc_frame_header_get(cmd->req_frame); 492 struct fc_frame_header *fh = fc_frame_header_get(cmd->req_frame);
539 struct fcp_cmnd *fcp; 493 struct fcp_cmnd *fcp;
540 int data_dir = 0; 494 int data_dir = 0;
541 u32 data_len;
542 int task_attr; 495 int task_attr;
543 496
544 fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp)); 497 fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
@@ -548,47 +501,6 @@ static void ft_send_work(struct work_struct *work)
548 if (fcp->fc_flags & FCP_CFL_LEN_MASK) 501 if (fcp->fc_flags & FCP_CFL_LEN_MASK)
549 goto err; /* not handling longer CDBs yet */ 502 goto err; /* not handling longer CDBs yet */
550 503
551 if (fcp->fc_tm_flags) {
552 task_attr = FCP_PTA_SIMPLE;
553 data_dir = DMA_NONE;
554 data_len = 0;
555 } else {
556 switch (fcp->fc_flags & (FCP_CFL_RDDATA | FCP_CFL_WRDATA)) {
557 case 0:
558 data_dir = DMA_NONE;
559 break;
560 case FCP_CFL_RDDATA:
561 data_dir = DMA_FROM_DEVICE;
562 break;
563 case FCP_CFL_WRDATA:
564 data_dir = DMA_TO_DEVICE;
565 break;
566 case FCP_CFL_WRDATA | FCP_CFL_RDDATA:
567 goto err; /* TBD not supported by tcm_fc yet */
568 }
569 /*
570 * Locate the SAM Task Attr from fc_pri_ta
571 */
572 switch (fcp->fc_pri_ta & FCP_PTA_MASK) {
573 case FCP_PTA_HEADQ:
574 task_attr = MSG_HEAD_TAG;
575 break;
576 case FCP_PTA_ORDERED:
577 task_attr = MSG_ORDERED_TAG;
578 break;
579 case FCP_PTA_ACA:
580 task_attr = MSG_ACA_TAG;
581 break;
582 case FCP_PTA_SIMPLE: /* Fallthrough */
583 default:
584 task_attr = MSG_SIMPLE_TAG;
585 }
586
587
588 task_attr = fcp->fc_pri_ta & FCP_PTA_MASK;
589 data_len = ntohl(fcp->fc_dl);
590 cmd->cdb = fcp->fc_cdb;
591 }
592 /* 504 /*
593 * Check for FCP task management flags 505 * Check for FCP task management flags
594 */ 506 */
@@ -596,15 +508,46 @@ static void ft_send_work(struct work_struct *work)
596 ft_send_tm(cmd); 508 ft_send_tm(cmd);
597 return; 509 return;
598 } 510 }
511
512 switch (fcp->fc_flags & (FCP_CFL_RDDATA | FCP_CFL_WRDATA)) {
513 case 0:
514 data_dir = DMA_NONE;
515 break;
516 case FCP_CFL_RDDATA:
517 data_dir = DMA_FROM_DEVICE;
518 break;
519 case FCP_CFL_WRDATA:
520 data_dir = DMA_TO_DEVICE;
521 break;
522 case FCP_CFL_WRDATA | FCP_CFL_RDDATA:
523 goto err; /* TBD not supported by tcm_fc yet */
524 }
525 /*
526 * Locate the SAM Task Attr from fc_pri_ta
527 */
528 switch (fcp->fc_pri_ta & FCP_PTA_MASK) {
529 case FCP_PTA_HEADQ:
530 task_attr = MSG_HEAD_TAG;
531 break;
532 case FCP_PTA_ORDERED:
533 task_attr = MSG_ORDERED_TAG;
534 break;
535 case FCP_PTA_ACA:
536 task_attr = MSG_ACA_TAG;
537 break;
538 case FCP_PTA_SIMPLE: /* Fallthrough */
539 default:
540 task_attr = MSG_SIMPLE_TAG;
541 }
542
599 fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd); 543 fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd);
600 cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
601 /* 544 /*
602 * Use a single se_cmd->cmd_kref as we expect to release se_cmd 545 * Use a single se_cmd->cmd_kref as we expect to release se_cmd
603 * directly from ft_check_stop_free callback in response path. 546 * directly from ft_check_stop_free callback in response path.
604 */ 547 */
605 target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, cmd->cdb, 548 target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb,
606 &cmd->ft_sense_buffer[0], cmd->lun, data_len, 549 &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun),
607 task_attr, data_dir, 0); 550 ntohl(fcp->fc_dl), task_attr, data_dir, 0);
608 pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl); 551 pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl);
609 return; 552 return;
610 553
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 73852fbc857b..f357039349ba 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -529,9 +529,6 @@ static struct target_core_fabric_ops ft_fabric_ops = {
529 .release_cmd = ft_release_cmd, 529 .release_cmd = ft_release_cmd,
530 .shutdown_session = ft_sess_shutdown, 530 .shutdown_session = ft_sess_shutdown,
531 .close_session = ft_sess_close, 531 .close_session = ft_sess_close,
532 .stop_session = ft_sess_stop,
533 .fall_back_to_erl0 = ft_sess_set_erl0,
534 .sess_logged_in = ft_sess_logged_in,
535 .sess_get_index = ft_sess_get_index, 532 .sess_get_index = ft_sess_get_index,
536 .sess_get_initiator_sid = NULL, 533 .sess_get_initiator_sid = NULL,
537 .write_pending = ft_write_pending, 534 .write_pending = ft_write_pending,
@@ -544,7 +541,6 @@ static struct target_core_fabric_ops ft_fabric_ops = {
544 .queue_tm_rsp = ft_queue_tm_resp, 541 .queue_tm_rsp = ft_queue_tm_resp,
545 .get_fabric_sense_len = ft_get_fabric_sense_len, 542 .get_fabric_sense_len = ft_get_fabric_sense_len,
546 .set_fabric_sense_len = ft_set_fabric_sense_len, 543 .set_fabric_sense_len = ft_set_fabric_sense_len,
547 .is_state_remove = ft_is_state_remove,
548 /* 544 /*
549 * Setup function pointers for generic logic in 545 * Setup function pointers for generic logic in
550 * target_core_fabric_configfs.c 546 * target_core_fabric_configfs.c
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index eff512b5a2a0..cb99da920068 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -309,11 +309,9 @@ int ft_sess_shutdown(struct se_session *se_sess)
309void ft_sess_close(struct se_session *se_sess) 309void ft_sess_close(struct se_session *se_sess)
310{ 310{
311 struct ft_sess *sess = se_sess->fabric_sess_ptr; 311 struct ft_sess *sess = se_sess->fabric_sess_ptr;
312 struct fc_lport *lport;
313 u32 port_id; 312 u32 port_id;
314 313
315 mutex_lock(&ft_lport_lock); 314 mutex_lock(&ft_lport_lock);
316 lport = sess->tport->lport;
317 port_id = sess->port_id; 315 port_id = sess->port_id;
318 if (port_id == -1) { 316 if (port_id == -1) {
319 mutex_unlock(&ft_lport_lock); 317 mutex_unlock(&ft_lport_lock);
@@ -328,20 +326,6 @@ void ft_sess_close(struct se_session *se_sess)
328 synchronize_rcu(); /* let transport deregister happen */ 326 synchronize_rcu(); /* let transport deregister happen */
329} 327}
330 328
331void ft_sess_stop(struct se_session *se_sess, int sess_sleep, int conn_sleep)
332{
333 struct ft_sess *sess = se_sess->fabric_sess_ptr;
334
335 pr_debug("port_id %x\n", sess->port_id);
336}
337
338int ft_sess_logged_in(struct se_session *se_sess)
339{
340 struct ft_sess *sess = se_sess->fabric_sess_ptr;
341
342 return sess->port_id != -1;
343}
344
345u32 ft_sess_get_index(struct se_session *se_sess) 329u32 ft_sess_get_index(struct se_session *se_sess)
346{ 330{
347 struct ft_sess *sess = se_sess->fabric_sess_ptr; 331 struct ft_sess *sess = se_sess->fabric_sess_ptr;
@@ -357,11 +341,6 @@ u32 ft_sess_get_port_name(struct se_session *se_sess,
357 return ft_format_wwn(buf, len, sess->port_name); 341 return ft_format_wwn(buf, len, sess->port_name);
358} 342}
359 343
360void ft_sess_set_erl0(struct se_session *se_sess)
361{
362 /* XXX TBD called when out of memory */
363}
364
365/* 344/*
366 * libfc ops involving sessions. 345 * libfc ops involving sessions.
367 */ 346 */