@@ -40,6 +40,210 @@ static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
40
40
static int qla84xx_init_chip (scsi_qla_host_t * );
41
41
static int qla25xx_init_queues (struct qla_hw_data * );
42
42
43
+ /* SRB Extensions ---------------------------------------------------------- */
44
+
45
+ static void
46
+ qla2x00_ctx_sp_timeout (unsigned long __data )
47
+ {
48
+ srb_t * sp = (srb_t * )__data ;
49
+ struct srb_ctx * ctx ;
50
+ fc_port_t * fcport = sp -> fcport ;
51
+ struct qla_hw_data * ha = fcport -> vha -> hw ;
52
+ struct req_que * req ;
53
+ unsigned long flags ;
54
+
55
+ spin_lock_irqsave (& ha -> hardware_lock , flags );
56
+ req = ha -> req_q_map [0 ];
57
+ req -> outstanding_cmds [sp -> handle ] = NULL ;
58
+ ctx = sp -> ctx ;
59
+ ctx -> timeout (sp );
60
+ spin_unlock_irqrestore (& ha -> hardware_lock , flags );
61
+
62
+ ctx -> free (sp );
63
+ }
64
+
65
+ static void
66
+ qla2x00_ctx_sp_free (srb_t * sp )
67
+ {
68
+ struct srb_ctx * ctx = sp -> ctx ;
69
+
70
+ kfree (ctx );
71
+ mempool_free (sp , sp -> fcport -> vha -> hw -> srb_mempool );
72
+ }
73
+
74
+ inline srb_t *
75
+ qla2x00_get_ctx_sp (scsi_qla_host_t * vha , fc_port_t * fcport , size_t size ,
76
+ unsigned long tmo )
77
+ {
78
+ srb_t * sp ;
79
+ struct qla_hw_data * ha = vha -> hw ;
80
+ struct srb_ctx * ctx ;
81
+
82
+ sp = mempool_alloc (ha -> srb_mempool , GFP_KERNEL );
83
+ if (!sp )
84
+ goto done ;
85
+ ctx = kzalloc (size , GFP_KERNEL );
86
+ if (!ctx ) {
87
+ mempool_free (sp , ha -> srb_mempool );
88
+ goto done ;
89
+ }
90
+
91
+ memset (sp , 0 , sizeof (* sp ));
92
+ sp -> fcport = fcport ;
93
+ sp -> ctx = ctx ;
94
+ ctx -> free = qla2x00_ctx_sp_free ;
95
+
96
+ init_timer (& ctx -> timer );
97
+ if (!tmo )
98
+ goto done ;
99
+ ctx -> timer .expires = jiffies + tmo * HZ ;
100
+ ctx -> timer .data = (unsigned long )sp ;
101
+ ctx -> timer .function = qla2x00_ctx_sp_timeout ;
102
+ add_timer (& ctx -> timer );
103
+ done :
104
+ return sp ;
105
+ }
106
+
107
+ /* Asynchronous Login/Logout Routines -------------------------------------- */
108
+
109
+ #define ELS_TMO_2_RATOV (ha ) ((ha)->r_a_tov / 10 * 2)
110
+
111
+ static void
112
+ qla2x00_async_logio_timeout (srb_t * sp )
113
+ {
114
+ fc_port_t * fcport = sp -> fcport ;
115
+ struct srb_logio * lio = sp -> ctx ;
116
+
117
+ DEBUG2 (printk (KERN_WARNING
118
+ "scsi(%ld:%x): Async-%s timeout.\n" ,
119
+ fcport -> vha -> host_no , sp -> handle ,
120
+ lio -> ctx .type == SRB_LOGIN_CMD ? "login" : "logout" ));
121
+
122
+ if (lio -> ctx .type == SRB_LOGIN_CMD )
123
+ qla2x00_post_async_logout_work (fcport -> vha , fcport , NULL );
124
+ }
125
+
126
+ int
127
+ qla2x00_async_login (struct scsi_qla_host * vha , fc_port_t * fcport ,
128
+ uint16_t * data )
129
+ {
130
+ struct qla_hw_data * ha = vha -> hw ;
131
+ srb_t * sp ;
132
+ struct srb_logio * lio ;
133
+ int rval ;
134
+
135
+ rval = QLA_FUNCTION_FAILED ;
136
+ sp = qla2x00_get_ctx_sp (vha , fcport , sizeof (struct srb_logio ),
137
+ ELS_TMO_2_RATOV (ha ) + 2 );
138
+ if (!sp )
139
+ goto done ;
140
+
141
+ lio = sp -> ctx ;
142
+ lio -> ctx .type = SRB_LOGIN_CMD ;
143
+ lio -> ctx .timeout = qla2x00_async_logio_timeout ;
144
+ lio -> flags |= SRB_LOGIN_COND_PLOGI ;
145
+ if (data [1 ] & QLA_LOGIO_LOGIN_RETRIED )
146
+ lio -> flags |= SRB_LOGIN_RETRIED ;
147
+ rval = qla2x00_start_sp (sp );
148
+ if (rval != QLA_SUCCESS )
149
+ goto done_free_sp ;
150
+
151
+ DEBUG2 (printk (KERN_DEBUG
152
+ "scsi(%ld:%x): Async-login - loop-id=%x portid=%02x%02x%02x "
153
+ "retries=%d.\n" , fcport -> vha -> host_no , sp -> handle , fcport -> loop_id ,
154
+ fcport -> d_id .b .domain , fcport -> d_id .b .area , fcport -> d_id .b .al_pa ,
155
+ fcport -> login_retry ));
156
+ return rval ;
157
+
158
+ done_free_sp :
159
+ del_timer_sync (& lio -> ctx .timer );
160
+ lio -> ctx .free (sp );
161
+ done :
162
+ return rval ;
163
+ }
164
+
165
+ int
166
+ qla2x00_async_logout (struct scsi_qla_host * vha , fc_port_t * fcport )
167
+ {
168
+ struct qla_hw_data * ha = vha -> hw ;
169
+ srb_t * sp ;
170
+ struct srb_logio * lio ;
171
+ int rval ;
172
+
173
+ rval = QLA_FUNCTION_FAILED ;
174
+ sp = qla2x00_get_ctx_sp (vha , fcport , sizeof (struct srb_logio ),
175
+ ELS_TMO_2_RATOV (ha ) + 2 );
176
+ if (!sp )
177
+ goto done ;
178
+
179
+ lio = sp -> ctx ;
180
+ lio -> ctx .type = SRB_LOGOUT_CMD ;
181
+ lio -> ctx .timeout = qla2x00_async_logio_timeout ;
182
+ rval = qla2x00_start_sp (sp );
183
+ if (rval != QLA_SUCCESS )
184
+ goto done_free_sp ;
185
+
186
+ DEBUG2 (printk (KERN_DEBUG
187
+ "scsi(%ld:%x): Async-logout - loop-id=%x portid=%02x%02x%02x.\n" ,
188
+ fcport -> vha -> host_no , sp -> handle , fcport -> loop_id ,
189
+ fcport -> d_id .b .domain , fcport -> d_id .b .area , fcport -> d_id .b .al_pa ));
190
+ return rval ;
191
+
192
+ done_free_sp :
193
+ del_timer_sync (& lio -> ctx .timer );
194
+ lio -> ctx .free (sp );
195
+ done :
196
+ return rval ;
197
+ }
198
+
199
+ int
200
+ qla2x00_async_login_done (struct scsi_qla_host * vha , fc_port_t * fcport ,
201
+ uint16_t * data )
202
+ {
203
+ int rval ;
204
+ uint8_t opts = 0 ;
205
+
206
+ switch (data [0 ]) {
207
+ case MBS_COMMAND_COMPLETE :
208
+ if (fcport -> flags & FCF_TAPE_PRESENT )
209
+ opts |= BIT_1 ;
210
+ rval = qla2x00_get_port_database (vha , fcport , opts );
211
+ if (rval != QLA_SUCCESS )
212
+ qla2x00_mark_device_lost (vha , fcport , 1 , 0 );
213
+ else
214
+ qla2x00_update_fcport (vha , fcport );
215
+ break ;
216
+ case MBS_COMMAND_ERROR :
217
+ if (data [1 ] & QLA_LOGIO_LOGIN_RETRIED )
218
+ set_bit (RELOGIN_NEEDED , & vha -> dpc_flags );
219
+ else
220
+ qla2x00_mark_device_lost (vha , fcport , 1 , 0 );
221
+ break ;
222
+ case MBS_PORT_ID_USED :
223
+ fcport -> loop_id = data [1 ];
224
+ qla2x00_post_async_login_work (vha , fcport , NULL );
225
+ break ;
226
+ case MBS_LOOP_ID_USED :
227
+ fcport -> loop_id ++ ;
228
+ rval = qla2x00_find_new_loop_id (vha , fcport );
229
+ if (rval != QLA_SUCCESS ) {
230
+ qla2x00_mark_device_lost (vha , fcport , 1 , 0 );
231
+ break ;
232
+ }
233
+ qla2x00_post_async_login_work (vha , fcport , NULL );
234
+ break ;
235
+ }
236
+ return QLA_SUCCESS ;
237
+ }
238
+
239
+ int
240
+ qla2x00_async_logout_done (struct scsi_qla_host * vha , fc_port_t * fcport ,
241
+ uint16_t * data )
242
+ {
243
+ qla2x00_mark_device_lost (vha , fcport , 1 , 0 );
244
+ return QLA_SUCCESS ;
245
+ }
246
+
43
247
/****************************************************************************/
44
248
/* QLogic ISP2x00 Hardware Support Functions. */
45
249
/****************************************************************************/
@@ -1977,7 +2181,7 @@ qla2x00_rport_del(void *data)
1977
2181
struct fc_rport * rport ;
1978
2182
1979
2183
spin_lock_irq (fcport -> vha -> host -> host_lock );
1980
- rport = fcport -> drport ;
2184
+ rport = fcport -> drport ? fcport -> drport : fcport -> rport ;
1981
2185
fcport -> drport = NULL ;
1982
2186
spin_unlock_irq (fcport -> vha -> host -> host_lock );
1983
2187
if (rport )
@@ -2344,8 +2548,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
2344
2548
struct fc_rport * rport ;
2345
2549
struct qla_hw_data * ha = vha -> hw ;
2346
2550
2347
- if (fcport -> drport )
2348
- qla2x00_rport_del (fcport );
2551
+ qla2x00_rport_del (fcport );
2349
2552
2350
2553
rport_ids .node_name = wwn_to_u64 (fcport -> node_name );
2351
2554
rport_ids .port_name = wwn_to_u64 (fcport -> port_name );
@@ -3038,6 +3241,12 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport,
3038
3241
rval = QLA_SUCCESS ;
3039
3242
retry = 0 ;
3040
3243
3244
+ if (IS_ALOGIO_CAPABLE (ha )) {
3245
+ rval = qla2x00_post_async_login_work (vha , fcport , NULL );
3246
+ if (!rval )
3247
+ return rval ;
3248
+ }
3249
+
3041
3250
rval = qla2x00_fabric_login (vha , fcport , next_loopid );
3042
3251
if (rval == QLA_SUCCESS ) {
3043
3252
/* Send an ADISC to tape devices.*/
0 commit comments