@@ -1047,9 +1047,9 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
10471047{
10481048 u8 type ;
10491049 u8 hdr_status ;
1050- struct fcpio_tag tag ;
1050+ struct fcpio_tag ftag ;
10511051 u32 id ;
1052- struct scsi_cmnd * sc ;
1052+ struct scsi_cmnd * sc = NULL ;
10531053 struct fnic_io_req * io_req ;
10541054 struct fnic_stats * fnic_stats = & fnic -> fnic_stats ;
10551055 struct abort_stats * abts_stats = & fnic -> fnic_stats .abts_stats ;
@@ -1058,27 +1058,43 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
10581058 unsigned long flags ;
10591059 spinlock_t * io_lock ;
10601060 unsigned long start_time ;
1061+ unsigned int tag ;
10611062
1062- fcpio_header_dec (& desc -> hdr , & type , & hdr_status , & tag );
1063- fcpio_tag_id_dec (& tag , & id );
1063+ fcpio_header_dec (& desc -> hdr , & type , & hdr_status , & ftag );
1064+ fcpio_tag_id_dec (& ftag , & id );
10641065
1065- if ((id & FNIC_TAG_MASK ) >= fnic -> fnic_max_tag_id ) {
1066+ tag = id & FNIC_TAG_MASK ;
1067+ if (tag == fnic -> fnic_max_tag_id ) {
1068+ if (!(id & FNIC_TAG_DEV_RST )) {
1069+ shost_printk (KERN_ERR , fnic -> lport -> host ,
1070+ "Tag out of range id 0x%x hdr status = %s\n" ,
1071+ id , fnic_fcpio_status_to_str (hdr_status ));
1072+ return ;
1073+ }
1074+ } else if (tag > fnic -> fnic_max_tag_id ) {
10661075 shost_printk (KERN_ERR , fnic -> lport -> host ,
1067- "Tag out of range tag %x hdr status = %s\n" ,
1068- id , fnic_fcpio_status_to_str (hdr_status ));
1076+ "Tag out of range tag 0x %x hdr status = %s\n" ,
1077+ tag , fnic_fcpio_status_to_str (hdr_status ));
10691078 return ;
10701079 }
10711080
1072- sc = scsi_host_find_tag (fnic -> lport -> host , id & FNIC_TAG_MASK );
1081+ if ((tag == fnic -> fnic_max_tag_id ) && (id & FNIC_TAG_DEV_RST )) {
1082+ sc = fnic -> sgreset_sc ;
1083+ io_lock = & fnic -> sgreset_lock ;
1084+ } else {
1085+ sc = scsi_host_find_tag (fnic -> lport -> host , id & FNIC_TAG_MASK );
1086+ io_lock = fnic_io_lock_hash (fnic , sc );
1087+ }
1088+
10731089 WARN_ON_ONCE (!sc );
10741090 if (!sc ) {
10751091 atomic64_inc (& fnic_stats -> io_stats .sc_null );
10761092 shost_printk (KERN_ERR , fnic -> lport -> host ,
10771093 "itmf_cmpl sc is null - hdr status = %s tag = 0x%x\n" ,
1078- fnic_fcpio_status_to_str (hdr_status ), id );
1094+ fnic_fcpio_status_to_str (hdr_status ), tag );
10791095 return ;
10801096 }
1081- io_lock = fnic_io_lock_hash ( fnic , sc );
1097+
10821098 spin_lock_irqsave (io_lock , flags );
10831099 io_req = fnic_priv (sc )-> io_req ;
10841100 WARN_ON_ONCE (!io_req );
@@ -1089,7 +1105,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
10891105 shost_printk (KERN_ERR , fnic -> lport -> host ,
10901106 "itmf_cmpl io_req is null - "
10911107 "hdr status = %s tag = 0x%x sc 0x%p\n" ,
1092- fnic_fcpio_status_to_str (hdr_status ), id , sc );
1108+ fnic_fcpio_status_to_str (hdr_status ), tag , sc );
10931109 return ;
10941110 }
10951111 start_time = io_req -> start_time ;
@@ -1938,6 +1954,10 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
19381954 struct scsi_lun fc_lun ;
19391955 int ret = 0 ;
19401956 unsigned long intr_flags ;
1957+ unsigned int tag = scsi_cmd_to_rq (sc )-> tag ;
1958+
1959+ if (tag == SCSI_NO_TAG )
1960+ tag = io_req -> tag ;
19411961
19421962 spin_lock_irqsave (host -> host_lock , intr_flags );
19431963 if (unlikely (fnic_chk_state_flags_locked (fnic ,
@@ -1964,7 +1984,8 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
19641984 /* fill in the lun info */
19651985 int_to_scsilun (sc -> device -> lun , & fc_lun );
19661986
1967- fnic_queue_wq_copy_desc_itmf (wq , scsi_cmd_to_rq (sc )-> tag | FNIC_TAG_DEV_RST ,
1987+ tag |= FNIC_TAG_DEV_RST ;
1988+ fnic_queue_wq_copy_desc_itmf (wq , tag ,
19681989 0 , FCPIO_ITMF_LUN_RESET , SCSI_NO_TAG ,
19691990 fc_lun .scsi_lun , io_req -> port_id ,
19701991 fnic -> config .ra_tov , fnic -> config .ed_tov );
@@ -2146,8 +2167,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
21462167 .ret = SUCCESS ,
21472168 };
21482169
2149- if (new_sc )
2150- iter_data .lr_sc = lr_sc ;
2170+ iter_data .lr_sc = lr_sc ;
21512171
21522172 scsi_host_busy_iter (fnic -> lport -> host ,
21532173 fnic_pending_aborts_iter , & iter_data );
@@ -2230,8 +2250,14 @@ int fnic_device_reset(struct scsi_cmnd *sc)
22302250 mutex_lock (& fnic -> sgreset_mutex );
22312251 tag = fnic -> fnic_max_tag_id ;
22322252 new_sc = 1 ;
2233- }
2234- io_lock = fnic_io_lock_hash (fnic , sc );
2253+ fnic -> sgreset_sc = sc ;
2254+ io_lock = & fnic -> sgreset_lock ;
2255+ FNIC_SCSI_DBG (KERN_INFO , fnic -> lport -> host ,
2256+ "fcid: 0x%x lun: 0x%llx flags: 0x%x tag: 0x%x Issuing sgreset\n" ,
2257+ rport -> port_id , sc -> device -> lun , fnic_priv (sc )-> flags , tag );
2258+ } else
2259+ io_lock = fnic_io_lock_hash (fnic , sc );
2260+
22352261 spin_lock_irqsave (io_lock , flags );
22362262 io_req = fnic_priv (sc )-> io_req ;
22372263
@@ -2247,6 +2273,8 @@ int fnic_device_reset(struct scsi_cmnd *sc)
22472273 }
22482274 memset (io_req , 0 , sizeof (* io_req ));
22492275 io_req -> port_id = rport -> port_id ;
2276+ io_req -> tag = tag ;
2277+ io_req -> sc = sc ;
22502278 fnic_priv (sc )-> io_req = io_req ;
22512279 }
22522280 io_req -> dr_done = & tm_done ;
@@ -2400,8 +2428,10 @@ int fnic_device_reset(struct scsi_cmnd *sc)
24002428 (u64 )sc -> cmnd [4 ] << 8 | sc -> cmnd [5 ]),
24012429 fnic_flags_and_state (sc ));
24022430
2403- if (new_sc )
2431+ if (new_sc ) {
2432+ fnic -> sgreset_sc = NULL ;
24042433 mutex_unlock (& fnic -> sgreset_mutex );
2434+ }
24052435
24062436 FNIC_SCSI_DBG (KERN_DEBUG , fnic -> lport -> host ,
24072437 "Returning from device reset %s\n" ,
0 commit comments