2240 }
2241 cmd->cmd_dflags = 0;
2242 }
2243
2244
2245 /*
2246 * Dedicated thread to perform various activities. One thread for
2247 * each fc_local_port_t (driver soft state) instance.
2248 * Note, this effectively works out to one thread for each local
2249 * port, but there are also some Solaris taskq threads in use on a per-local
2250 * port basis; these also need to be taken into consideration.
2251 */
2252 static void
2253 fp_job_handler(fc_local_port_t *port)
2254 {
2255 int rval;
2256 uint32_t *d_id;
2257 fc_remote_port_t *pd;
2258 job_request_t *job;
2259
2260 #ifndef __lock_lint
2261 /*
2262 * Solaris-internal stuff for proper operation of kernel threads
2263 * with Solaris CPR.
2264 */
2265 CALLB_CPR_INIT(&port->fp_cpr_info, &port->fp_mutex,
2266 callb_generic_cpr, "fp_job_handler");
2267 #endif
2268
2269
2270 /* Loop forever waiting for work to do */
2271 for (;;) {
2272
2273 mutex_enter(&port->fp_mutex);
2274
2275 /*
2276 * Sleep if no work to do right now, or if we want
2277 * to suspend or power-down.
2278 */
2279 while (port->fp_job_head == NULL ||
2280 (port->fp_soft_state & (FP_SOFT_POWER_DOWN |
2281 FP_SOFT_SUSPEND))) {
2282 CALLB_CPR_SAFE_BEGIN(&port->fp_cpr_info);
2283 cv_wait(&port->fp_cv, &port->fp_mutex);
2284 CALLB_CPR_SAFE_END(&port->fp_cpr_info, &port->fp_mutex);
2285 }
2286
2287 /*
2288 * OK, we've just been woken up, so retrieve the next entry
2289 * from the head of the job queue for this local port.
2291 job = fctl_deque_job(port);
2292
2293 /*
2294 * Handle all the fp driver's supported job codes here
2295 * in this big honkin' switch.
2296 */
2297 switch (job->job_code) {
2298 case JOB_PORT_SHUTDOWN:
2299 /*
2300 * fp_port_shutdown() is only called from here. This
2301 * will prepare the local port instance (softstate)
2302 * for detaching. This cancels timeout callbacks,
2303 * executes LOGOs with remote ports, cleans up tables,
2304 * and deallocates data structs.
2305 */
2306 fp_port_shutdown(port, job);
2307
2308 /*
2309 * This will exit the job thread.
2310 */
2311 #ifndef __lock_lint
2312 CALLB_CPR_EXIT(&(port->fp_cpr_info));
2313 #else
2314 mutex_exit(&port->fp_mutex);
2315 #endif
2316 fctl_jobdone(job);
2317 thread_exit();
2318
2319 /* NOTREACHED */
2320
2321 case JOB_ATTACH_ULP: {
2322 /*
2323 * This job is spawned in response to a ULP calling
2324 * fc_ulp_add().
2325 */
2326
2327 boolean_t do_attach_ulps = B_TRUE;
2328
2329 /*
2330 * If fp is detaching, we don't want to call
2331 * fp_startup_done as this asynchronous
2332 * notification may interfere with the re-attach.
2333 */
2334
2335 if (port->fp_soft_state & (FP_DETACH_INPROGRESS |
2439 job->job_flags |= JOB_TYPE_FP_ASYNC;
2440 job->job_counter = 1;
2441
2442 rval = fp_port_login(port, *d_id, job,
2443 FP_CMD_PLOGI_RETAIN, KM_SLEEP, pd, NULL);
2444
2445 if (rval != FC_SUCCESS) {
2446 job->job_result = rval;
2447 fctl_jobdone(job);
2448 }
2449 break;
2450
2451 case JOB_LOGO_ONE: {
2452 /*
2453 * Issue a PLOGO to a single remote port. Multiple
2454 * PLOGOs to different remote ports may occur in
2455 * parallel.
2456 */
2457 fc_remote_port_t *pd;
2458
2459 #ifndef __lock_lint
2460 ASSERT(job->job_counter > 0);
2461 #endif
2462
2463 pd = (fc_remote_port_t *)job->job_ulp_pkts;
2464
2465 mutex_enter(&pd->pd_mutex);
2466 if (pd->pd_state != PORT_DEVICE_LOGGED_IN) {
2467 mutex_exit(&pd->pd_mutex);
2468 job->job_result = FC_LOGINREQ;
2469 mutex_exit(&port->fp_mutex);
2470 fctl_jobdone(job);
2471 break;
2472 }
2473 if (pd->pd_login_count > 1) {
2474 pd->pd_login_count--;
2475 mutex_exit(&pd->pd_mutex);
2476 job->job_result = FC_SUCCESS;
2477 mutex_exit(&port->fp_mutex);
2478 fctl_jobdone(job);
2479 break;
2480 }
2481 mutex_exit(&pd->pd_mutex);
4199 FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_clsp1,
4200 (uint8_t *)&acc->class_1, sizeof (acc->class_1),
4201 DDI_DEV_AUTOINCR);
4202 FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_clsp2,
4203 (uint8_t *)&acc->class_2, sizeof (acc->class_2),
4204 DDI_DEV_AUTOINCR);
4205 FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_clsp3,
4206 (uint8_t *)&acc->class_3, sizeof (acc->class_3),
4207 DDI_DEV_AUTOINCR);
4208 } else {
4209 pd->pd_csp = acc->common_service;
4210 pd->pd_clsp1 = acc->class_1;
4211 pd->pd_clsp2 = acc->class_2;
4212 pd->pd_clsp3 = acc->class_3;
4213 }
4214
4215 pd->pd_state = PORT_DEVICE_LOGGED_IN;
4216 pd->pd_login_class = class;
4217 mutex_exit(&pd->pd_mutex);
4218
4219 #ifndef __lock_lint
4220 ASSERT(fctl_get_remote_port_by_did(pd->pd_port,
4221 pd->pd_port_id.port_id) == pd);
4222 #endif
4223
4224 mutex_enter(&node->fd_mutex);
4225 if (handle) {
4226 FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)node->fd_vv,
4227 (uint8_t *)acc->vendor_version, sizeof (node->fd_vv),
4228 DDI_DEV_AUTOINCR);
4229 } else {
4230 bcopy(acc->vendor_version, node->fd_vv, sizeof (node->fd_vv));
4231 }
4232 mutex_exit(&node->fd_mutex);
4233 }
4234
4235
4236 /*
4237 * Mark the remote port as OFFLINE
4238 */
4239 static void
4240 fp_remote_port_offline(fc_remote_port_t *pd)
4241 {
4242 ASSERT(MUTEX_HELD(&pd->pd_mutex));
6009 */
6010 static void
6011 fp_plogi_intr(fc_packet_t *pkt)
6012 {
6013 int nl_port;
6014 int bailout;
6015 uint32_t d_id;
6016 fp_cmd_t *cmd;
6017 la_els_logi_t *acc;
6018 fc_local_port_t *port;
6019 fc_remote_port_t *pd;
6020 la_wwn_t nwwn;
6021 la_wwn_t pwwn;
6022 ls_code_t resp;
6023
6024 nl_port = 0;
6025 cmd = pkt->pkt_ulp_private;
6026 port = cmd->cmd_port;
6027 d_id = pkt->pkt_cmd_fhdr.d_id;
6028
6029 #ifndef __lock_lint
6030 ASSERT(cmd->cmd_job && cmd->cmd_job->job_counter);
6031 #endif
6032
6033 FP_TRACE(FP_NHEAD1(3, 0), "fp_plogi_intr: port=%p, job=%p, d_id=%x,"
6034 " jcount=%d pkt=%p, state=%x", port, cmd->cmd_job, d_id,
6035 cmd->cmd_job->job_counter, pkt, pkt->pkt_state);
6036
6037 /*
6038 * Bail out early on ULP initiated requests if the
6039 * state change has occurred
6040 */
6041 mutex_enter(&port->fp_mutex);
6042 port->fp_out_fpcmds--;
6043 bailout = ((port->fp_statec_busy ||
6044 FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) &&
6045 cmd->cmd_ulp_pkt) ? 1 : 0;
6046 mutex_exit(&port->fp_mutex);
6047
6048 if (FP_IS_PKT_ERROR(pkt) || bailout) {
6049 int skip_msg = 0;
6050 int giveup = 0;
6051
6509 * Handle solicited ADISC response
6510 */
6511 static void
6512 fp_adisc_intr(fc_packet_t *pkt)
6513 {
6514 int rval;
6515 int bailout;
6516 fp_cmd_t *cmd, *logi_cmd;
6517 fc_local_port_t *port;
6518 fc_remote_port_t *pd;
6519 la_els_adisc_t *acc;
6520 ls_code_t resp;
6521 fc_hardaddr_t ha;
6522 fc_portmap_t *changelist;
6523 int initiator, adiscfail = 0;
6524
6525 pd = pkt->pkt_pd;
6526 cmd = pkt->pkt_ulp_private;
6527 port = cmd->cmd_port;
6528
6529 #ifndef __lock_lint
6530 ASSERT(cmd->cmd_job && cmd->cmd_job->job_counter);
6531 #endif
6532
6533 ASSERT(pd != NULL && port != NULL && cmd != NULL);
6534
6535 mutex_enter(&port->fp_mutex);
6536 port->fp_out_fpcmds--;
6537 bailout = ((port->fp_statec_busy ||
6538 FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) &&
6539 cmd->cmd_ulp_pkt) ? 1 : 0;
6540 mutex_exit(&port->fp_mutex);
6541
6542 if (bailout) {
6543 fp_iodone(cmd);
6544 return;
6545 }
6546
6547 if (pkt->pkt_state == FC_PKT_SUCCESS && pkt->pkt_resp_resid == 0) {
6548 acc = (la_els_adisc_t *)pkt->pkt_resp;
6549
6550 FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&resp,
6551 (uint8_t *)acc, sizeof (resp), DDI_DEV_AUTOINCR);
|
2240 }
2241 cmd->cmd_dflags = 0;
2242 }
2243
2244
2245 /*
2246 * Dedicated thread to perform various activities. One thread for
2247 * each fc_local_port_t (driver soft state) instance.
2248 * Note, this effectively works out to one thread for each local
2249 * port, but there are also some Solaris taskq threads in use on a per-local
2250 * port basis; these also need to be taken into consideration.
2251 */
2252 static void
2253 fp_job_handler(fc_local_port_t *port)
2254 {
2255 int rval;
2256 uint32_t *d_id;
2257 fc_remote_port_t *pd;
2258 job_request_t *job;
2259
2260 /*
2261 * Solaris-internal stuff for proper operation of kernel threads
2262 * with Solaris CPR.
2263 */
2264 CALLB_CPR_INIT(&port->fp_cpr_info, &port->fp_mutex,
2265 callb_generic_cpr, "fp_job_handler");
2266
2267 /* Loop forever waiting for work to do */
2268 for (;;) {
2269
2270 mutex_enter(&port->fp_mutex);
2271
2272 /*
2273 * Sleep if no work to do right now, or if we want
2274 * to suspend or power-down.
2275 */
2276 while (port->fp_job_head == NULL ||
2277 (port->fp_soft_state & (FP_SOFT_POWER_DOWN |
2278 FP_SOFT_SUSPEND))) {
2279 CALLB_CPR_SAFE_BEGIN(&port->fp_cpr_info);
2280 cv_wait(&port->fp_cv, &port->fp_mutex);
2281 CALLB_CPR_SAFE_END(&port->fp_cpr_info, &port->fp_mutex);
2282 }
2283
2284 /*
2285 * OK, we've just been woken up, so retrieve the next entry
2286 * from the head of the job queue for this local port.
2288 job = fctl_deque_job(port);
2289
2290 /*
2291 * Handle all the fp driver's supported job codes here
2292 * in this big honkin' switch.
2293 */
2294 switch (job->job_code) {
2295 case JOB_PORT_SHUTDOWN:
2296 /*
2297 * fp_port_shutdown() is only called from here. This
2298 * will prepare the local port instance (softstate)
2299 * for detaching. This cancels timeout callbacks,
2300 * executes LOGOs with remote ports, cleans up tables,
2301 * and deallocates data structs.
2302 */
2303 fp_port_shutdown(port, job);
2304
2305 /*
2306 * This will exit the job thread.
2307 */
2308 CALLB_CPR_EXIT(&(port->fp_cpr_info));
2309 fctl_jobdone(job);
2310 thread_exit();
2311
2312 /* NOTREACHED */
2313
2314 case JOB_ATTACH_ULP: {
2315 /*
2316 * This job is spawned in response to a ULP calling
2317 * fc_ulp_add().
2318 */
2319
2320 boolean_t do_attach_ulps = B_TRUE;
2321
2322 /*
2323 * If fp is detaching, we don't want to call
2324 * fp_startup_done as this asynchronous
2325 * notification may interfere with the re-attach.
2326 */
2327
2328 if (port->fp_soft_state & (FP_DETACH_INPROGRESS |
2432 job->job_flags |= JOB_TYPE_FP_ASYNC;
2433 job->job_counter = 1;
2434
2435 rval = fp_port_login(port, *d_id, job,
2436 FP_CMD_PLOGI_RETAIN, KM_SLEEP, pd, NULL);
2437
2438 if (rval != FC_SUCCESS) {
2439 job->job_result = rval;
2440 fctl_jobdone(job);
2441 }
2442 break;
2443
2444 case JOB_LOGO_ONE: {
2445 /*
2446 * Issue a PLOGO to a single remote port. Multiple
2447 * PLOGOs to different remote ports may occur in
2448 * parallel.
2449 */
2450 fc_remote_port_t *pd;
2451
2452 ASSERT(job->job_counter > 0);
2453
2454 pd = (fc_remote_port_t *)job->job_ulp_pkts;
2455
2456 mutex_enter(&pd->pd_mutex);
2457 if (pd->pd_state != PORT_DEVICE_LOGGED_IN) {
2458 mutex_exit(&pd->pd_mutex);
2459 job->job_result = FC_LOGINREQ;
2460 mutex_exit(&port->fp_mutex);
2461 fctl_jobdone(job);
2462 break;
2463 }
2464 if (pd->pd_login_count > 1) {
2465 pd->pd_login_count--;
2466 mutex_exit(&pd->pd_mutex);
2467 job->job_result = FC_SUCCESS;
2468 mutex_exit(&port->fp_mutex);
2469 fctl_jobdone(job);
2470 break;
2471 }
2472 mutex_exit(&pd->pd_mutex);
4190 FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_clsp1,
4191 (uint8_t *)&acc->class_1, sizeof (acc->class_1),
4192 DDI_DEV_AUTOINCR);
4193 FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_clsp2,
4194 (uint8_t *)&acc->class_2, sizeof (acc->class_2),
4195 DDI_DEV_AUTOINCR);
4196 FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_clsp3,
4197 (uint8_t *)&acc->class_3, sizeof (acc->class_3),
4198 DDI_DEV_AUTOINCR);
4199 } else {
4200 pd->pd_csp = acc->common_service;
4201 pd->pd_clsp1 = acc->class_1;
4202 pd->pd_clsp2 = acc->class_2;
4203 pd->pd_clsp3 = acc->class_3;
4204 }
4205
4206 pd->pd_state = PORT_DEVICE_LOGGED_IN;
4207 pd->pd_login_class = class;
4208 mutex_exit(&pd->pd_mutex);
4209
4210 ASSERT(fctl_get_remote_port_by_did(pd->pd_port,
4211 pd->pd_port_id.port_id) == pd);
4212
4213 mutex_enter(&node->fd_mutex);
4214 if (handle) {
4215 FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)node->fd_vv,
4216 (uint8_t *)acc->vendor_version, sizeof (node->fd_vv),
4217 DDI_DEV_AUTOINCR);
4218 } else {
4219 bcopy(acc->vendor_version, node->fd_vv, sizeof (node->fd_vv));
4220 }
4221 mutex_exit(&node->fd_mutex);
4222 }
4223
4224
4225 /*
4226 * Mark the remote port as OFFLINE
4227 */
4228 static void
4229 fp_remote_port_offline(fc_remote_port_t *pd)
4230 {
4231 ASSERT(MUTEX_HELD(&pd->pd_mutex));
5998 */
5999 static void
6000 fp_plogi_intr(fc_packet_t *pkt)
6001 {
6002 int nl_port;
6003 int bailout;
6004 uint32_t d_id;
6005 fp_cmd_t *cmd;
6006 la_els_logi_t *acc;
6007 fc_local_port_t *port;
6008 fc_remote_port_t *pd;
6009 la_wwn_t nwwn;
6010 la_wwn_t pwwn;
6011 ls_code_t resp;
6012
6013 nl_port = 0;
6014 cmd = pkt->pkt_ulp_private;
6015 port = cmd->cmd_port;
6016 d_id = pkt->pkt_cmd_fhdr.d_id;
6017
6018 ASSERT(cmd->cmd_job && cmd->cmd_job->job_counter);
6019
6020 FP_TRACE(FP_NHEAD1(3, 0), "fp_plogi_intr: port=%p, job=%p, d_id=%x,"
6021 " jcount=%d pkt=%p, state=%x", port, cmd->cmd_job, d_id,
6022 cmd->cmd_job->job_counter, pkt, pkt->pkt_state);
6023
6024 /*
6025 * Bail out early on ULP initiated requests if the
6026 * state change has occurred
6027 */
6028 mutex_enter(&port->fp_mutex);
6029 port->fp_out_fpcmds--;
6030 bailout = ((port->fp_statec_busy ||
6031 FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) &&
6032 cmd->cmd_ulp_pkt) ? 1 : 0;
6033 mutex_exit(&port->fp_mutex);
6034
6035 if (FP_IS_PKT_ERROR(pkt) || bailout) {
6036 int skip_msg = 0;
6037 int giveup = 0;
6038
6496 * Handle solicited ADISC response
6497 */
6498 static void
6499 fp_adisc_intr(fc_packet_t *pkt)
6500 {
6501 int rval;
6502 int bailout;
6503 fp_cmd_t *cmd, *logi_cmd;
6504 fc_local_port_t *port;
6505 fc_remote_port_t *pd;
6506 la_els_adisc_t *acc;
6507 ls_code_t resp;
6508 fc_hardaddr_t ha;
6509 fc_portmap_t *changelist;
6510 int initiator, adiscfail = 0;
6511
6512 pd = pkt->pkt_pd;
6513 cmd = pkt->pkt_ulp_private;
6514 port = cmd->cmd_port;
6515
6516 ASSERT(cmd->cmd_job && cmd->cmd_job->job_counter);
6517
6518 ASSERT(pd != NULL && port != NULL && cmd != NULL);
6519
6520 mutex_enter(&port->fp_mutex);
6521 port->fp_out_fpcmds--;
6522 bailout = ((port->fp_statec_busy ||
6523 FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) &&
6524 cmd->cmd_ulp_pkt) ? 1 : 0;
6525 mutex_exit(&port->fp_mutex);
6526
6527 if (bailout) {
6528 fp_iodone(cmd);
6529 return;
6530 }
6531
6532 if (pkt->pkt_state == FC_PKT_SUCCESS && pkt->pkt_resp_resid == 0) {
6533 acc = (la_els_adisc_t *)pkt->pkt_resp;
6534
6535 FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&resp,
6536 (uint8_t *)acc, sizeof (resp), DDI_DEV_AUTOINCR);
|