33 *
44 * Interface to Linux SCSI midlayer.
55 *
6- * Copyright IBM Corporation 2002, 2008
6+ * Copyright IBM Corporation 2002, 2009
77 */
88
99#define KMSG_COMPONENT "zfcp"
@@ -57,8 +57,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
5757{
5858 struct zfcp_unit * unit ;
5959 struct zfcp_adapter * adapter ;
60- int status ;
61- int ret ;
60+ int status , scsi_result , ret ;
61+ struct fc_rport * rport = starget_to_rport ( scsi_target ( scpnt -> device )) ;
6262
6363 /* reset the status for this request */
6464 scpnt -> result = 0 ;
@@ -80,6 +80,14 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
8080 return 0 ;
8181 }
8282
83+ scsi_result = fc_remote_port_chkready (rport );
84+ if (unlikely (scsi_result )) {
85+ scpnt -> result = scsi_result ;
86+ zfcp_scsi_dbf_event_result ("fail" , 4 , adapter , scpnt , NULL );
87+ scpnt -> scsi_done (scpnt );
88+ return 0 ;
89+ }
90+
8391 status = atomic_read (& unit -> status );
8492 if (unlikely ((status & ZFCP_STATUS_COMMON_ERP_FAILED ) ||
8593 !(status & ZFCP_STATUS_COMMON_RUNNING ))) {
@@ -473,6 +481,109 @@ static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
473481 rport -> dev_loss_tmo = timeout ;
474482}
475483
484+ /**
485+ * zfcp_scsi_dev_loss_tmo_callbk - Free any reference to rport
486+ * @rport: The rport that is about to be deleted.
487+ */
488+ static void zfcp_scsi_dev_loss_tmo_callbk (struct fc_rport * rport )
489+ {
490+ struct zfcp_port * port = rport -> dd_data ;
491+
492+ write_lock_irq (& zfcp_data .config_lock );
493+ port -> rport = NULL ;
494+ write_unlock_irq (& zfcp_data .config_lock );
495+ }
496+
497+ /**
498+ * zfcp_scsi_terminate_rport_io - Terminate all I/O on a rport
499+ * @rport: The FC rport where to teminate I/O
500+ *
501+ * Abort all pending SCSI commands for a port by closing the
502+ * port. Using a reopen for avoids a conflict with a shutdown
503+ * overwriting a reopen.
504+ */
505+ static void zfcp_scsi_terminate_rport_io (struct fc_rport * rport )
506+ {
507+ struct zfcp_port * port = rport -> dd_data ;
508+
509+ zfcp_erp_port_reopen (port , 0 , "sctrpi1" , NULL );
510+ }
511+
512+ static void zfcp_scsi_rport_register (struct zfcp_port * port )
513+ {
514+ struct fc_rport_identifiers ids ;
515+ struct fc_rport * rport ;
516+
517+ ids .node_name = port -> wwnn ;
518+ ids .port_name = port -> wwpn ;
519+ ids .port_id = port -> d_id ;
520+ ids .roles = FC_RPORT_ROLE_FCP_TARGET ;
521+
522+ rport = fc_remote_port_add (port -> adapter -> scsi_host , 0 , & ids );
523+ if (!rport ) {
524+ dev_err (& port -> adapter -> ccw_device -> dev ,
525+ "Registering port 0x%016Lx failed\n" ,
526+ (unsigned long long )port -> wwpn );
527+ return ;
528+ }
529+
530+ rport -> dd_data = port ;
531+ rport -> maxframe_size = port -> maxframe_size ;
532+ rport -> supported_classes = port -> supported_classes ;
533+ port -> rport = rport ;
534+ }
535+
536+ static void zfcp_scsi_rport_block (struct zfcp_port * port )
537+ {
538+ if (port -> rport )
539+ fc_remote_port_delete (port -> rport );
540+ }
541+
542+ void zfcp_scsi_schedule_rport_register (struct zfcp_port * port )
543+ {
544+ zfcp_port_get (port );
545+ port -> rport_task = RPORT_ADD ;
546+
547+ if (!queue_work (zfcp_data .work_queue , & port -> rport_work ))
548+ zfcp_port_put (port );
549+ }
550+
551+ void zfcp_scsi_schedule_rport_block (struct zfcp_port * port )
552+ {
553+ zfcp_port_get (port );
554+ port -> rport_task = RPORT_DEL ;
555+
556+ if (!queue_work (zfcp_data .work_queue , & port -> rport_work ))
557+ zfcp_port_put (port );
558+ }
559+
560+ void zfcp_scsi_schedule_rports_block (struct zfcp_adapter * adapter )
561+ {
562+ struct zfcp_port * port ;
563+
564+ list_for_each_entry (port , & adapter -> port_list_head , list )
565+ zfcp_scsi_schedule_rport_block (port );
566+ }
567+
568+ void zfcp_scsi_rport_work (struct work_struct * work )
569+ {
570+ struct zfcp_port * port = container_of (work , struct zfcp_port ,
571+ rport_work );
572+
573+ while (port -> rport_task ) {
574+ if (port -> rport_task == RPORT_ADD ) {
575+ port -> rport_task = RPORT_NONE ;
576+ zfcp_scsi_rport_register (port );
577+ } else {
578+ port -> rport_task = RPORT_NONE ;
579+ zfcp_scsi_rport_block (port );
580+ }
581+ }
582+
583+ zfcp_port_put (port );
584+ }
585+
586+
476587struct fc_function_template zfcp_transport_functions = {
477588 .show_starget_port_id = 1 ,
478589 .show_starget_port_name = 1 ,
@@ -491,6 +602,8 @@ struct fc_function_template zfcp_transport_functions = {
491602 .reset_fc_host_stats = zfcp_reset_fc_host_stats ,
492603 .set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo ,
493604 .get_host_port_state = zfcp_get_host_port_state ,
605+ .dev_loss_tmo_callbk = zfcp_scsi_dev_loss_tmo_callbk ,
606+ .terminate_rport_io = zfcp_scsi_terminate_rport_io ,
494607 .show_host_port_state = 1 ,
495608 /* no functions registered for following dynamic attributes but
496609 directly set by LLDD */
0 commit comments