1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * Fibre Channel SCSI ULP Mapping driver 26 */ 27 28 #include <sys/scsi/scsi.h> 29 #include <sys/types.h> 30 #include <sys/varargs.h> 31 #include <sys/devctl.h> 32 #include <sys/thread.h> 33 #include <sys/thread.h> 34 #include <sys/open.h> 35 #include <sys/file.h> 36 #include <sys/sunndi.h> 37 #include <sys/console.h> 38 #include <sys/proc.h> 39 #include <sys/time.h> 40 #include <sys/utsname.h> 41 #include <sys/scsi/impl/scsi_reset_notify.h> 42 #include <sys/ndi_impldefs.h> 43 #include <sys/byteorder.h> 44 #include <sys/fs/dv_node.h> 45 #include <sys/ctype.h> 46 #include <sys/sunmdi.h> 47 48 #include <sys/fibre-channel/fc.h> 49 #include <sys/fibre-channel/impl/fc_ulpif.h> 50 #include <sys/fibre-channel/ulp/fcpvar.h> 51 52 /* 53 * Discovery Process 54 * ================= 55 * 56 * The discovery process is a major function of FCP. In order to help 57 * understand that function a flow diagram is given here. This diagram 58 * doesn't claim to cover all the cases and the events that can occur during 59 * the discovery process nor the subtleties of the code. The code paths shown 60 * are simplified. Its purpose is to help the reader (and potentially bug 61 * fixer) have an overall view of the logic of the code. For that reason the 62 * diagram covers the simple case of the line coming up cleanly or of a new 63 * port attaching to FCP the link being up. The reader must keep in mind 64 * that: 65 * 66 * - There are special cases where bringing devices online and offline 67 * is driven by Ioctl. 68 * 69 * - The behavior of the discovery process can be modified through the 70 * .conf file. 71 * 72 * - The line can go down and come back up at any time during the 73 * discovery process which explains some of the complexity of the code. 74 * 75 * ............................................................................ 76 * 77 * STEP 1: The line comes up or a new Fibre Channel port attaches to FCP. 78 * 79 * 80 * +-------------------------+ 81 * fp/fctl module --->| fcp_port_attach | 82 * +-------------------------+ 83 * | | 84 * | | 85 * | v 86 * | +-------------------------+ 87 * | | fcp_handle_port_attach | 88 * | +-------------------------+ 89 * | | 90 * | | 91 * +--------------------+ | 92 * | | 93 * v v 94 * +-------------------------+ 95 * | fcp_statec_callback | 96 * +-------------------------+ 97 * | 98 * | 99 * v 100 * +-------------------------+ 101 * | fcp_handle_devices | 102 * +-------------------------+ 103 * | 104 * | 105 * v 106 * +-------------------------+ 107 * | fcp_handle_mapflags | 108 * +-------------------------+ 109 * | 110 * | 111 * v 112 * +-------------------------+ 113 * | fcp_send_els | 114 * | | 115 * | PLOGI or PRLI To all the| 116 * | reachable devices. | 117 * +-------------------------+ 118 * 119 * 120 * ............................................................................ 121 * 122 * STEP 2: The callback functions of the PLOGI and/or PRLI requests sent during 123 * STEP 1 are called (it is actually the same function). 124 * 125 * 126 * +-------------------------+ 127 * | fcp_icmd_callback | 128 * fp/fctl module --->| | 129 * | callback for PLOGI and | 130 * | PRLI. | 131 * +-------------------------+ 132 * | 133 * | 134 * Received PLOGI Accept /-\ Received PRLI Accept 135 * _ _ _ _ _ _ / \_ _ _ _ _ _ 136 * | \ / | 137 * | \-/ | 138 * | | 139 * v v 140 * +-------------------------+ +-------------------------+ 141 * | fcp_send_els | | fcp_send_scsi | 142 * | | | | 143 * | PRLI | | REPORT_LUN | 144 * +-------------------------+ +-------------------------+ 145 * 146 * ............................................................................ 147 * 148 * STEP 3: The callback functions of the SCSI commands issued by FCP are called 149 * (It is actually the same function). 150 * 151 * 152 * +-------------------------+ 153 * fp/fctl module ------->| fcp_scsi_callback | 154 * +-------------------------+ 155 * | 156 * | 157 * | 158 * Receive REPORT_LUN reply /-\ Receive INQUIRY PAGE83 reply 159 * _ _ _ _ _ _ _ _ _ _ / \_ _ _ _ _ _ _ _ _ _ _ _ 160 * | \ / | 161 * | \-/ | 162 * | | | 163 * | Receive INQUIRY reply| | 164 * | | | 165 * v v v 166 * +------------------------+ +----------------------+ +----------------------+ 167 * | fcp_handle_reportlun | | fcp_handle_inquiry | | fcp_handle_page83 | 168 * |(Called for each Target)| | (Called for each LUN)| |(Called for each LUN) | 169 * +------------------------+ +----------------------+ +----------------------+ 170 * | | | 171 * | | | 172 * | | | 173 * v v | 174 * +-----------------+ +-----------------+ | 175 * | fcp_send_scsi | | fcp_send_scsi | | 176 * | | | | | 177 * | INQUIRY | | INQUIRY PAGE83 | | 178 * | (To each LUN) | +-----------------+ | 179 * +-----------------+ | 180 * | 181 * v 182 * +------------------------+ 183 * | fcp_call_finish_init | 184 * +------------------------+ 185 * | 186 * v 187 * +-----------------------------+ 188 * | fcp_call_finish_init_held | 189 * +-----------------------------+ 190 * | 191 * | 192 * All LUNs scanned /-\ 193 * _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ / \ 194 * | \ / 195 * | \-/ 196 * v | 197 * +------------------+ | 198 * | fcp_finish_tgt | | 199 * +------------------+ | 200 * | Target Not Offline and | 201 * Target Not Offline and | not marked and tgt_node_state | 202 * marked /-\ not FCP_TGT_NODE_ON_DEMAND | 203 * _ _ _ _ _ _ / \_ _ _ _ _ _ _ _ | 204 * | \ / | | 205 * | \-/ | | 206 * v v | 207 * +----------------------------+ +-------------------+ | 208 * | fcp_offline_target | | fcp_create_luns | | 209 * | | +-------------------+ | 210 * | A structure fcp_tgt_elem | | | 211 * | is created and queued in | v | 212 * | the FCP port list | +-------------------+ | 213 * | port_offline_tgts. It | | fcp_pass_to_hp | | 214 * | will be unqueued by the | | | | 215 * | watchdog timer. | | Called for each | | 216 * +----------------------------+ | LUN. Dispatches | | 217 * | | fcp_hp_task | | 218 * | +-------------------+ | 219 * | | | 220 * | | | 221 * | | | 222 * | +---------------->| 223 * | | 224 * +---------------------------------------------->| 225 * | 226 * | 227 * All the targets (devices) have been scanned /-\ 228 * _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ / \ 229 * | \ / 230 * | \-/ 231 * +-------------------------------------+ | 232 * | fcp_finish_init | | 233 * | | | 234 * | Signal broadcasts the condition | | 235 * | variable port_config_cv of the FCP | | 236 * | port. One potential code sequence | | 237 * | waiting on the condition variable | | 238 * | the code sequence handling | | 239 * | BUS_CONFIG_ALL and BUS_CONFIG_DRIVER| | 240 * | The other is in the function | | 241 * | fcp_reconfig_wait which is called | | 242 * | in the transmit path preventing IOs | | 243 * | from going through till the disco- | | 244 * | very process is over. | | 245 * +-------------------------------------+ | 246 * | | 247 * | | 248 * +--------------------------------->| 249 * | 250 * v 251 * Return 252 * 253 * ............................................................................ 254 * 255 * STEP 4: The hot plug task is called (for each fcp_hp_elem). 256 * 257 * 258 * +-------------------------+ 259 * | fcp_hp_task | 260 * +-------------------------+ 261 * | 262 * | 263 * v 264 * +-------------------------+ 265 * | fcp_trigger_lun | 266 * +-------------------------+ 267 * | 268 * | 269 * v 270 * Bring offline /-\ Bring online 271 * _ _ _ _ _ _ _ _ _/ \_ _ _ _ _ _ _ _ _ _ 272 * | \ / | 273 * | \-/ | 274 * v v 275 * +---------------------+ +-----------------------+ 276 * | fcp_offline_child | | fcp_get_cip | 277 * +---------------------+ | | 278 * | Creates a dev_info_t | 279 * | or a mdi_pathinfo_t | 280 * | depending on whether | 281 * | mpxio is on or off. | 282 * +-----------------------+ 283 * | 284 * | 285 * v 286 * +-----------------------+ 287 * | fcp_online_child | 288 * | | 289 * | Set device online | 290 * | using NDI or MDI. | 291 * +-----------------------+ 292 * 293 * ............................................................................ 294 * 295 * STEP 5: The watchdog timer expires. The watch dog timer does much more that 296 * what is described here. We only show the target offline path. 297 * 298 * 299 * +--------------------------+ 300 * | fcp_watch | 301 * +--------------------------+ 302 * | 303 * | 304 * v 305 * +--------------------------+ 306 * | fcp_scan_offline_tgts | 307 * +--------------------------+ 308 * | 309 * | 310 * v 311 * +--------------------------+ 312 * | fcp_offline_target_now | 313 * +--------------------------+ 314 * | 315 * | 316 * v 317 * +--------------------------+ 318 * | fcp_offline_tgt_luns | 319 * +--------------------------+ 320 * | 321 * | 322 * v 323 * +--------------------------+ 324 * | fcp_offline_lun | 325 * +--------------------------+ 326 * | 327 * | 328 * v 329 * +----------------------------------+ 330 * | fcp_offline_lun_now | 331 * | | 332 * | A request (or two if mpxio) is | 333 * | sent to the hot plug task using | 334 * | a fcp_hp_elem structure. | 335 * +----------------------------------+ 336 */ 337 338 /* 339 * Functions registered with DDI framework 340 */ 341 static int fcp_attach(dev_info_t *devi, ddi_attach_cmd_t cmd); 342 static int fcp_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 343 static int fcp_open(dev_t *devp, int flag, int otype, cred_t *credp); 344 static int fcp_close(dev_t dev, int flag, int otype, cred_t *credp); 345 static int fcp_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 346 cred_t *credp, int *rval); 347 348 /* 349 * Functions registered with FC Transport framework 350 */ 351 static int fcp_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo, 352 fc_attach_cmd_t cmd, uint32_t s_id); 353 static int fcp_port_detach(opaque_t ulph, fc_ulp_port_info_t *info, 354 fc_detach_cmd_t cmd); 355 static int fcp_port_ioctl(opaque_t ulph, opaque_t port_handle, dev_t dev, 356 int cmd, intptr_t data, int mode, cred_t *credp, int *rval, 357 uint32_t claimed); 358 static int fcp_els_callback(opaque_t ulph, opaque_t port_handle, 359 fc_unsol_buf_t *buf, uint32_t claimed); 360 static int fcp_data_callback(opaque_t ulph, opaque_t port_handle, 361 fc_unsol_buf_t *buf, uint32_t claimed); 362 static void fcp_statec_callback(opaque_t ulph, opaque_t port_handle, 363 uint32_t port_state, uint32_t port_top, fc_portmap_t *devlist, 364 uint32_t dev_cnt, uint32_t port_sid); 365 366 /* 367 * Functions registered with SCSA framework 368 */ 369 static int fcp_phys_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 370 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 371 static int fcp_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 372 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 373 static void fcp_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 374 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 375 static int fcp_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); 376 static int fcp_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 377 static int fcp_scsi_reset(struct scsi_address *ap, int level); 378 static int fcp_scsi_getcap(struct scsi_address *ap, char *cap, int whom); 379 static int fcp_scsi_setcap(struct scsi_address *ap, char *cap, int value, 380 int whom); 381 static void fcp_pkt_teardown(struct scsi_pkt *pkt); 382 static int fcp_scsi_reset_notify(struct scsi_address *ap, int flag, 383 void (*callback)(caddr_t), caddr_t arg); 384 static int fcp_scsi_bus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip, 385 char *name, ddi_eventcookie_t *event_cookiep); 386 static int fcp_scsi_bus_add_eventcall(dev_info_t *dip, dev_info_t *rdip, 387 ddi_eventcookie_t eventid, void (*callback)(), void *arg, 388 ddi_callback_id_t *cb_id); 389 static int fcp_scsi_bus_remove_eventcall(dev_info_t *devi, 390 ddi_callback_id_t cb_id); 391 static int fcp_scsi_bus_post_event(dev_info_t *dip, dev_info_t *rdip, 392 ddi_eventcookie_t eventid, void *impldata); 393 static int fcp_scsi_bus_config(dev_info_t *parent, uint_t flag, 394 ddi_bus_config_op_t op, void *arg, dev_info_t **childp); 395 static int fcp_scsi_bus_unconfig(dev_info_t *parent, uint_t flag, 396 ddi_bus_config_op_t op, void *arg); 397 398 /* 399 * Internal functions 400 */ 401 static int fcp_setup_device_data_ioctl(int cmd, struct fcp_ioctl *data, 402 int mode, int *rval); 403 404 static int fcp_setup_scsi_ioctl(struct fcp_scsi_cmd *u_fscsi, 405 int mode, int *rval); 406 static int fcp_copyin_scsi_cmd(caddr_t base_addr, 407 struct fcp_scsi_cmd *fscsi, int mode); 408 static int fcp_copyout_scsi_cmd(struct fcp_scsi_cmd *fscsi, 409 caddr_t base_addr, int mode); 410 static int fcp_send_scsi_ioctl(struct fcp_scsi_cmd *fscsi); 411 412 static struct fcp_tgt *fcp_port_create_tgt(struct fcp_port *pptr, 413 la_wwn_t *pwwn, int *ret_val, int *fc_status, int *fc_pkt_state, 414 int *fc_pkt_reason, int *fc_pkt_action); 415 static int fcp_tgt_send_plogi(struct fcp_tgt *ptgt, int *fc_status, 416 int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action); 417 static int fcp_tgt_send_prli(struct fcp_tgt *ptgt, int *fc_status, 418 int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action); 419 static void fcp_ipkt_sema_init(struct fcp_ipkt *icmd); 420 static int fcp_ipkt_sema_wait(struct fcp_ipkt *icmd); 421 static void fcp_ipkt_sema_callback(struct fc_packet *fpkt); 422 static void fcp_ipkt_sema_cleanup(struct fcp_ipkt *icmd); 423 424 static void fcp_handle_devices(struct fcp_port *pptr, 425 fc_portmap_t devlist[], uint32_t dev_cnt, int link_cnt, 426 fcp_map_tag_t *map_tag, int cause); 427 static int fcp_handle_mapflags(struct fcp_port *pptr, 428 struct fcp_tgt *ptgt, fc_portmap_t *map_entry, int link_cnt, 429 int tgt_cnt, int cause); 430 static int fcp_handle_reportlun_changed(struct fcp_tgt *ptgt, int cause); 431 static int fcp_send_els(struct fcp_port *pptr, struct fcp_tgt *ptgt, 432 struct fcp_ipkt *icmd, uchar_t opcode, int lcount, int tcount, int cause); 433 static void fcp_update_state(struct fcp_port *pptr, uint32_t state, 434 int cause); 435 static void fcp_update_tgt_state(struct fcp_tgt *ptgt, int flag, 436 uint32_t state); 437 static struct fcp_port *fcp_get_port(opaque_t port_handle); 438 static void fcp_unsol_callback(fc_packet_t *fpkt); 439 static void fcp_unsol_resp_init(fc_packet_t *pkt, fc_unsol_buf_t *buf, 440 uchar_t r_ctl, uchar_t type); 441 static int fcp_unsol_prli(struct fcp_port *pptr, fc_unsol_buf_t *buf); 442 static struct fcp_ipkt *fcp_icmd_alloc(struct fcp_port *pptr, 443 struct fcp_tgt *ptgt, int cmd_len, int resp_len, int data_len, 444 int nodma, int lcount, int tcount, int cause, uint32_t rscn_count); 445 static void fcp_icmd_free(struct fcp_port *pptr, struct fcp_ipkt *icmd); 446 static int fcp_alloc_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd, 447 int nodma, int flags); 448 static void fcp_free_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd); 449 static struct fcp_tgt *fcp_lookup_target(struct fcp_port *pptr, 450 uchar_t *wwn); 451 static struct fcp_tgt *fcp_get_target_by_did(struct fcp_port *pptr, 452 uint32_t d_id); 453 static void fcp_icmd_callback(fc_packet_t *fpkt); 454 static int fcp_send_scsi(struct fcp_lun *plun, uchar_t opcode, 455 int len, int lcount, int tcount, int cause, uint32_t rscn_count); 456 static int fcp_check_reportlun(struct fcp_rsp *rsp, fc_packet_t *fpkt); 457 static void fcp_scsi_callback(fc_packet_t *fpkt); 458 static void fcp_retry_scsi_cmd(fc_packet_t *fpkt); 459 static void fcp_handle_inquiry(fc_packet_t *fpkt, struct fcp_ipkt *icmd); 460 static void fcp_handle_reportlun(fc_packet_t *fpkt, struct fcp_ipkt *icmd); 461 static struct fcp_lun *fcp_get_lun(struct fcp_tgt *ptgt, 462 uint16_t lun_num); 463 static int fcp_finish_tgt(struct fcp_port *pptr, struct fcp_tgt *ptgt, 464 int link_cnt, int tgt_cnt, int cause); 465 static void fcp_finish_init(struct fcp_port *pptr); 466 static void fcp_create_luns(struct fcp_tgt *ptgt, int link_cnt, 467 int tgt_cnt, int cause); 468 static int fcp_trigger_lun(struct fcp_lun *plun, child_info_t *cip, 469 int old_mpxio, int online, int link_cnt, int tgt_cnt, int flags); 470 static int fcp_offline_target(struct fcp_port *pptr, struct fcp_tgt *ptgt, 471 int link_cnt, int tgt_cnt, int nowait, int flags); 472 static void fcp_offline_target_now(struct fcp_port *pptr, 473 struct fcp_tgt *ptgt, int link_cnt, int tgt_cnt, int flags); 474 static void fcp_offline_tgt_luns(struct fcp_tgt *ptgt, int link_cnt, 475 int tgt_cnt, int flags); 476 static void fcp_offline_lun(struct fcp_lun *plun, int link_cnt, int tgt_cnt, 477 int nowait, int flags); 478 static void fcp_prepare_offline_lun(struct fcp_lun *plun, int link_cnt, 479 int tgt_cnt); 480 static void fcp_offline_lun_now(struct fcp_lun *plun, int link_cnt, 481 int tgt_cnt, int flags); 482 static void fcp_scan_offline_luns(struct fcp_port *pptr); 483 static void fcp_scan_offline_tgts(struct fcp_port *pptr); 484 static void fcp_update_offline_flags(struct fcp_lun *plun); 485 static struct fcp_pkt *fcp_scan_commands(struct fcp_lun *plun); 486 static void fcp_abort_commands(struct fcp_pkt *head, struct 487 fcp_port *pptr); 488 static void fcp_cmd_callback(fc_packet_t *fpkt); 489 static void fcp_complete_pkt(fc_packet_t *fpkt); 490 static int fcp_validate_fcp_response(struct fcp_rsp *rsp, 491 struct fcp_port *pptr); 492 static int fcp_device_changed(struct fcp_port *pptr, struct fcp_tgt *ptgt, 493 fc_portmap_t *map_entry, int link_cnt, int tgt_cnt, int cause); 494 static struct fcp_lun *fcp_alloc_lun(struct fcp_tgt *ptgt); 495 static void fcp_dealloc_lun(struct fcp_lun *plun); 496 static struct fcp_tgt *fcp_alloc_tgt(struct fcp_port *pptr, 497 fc_portmap_t *map_entry, int link_cnt); 498 static void fcp_dealloc_tgt(struct fcp_tgt *ptgt); 499 static void fcp_queue_ipkt(struct fcp_port *pptr, fc_packet_t *fpkt); 500 static int fcp_transport(opaque_t port_handle, fc_packet_t *fpkt, 501 int internal); 502 static void fcp_log(int level, dev_info_t *dip, const char *fmt, ...); 503 static int fcp_handle_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo, 504 uint32_t s_id, int instance); 505 static int fcp_handle_port_detach(struct fcp_port *pptr, int flag, 506 int instance); 507 static void fcp_cleanup_port(struct fcp_port *pptr, int instance); 508 static int fcp_kmem_cache_constructor(struct scsi_pkt *, scsi_hba_tran_t *, 509 int); 510 static void fcp_kmem_cache_destructor(struct scsi_pkt *, scsi_hba_tran_t *); 511 static int fcp_pkt_setup(struct scsi_pkt *, int (*)(), caddr_t); 512 static int fcp_alloc_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt, 513 int flags); 514 static void fcp_free_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt); 515 static int fcp_reset_target(struct scsi_address *ap, int level); 516 static int fcp_commoncap(struct scsi_address *ap, char *cap, 517 int val, int tgtonly, int doset); 518 static int fcp_scsi_get_name(struct scsi_device *sd, char *name, int len); 519 static int fcp_scsi_get_bus_addr(struct scsi_device *sd, char *name, int len); 520 static int fcp_linkreset(struct fcp_port *pptr, struct scsi_address *ap, 521 int sleep); 522 static int fcp_handle_port_resume(opaque_t ulph, fc_ulp_port_info_t *pinfo, 523 uint32_t s_id, fc_attach_cmd_t cmd, int instance); 524 static void fcp_cp_pinfo(struct fcp_port *pptr, fc_ulp_port_info_t *pinfo); 525 static void fcp_process_elem(struct fcp_hp_elem *elem, int result); 526 static child_info_t *fcp_get_cip(struct fcp_lun *plun, child_info_t *cip, 527 int lcount, int tcount); 528 static int fcp_is_dip_present(struct fcp_lun *plun, dev_info_t *cdip); 529 static int fcp_is_child_present(struct fcp_lun *plun, child_info_t *cip); 530 static dev_info_t *fcp_create_dip(struct fcp_lun *plun, int link_cnt, 531 int tgt_cnt); 532 static dev_info_t *fcp_find_existing_dip(struct fcp_lun *plun, 533 dev_info_t *pdip, caddr_t name); 534 static int fcp_online_child(struct fcp_lun *plun, child_info_t *cip, 535 int lcount, int tcount, int flags, int *circ); 536 static int fcp_offline_child(struct fcp_lun *plun, child_info_t *cip, 537 int lcount, int tcount, int flags, int *circ); 538 static void fcp_remove_child(struct fcp_lun *plun); 539 static void fcp_watch(void *arg); 540 static void fcp_check_reset_delay(struct fcp_port *pptr); 541 static void fcp_abort_all(struct fcp_port *pptr, struct fcp_tgt *ttgt, 542 struct fcp_lun *rlun, int tgt_cnt); 543 struct fcp_port *fcp_soft_state_unlink(struct fcp_port *pptr); 544 static struct fcp_lun *fcp_lookup_lun(struct fcp_port *pptr, 545 uchar_t *wwn, uint16_t lun); 546 static void fcp_prepare_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd, 547 struct fcp_lun *plun); 548 static void fcp_post_callback(struct fcp_pkt *cmd); 549 static int fcp_dopoll(struct fcp_port *pptr, struct fcp_pkt *cmd); 550 static struct fcp_port *fcp_dip2port(dev_info_t *dip); 551 struct fcp_lun *fcp_get_lun_from_cip(struct fcp_port *pptr, 552 child_info_t *cip); 553 static int fcp_pass_to_hp_and_wait(struct fcp_port *pptr, 554 struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt, 555 int tgt_cnt, int flags); 556 static struct fcp_hp_elem *fcp_pass_to_hp(struct fcp_port *pptr, 557 struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt, 558 int tgt_cnt, int flags, int wait); 559 static void fcp_retransport_cmd(struct fcp_port *pptr, 560 struct fcp_pkt *cmd); 561 static void fcp_fail_cmd(struct fcp_pkt *cmd, uchar_t reason, 562 uint_t statistics); 563 static void fcp_queue_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd); 564 static void fcp_update_targets(struct fcp_port *pptr, 565 fc_portmap_t *dev_list, uint32_t count, uint32_t state, int cause); 566 static int fcp_call_finish_init(struct fcp_port *pptr, 567 struct fcp_tgt *ptgt, int lcount, int tcount, int cause); 568 static int fcp_call_finish_init_held(struct fcp_port *pptr, 569 struct fcp_tgt *ptgt, int lcount, int tcount, int cause); 570 static void fcp_reconfigure_luns(void * tgt_handle); 571 static void fcp_free_targets(struct fcp_port *pptr); 572 static void fcp_free_target(struct fcp_tgt *ptgt); 573 static int fcp_is_retryable(struct fcp_ipkt *icmd); 574 static int fcp_create_on_demand(struct fcp_port *pptr, uchar_t *pwwn); 575 static void fcp_ascii_to_wwn(caddr_t string, uchar_t bytes[], unsigned int); 576 static void fcp_wwn_to_ascii(uchar_t bytes[], char *string); 577 static void fcp_print_error(fc_packet_t *fpkt); 578 static int fcp_handle_ipkt_errors(struct fcp_port *pptr, 579 struct fcp_tgt *ptgt, struct fcp_ipkt *icmd, int rval, caddr_t op); 580 static int fcp_outstanding_lun_cmds(struct fcp_tgt *ptgt); 581 static fc_portmap_t *fcp_construct_map(struct fcp_port *pptr, 582 uint32_t *dev_cnt); 583 static void fcp_offline_all(struct fcp_port *pptr, int lcount, int cause); 584 static int fcp_get_statec_count(struct fcp_ioctl *data, int mode, int *rval); 585 static int fcp_copyin_fcp_ioctl_data(struct fcp_ioctl *, int, int *, 586 struct fcp_ioctl *, struct fcp_port **); 587 static char *fcp_get_lun_path(struct fcp_lun *plun); 588 static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode, 589 int *rval); 590 static int fcp_do_ns_registry(struct fcp_port *pptr, uint32_t s_id); 591 static void fcp_retry_ns_registry(struct fcp_port *pptr, uint32_t s_id); 592 static char *fcp_get_lun_path(struct fcp_lun *plun); 593 static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode, 594 int *rval); 595 static void fcp_reconfig_wait(struct fcp_port *pptr); 596 597 /* 598 * New functions added for mpxio support 599 */ 600 static int fcp_virt_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 601 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 602 static mdi_pathinfo_t *fcp_create_pip(struct fcp_lun *plun, int lcount, 603 int tcount); 604 static mdi_pathinfo_t *fcp_find_existing_pip(struct fcp_lun *plun, 605 dev_info_t *pdip); 606 static int fcp_is_pip_present(struct fcp_lun *plun, mdi_pathinfo_t *pip); 607 static void fcp_handle_page83(fc_packet_t *, struct fcp_ipkt *, int); 608 static void fcp_update_mpxio_path_verifybusy(struct fcp_port *pptr); 609 static int fcp_copy_guid_2_lun_block(struct fcp_lun *plun, char *guidp); 610 static int fcp_update_mpxio_path(struct fcp_lun *plun, child_info_t *cip, 611 int what); 612 static int fcp_is_reconfig_needed(struct fcp_tgt *ptgt, 613 fc_packet_t *fpkt); 614 static int fcp_symmetric_device_probe(struct fcp_lun *plun); 615 616 /* 617 * New functions added for lun masking support 618 */ 619 static void fcp_read_blacklist(dev_info_t *dip, 620 struct fcp_black_list_entry **pplun_blacklist); 621 static void fcp_mask_pwwn_lun(char *curr_pwwn, char *curr_lun, 622 struct fcp_black_list_entry **pplun_blacklist); 623 static void fcp_add_one_mask(char *curr_pwwn, uint32_t lun_id, 624 struct fcp_black_list_entry **pplun_blacklist); 625 static int fcp_should_mask(la_wwn_t *wwn, uint32_t lun_id); 626 static void fcp_cleanup_blacklist(struct fcp_black_list_entry **lun_blacklist); 627 628 extern struct mod_ops mod_driverops; 629 /* 630 * This variable is defined in modctl.c and set to '1' after the root driver 631 * and fs are loaded. It serves as an indication that the root filesystem can 632 * be used. 633 */ 634 extern int modrootloaded; 635 /* 636 * This table contains strings associated with the SCSI sense key codes. It 637 * is used by FCP to print a clear explanation of the code returned in the 638 * sense information by a device. 639 */ 640 extern char *sense_keys[]; 641 /* 642 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is 643 * under this device that the paths to a physical device are created when 644 * MPxIO is used. 645 */ 646 extern dev_info_t *scsi_vhci_dip; 647 648 /* 649 * Report lun processing 650 */ 651 #define FCP_LUN_ADDRESSING 0x80 652 #define FCP_PD_ADDRESSING 0x00 653 #define FCP_VOLUME_ADDRESSING 0x40 654 655 #define FCP_SVE_THROTTLE 0x28 /* Vicom */ 656 #define MAX_INT_DMA 0x7fffffff 657 #define FCP_MAX_SENSE_LEN 252 658 #define FCP_MAX_RESPONSE_LEN 0xffffff 659 /* 660 * Property definitions 661 */ 662 #define NODE_WWN_PROP (char *)fcp_node_wwn_prop 663 #define PORT_WWN_PROP (char *)fcp_port_wwn_prop 664 #define TARGET_PROP (char *)fcp_target_prop 665 #define LUN_PROP (char *)fcp_lun_prop 666 #define SAM_LUN_PROP (char *)fcp_sam_lun_prop 667 #define CONF_WWN_PROP (char *)fcp_conf_wwn_prop 668 #define OBP_BOOT_WWN (char *)fcp_obp_boot_wwn 669 #define MANUAL_CFG_ONLY (char *)fcp_manual_config_only 670 #define INIT_PORT_PROP (char *)fcp_init_port_prop 671 #define TGT_PORT_PROP (char *)fcp_tgt_port_prop 672 #define LUN_BLACKLIST_PROP (char *)fcp_lun_blacklist_prop 673 /* 674 * Short hand macros. 675 */ 676 #define LUN_PORT (plun->lun_tgt->tgt_port) 677 #define LUN_TGT (plun->lun_tgt) 678 679 /* 680 * Driver private macros 681 */ 682 #define FCP_ATOB(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : \ 683 ((x) >= 'a' && (x) <= 'f') ? \ 684 ((x) - 'a' + 10) : ((x) - 'A' + 10)) 685 686 #define FCP_MAX(a, b) ((a) > (b) ? (a) : (b)) 687 688 #define FCP_N_NDI_EVENTS \ 689 (sizeof (fcp_ndi_event_defs) / sizeof (ndi_event_definition_t)) 690 691 #define FCP_LINK_STATE_CHANGED(p, c) \ 692 ((p)->port_link_cnt != (c)->ipkt_link_cnt) 693 694 #define FCP_TGT_STATE_CHANGED(t, c) \ 695 ((t)->tgt_change_cnt != (c)->ipkt_change_cnt) 696 697 #define FCP_STATE_CHANGED(p, t, c) \ 698 (FCP_TGT_STATE_CHANGED(t, c)) 699 700 #define FCP_MUST_RETRY(fpkt) \ 701 ((fpkt)->pkt_state == FC_PKT_LOCAL_BSY || \ 702 (fpkt)->pkt_state == FC_PKT_LOCAL_RJT || \ 703 (fpkt)->pkt_state == FC_PKT_TRAN_BSY || \ 704 (fpkt)->pkt_state == FC_PKT_ELS_IN_PROGRESS || \ 705 (fpkt)->pkt_state == FC_PKT_NPORT_BSY || \ 706 (fpkt)->pkt_state == FC_PKT_FABRIC_BSY || \ 707 (fpkt)->pkt_state == FC_PKT_PORT_OFFLINE || \ 708 (fpkt)->pkt_reason == FC_REASON_OFFLINE) 709 710 #define FCP_SENSE_REPORTLUN_CHANGED(es) \ 711 ((es)->es_key == KEY_UNIT_ATTENTION && \ 712 (es)->es_add_code == 0x3f && \ 713 (es)->es_qual_code == 0x0e) 714 715 #define FCP_SENSE_NO_LUN(es) \ 716 ((es)->es_key == KEY_ILLEGAL_REQUEST && \ 717 (es)->es_add_code == 0x25 && \ 718 (es)->es_qual_code == 0x0) 719 720 #define FCP_VERSION "1.189" 721 #define FCP_NAME_VERSION "SunFC FCP v" FCP_VERSION 722 723 #define FCP_NUM_ELEMENTS(array) \ 724 (sizeof (array) / sizeof ((array)[0])) 725 726 /* 727 * Debugging, Error reporting, and tracing 728 */ 729 #define FCP_LOG_SIZE 1024 * 1024 730 731 #define FCP_LEVEL_1 0x00001 /* attach/detach PM CPR */ 732 #define FCP_LEVEL_2 0x00002 /* failures/Invalid data */ 733 #define FCP_LEVEL_3 0x00004 /* state change, discovery */ 734 #define FCP_LEVEL_4 0x00008 /* ULP messages */ 735 #define FCP_LEVEL_5 0x00010 /* ELS/SCSI cmds */ 736 #define FCP_LEVEL_6 0x00020 /* Transport failures */ 737 #define FCP_LEVEL_7 0x00040 738 #define FCP_LEVEL_8 0x00080 /* I/O tracing */ 739 #define FCP_LEVEL_9 0x00100 /* I/O tracing */ 740 741 742 743 /* 744 * Log contents to system messages file 745 */ 746 #define FCP_MSG_LEVEL_1 (FCP_LEVEL_1 | FC_TRACE_LOG_MSG) 747 #define FCP_MSG_LEVEL_2 (FCP_LEVEL_2 | FC_TRACE_LOG_MSG) 748 #define FCP_MSG_LEVEL_3 (FCP_LEVEL_3 | FC_TRACE_LOG_MSG) 749 #define FCP_MSG_LEVEL_4 (FCP_LEVEL_4 | FC_TRACE_LOG_MSG) 750 #define FCP_MSG_LEVEL_5 (FCP_LEVEL_5 | FC_TRACE_LOG_MSG) 751 #define FCP_MSG_LEVEL_6 (FCP_LEVEL_6 | FC_TRACE_LOG_MSG) 752 #define FCP_MSG_LEVEL_7 (FCP_LEVEL_7 | FC_TRACE_LOG_MSG) 753 #define FCP_MSG_LEVEL_8 (FCP_LEVEL_8 | FC_TRACE_LOG_MSG) 754 #define FCP_MSG_LEVEL_9 (FCP_LEVEL_9 | FC_TRACE_LOG_MSG) 755 756 757 /* 758 * Log contents to trace buffer 759 */ 760 #define FCP_BUF_LEVEL_1 (FCP_LEVEL_1 | FC_TRACE_LOG_BUF) 761 #define FCP_BUF_LEVEL_2 (FCP_LEVEL_2 | FC_TRACE_LOG_BUF) 762 #define FCP_BUF_LEVEL_3 (FCP_LEVEL_3 | FC_TRACE_LOG_BUF) 763 #define FCP_BUF_LEVEL_4 (FCP_LEVEL_4 | FC_TRACE_LOG_BUF) 764 #define FCP_BUF_LEVEL_5 (FCP_LEVEL_5 | FC_TRACE_LOG_BUF) 765 #define FCP_BUF_LEVEL_6 (FCP_LEVEL_6 | FC_TRACE_LOG_BUF) 766 #define FCP_BUF_LEVEL_7 (FCP_LEVEL_7 | FC_TRACE_LOG_BUF) 767 #define FCP_BUF_LEVEL_8 (FCP_LEVEL_8 | FC_TRACE_LOG_BUF) 768 #define FCP_BUF_LEVEL_9 (FCP_LEVEL_9 | FC_TRACE_LOG_BUF) 769 770 771 /* 772 * Log contents to both system messages file and trace buffer 773 */ 774 #define FCP_MSG_BUF_LEVEL_1 (FCP_LEVEL_1 | FC_TRACE_LOG_BUF | \ 775 FC_TRACE_LOG_MSG) 776 #define FCP_MSG_BUF_LEVEL_2 (FCP_LEVEL_2 | FC_TRACE_LOG_BUF | \ 777 FC_TRACE_LOG_MSG) 778 #define FCP_MSG_BUF_LEVEL_3 (FCP_LEVEL_3 | FC_TRACE_LOG_BUF | \ 779 FC_TRACE_LOG_MSG) 780 #define FCP_MSG_BUF_LEVEL_4 (FCP_LEVEL_4 | FC_TRACE_LOG_BUF | \ 781 FC_TRACE_LOG_MSG) 782 #define FCP_MSG_BUF_LEVEL_5 (FCP_LEVEL_5 | FC_TRACE_LOG_BUF | \ 783 FC_TRACE_LOG_MSG) 784 #define FCP_MSG_BUF_LEVEL_6 (FCP_LEVEL_6 | FC_TRACE_LOG_BUF | \ 785 FC_TRACE_LOG_MSG) 786 #define FCP_MSG_BUF_LEVEL_7 (FCP_LEVEL_7 | FC_TRACE_LOG_BUF | \ 787 FC_TRACE_LOG_MSG) 788 #define FCP_MSG_BUF_LEVEL_8 (FCP_LEVEL_8 | FC_TRACE_LOG_BUF | \ 789 FC_TRACE_LOG_MSG) 790 #define FCP_MSG_BUF_LEVEL_9 (FCP_LEVEL_9 | FC_TRACE_LOG_BUF | \ 791 FC_TRACE_LOG_MSG) 792 #ifdef DEBUG 793 #define FCP_DTRACE fc_trace_debug 794 #else 795 #define FCP_DTRACE 796 #endif 797 798 #define FCP_TRACE fc_trace_debug 799 800 static struct cb_ops fcp_cb_ops = { 801 fcp_open, /* open */ 802 fcp_close, /* close */ 803 nodev, /* strategy */ 804 nodev, /* print */ 805 nodev, /* dump */ 806 nodev, /* read */ 807 nodev, /* write */ 808 fcp_ioctl, /* ioctl */ 809 nodev, /* devmap */ 810 nodev, /* mmap */ 811 nodev, /* segmap */ 812 nochpoll, /* chpoll */ 813 ddi_prop_op, /* cb_prop_op */ 814 0, /* streamtab */ 815 D_NEW | D_MP | D_HOTPLUG, /* cb_flag */ 816 CB_REV, /* rev */ 817 nodev, /* aread */ 818 nodev /* awrite */ 819 }; 820 821 822 static struct dev_ops fcp_ops = { 823 DEVO_REV, 824 0, 825 ddi_getinfo_1to1, 826 nulldev, /* identify */ 827 nulldev, /* probe */ 828 fcp_attach, /* attach and detach are mandatory */ 829 fcp_detach, 830 nodev, /* reset */ 831 &fcp_cb_ops, /* cb_ops */ 832 NULL, /* bus_ops */ 833 NULL, /* power */ 834 }; 835 836 837 char *fcp_version = FCP_NAME_VERSION; 838 839 static struct modldrv modldrv = { 840 &mod_driverops, 841 FCP_NAME_VERSION, 842 &fcp_ops 843 }; 844 845 846 static struct modlinkage modlinkage = { 847 MODREV_1, 848 &modldrv, 849 NULL 850 }; 851 852 853 static fc_ulp_modinfo_t fcp_modinfo = { 854 &fcp_modinfo, /* ulp_handle */ 855 FCTL_ULP_MODREV_4, /* ulp_rev */ 856 FC4_SCSI_FCP, /* ulp_type */ 857 "fcp", /* ulp_name */ 858 FCP_STATEC_MASK, /* ulp_statec_mask */ 859 fcp_port_attach, /* ulp_port_attach */ 860 fcp_port_detach, /* ulp_port_detach */ 861 fcp_port_ioctl, /* ulp_port_ioctl */ 862 fcp_els_callback, /* ulp_els_callback */ 863 fcp_data_callback, /* ulp_data_callback */ 864 fcp_statec_callback /* ulp_statec_callback */ 865 }; 866 867 #ifdef DEBUG 868 #define FCP_TRACE_DEFAULT (FC_TRACE_LOG_MASK | FCP_LEVEL_1 | \ 869 FCP_LEVEL_2 | FCP_LEVEL_3 | \ 870 FCP_LEVEL_4 | FCP_LEVEL_5 | \ 871 FCP_LEVEL_6 | FCP_LEVEL_7) 872 #else 873 #define FCP_TRACE_DEFAULT (FC_TRACE_LOG_MASK | FCP_LEVEL_1 | \ 874 FCP_LEVEL_2 | FCP_LEVEL_3 | \ 875 FCP_LEVEL_4 | FCP_LEVEL_5 | \ 876 FCP_LEVEL_6 | FCP_LEVEL_7) 877 #endif 878 879 /* FCP global variables */ 880 int fcp_bus_config_debug = 0; 881 static int fcp_log_size = FCP_LOG_SIZE; 882 static int fcp_trace = FCP_TRACE_DEFAULT; 883 static fc_trace_logq_t *fcp_logq = NULL; 884 static struct fcp_black_list_entry *fcp_lun_blacklist = NULL; 885 /* 886 * The auto-configuration is set by default. The only way of disabling it is 887 * through the property MANUAL_CFG_ONLY in the fcp.conf file. 888 */ 889 static int fcp_enable_auto_configuration = 1; 890 static int fcp_max_bus_config_retries = 4; 891 static int fcp_lun_ready_retry = 300; 892 /* 893 * The value assigned to the following variable has changed several times due 894 * to a problem with the data underruns reporting of some firmware(s). The 895 * current value of 50 gives a timeout value of 25 seconds for a max number 896 * of 256 LUNs. 897 */ 898 static int fcp_max_target_retries = 50; 899 /* 900 * Watchdog variables 901 * ------------------ 902 * 903 * fcp_watchdog_init 904 * 905 * Indicates if the watchdog timer is running or not. This is actually 906 * a counter of the number of Fibre Channel ports that attached. When 907 * the first port attaches the watchdog is started. When the last port 908 * detaches the watchdog timer is stopped. 909 * 910 * fcp_watchdog_time 911 * 912 * This is the watchdog clock counter. It is incremented by 913 * fcp_watchdog_time each time the watchdog timer expires. 914 * 915 * fcp_watchdog_timeout 916 * 917 * Increment value of the variable fcp_watchdog_time as well as the 918 * the timeout value of the watchdog timer. The unit is 1 second. It 919 * is strange that this is not a #define but a variable since the code 920 * never changes this value. The reason why it can be said that the 921 * unit is 1 second is because the number of ticks for the watchdog 922 * timer is determined like this: 923 * 924 * fcp_watchdog_tick = fcp_watchdog_timeout * 925 * drv_usectohz(1000000); 926 * 927 * The value 1000000 is hard coded in the code. 928 * 929 * fcp_watchdog_tick 930 * 931 * Watchdog timer value in ticks. 932 */ 933 static int fcp_watchdog_init = 0; 934 static int fcp_watchdog_time = 0; 935 static int fcp_watchdog_timeout = 1; 936 static int fcp_watchdog_tick; 937 938 /* 939 * fcp_offline_delay is a global variable to enable customisation of 940 * the timeout on link offlines or RSCNs. The default value is set 941 * to match FCP_OFFLINE_DELAY (20sec), which is 2*RA_TOV_els as 942 * specified in FCP4 Chapter 11 (see www.t10.org). 943 * 944 * The variable fcp_offline_delay is specified in SECONDS. 945 * 946 * If we made this a static var then the user would not be able to 947 * change it. This variable is set in fcp_attach(). 948 */ 949 unsigned int fcp_offline_delay = FCP_OFFLINE_DELAY; 950 951 static void *fcp_softstate = NULL; /* for soft state */ 952 static uchar_t fcp_oflag = FCP_IDLE; /* open flag */ 953 static kmutex_t fcp_global_mutex; 954 static kmutex_t fcp_ioctl_mutex; 955 static dev_info_t *fcp_global_dip = NULL; 956 static timeout_id_t fcp_watchdog_id; 957 const char *fcp_lun_prop = "lun"; 958 const char *fcp_sam_lun_prop = "sam-lun"; 959 const char *fcp_target_prop = "target"; 960 /* 961 * NOTE: consumers of "node-wwn" property include stmsboot in ON 962 * consolidation. 963 */ 964 const char *fcp_node_wwn_prop = "node-wwn"; 965 const char *fcp_port_wwn_prop = "port-wwn"; 966 const char *fcp_conf_wwn_prop = "fc-port-wwn"; 967 const char *fcp_obp_boot_wwn = "fc-boot-dev-portwwn"; 968 const char *fcp_manual_config_only = "manual_configuration_only"; 969 const char *fcp_init_port_prop = "initiator-port"; 970 const char *fcp_tgt_port_prop = "target-port"; 971 const char *fcp_lun_blacklist_prop = "pwwn-lun-blacklist"; 972 973 static struct fcp_port *fcp_port_head = NULL; 974 static ddi_eventcookie_t fcp_insert_eid; 975 static ddi_eventcookie_t fcp_remove_eid; 976 977 static ndi_event_definition_t fcp_ndi_event_defs[] = { 978 { FCP_EVENT_TAG_INSERT, FCAL_INSERT_EVENT, EPL_KERNEL }, 979 { FCP_EVENT_TAG_REMOVE, FCAL_REMOVE_EVENT, EPL_INTERRUPT } 980 }; 981 982 /* 983 * List of valid commands for the scsi_ioctl call 984 */ 985 static uint8_t scsi_ioctl_list[] = { 986 SCMD_INQUIRY, 987 SCMD_REPORT_LUN, 988 SCMD_READ_CAPACITY 989 }; 990 991 /* 992 * this is used to dummy up a report lun response for cases 993 * where the target doesn't support it 994 */ 995 static uchar_t fcp_dummy_lun[] = { 996 0x00, /* MSB length (length = no of luns * 8) */ 997 0x00, 998 0x00, 999 0x08, /* LSB length */ 1000 0x00, /* MSB reserved */ 1001 0x00, 1002 0x00, 1003 0x00, /* LSB reserved */ 1004 FCP_PD_ADDRESSING, 1005 0x00, /* LUN is ZERO at the first level */ 1006 0x00, 1007 0x00, /* second level is zero */ 1008 0x00, 1009 0x00, /* third level is zero */ 1010 0x00, 1011 0x00 /* fourth level is zero */ 1012 }; 1013 1014 static uchar_t fcp_alpa_to_switch[] = { 1015 0x00, 0x7d, 0x7c, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x7a, 0x00, 1016 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x78, 0x00, 0x00, 0x00, 1017 0x00, 0x00, 0x00, 0x77, 0x76, 0x00, 0x00, 0x75, 0x00, 0x74, 1018 0x73, 0x72, 0x00, 0x00, 0x00, 0x71, 0x00, 0x70, 0x6f, 0x6e, 1019 0x00, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x00, 0x00, 0x67, 1020 0x66, 0x65, 0x64, 0x63, 0x62, 0x00, 0x00, 0x61, 0x60, 0x00, 1021 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x5d, 1022 0x5c, 0x5b, 0x00, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x00, 1023 0x00, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x00, 0x00, 0x4e, 1024 0x4d, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 1025 0x00, 0x4a, 0x49, 0x48, 0x00, 0x47, 0x46, 0x45, 0x44, 0x43, 1026 0x42, 0x00, 0x00, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x00, 1027 0x00, 0x3b, 0x3a, 0x00, 0x39, 0x00, 0x00, 0x00, 0x38, 0x37, 1028 0x36, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 1029 0x00, 0x00, 0x00, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 1030 0x00, 0x31, 0x30, 0x00, 0x00, 0x2f, 0x00, 0x2e, 0x2d, 0x2c, 1031 0x00, 0x00, 0x00, 0x2b, 0x00, 0x2a, 0x29, 0x28, 0x00, 0x27, 1032 0x26, 0x25, 0x24, 0x23, 0x22, 0x00, 0x00, 0x21, 0x20, 0x1f, 1033 0x1e, 0x1d, 0x1c, 0x00, 0x00, 0x1b, 0x1a, 0x00, 0x19, 0x00, 1034 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x17, 0x16, 0x15, 1035 0x00, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x00, 0x00, 0x0e, 1036 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x00, 0x00, 0x08, 0x07, 0x00, 1037 0x06, 0x00, 0x00, 0x00, 0x05, 0x04, 0x03, 0x00, 0x02, 0x00, 1038 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1039 }; 1040 1041 static caddr_t pid = "SESS01 "; 1042 1043 #if !defined(lint) 1044 1045 _NOTE(MUTEX_PROTECTS_DATA(fcp_global_mutex, 1046 fcp_port::fcp_next fcp_watchdog_id)) 1047 1048 _NOTE(DATA_READABLE_WITHOUT_LOCK(fcp_watchdog_time)) 1049 1050 _NOTE(SCHEME_PROTECTS_DATA("Unshared", 1051 fcp_insert_eid 1052 fcp_remove_eid 1053 fcp_watchdog_time)) 1054 1055 _NOTE(SCHEME_PROTECTS_DATA("Unshared", 1056 fcp_cb_ops 1057 fcp_ops 1058 callb_cpr)) 1059 1060 #endif /* lint */ 1061 1062 /* 1063 * This table is used to determine whether or not it's safe to copy in 1064 * the target node name for a lun. Since all luns behind the same target 1065 * have the same wwnn, only tagets that do not support multiple luns are 1066 * eligible to be enumerated under mpxio if they aren't page83 compliant. 1067 */ 1068 1069 char *fcp_symmetric_disk_table[] = { 1070 "SEAGATE ST", 1071 "IBM DDYFT", 1072 "SUNW SUNWGS", /* Daktari enclosure */ 1073 "SUN SENA", /* SES device */ 1074 "SUN SESS01" /* VICOM SVE box */ 1075 }; 1076 1077 int fcp_symmetric_disk_table_size = 1078 sizeof (fcp_symmetric_disk_table)/sizeof (char *); 1079 1080 /* 1081 * The _init(9e) return value should be that of mod_install(9f). Under 1082 * some circumstances, a failure may not be related mod_install(9f) and 1083 * one would then require a return value to indicate the failure. Looking 1084 * at mod_install(9f), it is expected to return 0 for success and non-zero 1085 * for failure. mod_install(9f) for device drivers, further goes down the 1086 * calling chain and ends up in ddi_installdrv(), whose return values are 1087 * DDI_SUCCESS and DDI_FAILURE - There are also other functions in the 1088 * calling chain of mod_install(9f) which return values like EINVAL and 1089 * in some even return -1. 1090 * 1091 * To work around the vagaries of the mod_install() calling chain, return 1092 * either 0 or ENODEV depending on the success or failure of mod_install() 1093 */ 1094 int 1095 _init(void) 1096 { 1097 int rval; 1098 1099 /* 1100 * Allocate soft state and prepare to do ddi_soft_state_zalloc() 1101 * before registering with the transport first. 1102 */ 1103 if (ddi_soft_state_init(&fcp_softstate, 1104 sizeof (struct fcp_port), FCP_INIT_ITEMS) != 0) { 1105 return (EINVAL); 1106 } 1107 1108 mutex_init(&fcp_global_mutex, NULL, MUTEX_DRIVER, NULL); 1109 mutex_init(&fcp_ioctl_mutex, NULL, MUTEX_DRIVER, NULL); 1110 1111 if ((rval = fc_ulp_add(&fcp_modinfo)) != FC_SUCCESS) { 1112 cmn_err(CE_WARN, "fcp: fc_ulp_add failed"); 1113 mutex_destroy(&fcp_global_mutex); 1114 mutex_destroy(&fcp_ioctl_mutex); 1115 ddi_soft_state_fini(&fcp_softstate); 1116 return (ENODEV); 1117 } 1118 1119 fcp_logq = fc_trace_alloc_logq(fcp_log_size); 1120 1121 if ((rval = mod_install(&modlinkage)) != 0) { 1122 fc_trace_free_logq(fcp_logq); 1123 (void) fc_ulp_remove(&fcp_modinfo); 1124 mutex_destroy(&fcp_global_mutex); 1125 mutex_destroy(&fcp_ioctl_mutex); 1126 ddi_soft_state_fini(&fcp_softstate); 1127 rval = ENODEV; 1128 } 1129 1130 return (rval); 1131 } 1132 1133 1134 /* 1135 * the system is done with us as a driver, so clean up 1136 */ 1137 int 1138 _fini(void) 1139 { 1140 int rval; 1141 1142 /* 1143 * don't start cleaning up until we know that the module remove 1144 * has worked -- if this works, then we know that each instance 1145 * has successfully been DDI_DETACHed 1146 */ 1147 if ((rval = mod_remove(&modlinkage)) != 0) { 1148 return (rval); 1149 } 1150 1151 (void) fc_ulp_remove(&fcp_modinfo); 1152 1153 ddi_soft_state_fini(&fcp_softstate); 1154 mutex_destroy(&fcp_global_mutex); 1155 mutex_destroy(&fcp_ioctl_mutex); 1156 fc_trace_free_logq(fcp_logq); 1157 1158 return (rval); 1159 } 1160 1161 1162 int 1163 _info(struct modinfo *modinfop) 1164 { 1165 return (mod_info(&modlinkage, modinfop)); 1166 } 1167 1168 1169 /* 1170 * attach the module 1171 */ 1172 static int 1173 fcp_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 1174 { 1175 int rval = DDI_SUCCESS; 1176 1177 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 1178 FCP_BUF_LEVEL_8, 0, "fcp module attach: cmd=0x%x", cmd); 1179 1180 if (cmd == DDI_ATTACH) { 1181 /* The FCP pseudo device is created here. */ 1182 mutex_enter(&fcp_global_mutex); 1183 fcp_global_dip = devi; 1184 mutex_exit(&fcp_global_mutex); 1185 1186 if (ddi_create_minor_node(fcp_global_dip, "fcp", S_IFCHR, 1187 0, DDI_PSEUDO, 0) == DDI_SUCCESS) { 1188 ddi_report_dev(fcp_global_dip); 1189 } else { 1190 cmn_err(CE_WARN, "FCP: Cannot create minor node"); 1191 mutex_enter(&fcp_global_mutex); 1192 fcp_global_dip = NULL; 1193 mutex_exit(&fcp_global_mutex); 1194 1195 rval = DDI_FAILURE; 1196 } 1197 /* 1198 * We check the fcp_offline_delay property at this 1199 * point. This variable is global for the driver, 1200 * not specific to an instance. 1201 * 1202 * We do not recommend setting the value to less 1203 * than 10 seconds (RA_TOV_els), or greater than 1204 * 60 seconds. 1205 */ 1206 fcp_offline_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 1207 devi, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 1208 "fcp_offline_delay", FCP_OFFLINE_DELAY); 1209 if ((fcp_offline_delay < 10) || 1210 (fcp_offline_delay > 60)) { 1211 cmn_err(CE_WARN, "Setting fcp_offline_delay " 1212 "to %d second(s). This is outside the " 1213 "recommended range of 10..60 seconds.", 1214 fcp_offline_delay); 1215 } 1216 } 1217 1218 return (rval); 1219 } 1220 1221 1222 /*ARGSUSED*/ 1223 static int 1224 fcp_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1225 { 1226 int res = DDI_SUCCESS; 1227 1228 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 1229 FCP_BUF_LEVEL_8, 0, "module detach: cmd=0x%x", cmd); 1230 1231 if (cmd == DDI_DETACH) { 1232 /* 1233 * Check if there are active ports/threads. If there 1234 * are any, we will fail, else we will succeed (there 1235 * should not be much to clean up) 1236 */ 1237 mutex_enter(&fcp_global_mutex); 1238 FCP_DTRACE(fcp_logq, "fcp", 1239 fcp_trace, FCP_BUF_LEVEL_8, 0, "port_head=%p", 1240 (void *) fcp_port_head); 1241 1242 if (fcp_port_head == NULL) { 1243 ddi_remove_minor_node(fcp_global_dip, NULL); 1244 fcp_global_dip = NULL; 1245 mutex_exit(&fcp_global_mutex); 1246 } else { 1247 mutex_exit(&fcp_global_mutex); 1248 res = DDI_FAILURE; 1249 } 1250 } 1251 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 1252 FCP_BUF_LEVEL_8, 0, "module detach returning %d", res); 1253 1254 return (res); 1255 } 1256 1257 1258 /* ARGSUSED */ 1259 static int 1260 fcp_open(dev_t *devp, int flag, int otype, cred_t *credp) 1261 { 1262 if (otype != OTYP_CHR) { 1263 return (EINVAL); 1264 } 1265 1266 /* 1267 * Allow only root to talk; 1268 */ 1269 if (drv_priv(credp)) { 1270 return (EPERM); 1271 } 1272 1273 mutex_enter(&fcp_global_mutex); 1274 if (fcp_oflag & FCP_EXCL) { 1275 mutex_exit(&fcp_global_mutex); 1276 return (EBUSY); 1277 } 1278 1279 if (flag & FEXCL) { 1280 if (fcp_oflag & FCP_OPEN) { 1281 mutex_exit(&fcp_global_mutex); 1282 return (EBUSY); 1283 } 1284 fcp_oflag |= FCP_EXCL; 1285 } 1286 fcp_oflag |= FCP_OPEN; 1287 mutex_exit(&fcp_global_mutex); 1288 1289 return (0); 1290 } 1291 1292 1293 /* ARGSUSED */ 1294 static int 1295 fcp_close(dev_t dev, int flag, int otype, cred_t *credp) 1296 { 1297 if (otype != OTYP_CHR) { 1298 return (EINVAL); 1299 } 1300 1301 mutex_enter(&fcp_global_mutex); 1302 if (!(fcp_oflag & FCP_OPEN)) { 1303 mutex_exit(&fcp_global_mutex); 1304 return (ENODEV); 1305 } 1306 fcp_oflag = FCP_IDLE; 1307 mutex_exit(&fcp_global_mutex); 1308 1309 return (0); 1310 } 1311 1312 1313 /* 1314 * fcp_ioctl 1315 * Entry point for the FCP ioctls 1316 * 1317 * Input: 1318 * See ioctl(9E) 1319 * 1320 * Output: 1321 * See ioctl(9E) 1322 * 1323 * Returns: 1324 * See ioctl(9E) 1325 * 1326 * Context: 1327 * Kernel context. 1328 */ 1329 /* ARGSUSED */ 1330 static int 1331 fcp_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 1332 int *rval) 1333 { 1334 int ret = 0; 1335 1336 mutex_enter(&fcp_global_mutex); 1337 if (!(fcp_oflag & FCP_OPEN)) { 1338 mutex_exit(&fcp_global_mutex); 1339 return (ENXIO); 1340 } 1341 mutex_exit(&fcp_global_mutex); 1342 1343 switch (cmd) { 1344 case FCP_TGT_INQUIRY: 1345 case FCP_TGT_CREATE: 1346 case FCP_TGT_DELETE: 1347 ret = fcp_setup_device_data_ioctl(cmd, 1348 (struct fcp_ioctl *)data, mode, rval); 1349 break; 1350 1351 case FCP_TGT_SEND_SCSI: 1352 mutex_enter(&fcp_ioctl_mutex); 1353 ret = fcp_setup_scsi_ioctl( 1354 (struct fcp_scsi_cmd *)data, mode, rval); 1355 mutex_exit(&fcp_ioctl_mutex); 1356 break; 1357 1358 case FCP_STATE_COUNT: 1359 ret = fcp_get_statec_count((struct fcp_ioctl *)data, 1360 mode, rval); 1361 break; 1362 case FCP_GET_TARGET_MAPPINGS: 1363 ret = fcp_get_target_mappings((struct fcp_ioctl *)data, 1364 mode, rval); 1365 break; 1366 default: 1367 fcp_log(CE_WARN, NULL, 1368 "!Invalid ioctl opcode = 0x%x", cmd); 1369 ret = EINVAL; 1370 } 1371 1372 return (ret); 1373 } 1374 1375 1376 /* 1377 * fcp_setup_device_data_ioctl 1378 * Setup handler for the "device data" style of 1379 * ioctl for FCP. See "fcp_util.h" for data structure 1380 * definition. 1381 * 1382 * Input: 1383 * cmd = FCP ioctl command 1384 * data = ioctl data 1385 * mode = See ioctl(9E) 1386 * 1387 * Output: 1388 * data = ioctl data 1389 * rval = return value - see ioctl(9E) 1390 * 1391 * Returns: 1392 * See ioctl(9E) 1393 * 1394 * Context: 1395 * Kernel context. 1396 */ 1397 /* ARGSUSED */ 1398 static int 1399 fcp_setup_device_data_ioctl(int cmd, struct fcp_ioctl *data, int mode, 1400 int *rval) 1401 { 1402 struct fcp_port *pptr; 1403 struct device_data *dev_data; 1404 uint32_t link_cnt; 1405 la_wwn_t *wwn_ptr = NULL; 1406 struct fcp_tgt *ptgt = NULL; 1407 struct fcp_lun *plun = NULL; 1408 int i, error; 1409 struct fcp_ioctl fioctl; 1410 1411 #ifdef _MULTI_DATAMODEL 1412 switch (ddi_model_convert_from(mode & FMODELS)) { 1413 case DDI_MODEL_ILP32: { 1414 struct fcp32_ioctl f32_ioctl; 1415 1416 if (ddi_copyin((void *)data, (void *)&f32_ioctl, 1417 sizeof (struct fcp32_ioctl), mode)) { 1418 return (EFAULT); 1419 } 1420 fioctl.fp_minor = f32_ioctl.fp_minor; 1421 fioctl.listlen = f32_ioctl.listlen; 1422 fioctl.list = (caddr_t)(long)f32_ioctl.list; 1423 break; 1424 } 1425 case DDI_MODEL_NONE: 1426 if (ddi_copyin((void *)data, (void *)&fioctl, 1427 sizeof (struct fcp_ioctl), mode)) { 1428 return (EFAULT); 1429 } 1430 break; 1431 } 1432 1433 #else /* _MULTI_DATAMODEL */ 1434 if (ddi_copyin((void *)data, (void *)&fioctl, 1435 sizeof (struct fcp_ioctl), mode)) { 1436 return (EFAULT); 1437 } 1438 #endif /* _MULTI_DATAMODEL */ 1439 1440 /* 1441 * Right now we can assume that the minor number matches with 1442 * this instance of fp. If this changes we will need to 1443 * revisit this logic. 1444 */ 1445 mutex_enter(&fcp_global_mutex); 1446 pptr = fcp_port_head; 1447 while (pptr) { 1448 if (pptr->port_instance == (uint32_t)fioctl.fp_minor) { 1449 break; 1450 } else { 1451 pptr = pptr->port_next; 1452 } 1453 } 1454 mutex_exit(&fcp_global_mutex); 1455 if (pptr == NULL) { 1456 return (ENXIO); 1457 } 1458 mutex_enter(&pptr->port_mutex); 1459 1460 1461 if ((dev_data = kmem_zalloc((sizeof (struct device_data)) * 1462 fioctl.listlen, KM_NOSLEEP)) == NULL) { 1463 mutex_exit(&pptr->port_mutex); 1464 return (ENOMEM); 1465 } 1466 1467 if (ddi_copyin(fioctl.list, dev_data, 1468 (sizeof (struct device_data)) * fioctl.listlen, mode)) { 1469 kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen); 1470 mutex_exit(&pptr->port_mutex); 1471 return (EFAULT); 1472 } 1473 link_cnt = pptr->port_link_cnt; 1474 1475 if (cmd == FCP_TGT_INQUIRY) { 1476 wwn_ptr = (la_wwn_t *)&(dev_data[0].dev_pwwn); 1477 if (bcmp(wwn_ptr->raw_wwn, pptr->port_pwwn.raw_wwn, 1478 sizeof (wwn_ptr->raw_wwn)) == 0) { 1479 /* This ioctl is requesting INQ info of local HBA */ 1480 mutex_exit(&pptr->port_mutex); 1481 dev_data[0].dev0_type = DTYPE_UNKNOWN; 1482 dev_data[0].dev_status = 0; 1483 if (ddi_copyout(dev_data, fioctl.list, 1484 (sizeof (struct device_data)) * fioctl.listlen, 1485 mode)) { 1486 kmem_free(dev_data, 1487 sizeof (*dev_data) * fioctl.listlen); 1488 return (EFAULT); 1489 } 1490 kmem_free(dev_data, 1491 sizeof (*dev_data) * fioctl.listlen); 1492 #ifdef _MULTI_DATAMODEL 1493 switch (ddi_model_convert_from(mode & FMODELS)) { 1494 case DDI_MODEL_ILP32: { 1495 struct fcp32_ioctl f32_ioctl; 1496 f32_ioctl.fp_minor = fioctl.fp_minor; 1497 f32_ioctl.listlen = fioctl.listlen; 1498 f32_ioctl.list = (caddr32_t)(long)fioctl.list; 1499 if (ddi_copyout((void *)&f32_ioctl, 1500 (void *)data, 1501 sizeof (struct fcp32_ioctl), mode)) { 1502 return (EFAULT); 1503 } 1504 break; 1505 } 1506 case DDI_MODEL_NONE: 1507 if (ddi_copyout((void *)&fioctl, (void *)data, 1508 sizeof (struct fcp_ioctl), mode)) { 1509 return (EFAULT); 1510 } 1511 break; 1512 } 1513 #else /* _MULTI_DATAMODEL */ 1514 if (ddi_copyout((void *)&fioctl, (void *)data, 1515 sizeof (struct fcp_ioctl), mode)) { 1516 return (EFAULT); 1517 } 1518 #endif /* _MULTI_DATAMODEL */ 1519 return (0); 1520 } 1521 } 1522 1523 if (pptr->port_state & (FCP_STATE_INIT | FCP_STATE_OFFLINE)) { 1524 kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen); 1525 mutex_exit(&pptr->port_mutex); 1526 return (ENXIO); 1527 } 1528 1529 for (i = 0; (i < fioctl.listlen) && (link_cnt == pptr->port_link_cnt); 1530 i++) { 1531 wwn_ptr = (la_wwn_t *)&(dev_data[i].dev_pwwn); 1532 1533 dev_data[i].dev0_type = DTYPE_UNKNOWN; 1534 1535 1536 dev_data[i].dev_status = ENXIO; 1537 1538 if ((ptgt = fcp_lookup_target(pptr, 1539 (uchar_t *)wwn_ptr)) == NULL) { 1540 mutex_exit(&pptr->port_mutex); 1541 if (fc_ulp_get_remote_port(pptr->port_fp_handle, 1542 wwn_ptr, &error, 0) == NULL) { 1543 dev_data[i].dev_status = ENODEV; 1544 mutex_enter(&pptr->port_mutex); 1545 continue; 1546 } else { 1547 1548 dev_data[i].dev_status = EAGAIN; 1549 1550 mutex_enter(&pptr->port_mutex); 1551 continue; 1552 } 1553 } else { 1554 mutex_enter(&ptgt->tgt_mutex); 1555 if (ptgt->tgt_state & (FCP_TGT_MARK | 1556 FCP_TGT_BUSY)) { 1557 dev_data[i].dev_status = EAGAIN; 1558 mutex_exit(&ptgt->tgt_mutex); 1559 continue; 1560 } 1561 1562 if (ptgt->tgt_state & FCP_TGT_OFFLINE) { 1563 if (ptgt->tgt_icap && !ptgt->tgt_tcap) { 1564 dev_data[i].dev_status = ENOTSUP; 1565 } else { 1566 dev_data[i].dev_status = ENXIO; 1567 } 1568 mutex_exit(&ptgt->tgt_mutex); 1569 continue; 1570 } 1571 1572 switch (cmd) { 1573 case FCP_TGT_INQUIRY: 1574 /* 1575 * The reason we give device type of 1576 * lun 0 only even though in some 1577 * cases(like maxstrat) lun 0 device 1578 * type may be 0x3f(invalid) is that 1579 * for bridge boxes target will appear 1580 * as luns and the first lun could be 1581 * a device that utility may not care 1582 * about (like a tape device). 1583 */ 1584 dev_data[i].dev_lun_cnt = ptgt->tgt_lun_cnt; 1585 dev_data[i].dev_status = 0; 1586 mutex_exit(&ptgt->tgt_mutex); 1587 1588 if ((plun = fcp_get_lun(ptgt, 0)) == NULL) { 1589 dev_data[i].dev0_type = DTYPE_UNKNOWN; 1590 } else { 1591 dev_data[i].dev0_type = plun->lun_type; 1592 } 1593 mutex_enter(&ptgt->tgt_mutex); 1594 break; 1595 1596 case FCP_TGT_CREATE: 1597 mutex_exit(&ptgt->tgt_mutex); 1598 mutex_exit(&pptr->port_mutex); 1599 1600 /* 1601 * serialize state change call backs. 1602 * only one call back will be handled 1603 * at a time. 1604 */ 1605 mutex_enter(&fcp_global_mutex); 1606 if (fcp_oflag & FCP_BUSY) { 1607 mutex_exit(&fcp_global_mutex); 1608 if (dev_data) { 1609 kmem_free(dev_data, 1610 sizeof (*dev_data) * 1611 fioctl.listlen); 1612 } 1613 return (EBUSY); 1614 } 1615 fcp_oflag |= FCP_BUSY; 1616 mutex_exit(&fcp_global_mutex); 1617 1618 dev_data[i].dev_status = 1619 fcp_create_on_demand(pptr, 1620 wwn_ptr->raw_wwn); 1621 1622 if (dev_data[i].dev_status != 0) { 1623 char buf[25]; 1624 1625 for (i = 0; i < FC_WWN_SIZE; i++) { 1626 (void) sprintf(&buf[i << 1], 1627 "%02x", 1628 wwn_ptr->raw_wwn[i]); 1629 } 1630 1631 fcp_log(CE_WARN, pptr->port_dip, 1632 "!Failed to create nodes for" 1633 " pwwn=%s; error=%x", buf, 1634 dev_data[i].dev_status); 1635 } 1636 1637 /* allow state change call backs again */ 1638 mutex_enter(&fcp_global_mutex); 1639 fcp_oflag &= ~FCP_BUSY; 1640 mutex_exit(&fcp_global_mutex); 1641 1642 mutex_enter(&pptr->port_mutex); 1643 mutex_enter(&ptgt->tgt_mutex); 1644 1645 break; 1646 1647 case FCP_TGT_DELETE: 1648 break; 1649 1650 default: 1651 fcp_log(CE_WARN, pptr->port_dip, 1652 "!Invalid device data ioctl " 1653 "opcode = 0x%x", cmd); 1654 } 1655 mutex_exit(&ptgt->tgt_mutex); 1656 } 1657 } 1658 mutex_exit(&pptr->port_mutex); 1659 1660 if (ddi_copyout(dev_data, fioctl.list, 1661 (sizeof (struct device_data)) * fioctl.listlen, mode)) { 1662 kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen); 1663 return (EFAULT); 1664 } 1665 kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen); 1666 1667 #ifdef _MULTI_DATAMODEL 1668 switch (ddi_model_convert_from(mode & FMODELS)) { 1669 case DDI_MODEL_ILP32: { 1670 struct fcp32_ioctl f32_ioctl; 1671 1672 f32_ioctl.fp_minor = fioctl.fp_minor; 1673 f32_ioctl.listlen = fioctl.listlen; 1674 f32_ioctl.list = (caddr32_t)(long)fioctl.list; 1675 if (ddi_copyout((void *)&f32_ioctl, (void *)data, 1676 sizeof (struct fcp32_ioctl), mode)) { 1677 return (EFAULT); 1678 } 1679 break; 1680 } 1681 case DDI_MODEL_NONE: 1682 if (ddi_copyout((void *)&fioctl, (void *)data, 1683 sizeof (struct fcp_ioctl), mode)) { 1684 return (EFAULT); 1685 } 1686 break; 1687 } 1688 #else /* _MULTI_DATAMODEL */ 1689 1690 if (ddi_copyout((void *)&fioctl, (void *)data, 1691 sizeof (struct fcp_ioctl), mode)) { 1692 return (EFAULT); 1693 } 1694 #endif /* _MULTI_DATAMODEL */ 1695 1696 return (0); 1697 } 1698 1699 /* 1700 * Fetch the target mappings (path, etc.) for all LUNs 1701 * on this port. 1702 */ 1703 /* ARGSUSED */ 1704 static int 1705 fcp_get_target_mappings(struct fcp_ioctl *data, 1706 int mode, int *rval) 1707 { 1708 struct fcp_port *pptr; 1709 fc_hba_target_mappings_t *mappings; 1710 fc_hba_mapping_entry_t *map; 1711 struct fcp_tgt *ptgt = NULL; 1712 struct fcp_lun *plun = NULL; 1713 int i, mapIndex, mappingSize; 1714 int listlen; 1715 struct fcp_ioctl fioctl; 1716 char *path; 1717 fcp_ent_addr_t sam_lun_addr; 1718 1719 #ifdef _MULTI_DATAMODEL 1720 switch (ddi_model_convert_from(mode & FMODELS)) { 1721 case DDI_MODEL_ILP32: { 1722 struct fcp32_ioctl f32_ioctl; 1723 1724 if (ddi_copyin((void *)data, (void *)&f32_ioctl, 1725 sizeof (struct fcp32_ioctl), mode)) { 1726 return (EFAULT); 1727 } 1728 fioctl.fp_minor = f32_ioctl.fp_minor; 1729 fioctl.listlen = f32_ioctl.listlen; 1730 fioctl.list = (caddr_t)(long)f32_ioctl.list; 1731 break; 1732 } 1733 case DDI_MODEL_NONE: 1734 if (ddi_copyin((void *)data, (void *)&fioctl, 1735 sizeof (struct fcp_ioctl), mode)) { 1736 return (EFAULT); 1737 } 1738 break; 1739 } 1740 1741 #else /* _MULTI_DATAMODEL */ 1742 if (ddi_copyin((void *)data, (void *)&fioctl, 1743 sizeof (struct fcp_ioctl), mode)) { 1744 return (EFAULT); 1745 } 1746 #endif /* _MULTI_DATAMODEL */ 1747 1748 /* 1749 * Right now we can assume that the minor number matches with 1750 * this instance of fp. If this changes we will need to 1751 * revisit this logic. 1752 */ 1753 mutex_enter(&fcp_global_mutex); 1754 pptr = fcp_port_head; 1755 while (pptr) { 1756 if (pptr->port_instance == (uint32_t)fioctl.fp_minor) { 1757 break; 1758 } else { 1759 pptr = pptr->port_next; 1760 } 1761 } 1762 mutex_exit(&fcp_global_mutex); 1763 if (pptr == NULL) { 1764 cmn_err(CE_NOTE, "target mappings: unknown instance number: %d", 1765 fioctl.fp_minor); 1766 return (ENXIO); 1767 } 1768 1769 1770 /* We use listlen to show the total buffer size */ 1771 mappingSize = fioctl.listlen; 1772 1773 /* Now calculate how many mapping entries will fit */ 1774 listlen = fioctl.listlen + sizeof (fc_hba_mapping_entry_t) 1775 - sizeof (fc_hba_target_mappings_t); 1776 if (listlen <= 0) { 1777 cmn_err(CE_NOTE, "target mappings: Insufficient buffer"); 1778 return (ENXIO); 1779 } 1780 listlen = listlen / sizeof (fc_hba_mapping_entry_t); 1781 1782 if ((mappings = kmem_zalloc(mappingSize, KM_SLEEP)) == NULL) { 1783 return (ENOMEM); 1784 } 1785 mappings->version = FC_HBA_TARGET_MAPPINGS_VERSION; 1786 1787 /* Now get to work */ 1788 mapIndex = 0; 1789 1790 mutex_enter(&pptr->port_mutex); 1791 /* Loop through all targets on this port */ 1792 for (i = 0; i < FCP_NUM_HASH; i++) { 1793 for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL; 1794 ptgt = ptgt->tgt_next) { 1795 1796 1797 /* Loop through all LUNs on this target */ 1798 for (plun = ptgt->tgt_lun; plun != NULL; 1799 plun = plun->lun_next) { 1800 if (plun->lun_state & FCP_LUN_OFFLINE) { 1801 continue; 1802 } 1803 1804 path = fcp_get_lun_path(plun); 1805 if (path == NULL) { 1806 continue; 1807 } 1808 1809 if (mapIndex >= listlen) { 1810 mapIndex ++; 1811 kmem_free(path, MAXPATHLEN); 1812 continue; 1813 } 1814 map = &mappings->entries[mapIndex++]; 1815 bcopy(path, map->targetDriver, 1816 sizeof (map->targetDriver)); 1817 map->d_id = ptgt->tgt_d_id; 1818 map->busNumber = 0; 1819 map->targetNumber = ptgt->tgt_d_id; 1820 map->osLUN = plun->lun_num; 1821 1822 /* 1823 * We had swapped lun when we stored it in 1824 * lun_addr. We need to swap it back before 1825 * returning it to user land 1826 */ 1827 1828 sam_lun_addr.ent_addr_0 = 1829 BE_16(plun->lun_addr.ent_addr_0); 1830 sam_lun_addr.ent_addr_1 = 1831 BE_16(plun->lun_addr.ent_addr_1); 1832 sam_lun_addr.ent_addr_2 = 1833 BE_16(plun->lun_addr.ent_addr_2); 1834 sam_lun_addr.ent_addr_3 = 1835 BE_16(plun->lun_addr.ent_addr_3); 1836 1837 bcopy(&sam_lun_addr, &map->samLUN, 1838 FCP_LUN_SIZE); 1839 bcopy(ptgt->tgt_node_wwn.raw_wwn, 1840 map->NodeWWN.raw_wwn, sizeof (la_wwn_t)); 1841 bcopy(ptgt->tgt_port_wwn.raw_wwn, 1842 map->PortWWN.raw_wwn, sizeof (la_wwn_t)); 1843 1844 if (plun->lun_guid) { 1845 1846 /* convert ascii wwn to bytes */ 1847 fcp_ascii_to_wwn(plun->lun_guid, 1848 map->guid, sizeof (map->guid)); 1849 1850 if ((sizeof (map->guid)) < 1851 plun->lun_guid_size / 2) { 1852 cmn_err(CE_WARN, 1853 "fcp_get_target_mappings:" 1854 "guid copy space " 1855 "insufficient." 1856 "Copy Truncation - " 1857 "available %d; need %d", 1858 (int)sizeof (map->guid), 1859 (int) 1860 plun->lun_guid_size / 2); 1861 } 1862 } 1863 kmem_free(path, MAXPATHLEN); 1864 } 1865 } 1866 } 1867 mutex_exit(&pptr->port_mutex); 1868 mappings->numLuns = mapIndex; 1869 1870 if (ddi_copyout(mappings, fioctl.list, mappingSize, mode)) { 1871 kmem_free(mappings, mappingSize); 1872 return (EFAULT); 1873 } 1874 kmem_free(mappings, mappingSize); 1875 1876 #ifdef _MULTI_DATAMODEL 1877 switch (ddi_model_convert_from(mode & FMODELS)) { 1878 case DDI_MODEL_ILP32: { 1879 struct fcp32_ioctl f32_ioctl; 1880 1881 f32_ioctl.fp_minor = fioctl.fp_minor; 1882 f32_ioctl.listlen = fioctl.listlen; 1883 f32_ioctl.list = (caddr32_t)(long)fioctl.list; 1884 if (ddi_copyout((void *)&f32_ioctl, (void *)data, 1885 sizeof (struct fcp32_ioctl), mode)) { 1886 return (EFAULT); 1887 } 1888 break; 1889 } 1890 case DDI_MODEL_NONE: 1891 if (ddi_copyout((void *)&fioctl, (void *)data, 1892 sizeof (struct fcp_ioctl), mode)) { 1893 return (EFAULT); 1894 } 1895 break; 1896 } 1897 #else /* _MULTI_DATAMODEL */ 1898 1899 if (ddi_copyout((void *)&fioctl, (void *)data, 1900 sizeof (struct fcp_ioctl), mode)) { 1901 return (EFAULT); 1902 } 1903 #endif /* _MULTI_DATAMODEL */ 1904 1905 return (0); 1906 } 1907 1908 /* 1909 * fcp_setup_scsi_ioctl 1910 * Setup handler for the "scsi passthru" style of 1911 * ioctl for FCP. See "fcp_util.h" for data structure 1912 * definition. 1913 * 1914 * Input: 1915 * u_fscsi = ioctl data (user address space) 1916 * mode = See ioctl(9E) 1917 * 1918 * Output: 1919 * u_fscsi = ioctl data (user address space) 1920 * rval = return value - see ioctl(9E) 1921 * 1922 * Returns: 1923 * 0 = OK 1924 * EAGAIN = See errno.h 1925 * EBUSY = See errno.h 1926 * EFAULT = See errno.h 1927 * EINTR = See errno.h 1928 * EINVAL = See errno.h 1929 * EIO = See errno.h 1930 * ENOMEM = See errno.h 1931 * ENXIO = See errno.h 1932 * 1933 * Context: 1934 * Kernel context. 1935 */ 1936 /* ARGSUSED */ 1937 static int 1938 fcp_setup_scsi_ioctl(struct fcp_scsi_cmd *u_fscsi, 1939 int mode, int *rval) 1940 { 1941 int ret = 0; 1942 int temp_ret; 1943 caddr_t k_cdbbufaddr = NULL; 1944 caddr_t k_bufaddr = NULL; 1945 caddr_t k_rqbufaddr = NULL; 1946 caddr_t u_cdbbufaddr; 1947 caddr_t u_bufaddr; 1948 caddr_t u_rqbufaddr; 1949 struct fcp_scsi_cmd k_fscsi; 1950 1951 /* 1952 * Get fcp_scsi_cmd array element from user address space 1953 */ 1954 if ((ret = fcp_copyin_scsi_cmd((caddr_t)u_fscsi, &k_fscsi, mode)) 1955 != 0) { 1956 return (ret); 1957 } 1958 1959 1960 /* 1961 * Even though kmem_alloc() checks the validity of the 1962 * buffer length, this check is needed when the 1963 * kmem_flags set and the zero buffer length is passed. 1964 */ 1965 if ((k_fscsi.scsi_cdblen <= 0) || 1966 (k_fscsi.scsi_buflen <= 0) || 1967 (k_fscsi.scsi_buflen > FCP_MAX_RESPONSE_LEN) || 1968 (k_fscsi.scsi_rqlen <= 0) || 1969 (k_fscsi.scsi_rqlen > FCP_MAX_SENSE_LEN)) { 1970 return (EINVAL); 1971 } 1972 1973 /* 1974 * Allocate data for fcp_scsi_cmd pointer fields 1975 */ 1976 if (ret == 0) { 1977 k_cdbbufaddr = kmem_alloc(k_fscsi.scsi_cdblen, KM_NOSLEEP); 1978 k_bufaddr = kmem_alloc(k_fscsi.scsi_buflen, KM_NOSLEEP); 1979 k_rqbufaddr = kmem_alloc(k_fscsi.scsi_rqlen, KM_NOSLEEP); 1980 1981 if (k_cdbbufaddr == NULL || 1982 k_bufaddr == NULL || 1983 k_rqbufaddr == NULL) { 1984 ret = ENOMEM; 1985 } 1986 } 1987 1988 /* 1989 * Get fcp_scsi_cmd pointer fields from user 1990 * address space 1991 */ 1992 if (ret == 0) { 1993 u_cdbbufaddr = k_fscsi.scsi_cdbbufaddr; 1994 u_bufaddr = k_fscsi.scsi_bufaddr; 1995 u_rqbufaddr = k_fscsi.scsi_rqbufaddr; 1996 1997 if (ddi_copyin(u_cdbbufaddr, 1998 k_cdbbufaddr, 1999 k_fscsi.scsi_cdblen, 2000 mode)) { 2001 ret = EFAULT; 2002 } else if (ddi_copyin(u_bufaddr, 2003 k_bufaddr, 2004 k_fscsi.scsi_buflen, 2005 mode)) { 2006 ret = EFAULT; 2007 } else if (ddi_copyin(u_rqbufaddr, 2008 k_rqbufaddr, 2009 k_fscsi.scsi_rqlen, 2010 mode)) { 2011 ret = EFAULT; 2012 } 2013 } 2014 2015 /* 2016 * Send scsi command (blocking) 2017 */ 2018 if (ret == 0) { 2019 /* 2020 * Prior to sending the scsi command, the 2021 * fcp_scsi_cmd data structure must contain kernel, 2022 * not user, addresses. 2023 */ 2024 k_fscsi.scsi_cdbbufaddr = k_cdbbufaddr; 2025 k_fscsi.scsi_bufaddr = k_bufaddr; 2026 k_fscsi.scsi_rqbufaddr = k_rqbufaddr; 2027 2028 ret = fcp_send_scsi_ioctl(&k_fscsi); 2029 2030 /* 2031 * After sending the scsi command, the 2032 * fcp_scsi_cmd data structure must contain user, 2033 * not kernel, addresses. 2034 */ 2035 k_fscsi.scsi_cdbbufaddr = u_cdbbufaddr; 2036 k_fscsi.scsi_bufaddr = u_bufaddr; 2037 k_fscsi.scsi_rqbufaddr = u_rqbufaddr; 2038 } 2039 2040 /* 2041 * Put fcp_scsi_cmd pointer fields to user address space 2042 */ 2043 if (ret == 0) { 2044 if (ddi_copyout(k_cdbbufaddr, 2045 u_cdbbufaddr, 2046 k_fscsi.scsi_cdblen, 2047 mode)) { 2048 ret = EFAULT; 2049 } else if (ddi_copyout(k_bufaddr, 2050 u_bufaddr, 2051 k_fscsi.scsi_buflen, 2052 mode)) { 2053 ret = EFAULT; 2054 } else if (ddi_copyout(k_rqbufaddr, 2055 u_rqbufaddr, 2056 k_fscsi.scsi_rqlen, 2057 mode)) { 2058 ret = EFAULT; 2059 } 2060 } 2061 2062 /* 2063 * Free data for fcp_scsi_cmd pointer fields 2064 */ 2065 if (k_cdbbufaddr != NULL) { 2066 kmem_free(k_cdbbufaddr, k_fscsi.scsi_cdblen); 2067 } 2068 if (k_bufaddr != NULL) { 2069 kmem_free(k_bufaddr, k_fscsi.scsi_buflen); 2070 } 2071 if (k_rqbufaddr != NULL) { 2072 kmem_free(k_rqbufaddr, k_fscsi.scsi_rqlen); 2073 } 2074 2075 /* 2076 * Put fcp_scsi_cmd array element to user address space 2077 */ 2078 temp_ret = fcp_copyout_scsi_cmd(&k_fscsi, (caddr_t)u_fscsi, mode); 2079 if (temp_ret != 0) { 2080 ret = temp_ret; 2081 } 2082 2083 /* 2084 * Return status 2085 */ 2086 return (ret); 2087 } 2088 2089 2090 /* 2091 * fcp_copyin_scsi_cmd 2092 * Copy in fcp_scsi_cmd data structure from user address space. 2093 * The data may be in 32 bit or 64 bit modes. 2094 * 2095 * Input: 2096 * base_addr = from address (user address space) 2097 * mode = See ioctl(9E) and ddi_copyin(9F) 2098 * 2099 * Output: 2100 * fscsi = to address (kernel address space) 2101 * 2102 * Returns: 2103 * 0 = OK 2104 * EFAULT = Error 2105 * 2106 * Context: 2107 * Kernel context. 2108 */ 2109 static int 2110 fcp_copyin_scsi_cmd(caddr_t base_addr, struct fcp_scsi_cmd *fscsi, int mode) 2111 { 2112 #ifdef _MULTI_DATAMODEL 2113 struct fcp32_scsi_cmd f32scsi; 2114 2115 switch (ddi_model_convert_from(mode & FMODELS)) { 2116 case DDI_MODEL_ILP32: 2117 /* 2118 * Copy data from user address space 2119 */ 2120 if (ddi_copyin((void *)base_addr, 2121 &f32scsi, 2122 sizeof (struct fcp32_scsi_cmd), 2123 mode)) { 2124 return (EFAULT); 2125 } 2126 /* 2127 * Convert from 32 bit to 64 bit 2128 */ 2129 FCP32_SCSI_CMD_TO_FCP_SCSI_CMD(&f32scsi, fscsi); 2130 break; 2131 case DDI_MODEL_NONE: 2132 /* 2133 * Copy data from user address space 2134 */ 2135 if (ddi_copyin((void *)base_addr, 2136 fscsi, 2137 sizeof (struct fcp_scsi_cmd), 2138 mode)) { 2139 return (EFAULT); 2140 } 2141 break; 2142 } 2143 #else /* _MULTI_DATAMODEL */ 2144 /* 2145 * Copy data from user address space 2146 */ 2147 if (ddi_copyin((void *)base_addr, 2148 fscsi, 2149 sizeof (struct fcp_scsi_cmd), 2150 mode)) { 2151 return (EFAULT); 2152 } 2153 #endif /* _MULTI_DATAMODEL */ 2154 2155 return (0); 2156 } 2157 2158 2159 /* 2160 * fcp_copyout_scsi_cmd 2161 * Copy out fcp_scsi_cmd data structure to user address space. 2162 * The data may be in 32 bit or 64 bit modes. 2163 * 2164 * Input: 2165 * fscsi = to address (kernel address space) 2166 * mode = See ioctl(9E) and ddi_copyin(9F) 2167 * 2168 * Output: 2169 * base_addr = from address (user address space) 2170 * 2171 * Returns: 2172 * 0 = OK 2173 * EFAULT = Error 2174 * 2175 * Context: 2176 * Kernel context. 2177 */ 2178 static int 2179 fcp_copyout_scsi_cmd(struct fcp_scsi_cmd *fscsi, caddr_t base_addr, int mode) 2180 { 2181 #ifdef _MULTI_DATAMODEL 2182 struct fcp32_scsi_cmd f32scsi; 2183 2184 switch (ddi_model_convert_from(mode & FMODELS)) { 2185 case DDI_MODEL_ILP32: 2186 /* 2187 * Convert from 64 bit to 32 bit 2188 */ 2189 FCP_SCSI_CMD_TO_FCP32_SCSI_CMD(fscsi, &f32scsi); 2190 /* 2191 * Copy data to user address space 2192 */ 2193 if (ddi_copyout(&f32scsi, 2194 (void *)base_addr, 2195 sizeof (struct fcp32_scsi_cmd), 2196 mode)) { 2197 return (EFAULT); 2198 } 2199 break; 2200 case DDI_MODEL_NONE: 2201 /* 2202 * Copy data to user address space 2203 */ 2204 if (ddi_copyout(fscsi, 2205 (void *)base_addr, 2206 sizeof (struct fcp_scsi_cmd), 2207 mode)) { 2208 return (EFAULT); 2209 } 2210 break; 2211 } 2212 #else /* _MULTI_DATAMODEL */ 2213 /* 2214 * Copy data to user address space 2215 */ 2216 if (ddi_copyout(fscsi, 2217 (void *)base_addr, 2218 sizeof (struct fcp_scsi_cmd), 2219 mode)) { 2220 return (EFAULT); 2221 } 2222 #endif /* _MULTI_DATAMODEL */ 2223 2224 return (0); 2225 } 2226 2227 2228 /* 2229 * fcp_send_scsi_ioctl 2230 * Sends the SCSI command in blocking mode. 2231 * 2232 * Input: 2233 * fscsi = SCSI command data structure 2234 * 2235 * Output: 2236 * fscsi = SCSI command data structure 2237 * 2238 * Returns: 2239 * 0 = OK 2240 * EAGAIN = See errno.h 2241 * EBUSY = See errno.h 2242 * EINTR = See errno.h 2243 * EINVAL = See errno.h 2244 * EIO = See errno.h 2245 * ENOMEM = See errno.h 2246 * ENXIO = See errno.h 2247 * 2248 * Context: 2249 * Kernel context. 2250 */ 2251 static int 2252 fcp_send_scsi_ioctl(struct fcp_scsi_cmd *fscsi) 2253 { 2254 struct fcp_lun *plun = NULL; 2255 struct fcp_port *pptr = NULL; 2256 struct fcp_tgt *ptgt = NULL; 2257 fc_packet_t *fpkt = NULL; 2258 struct fcp_ipkt *icmd = NULL; 2259 int target_created = FALSE; 2260 fc_frame_hdr_t *hp; 2261 struct fcp_cmd fcp_cmd; 2262 struct fcp_cmd *fcmd; 2263 union scsi_cdb *scsi_cdb; 2264 la_wwn_t *wwn_ptr; 2265 int nodma; 2266 struct fcp_rsp *rsp; 2267 struct fcp_rsp_info *rsp_info; 2268 caddr_t rsp_sense; 2269 int buf_len; 2270 int info_len; 2271 int sense_len; 2272 struct scsi_extended_sense *sense_to = NULL; 2273 timeout_id_t tid; 2274 uint8_t reconfig_lun = FALSE; 2275 uint8_t reconfig_pending = FALSE; 2276 uint8_t scsi_cmd; 2277 int rsp_len; 2278 int cmd_index; 2279 int fc_status; 2280 int pkt_state; 2281 int pkt_action; 2282 int pkt_reason; 2283 int ret, xport_retval = ~FC_SUCCESS; 2284 int lcount; 2285 int tcount; 2286 int reconfig_status; 2287 int port_busy = FALSE; 2288 uchar_t *lun_string; 2289 2290 /* 2291 * Check valid SCSI command 2292 */ 2293 scsi_cmd = ((uint8_t *)fscsi->scsi_cdbbufaddr)[0]; 2294 ret = EINVAL; 2295 for (cmd_index = 0; 2296 cmd_index < FCP_NUM_ELEMENTS(scsi_ioctl_list) && 2297 ret != 0; 2298 cmd_index++) { 2299 /* 2300 * First byte of CDB is the SCSI command 2301 */ 2302 if (scsi_ioctl_list[cmd_index] == scsi_cmd) { 2303 ret = 0; 2304 } 2305 } 2306 2307 /* 2308 * Check inputs 2309 */ 2310 if (fscsi->scsi_flags != FCP_SCSI_READ) { 2311 ret = EINVAL; 2312 } else if (fscsi->scsi_cdblen > FCP_CDB_SIZE) { 2313 /* no larger than */ 2314 ret = EINVAL; 2315 } 2316 2317 2318 /* 2319 * Find FC port 2320 */ 2321 if (ret == 0) { 2322 /* 2323 * Acquire global mutex 2324 */ 2325 mutex_enter(&fcp_global_mutex); 2326 2327 pptr = fcp_port_head; 2328 while (pptr) { 2329 if (pptr->port_instance == 2330 (uint32_t)fscsi->scsi_fc_port_num) { 2331 break; 2332 } else { 2333 pptr = pptr->port_next; 2334 } 2335 } 2336 2337 if (pptr == NULL) { 2338 ret = ENXIO; 2339 } else { 2340 /* 2341 * fc_ulp_busy_port can raise power 2342 * so, we must not hold any mutexes involved in PM 2343 */ 2344 mutex_exit(&fcp_global_mutex); 2345 ret = fc_ulp_busy_port(pptr->port_fp_handle); 2346 } 2347 2348 if (ret == 0) { 2349 2350 /* remember port is busy, so we will release later */ 2351 port_busy = TRUE; 2352 2353 /* 2354 * If there is a reconfiguration in progress, wait 2355 * for it to complete. 2356 */ 2357 2358 fcp_reconfig_wait(pptr); 2359 2360 /* reacquire mutexes in order */ 2361 mutex_enter(&fcp_global_mutex); 2362 mutex_enter(&pptr->port_mutex); 2363 2364 /* 2365 * Will port accept DMA? 2366 */ 2367 nodma = (pptr->port_fcp_dma == FC_NO_DVMA_SPACE) 2368 ? 1 : 0; 2369 2370 /* 2371 * If init or offline, device not known 2372 * 2373 * If we are discovering (onlining), we can 2374 * NOT obviously provide reliable data about 2375 * devices until it is complete 2376 */ 2377 if (pptr->port_state & (FCP_STATE_INIT | 2378 FCP_STATE_OFFLINE)) { 2379 ret = ENXIO; 2380 } else if (pptr->port_state & FCP_STATE_ONLINING) { 2381 ret = EBUSY; 2382 } else { 2383 /* 2384 * Find target from pwwn 2385 * 2386 * The wwn must be put into a local 2387 * variable to ensure alignment. 2388 */ 2389 wwn_ptr = (la_wwn_t *)&(fscsi->scsi_fc_pwwn); 2390 ptgt = fcp_lookup_target(pptr, 2391 (uchar_t *)wwn_ptr); 2392 2393 /* 2394 * If target not found, 2395 */ 2396 if (ptgt == NULL) { 2397 /* 2398 * Note: Still have global & 2399 * port mutexes 2400 */ 2401 mutex_exit(&pptr->port_mutex); 2402 ptgt = fcp_port_create_tgt(pptr, 2403 wwn_ptr, &ret, &fc_status, 2404 &pkt_state, &pkt_action, 2405 &pkt_reason); 2406 mutex_enter(&pptr->port_mutex); 2407 2408 fscsi->scsi_fc_status = fc_status; 2409 fscsi->scsi_pkt_state = 2410 (uchar_t)pkt_state; 2411 fscsi->scsi_pkt_reason = pkt_reason; 2412 fscsi->scsi_pkt_action = 2413 (uchar_t)pkt_action; 2414 2415 if (ptgt != NULL) { 2416 target_created = TRUE; 2417 } else if (ret == 0) { 2418 ret = ENOMEM; 2419 } 2420 } 2421 2422 if (ret == 0) { 2423 /* 2424 * Acquire target 2425 */ 2426 mutex_enter(&ptgt->tgt_mutex); 2427 2428 /* 2429 * If target is mark or busy, 2430 * then target can not be used 2431 */ 2432 if (ptgt->tgt_state & 2433 (FCP_TGT_MARK | 2434 FCP_TGT_BUSY)) { 2435 ret = EBUSY; 2436 } else { 2437 /* 2438 * Mark target as busy 2439 */ 2440 ptgt->tgt_state |= 2441 FCP_TGT_BUSY; 2442 } 2443 2444 /* 2445 * Release target 2446 */ 2447 lcount = pptr->port_link_cnt; 2448 tcount = ptgt->tgt_change_cnt; 2449 mutex_exit(&ptgt->tgt_mutex); 2450 } 2451 } 2452 2453 /* 2454 * Release port 2455 */ 2456 mutex_exit(&pptr->port_mutex); 2457 } 2458 2459 /* 2460 * Release global mutex 2461 */ 2462 mutex_exit(&fcp_global_mutex); 2463 } 2464 2465 if (ret == 0) { 2466 uint64_t belun = BE_64(fscsi->scsi_lun); 2467 2468 /* 2469 * If it's a target device, find lun from pwwn 2470 * The wwn must be put into a local 2471 * variable to ensure alignment. 2472 */ 2473 mutex_enter(&pptr->port_mutex); 2474 wwn_ptr = (la_wwn_t *)&(fscsi->scsi_fc_pwwn); 2475 if (!ptgt->tgt_tcap && ptgt->tgt_icap) { 2476 /* this is not a target */ 2477 fscsi->scsi_fc_status = FC_DEVICE_NOT_TGT; 2478 ret = ENXIO; 2479 } else if ((belun << 16) != 0) { 2480 /* 2481 * Since fcp only support PD and LU addressing method 2482 * so far, the last 6 bytes of a valid LUN are expected 2483 * to be filled with 00h. 2484 */ 2485 fscsi->scsi_fc_status = FC_INVALID_LUN; 2486 cmn_err(CE_WARN, "fcp: Unsupported LUN addressing" 2487 " method 0x%02x with LUN number 0x%016" PRIx64, 2488 (uint8_t)(belun >> 62), belun); 2489 ret = ENXIO; 2490 } else if ((plun = fcp_lookup_lun(pptr, (uchar_t *)wwn_ptr, 2491 (uint16_t)((belun >> 48) & 0x3fff))) == NULL) { 2492 /* 2493 * This is a SCSI target, but no LUN at this 2494 * address. 2495 * 2496 * In the future, we may want to send this to 2497 * the target, and let it respond 2498 * appropriately 2499 */ 2500 ret = ENXIO; 2501 } 2502 mutex_exit(&pptr->port_mutex); 2503 } 2504 2505 /* 2506 * Finished grabbing external resources 2507 * Allocate internal packet (icmd) 2508 */ 2509 if (ret == 0) { 2510 /* 2511 * Calc rsp len assuming rsp info included 2512 */ 2513 rsp_len = sizeof (struct fcp_rsp) + 2514 sizeof (struct fcp_rsp_info) + fscsi->scsi_rqlen; 2515 2516 icmd = fcp_icmd_alloc(pptr, ptgt, 2517 sizeof (struct fcp_cmd), 2518 rsp_len, 2519 fscsi->scsi_buflen, 2520 nodma, 2521 lcount, /* ipkt_link_cnt */ 2522 tcount, /* ipkt_change_cnt */ 2523 0, /* cause */ 2524 FC_INVALID_RSCN_COUNT); /* invalidate the count */ 2525 2526 if (icmd == NULL) { 2527 ret = ENOMEM; 2528 } else { 2529 /* 2530 * Setup internal packet as sema sync 2531 */ 2532 fcp_ipkt_sema_init(icmd); 2533 } 2534 } 2535 2536 if (ret == 0) { 2537 /* 2538 * Init fpkt pointer for use. 2539 */ 2540 2541 fpkt = icmd->ipkt_fpkt; 2542 2543 fpkt->pkt_tran_flags = FC_TRAN_CLASS3 | FC_TRAN_INTR; 2544 fpkt->pkt_tran_type = FC_PKT_FCP_READ; /* only rd for now */ 2545 fpkt->pkt_timeout = fscsi->scsi_timeout; 2546 2547 /* 2548 * Init fcmd pointer for use by SCSI command 2549 */ 2550 2551 if (nodma) { 2552 fcmd = (struct fcp_cmd *)fpkt->pkt_cmd; 2553 } else { 2554 fcmd = &fcp_cmd; 2555 } 2556 bzero(fcmd, sizeof (struct fcp_cmd)); 2557 ptgt = plun->lun_tgt; 2558 2559 lun_string = (uchar_t *)&fscsi->scsi_lun; 2560 2561 fcmd->fcp_ent_addr.ent_addr_0 = 2562 BE_16(*(uint16_t *)&(lun_string[0])); 2563 fcmd->fcp_ent_addr.ent_addr_1 = 2564 BE_16(*(uint16_t *)&(lun_string[2])); 2565 fcmd->fcp_ent_addr.ent_addr_2 = 2566 BE_16(*(uint16_t *)&(lun_string[4])); 2567 fcmd->fcp_ent_addr.ent_addr_3 = 2568 BE_16(*(uint16_t *)&(lun_string[6])); 2569 2570 /* 2571 * Setup internal packet(icmd) 2572 */ 2573 icmd->ipkt_lun = plun; 2574 icmd->ipkt_restart = 0; 2575 icmd->ipkt_retries = 0; 2576 icmd->ipkt_opcode = 0; 2577 2578 /* 2579 * Init the frame HEADER Pointer for use 2580 */ 2581 hp = &fpkt->pkt_cmd_fhdr; 2582 2583 hp->s_id = pptr->port_id; 2584 hp->d_id = ptgt->tgt_d_id; 2585 hp->r_ctl = R_CTL_COMMAND; 2586 hp->type = FC_TYPE_SCSI_FCP; 2587 hp->f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ; 2588 hp->rsvd = 0; 2589 hp->seq_id = 0; 2590 hp->seq_cnt = 0; 2591 hp->ox_id = 0xffff; 2592 hp->rx_id = 0xffff; 2593 hp->ro = 0; 2594 2595 fcmd->fcp_cntl.cntl_qtype = FCP_QTYPE_SIMPLE; 2596 fcmd->fcp_cntl.cntl_read_data = 1; /* only rd for now */ 2597 fcmd->fcp_cntl.cntl_write_data = 0; 2598 fcmd->fcp_data_len = fscsi->scsi_buflen; 2599 2600 scsi_cdb = (union scsi_cdb *)fcmd->fcp_cdb; 2601 bcopy((char *)fscsi->scsi_cdbbufaddr, (char *)scsi_cdb, 2602 fscsi->scsi_cdblen); 2603 2604 if (!nodma) { 2605 FCP_CP_OUT((uint8_t *)fcmd, fpkt->pkt_cmd, 2606 fpkt->pkt_cmd_acc, sizeof (struct fcp_cmd)); 2607 } 2608 2609 /* 2610 * Send SCSI command to FC transport 2611 */ 2612 2613 if (ret == 0) { 2614 mutex_enter(&ptgt->tgt_mutex); 2615 2616 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 2617 mutex_exit(&ptgt->tgt_mutex); 2618 fscsi->scsi_fc_status = xport_retval = 2619 fc_ulp_transport(pptr->port_fp_handle, 2620 fpkt); 2621 if (fscsi->scsi_fc_status != FC_SUCCESS) { 2622 ret = EIO; 2623 } 2624 } else { 2625 mutex_exit(&ptgt->tgt_mutex); 2626 ret = EBUSY; 2627 } 2628 } 2629 } 2630 2631 /* 2632 * Wait for completion only if fc_ulp_transport was called and it 2633 * returned a success. This is the only time callback will happen. 2634 * Otherwise, there is no point in waiting 2635 */ 2636 if ((ret == 0) && (xport_retval == FC_SUCCESS)) { 2637 ret = fcp_ipkt_sema_wait(icmd); 2638 } 2639 2640 /* 2641 * Copy data to IOCTL data structures 2642 */ 2643 rsp = NULL; 2644 if ((ret == 0) && (xport_retval == FC_SUCCESS)) { 2645 rsp = (struct fcp_rsp *)fpkt->pkt_resp; 2646 2647 if (fcp_validate_fcp_response(rsp, pptr) != FC_SUCCESS) { 2648 fcp_log(CE_WARN, pptr->port_dip, 2649 "!SCSI command to d_id=0x%x lun=0x%x" 2650 " failed, Bad FCP response values:" 2651 " rsvd1=%x, rsvd2=%x, sts-rsvd1=%x," 2652 " sts-rsvd2=%x, rsplen=%x, senselen=%x", 2653 ptgt->tgt_d_id, plun->lun_num, 2654 rsp->reserved_0, rsp->reserved_1, 2655 rsp->fcp_u.fcp_status.reserved_0, 2656 rsp->fcp_u.fcp_status.reserved_1, 2657 rsp->fcp_response_len, rsp->fcp_sense_len); 2658 2659 ret = EIO; 2660 } 2661 } 2662 2663 if ((ret == 0) && (rsp != NULL)) { 2664 /* 2665 * Calc response lengths 2666 */ 2667 sense_len = 0; 2668 info_len = 0; 2669 2670 if (rsp->fcp_u.fcp_status.rsp_len_set) { 2671 info_len = rsp->fcp_response_len; 2672 } 2673 2674 rsp_info = (struct fcp_rsp_info *) 2675 ((uint8_t *)rsp + sizeof (struct fcp_rsp)); 2676 2677 /* 2678 * Get SCSI status 2679 */ 2680 fscsi->scsi_bufstatus = rsp->fcp_u.fcp_status.scsi_status; 2681 /* 2682 * If a lun was just added or removed and the next command 2683 * comes through this interface, we need to capture the check 2684 * condition so we can discover the new topology. 2685 */ 2686 if (fscsi->scsi_bufstatus != STATUS_GOOD && 2687 rsp->fcp_u.fcp_status.sense_len_set) { 2688 sense_len = rsp->fcp_sense_len; 2689 rsp_sense = (caddr_t)((uint8_t *)rsp_info + info_len); 2690 sense_to = (struct scsi_extended_sense *)rsp_sense; 2691 if ((FCP_SENSE_REPORTLUN_CHANGED(sense_to)) || 2692 (FCP_SENSE_NO_LUN(sense_to))) { 2693 reconfig_lun = TRUE; 2694 } 2695 } 2696 2697 if (fscsi->scsi_bufstatus == STATUS_GOOD && (ptgt != NULL) && 2698 (reconfig_lun || (scsi_cdb->scc_cmd == SCMD_REPORT_LUN))) { 2699 if (reconfig_lun == FALSE) { 2700 reconfig_status = 2701 fcp_is_reconfig_needed(ptgt, fpkt); 2702 } 2703 2704 if ((reconfig_lun == TRUE) || 2705 (reconfig_status == TRUE)) { 2706 mutex_enter(&ptgt->tgt_mutex); 2707 if (ptgt->tgt_tid == NULL) { 2708 /* 2709 * Either we've been notified the 2710 * REPORT_LUN data has changed, or 2711 * we've determined on our own that 2712 * we're out of date. Kick off 2713 * rediscovery. 2714 */ 2715 tid = timeout(fcp_reconfigure_luns, 2716 (caddr_t)ptgt, drv_usectohz(1)); 2717 2718 ptgt->tgt_tid = tid; 2719 ptgt->tgt_state |= FCP_TGT_BUSY; 2720 ret = EBUSY; 2721 reconfig_pending = TRUE; 2722 } 2723 mutex_exit(&ptgt->tgt_mutex); 2724 } 2725 } 2726 2727 /* 2728 * Calc residuals and buffer lengths 2729 */ 2730 2731 if (ret == 0) { 2732 buf_len = fscsi->scsi_buflen; 2733 fscsi->scsi_bufresid = 0; 2734 if (rsp->fcp_u.fcp_status.resid_under) { 2735 if (rsp->fcp_resid <= fscsi->scsi_buflen) { 2736 fscsi->scsi_bufresid = rsp->fcp_resid; 2737 } else { 2738 cmn_err(CE_WARN, "fcp: bad residue %x " 2739 "for txfer len %x", rsp->fcp_resid, 2740 fscsi->scsi_buflen); 2741 fscsi->scsi_bufresid = 2742 fscsi->scsi_buflen; 2743 } 2744 buf_len -= fscsi->scsi_bufresid; 2745 } 2746 if (rsp->fcp_u.fcp_status.resid_over) { 2747 fscsi->scsi_bufresid = -rsp->fcp_resid; 2748 } 2749 2750 fscsi->scsi_rqresid = fscsi->scsi_rqlen - sense_len; 2751 if (fscsi->scsi_rqlen < sense_len) { 2752 sense_len = fscsi->scsi_rqlen; 2753 } 2754 2755 fscsi->scsi_fc_rspcode = 0; 2756 if (rsp->fcp_u.fcp_status.rsp_len_set) { 2757 fscsi->scsi_fc_rspcode = rsp_info->rsp_code; 2758 } 2759 fscsi->scsi_pkt_state = fpkt->pkt_state; 2760 fscsi->scsi_pkt_action = fpkt->pkt_action; 2761 fscsi->scsi_pkt_reason = fpkt->pkt_reason; 2762 2763 /* 2764 * Copy data and request sense 2765 * 2766 * Data must be copied by using the FCP_CP_IN macro. 2767 * This will ensure the proper byte order since the data 2768 * is being copied directly from the memory mapped 2769 * device register. 2770 * 2771 * The response (and request sense) will be in the 2772 * correct byte order. No special copy is necessary. 2773 */ 2774 2775 if (buf_len) { 2776 FCP_CP_IN(fpkt->pkt_data, 2777 fscsi->scsi_bufaddr, 2778 fpkt->pkt_data_acc, 2779 buf_len); 2780 } 2781 bcopy((void *)rsp_sense, 2782 (void *)fscsi->scsi_rqbufaddr, 2783 sense_len); 2784 } 2785 } 2786 2787 /* 2788 * Cleanup transport data structures if icmd was alloc-ed 2789 * So, cleanup happens in the same thread that icmd was alloc-ed 2790 */ 2791 if (icmd != NULL) { 2792 fcp_ipkt_sema_cleanup(icmd); 2793 } 2794 2795 /* restore pm busy/idle status */ 2796 if (port_busy) { 2797 fc_ulp_idle_port(pptr->port_fp_handle); 2798 } 2799 2800 /* 2801 * Cleanup target. if a reconfig is pending, don't clear the BUSY 2802 * flag, it'll be cleared when the reconfig is complete. 2803 */ 2804 if ((ptgt != NULL) && !reconfig_pending) { 2805 /* 2806 * If target was created, 2807 */ 2808 if (target_created) { 2809 mutex_enter(&ptgt->tgt_mutex); 2810 ptgt->tgt_state &= ~FCP_TGT_BUSY; 2811 mutex_exit(&ptgt->tgt_mutex); 2812 } else { 2813 /* 2814 * De-mark target as busy 2815 */ 2816 mutex_enter(&ptgt->tgt_mutex); 2817 ptgt->tgt_state &= ~FCP_TGT_BUSY; 2818 mutex_exit(&ptgt->tgt_mutex); 2819 } 2820 } 2821 return (ret); 2822 } 2823 2824 2825 static int 2826 fcp_is_reconfig_needed(struct fcp_tgt *ptgt, 2827 fc_packet_t *fpkt) 2828 { 2829 uchar_t *lun_string; 2830 uint16_t lun_num, i; 2831 int num_luns; 2832 int actual_luns; 2833 int num_masked_luns; 2834 int lun_buflen; 2835 struct fcp_lun *plun = NULL; 2836 struct fcp_reportlun_resp *report_lun; 2837 uint8_t reconfig_needed = FALSE; 2838 uint8_t lun_exists = FALSE; 2839 2840 report_lun = kmem_zalloc(fpkt->pkt_datalen, KM_SLEEP); 2841 2842 FCP_CP_IN(fpkt->pkt_data, report_lun, fpkt->pkt_data_acc, 2843 fpkt->pkt_datalen); 2844 2845 /* get number of luns (which is supplied as LUNS * 8) */ 2846 num_luns = BE_32(report_lun->num_lun) >> 3; 2847 2848 /* 2849 * Figure out exactly how many lun strings our response buffer 2850 * can hold. 2851 */ 2852 lun_buflen = (fpkt->pkt_datalen - 2853 2 * sizeof (uint32_t)) / sizeof (longlong_t); 2854 2855 /* 2856 * Is our response buffer full or not? We don't want to 2857 * potentially walk beyond the number of luns we have. 2858 */ 2859 if (num_luns <= lun_buflen) { 2860 actual_luns = num_luns; 2861 } else { 2862 actual_luns = lun_buflen; 2863 } 2864 2865 mutex_enter(&ptgt->tgt_mutex); 2866 2867 /* Scan each lun to see if we have masked it. */ 2868 num_masked_luns = 0; 2869 if (fcp_lun_blacklist != NULL) { 2870 for (i = 0; i < actual_luns; i++) { 2871 lun_string = (uchar_t *)&(report_lun->lun_string[i]); 2872 switch (lun_string[0] & 0xC0) { 2873 case FCP_LUN_ADDRESSING: 2874 case FCP_PD_ADDRESSING: 2875 case FCP_VOLUME_ADDRESSING: 2876 lun_num = ((lun_string[0] & 0x3F) << 8) 2877 | lun_string[1]; 2878 if (fcp_should_mask(&ptgt->tgt_port_wwn, 2879 lun_num) == TRUE) { 2880 num_masked_luns++; 2881 } 2882 break; 2883 default: 2884 break; 2885 } 2886 } 2887 } 2888 2889 /* 2890 * The quick and easy check. If the number of LUNs reported 2891 * doesn't match the number we currently know about, we need 2892 * to reconfigure. 2893 */ 2894 if (num_luns && num_luns != (ptgt->tgt_lun_cnt + num_masked_luns)) { 2895 mutex_exit(&ptgt->tgt_mutex); 2896 kmem_free(report_lun, fpkt->pkt_datalen); 2897 return (TRUE); 2898 } 2899 2900 /* 2901 * If the quick and easy check doesn't turn up anything, we walk 2902 * the list of luns from the REPORT_LUN response and look for 2903 * any luns we don't know about. If we find one, we know we need 2904 * to reconfigure. We will skip LUNs that are masked because of the 2905 * blacklist. 2906 */ 2907 for (i = 0; i < actual_luns; i++) { 2908 lun_string = (uchar_t *)&(report_lun->lun_string[i]); 2909 lun_exists = FALSE; 2910 switch (lun_string[0] & 0xC0) { 2911 case FCP_LUN_ADDRESSING: 2912 case FCP_PD_ADDRESSING: 2913 case FCP_VOLUME_ADDRESSING: 2914 lun_num = ((lun_string[0] & 0x3F) << 8) | lun_string[1]; 2915 2916 if ((fcp_lun_blacklist != NULL) && (fcp_should_mask( 2917 &ptgt->tgt_port_wwn, lun_num) == TRUE)) { 2918 lun_exists = TRUE; 2919 break; 2920 } 2921 2922 for (plun = ptgt->tgt_lun; plun; 2923 plun = plun->lun_next) { 2924 if (plun->lun_num == lun_num) { 2925 lun_exists = TRUE; 2926 break; 2927 } 2928 } 2929 break; 2930 default: 2931 break; 2932 } 2933 2934 if (lun_exists == FALSE) { 2935 reconfig_needed = TRUE; 2936 break; 2937 } 2938 } 2939 2940 mutex_exit(&ptgt->tgt_mutex); 2941 kmem_free(report_lun, fpkt->pkt_datalen); 2942 2943 return (reconfig_needed); 2944 } 2945 2946 /* 2947 * This function is called by fcp_handle_page83 and uses inquiry response data 2948 * stored in plun->lun_inq to determine whether or not a device is a member of 2949 * the table fcp_symmetric_disk_table_size. We return 0 if it is in the table, 2950 * otherwise 1. 2951 */ 2952 static int 2953 fcp_symmetric_device_probe(struct fcp_lun *plun) 2954 { 2955 struct scsi_inquiry *stdinq = &plun->lun_inq; 2956 char *devidptr; 2957 int i, len; 2958 2959 for (i = 0; i < fcp_symmetric_disk_table_size; i++) { 2960 devidptr = fcp_symmetric_disk_table[i]; 2961 len = (int)strlen(devidptr); 2962 2963 if (bcmp(stdinq->inq_vid, devidptr, len) == 0) { 2964 return (0); 2965 } 2966 } 2967 return (1); 2968 } 2969 2970 2971 /* 2972 * This function is called by fcp_ioctl for the FCP_STATE_COUNT ioctl 2973 * It basically returns the current count of # of state change callbacks 2974 * i.e the value of tgt_change_cnt. 2975 * 2976 * INPUT: 2977 * fcp_ioctl.fp_minor -> The minor # of the fp port 2978 * fcp_ioctl.listlen -> 1 2979 * fcp_ioctl.list -> Pointer to a 32 bit integer 2980 */ 2981 /*ARGSUSED2*/ 2982 static int 2983 fcp_get_statec_count(struct fcp_ioctl *data, int mode, int *rval) 2984 { 2985 int ret; 2986 uint32_t link_cnt; 2987 struct fcp_ioctl fioctl; 2988 struct fcp_port *pptr = NULL; 2989 2990 if ((ret = fcp_copyin_fcp_ioctl_data(data, mode, rval, &fioctl, 2991 &pptr)) != 0) { 2992 return (ret); 2993 } 2994 2995 ASSERT(pptr != NULL); 2996 2997 if (fioctl.listlen != 1) { 2998 return (EINVAL); 2999 } 3000 3001 mutex_enter(&pptr->port_mutex); 3002 if (pptr->port_state & FCP_STATE_OFFLINE) { 3003 mutex_exit(&pptr->port_mutex); 3004 return (ENXIO); 3005 } 3006 3007 /* 3008 * FCP_STATE_INIT is set in 2 cases (not sure why it is overloaded): 3009 * When the fcp initially attaches to the port and there are nothing 3010 * hanging out of the port or if there was a repeat offline state change 3011 * callback (refer fcp_statec_callback() FC_STATE_OFFLINE case). 3012 * In the latter case, port_tmp_cnt will be non-zero and that is how we 3013 * will differentiate the 2 cases. 3014 */ 3015 if ((pptr->port_state & FCP_STATE_INIT) && pptr->port_tmp_cnt) { 3016 mutex_exit(&pptr->port_mutex); 3017 return (ENXIO); 3018 } 3019 3020 link_cnt = pptr->port_link_cnt; 3021 mutex_exit(&pptr->port_mutex); 3022 3023 if (ddi_copyout(&link_cnt, fioctl.list, (sizeof (uint32_t)), mode)) { 3024 return (EFAULT); 3025 } 3026 3027 #ifdef _MULTI_DATAMODEL 3028 switch (ddi_model_convert_from(mode & FMODELS)) { 3029 case DDI_MODEL_ILP32: { 3030 struct fcp32_ioctl f32_ioctl; 3031 3032 f32_ioctl.fp_minor = fioctl.fp_minor; 3033 f32_ioctl.listlen = fioctl.listlen; 3034 f32_ioctl.list = (caddr32_t)(long)fioctl.list; 3035 if (ddi_copyout((void *)&f32_ioctl, (void *)data, 3036 sizeof (struct fcp32_ioctl), mode)) { 3037 return (EFAULT); 3038 } 3039 break; 3040 } 3041 case DDI_MODEL_NONE: 3042 if (ddi_copyout((void *)&fioctl, (void *)data, 3043 sizeof (struct fcp_ioctl), mode)) { 3044 return (EFAULT); 3045 } 3046 break; 3047 } 3048 #else /* _MULTI_DATAMODEL */ 3049 3050 if (ddi_copyout((void *)&fioctl, (void *)data, 3051 sizeof (struct fcp_ioctl), mode)) { 3052 return (EFAULT); 3053 } 3054 #endif /* _MULTI_DATAMODEL */ 3055 3056 return (0); 3057 } 3058 3059 /* 3060 * This function copies the fcp_ioctl structure passed in from user land 3061 * into kernel land. Handles 32 bit applications. 3062 */ 3063 /*ARGSUSED*/ 3064 static int 3065 fcp_copyin_fcp_ioctl_data(struct fcp_ioctl *data, int mode, int *rval, 3066 struct fcp_ioctl *fioctl, struct fcp_port **pptr) 3067 { 3068 struct fcp_port *t_pptr; 3069 3070 #ifdef _MULTI_DATAMODEL 3071 switch (ddi_model_convert_from(mode & FMODELS)) { 3072 case DDI_MODEL_ILP32: { 3073 struct fcp32_ioctl f32_ioctl; 3074 3075 if (ddi_copyin((void *)data, (void *)&f32_ioctl, 3076 sizeof (struct fcp32_ioctl), mode)) { 3077 return (EFAULT); 3078 } 3079 fioctl->fp_minor = f32_ioctl.fp_minor; 3080 fioctl->listlen = f32_ioctl.listlen; 3081 fioctl->list = (caddr_t)(long)f32_ioctl.list; 3082 break; 3083 } 3084 case DDI_MODEL_NONE: 3085 if (ddi_copyin((void *)data, (void *)fioctl, 3086 sizeof (struct fcp_ioctl), mode)) { 3087 return (EFAULT); 3088 } 3089 break; 3090 } 3091 3092 #else /* _MULTI_DATAMODEL */ 3093 if (ddi_copyin((void *)data, (void *)fioctl, 3094 sizeof (struct fcp_ioctl), mode)) { 3095 return (EFAULT); 3096 } 3097 #endif /* _MULTI_DATAMODEL */ 3098 3099 /* 3100 * Right now we can assume that the minor number matches with 3101 * this instance of fp. If this changes we will need to 3102 * revisit this logic. 3103 */ 3104 mutex_enter(&fcp_global_mutex); 3105 t_pptr = fcp_port_head; 3106 while (t_pptr) { 3107 if (t_pptr->port_instance == (uint32_t)fioctl->fp_minor) { 3108 break; 3109 } else { 3110 t_pptr = t_pptr->port_next; 3111 } 3112 } 3113 *pptr = t_pptr; 3114 mutex_exit(&fcp_global_mutex); 3115 if (t_pptr == NULL) { 3116 return (ENXIO); 3117 } 3118 3119 return (0); 3120 } 3121 3122 /* 3123 * Function: fcp_port_create_tgt 3124 * 3125 * Description: As the name suggest this function creates the target context 3126 * specified by the the WWN provided by the caller. If the 3127 * creation goes well and the target is known by fp/fctl a PLOGI 3128 * followed by a PRLI are issued. 3129 * 3130 * Argument: pptr fcp port structure 3131 * pwwn WWN of the target 3132 * ret_val Address of the return code. It could be: 3133 * EIO, ENOMEM or 0. 3134 * fc_status PLOGI or PRLI status completion 3135 * fc_pkt_state PLOGI or PRLI state completion 3136 * fc_pkt_reason PLOGI or PRLI reason completion 3137 * fc_pkt_action PLOGI or PRLI action completion 3138 * 3139 * Return Value: NULL if it failed 3140 * Target structure address if it succeeds 3141 */ 3142 static struct fcp_tgt * 3143 fcp_port_create_tgt(struct fcp_port *pptr, la_wwn_t *pwwn, int *ret_val, 3144 int *fc_status, int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action) 3145 { 3146 struct fcp_tgt *ptgt = NULL; 3147 fc_portmap_t devlist; 3148 int lcount; 3149 int error; 3150 3151 *ret_val = 0; 3152 3153 /* 3154 * Check FC port device & get port map 3155 */ 3156 if (fc_ulp_get_remote_port(pptr->port_fp_handle, pwwn, 3157 &error, 1) == NULL) { 3158 *ret_val = EIO; 3159 } else { 3160 if (fc_ulp_pwwn_to_portmap(pptr->port_fp_handle, pwwn, 3161 &devlist) != FC_SUCCESS) { 3162 *ret_val = EIO; 3163 } 3164 } 3165 3166 /* Set port map flags */ 3167 devlist.map_type = PORT_DEVICE_USER_CREATE; 3168 3169 /* Allocate target */ 3170 if (*ret_val == 0) { 3171 lcount = pptr->port_link_cnt; 3172 ptgt = fcp_alloc_tgt(pptr, &devlist, lcount); 3173 if (ptgt == NULL) { 3174 fcp_log(CE_WARN, pptr->port_dip, 3175 "!FC target allocation failed"); 3176 *ret_val = ENOMEM; 3177 } else { 3178 /* Setup target */ 3179 mutex_enter(&ptgt->tgt_mutex); 3180 3181 ptgt->tgt_statec_cause = FCP_CAUSE_TGT_CHANGE; 3182 ptgt->tgt_tmp_cnt = 1; 3183 ptgt->tgt_d_id = devlist.map_did.port_id; 3184 ptgt->tgt_hard_addr = 3185 devlist.map_hard_addr.hard_addr; 3186 ptgt->tgt_pd_handle = devlist.map_pd; 3187 ptgt->tgt_fca_dev = NULL; 3188 3189 bcopy(&devlist.map_nwwn, &ptgt->tgt_node_wwn.raw_wwn[0], 3190 FC_WWN_SIZE); 3191 bcopy(&devlist.map_pwwn, &ptgt->tgt_port_wwn.raw_wwn[0], 3192 FC_WWN_SIZE); 3193 3194 mutex_exit(&ptgt->tgt_mutex); 3195 } 3196 } 3197 3198 /* Release global mutex for PLOGI and PRLI */ 3199 mutex_exit(&fcp_global_mutex); 3200 3201 /* Send PLOGI (If necessary) */ 3202 if (*ret_val == 0) { 3203 *ret_val = fcp_tgt_send_plogi(ptgt, fc_status, 3204 fc_pkt_state, fc_pkt_reason, fc_pkt_action); 3205 } 3206 3207 /* Send PRLI (If necessary) */ 3208 if (*ret_val == 0) { 3209 *ret_val = fcp_tgt_send_prli(ptgt, fc_status, 3210 fc_pkt_state, fc_pkt_reason, fc_pkt_action); 3211 } 3212 3213 mutex_enter(&fcp_global_mutex); 3214 3215 return (ptgt); 3216 } 3217 3218 /* 3219 * Function: fcp_tgt_send_plogi 3220 * 3221 * Description: This function sends a PLOGI to the target specified by the 3222 * caller and waits till it completes. 3223 * 3224 * Argument: ptgt Target to send the plogi to. 3225 * fc_status Status returned by fp/fctl in the PLOGI request. 3226 * fc_pkt_state State returned by fp/fctl in the PLOGI request. 3227 * fc_pkt_reason Reason returned by fp/fctl in the PLOGI request. 3228 * fc_pkt_action Action returned by fp/fctl in the PLOGI request. 3229 * 3230 * Return Value: 0 3231 * ENOMEM 3232 * EIO 3233 * 3234 * Context: User context. 3235 */ 3236 static int 3237 fcp_tgt_send_plogi(struct fcp_tgt *ptgt, int *fc_status, int *fc_pkt_state, 3238 int *fc_pkt_reason, int *fc_pkt_action) 3239 { 3240 struct fcp_port *pptr; 3241 struct fcp_ipkt *icmd; 3242 struct fc_packet *fpkt; 3243 fc_frame_hdr_t *hp; 3244 struct la_els_logi logi; 3245 int tcount; 3246 int lcount; 3247 int ret, login_retval = ~FC_SUCCESS; 3248 3249 ret = 0; 3250 3251 pptr = ptgt->tgt_port; 3252 3253 lcount = pptr->port_link_cnt; 3254 tcount = ptgt->tgt_change_cnt; 3255 3256 /* Alloc internal packet */ 3257 icmd = fcp_icmd_alloc(pptr, ptgt, sizeof (la_els_logi_t), 3258 sizeof (la_els_logi_t), 0, 0, lcount, tcount, 0, 3259 FC_INVALID_RSCN_COUNT); 3260 3261 if (icmd == NULL) { 3262 ret = ENOMEM; 3263 } else { 3264 /* 3265 * Setup internal packet as sema sync 3266 */ 3267 fcp_ipkt_sema_init(icmd); 3268 3269 /* 3270 * Setup internal packet (icmd) 3271 */ 3272 icmd->ipkt_lun = NULL; 3273 icmd->ipkt_restart = 0; 3274 icmd->ipkt_retries = 0; 3275 icmd->ipkt_opcode = LA_ELS_PLOGI; 3276 3277 /* 3278 * Setup fc_packet 3279 */ 3280 fpkt = icmd->ipkt_fpkt; 3281 3282 fpkt->pkt_tran_flags = FC_TRAN_CLASS3 | FC_TRAN_INTR; 3283 fpkt->pkt_tran_type = FC_PKT_EXCHANGE; 3284 fpkt->pkt_timeout = FCP_ELS_TIMEOUT; 3285 3286 /* 3287 * Setup FC frame header 3288 */ 3289 hp = &fpkt->pkt_cmd_fhdr; 3290 3291 hp->s_id = pptr->port_id; /* source ID */ 3292 hp->d_id = ptgt->tgt_d_id; /* dest ID */ 3293 hp->r_ctl = R_CTL_ELS_REQ; 3294 hp->type = FC_TYPE_EXTENDED_LS; 3295 hp->f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ; 3296 hp->seq_id = 0; 3297 hp->rsvd = 0; 3298 hp->df_ctl = 0; 3299 hp->seq_cnt = 0; 3300 hp->ox_id = 0xffff; /* i.e. none */ 3301 hp->rx_id = 0xffff; /* i.e. none */ 3302 hp->ro = 0; 3303 3304 /* 3305 * Setup PLOGI 3306 */ 3307 bzero(&logi, sizeof (struct la_els_logi)); 3308 logi.ls_code.ls_code = LA_ELS_PLOGI; 3309 3310 FCP_CP_OUT((uint8_t *)&logi, fpkt->pkt_cmd, 3311 fpkt->pkt_cmd_acc, sizeof (struct la_els_logi)); 3312 3313 /* 3314 * Send PLOGI 3315 */ 3316 *fc_status = login_retval = 3317 fc_ulp_login(pptr->port_fp_handle, &fpkt, 1); 3318 if (*fc_status != FC_SUCCESS) { 3319 ret = EIO; 3320 } 3321 } 3322 3323 /* 3324 * Wait for completion 3325 */ 3326 if ((ret == 0) && (login_retval == FC_SUCCESS)) { 3327 ret = fcp_ipkt_sema_wait(icmd); 3328 3329 *fc_pkt_state = fpkt->pkt_state; 3330 *fc_pkt_reason = fpkt->pkt_reason; 3331 *fc_pkt_action = fpkt->pkt_action; 3332 } 3333 3334 /* 3335 * Cleanup transport data structures if icmd was alloc-ed AND if there 3336 * is going to be no callback (i.e if fc_ulp_login() failed). 3337 * Otherwise, cleanup happens in callback routine. 3338 */ 3339 if (icmd != NULL) { 3340 fcp_ipkt_sema_cleanup(icmd); 3341 } 3342 3343 return (ret); 3344 } 3345 3346 /* 3347 * Function: fcp_tgt_send_prli 3348 * 3349 * Description: Does nothing as of today. 3350 * 3351 * Argument: ptgt Target to send the prli to. 3352 * fc_status Status returned by fp/fctl in the PRLI request. 3353 * fc_pkt_state State returned by fp/fctl in the PRLI request. 3354 * fc_pkt_reason Reason returned by fp/fctl in the PRLI request. 3355 * fc_pkt_action Action returned by fp/fctl in the PRLI request. 3356 * 3357 * Return Value: 0 3358 */ 3359 /*ARGSUSED*/ 3360 static int 3361 fcp_tgt_send_prli(struct fcp_tgt *ptgt, int *fc_status, int *fc_pkt_state, 3362 int *fc_pkt_reason, int *fc_pkt_action) 3363 { 3364 return (0); 3365 } 3366 3367 /* 3368 * Function: fcp_ipkt_sema_init 3369 * 3370 * Description: Initializes the semaphore contained in the internal packet. 3371 * 3372 * Argument: icmd Internal packet the semaphore of which must be 3373 * initialized. 3374 * 3375 * Return Value: None 3376 * 3377 * Context: User context only. 3378 */ 3379 static void 3380 fcp_ipkt_sema_init(struct fcp_ipkt *icmd) 3381 { 3382 struct fc_packet *fpkt; 3383 3384 fpkt = icmd->ipkt_fpkt; 3385 3386 /* Create semaphore for sync */ 3387 sema_init(&(icmd->ipkt_sema), 0, NULL, SEMA_DRIVER, NULL); 3388 3389 /* Setup the completion callback */ 3390 fpkt->pkt_comp = fcp_ipkt_sema_callback; 3391 } 3392 3393 /* 3394 * Function: fcp_ipkt_sema_wait 3395 * 3396 * Description: Wait on the semaphore embedded in the internal packet. The 3397 * semaphore is released in the callback. 3398 * 3399 * Argument: icmd Internal packet to wait on for completion. 3400 * 3401 * Return Value: 0 3402 * EIO 3403 * EBUSY 3404 * EAGAIN 3405 * 3406 * Context: User context only. 3407 * 3408 * This function does a conversion between the field pkt_state of the fc_packet 3409 * embedded in the internal packet (icmd) and the code it returns. 3410 */ 3411 static int 3412 fcp_ipkt_sema_wait(struct fcp_ipkt *icmd) 3413 { 3414 struct fc_packet *fpkt; 3415 int ret; 3416 3417 ret = EIO; 3418 fpkt = icmd->ipkt_fpkt; 3419 3420 /* 3421 * Wait on semaphore 3422 */ 3423 sema_p(&(icmd->ipkt_sema)); 3424 3425 /* 3426 * Check the status of the FC packet 3427 */ 3428 switch (fpkt->pkt_state) { 3429 case FC_PKT_SUCCESS: 3430 ret = 0; 3431 break; 3432 case FC_PKT_LOCAL_RJT: 3433 switch (fpkt->pkt_reason) { 3434 case FC_REASON_SEQ_TIMEOUT: 3435 case FC_REASON_RX_BUF_TIMEOUT: 3436 ret = EAGAIN; 3437 break; 3438 case FC_REASON_PKT_BUSY: 3439 ret = EBUSY; 3440 break; 3441 } 3442 break; 3443 case FC_PKT_TIMEOUT: 3444 ret = EAGAIN; 3445 break; 3446 case FC_PKT_LOCAL_BSY: 3447 case FC_PKT_TRAN_BSY: 3448 case FC_PKT_NPORT_BSY: 3449 case FC_PKT_FABRIC_BSY: 3450 ret = EBUSY; 3451 break; 3452 case FC_PKT_LS_RJT: 3453 case FC_PKT_BA_RJT: 3454 switch (fpkt->pkt_reason) { 3455 case FC_REASON_LOGICAL_BSY: 3456 ret = EBUSY; 3457 break; 3458 } 3459 break; 3460 case FC_PKT_FS_RJT: 3461 switch (fpkt->pkt_reason) { 3462 case FC_REASON_FS_LOGICAL_BUSY: 3463 ret = EBUSY; 3464 break; 3465 } 3466 break; 3467 } 3468 3469 return (ret); 3470 } 3471 3472 /* 3473 * Function: fcp_ipkt_sema_callback 3474 * 3475 * Description: Registered as the completion callback function for the FC 3476 * transport when the ipkt semaphore is used for sync. This will 3477 * cleanup the used data structures, if necessary and wake up 3478 * the user thread to complete the transaction. 3479 * 3480 * Argument: fpkt FC packet (points to the icmd) 3481 * 3482 * Return Value: None 3483 * 3484 * Context: User context only 3485 */ 3486 static void 3487 fcp_ipkt_sema_callback(struct fc_packet *fpkt) 3488 { 3489 struct fcp_ipkt *icmd; 3490 3491 icmd = (struct fcp_ipkt *)fpkt->pkt_ulp_private; 3492 3493 /* 3494 * Wake up user thread 3495 */ 3496 sema_v(&(icmd->ipkt_sema)); 3497 } 3498 3499 /* 3500 * Function: fcp_ipkt_sema_cleanup 3501 * 3502 * Description: Called to cleanup (if necessary) the data structures used 3503 * when ipkt sema is used for sync. This function will detect 3504 * whether the caller is the last thread (via counter) and 3505 * cleanup only if necessary. 3506 * 3507 * Argument: icmd Internal command packet 3508 * 3509 * Return Value: None 3510 * 3511 * Context: User context only 3512 */ 3513 static void 3514 fcp_ipkt_sema_cleanup(struct fcp_ipkt *icmd) 3515 { 3516 struct fcp_tgt *ptgt; 3517 struct fcp_port *pptr; 3518 3519 ptgt = icmd->ipkt_tgt; 3520 pptr = icmd->ipkt_port; 3521 3522 /* 3523 * Acquire data structure 3524 */ 3525 mutex_enter(&ptgt->tgt_mutex); 3526 3527 /* 3528 * Destroy semaphore 3529 */ 3530 sema_destroy(&(icmd->ipkt_sema)); 3531 3532 /* 3533 * Cleanup internal packet 3534 */ 3535 mutex_exit(&ptgt->tgt_mutex); 3536 fcp_icmd_free(pptr, icmd); 3537 } 3538 3539 /* 3540 * Function: fcp_port_attach 3541 * 3542 * Description: Called by the transport framework to resume, suspend or 3543 * attach a new port. 3544 * 3545 * Argument: ulph Port handle 3546 * *pinfo Port information 3547 * cmd Command 3548 * s_id Port ID 3549 * 3550 * Return Value: FC_FAILURE or FC_SUCCESS 3551 */ 3552 /*ARGSUSED*/ 3553 static int 3554 fcp_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo, 3555 fc_attach_cmd_t cmd, uint32_t s_id) 3556 { 3557 int instance; 3558 int res = FC_FAILURE; /* default result */ 3559 3560 ASSERT(pinfo != NULL); 3561 3562 instance = ddi_get_instance(pinfo->port_dip); 3563 3564 switch (cmd) { 3565 case FC_CMD_ATTACH: 3566 /* 3567 * this port instance attaching for the first time (or after 3568 * being detached before) 3569 */ 3570 if (fcp_handle_port_attach(ulph, pinfo, s_id, 3571 instance) == DDI_SUCCESS) { 3572 res = FC_SUCCESS; 3573 } else { 3574 ASSERT(ddi_get_soft_state(fcp_softstate, 3575 instance) == NULL); 3576 } 3577 break; 3578 3579 case FC_CMD_RESUME: 3580 case FC_CMD_POWER_UP: 3581 /* 3582 * this port instance was attached and the suspended and 3583 * will now be resumed 3584 */ 3585 if (fcp_handle_port_resume(ulph, pinfo, s_id, cmd, 3586 instance) == DDI_SUCCESS) { 3587 res = FC_SUCCESS; 3588 } 3589 break; 3590 3591 default: 3592 /* shouldn't happen */ 3593 FCP_TRACE(fcp_logq, "fcp", 3594 fcp_trace, FCP_BUF_LEVEL_2, 0, 3595 "port_attach: unknown cmdcommand: %d", cmd); 3596 break; 3597 } 3598 3599 /* return result */ 3600 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 3601 FCP_BUF_LEVEL_1, 0, "fcp_port_attach returning %d", res); 3602 3603 return (res); 3604 } 3605 3606 3607 /* 3608 * detach or suspend this port instance 3609 * 3610 * acquires and releases the global mutex 3611 * 3612 * acquires and releases the mutex for this port 3613 * 3614 * acquires and releases the hotplug mutex for this port 3615 */ 3616 /*ARGSUSED*/ 3617 static int 3618 fcp_port_detach(opaque_t ulph, fc_ulp_port_info_t *info, 3619 fc_detach_cmd_t cmd) 3620 { 3621 int flag; 3622 int instance; 3623 struct fcp_port *pptr; 3624 3625 instance = ddi_get_instance(info->port_dip); 3626 pptr = ddi_get_soft_state(fcp_softstate, instance); 3627 3628 switch (cmd) { 3629 case FC_CMD_SUSPEND: 3630 FCP_DTRACE(fcp_logq, "fcp", 3631 fcp_trace, FCP_BUF_LEVEL_8, 0, 3632 "port suspend called for port %d", instance); 3633 flag = FCP_STATE_SUSPENDED; 3634 break; 3635 3636 case FC_CMD_POWER_DOWN: 3637 FCP_DTRACE(fcp_logq, "fcp", 3638 fcp_trace, FCP_BUF_LEVEL_8, 0, 3639 "port power down called for port %d", instance); 3640 flag = FCP_STATE_POWER_DOWN; 3641 break; 3642 3643 case FC_CMD_DETACH: 3644 FCP_DTRACE(fcp_logq, "fcp", 3645 fcp_trace, FCP_BUF_LEVEL_8, 0, 3646 "port detach called for port %d", instance); 3647 flag = FCP_STATE_DETACHING; 3648 break; 3649 3650 default: 3651 /* shouldn't happen */ 3652 return (FC_FAILURE); 3653 } 3654 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 3655 FCP_BUF_LEVEL_1, 0, "fcp_port_detach returning"); 3656 3657 return (fcp_handle_port_detach(pptr, flag, instance)); 3658 } 3659 3660 3661 /* 3662 * called for ioctls on the transport's devctl interface, and the transport 3663 * has passed it to us 3664 * 3665 * this will only be called for device control ioctls (i.e. hotplugging stuff) 3666 * 3667 * return FC_SUCCESS if we decide to claim the ioctl, 3668 * else return FC_UNCLAIMED 3669 * 3670 * *rval is set iff we decide to claim the ioctl 3671 */ 3672 /*ARGSUSED*/ 3673 static int 3674 fcp_port_ioctl(opaque_t ulph, opaque_t port_handle, dev_t dev, int cmd, 3675 intptr_t data, int mode, cred_t *credp, int *rval, uint32_t claimed) 3676 { 3677 int retval = FC_UNCLAIMED; /* return value */ 3678 struct fcp_port *pptr = NULL; /* our soft state */ 3679 struct devctl_iocdata *dcp = NULL; /* for devctl */ 3680 dev_info_t *cdip; 3681 mdi_pathinfo_t *pip = NULL; 3682 char *ndi_nm; /* NDI name */ 3683 char *ndi_addr; /* NDI addr */ 3684 int is_mpxio, circ; 3685 int devi_entered = 0; 3686 time_t end_time; 3687 3688 ASSERT(rval != NULL); 3689 3690 FCP_DTRACE(fcp_logq, "fcp", 3691 fcp_trace, FCP_BUF_LEVEL_8, 0, 3692 "fcp_port_ioctl(cmd=0x%x, claimed=%d)", cmd, claimed); 3693 3694 /* if already claimed then forget it */ 3695 if (claimed) { 3696 /* 3697 * for now, if this ioctl has already been claimed, then 3698 * we just ignore it 3699 */ 3700 return (retval); 3701 } 3702 3703 /* get our port info */ 3704 if ((pptr = fcp_get_port(port_handle)) == NULL) { 3705 fcp_log(CE_WARN, NULL, 3706 "!fcp:Invalid port handle handle in ioctl"); 3707 *rval = ENXIO; 3708 return (retval); 3709 } 3710 is_mpxio = pptr->port_mpxio; 3711 3712 switch (cmd) { 3713 case DEVCTL_BUS_GETSTATE: 3714 case DEVCTL_BUS_QUIESCE: 3715 case DEVCTL_BUS_UNQUIESCE: 3716 case DEVCTL_BUS_RESET: 3717 case DEVCTL_BUS_RESETALL: 3718 3719 case DEVCTL_BUS_DEV_CREATE: 3720 if (ndi_dc_allochdl((void *)data, &dcp) != NDI_SUCCESS) { 3721 return (retval); 3722 } 3723 break; 3724 3725 case DEVCTL_DEVICE_GETSTATE: 3726 case DEVCTL_DEVICE_OFFLINE: 3727 case DEVCTL_DEVICE_ONLINE: 3728 case DEVCTL_DEVICE_REMOVE: 3729 case DEVCTL_DEVICE_RESET: 3730 if (ndi_dc_allochdl((void *)data, &dcp) != NDI_SUCCESS) { 3731 return (retval); 3732 } 3733 3734 ASSERT(dcp != NULL); 3735 3736 /* ensure we have a name and address */ 3737 if (((ndi_nm = ndi_dc_getname(dcp)) == NULL) || 3738 ((ndi_addr = ndi_dc_getaddr(dcp)) == NULL)) { 3739 FCP_TRACE(fcp_logq, pptr->port_instbuf, 3740 fcp_trace, FCP_BUF_LEVEL_2, 0, 3741 "ioctl: can't get name (%s) or addr (%s)", 3742 ndi_nm ? ndi_nm : "<null ptr>", 3743 ndi_addr ? ndi_addr : "<null ptr>"); 3744 ndi_dc_freehdl(dcp); 3745 return (retval); 3746 } 3747 3748 3749 /* get our child's DIP */ 3750 ASSERT(pptr != NULL); 3751 if (is_mpxio) { 3752 mdi_devi_enter(pptr->port_dip, &circ); 3753 } else { 3754 ndi_devi_enter(pptr->port_dip, &circ); 3755 } 3756 devi_entered = 1; 3757 3758 if ((cdip = ndi_devi_find(pptr->port_dip, ndi_nm, 3759 ndi_addr)) == NULL) { 3760 /* Look for virtually enumerated devices. */ 3761 pip = mdi_pi_find(pptr->port_dip, NULL, ndi_addr); 3762 if (pip == NULL || 3763 ((cdip = mdi_pi_get_client(pip)) == NULL)) { 3764 *rval = ENXIO; 3765 goto out; 3766 } 3767 } 3768 break; 3769 3770 default: 3771 *rval = ENOTTY; 3772 return (retval); 3773 } 3774 3775 /* this ioctl is ours -- process it */ 3776 3777 retval = FC_SUCCESS; /* just means we claim the ioctl */ 3778 3779 /* we assume it will be a success; else we'll set error value */ 3780 *rval = 0; 3781 3782 3783 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 3784 fcp_trace, FCP_BUF_LEVEL_8, 0, 3785 "ioctl: claiming this one"); 3786 3787 /* handle ioctls now */ 3788 switch (cmd) { 3789 case DEVCTL_DEVICE_GETSTATE: 3790 ASSERT(cdip != NULL); 3791 ASSERT(dcp != NULL); 3792 if (ndi_dc_return_dev_state(cdip, dcp) != NDI_SUCCESS) { 3793 *rval = EFAULT; 3794 } 3795 break; 3796 3797 case DEVCTL_DEVICE_REMOVE: 3798 case DEVCTL_DEVICE_OFFLINE: { 3799 int flag = 0; 3800 int lcount; 3801 int tcount; 3802 struct fcp_pkt *head = NULL; 3803 struct fcp_lun *plun; 3804 child_info_t *cip = CIP(cdip); 3805 int all = 1; 3806 struct fcp_lun *tplun; 3807 struct fcp_tgt *ptgt; 3808 3809 ASSERT(pptr != NULL); 3810 ASSERT(cdip != NULL); 3811 3812 mutex_enter(&pptr->port_mutex); 3813 if (pip != NULL) { 3814 cip = CIP(pip); 3815 } 3816 if ((plun = fcp_get_lun_from_cip(pptr, cip)) == NULL) { 3817 mutex_exit(&pptr->port_mutex); 3818 *rval = ENXIO; 3819 break; 3820 } 3821 3822 head = fcp_scan_commands(plun); 3823 if (head != NULL) { 3824 fcp_abort_commands(head, LUN_PORT); 3825 } 3826 lcount = pptr->port_link_cnt; 3827 tcount = plun->lun_tgt->tgt_change_cnt; 3828 mutex_exit(&pptr->port_mutex); 3829 3830 if (cmd == DEVCTL_DEVICE_REMOVE) { 3831 flag = NDI_DEVI_REMOVE; 3832 } 3833 3834 if (is_mpxio) { 3835 mdi_devi_exit(pptr->port_dip, circ); 3836 } else { 3837 ndi_devi_exit(pptr->port_dip, circ); 3838 } 3839 devi_entered = 0; 3840 3841 *rval = fcp_pass_to_hp_and_wait(pptr, plun, cip, 3842 FCP_OFFLINE, lcount, tcount, flag); 3843 3844 if (*rval != NDI_SUCCESS) { 3845 *rval = (*rval == NDI_BUSY) ? EBUSY : EIO; 3846 break; 3847 } 3848 3849 fcp_update_offline_flags(plun); 3850 3851 ptgt = plun->lun_tgt; 3852 mutex_enter(&ptgt->tgt_mutex); 3853 for (tplun = ptgt->tgt_lun; tplun != NULL; tplun = 3854 tplun->lun_next) { 3855 mutex_enter(&tplun->lun_mutex); 3856 if (!(tplun->lun_state & FCP_LUN_OFFLINE)) { 3857 all = 0; 3858 } 3859 mutex_exit(&tplun->lun_mutex); 3860 } 3861 3862 if (all) { 3863 ptgt->tgt_node_state = FCP_TGT_NODE_NONE; 3864 /* 3865 * The user is unconfiguring/offlining the device. 3866 * If fabric and the auto configuration is set 3867 * then make sure the user is the only one who 3868 * can reconfigure the device. 3869 */ 3870 if (FC_TOP_EXTERNAL(pptr->port_topology) && 3871 fcp_enable_auto_configuration) { 3872 ptgt->tgt_manual_config_only = 1; 3873 } 3874 } 3875 mutex_exit(&ptgt->tgt_mutex); 3876 break; 3877 } 3878 3879 case DEVCTL_DEVICE_ONLINE: { 3880 int lcount; 3881 int tcount; 3882 struct fcp_lun *plun; 3883 child_info_t *cip = CIP(cdip); 3884 3885 ASSERT(cdip != NULL); 3886 ASSERT(pptr != NULL); 3887 3888 mutex_enter(&pptr->port_mutex); 3889 if (pip != NULL) { 3890 cip = CIP(pip); 3891 } 3892 if ((plun = fcp_get_lun_from_cip(pptr, cip)) == NULL) { 3893 mutex_exit(&pptr->port_mutex); 3894 *rval = ENXIO; 3895 break; 3896 } 3897 lcount = pptr->port_link_cnt; 3898 tcount = plun->lun_tgt->tgt_change_cnt; 3899 mutex_exit(&pptr->port_mutex); 3900 3901 /* 3902 * The FCP_LUN_ONLINING flag is used in fcp_scsi_start() 3903 * to allow the device attach to occur when the device is 3904 * FCP_LUN_OFFLINE (so we don't reject the INQUIRY command 3905 * from the scsi_probe()). 3906 */ 3907 mutex_enter(&LUN_TGT->tgt_mutex); 3908 plun->lun_state |= FCP_LUN_ONLINING; 3909 mutex_exit(&LUN_TGT->tgt_mutex); 3910 3911 if (is_mpxio) { 3912 mdi_devi_exit(pptr->port_dip, circ); 3913 } else { 3914 ndi_devi_exit(pptr->port_dip, circ); 3915 } 3916 devi_entered = 0; 3917 3918 *rval = fcp_pass_to_hp_and_wait(pptr, plun, cip, 3919 FCP_ONLINE, lcount, tcount, 0); 3920 3921 if (*rval != NDI_SUCCESS) { 3922 /* Reset the FCP_LUN_ONLINING bit */ 3923 mutex_enter(&LUN_TGT->tgt_mutex); 3924 plun->lun_state &= ~FCP_LUN_ONLINING; 3925 mutex_exit(&LUN_TGT->tgt_mutex); 3926 *rval = EIO; 3927 break; 3928 } 3929 mutex_enter(&LUN_TGT->tgt_mutex); 3930 plun->lun_state &= ~(FCP_LUN_OFFLINE | FCP_LUN_BUSY | 3931 FCP_LUN_ONLINING); 3932 mutex_exit(&LUN_TGT->tgt_mutex); 3933 break; 3934 } 3935 3936 case DEVCTL_BUS_DEV_CREATE: { 3937 uchar_t *bytes = NULL; 3938 uint_t nbytes; 3939 struct fcp_tgt *ptgt = NULL; 3940 struct fcp_lun *plun = NULL; 3941 dev_info_t *useless_dip = NULL; 3942 3943 *rval = ndi_dc_devi_create(dcp, pptr->port_dip, 3944 DEVCTL_CONSTRUCT, &useless_dip); 3945 if (*rval != 0 || useless_dip == NULL) { 3946 break; 3947 } 3948 3949 if ((ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, useless_dip, 3950 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, PORT_WWN_PROP, &bytes, 3951 &nbytes) != DDI_PROP_SUCCESS) || nbytes != FC_WWN_SIZE) { 3952 *rval = EINVAL; 3953 (void) ndi_devi_free(useless_dip); 3954 if (bytes != NULL) { 3955 ddi_prop_free(bytes); 3956 } 3957 break; 3958 } 3959 3960 *rval = fcp_create_on_demand(pptr, bytes); 3961 if (*rval == 0) { 3962 mutex_enter(&pptr->port_mutex); 3963 ptgt = fcp_lookup_target(pptr, (uchar_t *)bytes); 3964 if (ptgt) { 3965 /* 3966 * We now have a pointer to the target that 3967 * was created. Lets point to the first LUN on 3968 * this new target. 3969 */ 3970 mutex_enter(&ptgt->tgt_mutex); 3971 3972 plun = ptgt->tgt_lun; 3973 /* 3974 * There may be stale/offline LUN entries on 3975 * this list (this is by design) and so we have 3976 * to make sure we point to the first online 3977 * LUN 3978 */ 3979 while (plun && 3980 plun->lun_state & FCP_LUN_OFFLINE) { 3981 plun = plun->lun_next; 3982 } 3983 3984 mutex_exit(&ptgt->tgt_mutex); 3985 } 3986 mutex_exit(&pptr->port_mutex); 3987 } 3988 3989 if (*rval == 0 && ptgt && plun) { 3990 mutex_enter(&plun->lun_mutex); 3991 /* 3992 * Allow up to fcp_lun_ready_retry seconds to 3993 * configure all the luns behind the target. 3994 * 3995 * The intent here is to allow targets with long 3996 * reboot/reset-recovery times to become available 3997 * while limiting the maximum wait time for an 3998 * unresponsive target. 3999 */ 4000 end_time = ddi_get_lbolt() + 4001 SEC_TO_TICK(fcp_lun_ready_retry); 4002 4003 while (ddi_get_lbolt() < end_time) { 4004 retval = FC_SUCCESS; 4005 4006 /* 4007 * The new ndi interfaces for on-demand creation 4008 * are inflexible, Do some more work to pass on 4009 * a path name of some LUN (design is broken !) 4010 */ 4011 if (plun->lun_cip) { 4012 if (plun->lun_mpxio == 0) { 4013 cdip = DIP(plun->lun_cip); 4014 } else { 4015 cdip = mdi_pi_get_client( 4016 PIP(plun->lun_cip)); 4017 } 4018 if (cdip == NULL) { 4019 *rval = ENXIO; 4020 break; 4021 } 4022 4023 if (!i_ddi_devi_attached(cdip)) { 4024 mutex_exit(&plun->lun_mutex); 4025 delay(drv_usectohz(1000000)); 4026 mutex_enter(&plun->lun_mutex); 4027 } else { 4028 /* 4029 * This Lun is ready, lets 4030 * check the next one. 4031 */ 4032 mutex_exit(&plun->lun_mutex); 4033 plun = plun->lun_next; 4034 while (plun && (plun->lun_state 4035 & FCP_LUN_OFFLINE)) { 4036 plun = plun->lun_next; 4037 } 4038 if (!plun) { 4039 break; 4040 } 4041 mutex_enter(&plun->lun_mutex); 4042 } 4043 } else { 4044 /* 4045 * lun_cip field for a valid lun 4046 * should never be NULL. Fail the 4047 * command. 4048 */ 4049 *rval = ENXIO; 4050 break; 4051 } 4052 } 4053 if (plun) { 4054 mutex_exit(&plun->lun_mutex); 4055 } else { 4056 char devnm[MAXNAMELEN]; 4057 int nmlen; 4058 4059 nmlen = snprintf(devnm, MAXNAMELEN, "%s@%s", 4060 ddi_node_name(cdip), 4061 ddi_get_name_addr(cdip)); 4062 4063 if (copyout(&devnm, dcp->cpyout_buf, nmlen) != 4064 0) { 4065 *rval = EFAULT; 4066 } 4067 } 4068 } else { 4069 int i; 4070 char buf[25]; 4071 4072 for (i = 0; i < FC_WWN_SIZE; i++) { 4073 (void) sprintf(&buf[i << 1], "%02x", bytes[i]); 4074 } 4075 4076 fcp_log(CE_WARN, pptr->port_dip, 4077 "!Failed to create nodes for pwwn=%s; error=%x", 4078 buf, *rval); 4079 } 4080 4081 (void) ndi_devi_free(useless_dip); 4082 ddi_prop_free(bytes); 4083 break; 4084 } 4085 4086 case DEVCTL_DEVICE_RESET: { 4087 struct fcp_lun *plun; 4088 child_info_t *cip = CIP(cdip); 4089 4090 ASSERT(cdip != NULL); 4091 ASSERT(pptr != NULL); 4092 mutex_enter(&pptr->port_mutex); 4093 if (pip != NULL) { 4094 cip = CIP(pip); 4095 } 4096 if ((plun = fcp_get_lun_from_cip(pptr, cip)) == NULL) { 4097 mutex_exit(&pptr->port_mutex); 4098 *rval = ENXIO; 4099 break; 4100 } 4101 mutex_exit(&pptr->port_mutex); 4102 4103 mutex_enter(&plun->lun_tgt->tgt_mutex); 4104 if (!(plun->lun_state & FCP_SCSI_LUN_TGT_INIT)) { 4105 mutex_exit(&plun->lun_tgt->tgt_mutex); 4106 4107 *rval = ENXIO; 4108 break; 4109 } 4110 4111 if (plun->lun_sd == NULL) { 4112 mutex_exit(&plun->lun_tgt->tgt_mutex); 4113 4114 *rval = ENXIO; 4115 break; 4116 } 4117 mutex_exit(&plun->lun_tgt->tgt_mutex); 4118 4119 /* 4120 * set up ap so that fcp_reset can figure out 4121 * which target to reset 4122 */ 4123 if (fcp_scsi_reset(&plun->lun_sd->sd_address, 4124 RESET_TARGET) == FALSE) { 4125 *rval = EIO; 4126 } 4127 break; 4128 } 4129 4130 case DEVCTL_BUS_GETSTATE: 4131 ASSERT(dcp != NULL); 4132 ASSERT(pptr != NULL); 4133 ASSERT(pptr->port_dip != NULL); 4134 if (ndi_dc_return_bus_state(pptr->port_dip, dcp) != 4135 NDI_SUCCESS) { 4136 *rval = EFAULT; 4137 } 4138 break; 4139 4140 case DEVCTL_BUS_QUIESCE: 4141 case DEVCTL_BUS_UNQUIESCE: 4142 *rval = ENOTSUP; 4143 break; 4144 4145 case DEVCTL_BUS_RESET: 4146 case DEVCTL_BUS_RESETALL: 4147 ASSERT(pptr != NULL); 4148 (void) fcp_linkreset(pptr, NULL, KM_SLEEP); 4149 break; 4150 4151 default: 4152 ASSERT(dcp != NULL); 4153 *rval = ENOTTY; 4154 break; 4155 } 4156 4157 /* all done -- clean up and return */ 4158 out: if (devi_entered) { 4159 if (is_mpxio) { 4160 mdi_devi_exit(pptr->port_dip, circ); 4161 } else { 4162 ndi_devi_exit(pptr->port_dip, circ); 4163 } 4164 } 4165 4166 if (dcp != NULL) { 4167 ndi_dc_freehdl(dcp); 4168 } 4169 4170 return (retval); 4171 } 4172 4173 4174 /*ARGSUSED*/ 4175 static int 4176 fcp_els_callback(opaque_t ulph, opaque_t port_handle, fc_unsol_buf_t *buf, 4177 uint32_t claimed) 4178 { 4179 uchar_t r_ctl; 4180 uchar_t ls_code; 4181 struct fcp_port *pptr; 4182 4183 if ((pptr = fcp_get_port(port_handle)) == NULL || claimed) { 4184 return (FC_UNCLAIMED); 4185 } 4186 4187 mutex_enter(&pptr->port_mutex); 4188 if (pptr->port_state & (FCP_STATE_DETACHING | 4189 FCP_STATE_SUSPENDED | FCP_STATE_POWER_DOWN)) { 4190 mutex_exit(&pptr->port_mutex); 4191 return (FC_UNCLAIMED); 4192 } 4193 mutex_exit(&pptr->port_mutex); 4194 4195 r_ctl = buf->ub_frame.r_ctl; 4196 4197 switch (r_ctl & R_CTL_ROUTING) { 4198 case R_CTL_EXTENDED_SVC: 4199 if (r_ctl == R_CTL_ELS_REQ) { 4200 ls_code = buf->ub_buffer[0]; 4201 4202 switch (ls_code) { 4203 case LA_ELS_PRLI: 4204 /* 4205 * We really don't care if something fails. 4206 * If the PRLI was not sent out, then the 4207 * other end will time it out. 4208 */ 4209 if (fcp_unsol_prli(pptr, buf) == FC_SUCCESS) { 4210 return (FC_SUCCESS); 4211 } 4212 return (FC_UNCLAIMED); 4213 /* NOTREACHED */ 4214 4215 default: 4216 break; 4217 } 4218 } 4219 /* FALLTHROUGH */ 4220 4221 default: 4222 return (FC_UNCLAIMED); 4223 } 4224 } 4225 4226 4227 /*ARGSUSED*/ 4228 static int 4229 fcp_data_callback(opaque_t ulph, opaque_t port_handle, fc_unsol_buf_t *buf, 4230 uint32_t claimed) 4231 { 4232 return (FC_UNCLAIMED); 4233 } 4234 4235 /* 4236 * Function: fcp_statec_callback 4237 * 4238 * Description: The purpose of this function is to handle a port state change. 4239 * It is called from fp/fctl and, in a few instances, internally. 4240 * 4241 * Argument: ulph fp/fctl port handle 4242 * port_handle fcp_port structure 4243 * port_state Physical state of the port 4244 * port_top Topology 4245 * *devlist Pointer to the first entry of a table 4246 * containing the remote ports that can be 4247 * reached. 4248 * dev_cnt Number of entries pointed by devlist. 4249 * port_sid Port ID of the local port. 4250 * 4251 * Return Value: None 4252 */ 4253 /*ARGSUSED*/ 4254 static void 4255 fcp_statec_callback(opaque_t ulph, opaque_t port_handle, 4256 uint32_t port_state, uint32_t port_top, fc_portmap_t *devlist, 4257 uint32_t dev_cnt, uint32_t port_sid) 4258 { 4259 uint32_t link_count; 4260 int map_len = 0; 4261 struct fcp_port *pptr; 4262 fcp_map_tag_t *map_tag = NULL; 4263 4264 if ((pptr = fcp_get_port(port_handle)) == NULL) { 4265 fcp_log(CE_WARN, NULL, "!Invalid port handle in callback"); 4266 return; /* nothing to work with! */ 4267 } 4268 4269 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4270 fcp_trace, FCP_BUF_LEVEL_2, 0, 4271 "fcp_statec_callback: port state/dev_cnt/top =" 4272 "%d/%d/%d", FC_PORT_STATE_MASK(port_state), 4273 dev_cnt, port_top); 4274 4275 mutex_enter(&pptr->port_mutex); 4276 4277 /* 4278 * If a thread is in detach, don't do anything. 4279 */ 4280 if (pptr->port_state & (FCP_STATE_DETACHING | 4281 FCP_STATE_SUSPENDED | FCP_STATE_POWER_DOWN)) { 4282 mutex_exit(&pptr->port_mutex); 4283 return; 4284 } 4285 4286 /* 4287 * First thing we do is set the FCP_STATE_IN_CB_DEVC flag so that if 4288 * init_pkt is called, it knows whether or not the target's status 4289 * (or pd) might be changing. 4290 */ 4291 4292 if (FC_PORT_STATE_MASK(port_state) == FC_STATE_DEVICE_CHANGE) { 4293 pptr->port_state |= FCP_STATE_IN_CB_DEVC; 4294 } 4295 4296 /* 4297 * the transport doesn't allocate or probe unless being 4298 * asked to by either the applications or ULPs 4299 * 4300 * in cases where the port is OFFLINE at the time of port 4301 * attach callback and the link comes ONLINE later, for 4302 * easier automatic node creation (i.e. without you having to 4303 * go out and run the utility to perform LOGINs) the 4304 * following conditional is helpful 4305 */ 4306 pptr->port_phys_state = port_state; 4307 4308 if (dev_cnt) { 4309 mutex_exit(&pptr->port_mutex); 4310 4311 map_len = sizeof (*map_tag) * dev_cnt; 4312 map_tag = kmem_alloc(map_len, KM_NOSLEEP); 4313 if (map_tag == NULL) { 4314 fcp_log(CE_WARN, pptr->port_dip, 4315 "!fcp%d: failed to allocate for map tags; " 4316 " state change will not be processed", 4317 pptr->port_instance); 4318 4319 mutex_enter(&pptr->port_mutex); 4320 pptr->port_state &= ~FCP_STATE_IN_CB_DEVC; 4321 mutex_exit(&pptr->port_mutex); 4322 4323 return; 4324 } 4325 4326 mutex_enter(&pptr->port_mutex); 4327 } 4328 4329 if (pptr->port_id != port_sid) { 4330 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4331 fcp_trace, FCP_BUF_LEVEL_3, 0, 4332 "fcp: Port S_ID=0x%x => 0x%x", pptr->port_id, 4333 port_sid); 4334 /* 4335 * The local port changed ID. It is the first time a port ID 4336 * is assigned or something drastic happened. We might have 4337 * been unplugged and replugged on another loop or fabric port 4338 * or somebody grabbed the AL_PA we had or somebody rezoned 4339 * the fabric we were plugged into. 4340 */ 4341 pptr->port_id = port_sid; 4342 } 4343 4344 switch (FC_PORT_STATE_MASK(port_state)) { 4345 case FC_STATE_OFFLINE: 4346 case FC_STATE_RESET_REQUESTED: 4347 /* 4348 * link has gone from online to offline -- just update the 4349 * state of this port to BUSY and MARKed to go offline 4350 */ 4351 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4352 fcp_trace, FCP_BUF_LEVEL_3, 0, 4353 "link went offline"); 4354 if ((pptr->port_state & FCP_STATE_OFFLINE) && dev_cnt) { 4355 /* 4356 * We were offline a while ago and this one 4357 * seems to indicate that the loop has gone 4358 * dead forever. 4359 */ 4360 pptr->port_tmp_cnt += dev_cnt; 4361 pptr->port_state &= ~FCP_STATE_OFFLINE; 4362 pptr->port_state |= FCP_STATE_INIT; 4363 link_count = pptr->port_link_cnt; 4364 fcp_handle_devices(pptr, devlist, dev_cnt, 4365 link_count, map_tag, FCP_CAUSE_LINK_DOWN); 4366 } else { 4367 pptr->port_link_cnt++; 4368 ASSERT(!(pptr->port_state & FCP_STATE_SUSPENDED)); 4369 fcp_update_state(pptr, (FCP_LUN_BUSY | 4370 FCP_LUN_MARK), FCP_CAUSE_LINK_DOWN); 4371 if (pptr->port_mpxio) { 4372 fcp_update_mpxio_path_verifybusy(pptr); 4373 } 4374 pptr->port_state |= FCP_STATE_OFFLINE; 4375 pptr->port_state &= 4376 ~(FCP_STATE_ONLINING | FCP_STATE_ONLINE); 4377 pptr->port_tmp_cnt = 0; 4378 } 4379 mutex_exit(&pptr->port_mutex); 4380 break; 4381 4382 case FC_STATE_ONLINE: 4383 case FC_STATE_LIP: 4384 case FC_STATE_LIP_LBIT_SET: 4385 /* 4386 * link has gone from offline to online 4387 */ 4388 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4389 fcp_trace, FCP_BUF_LEVEL_3, 0, 4390 "link went online"); 4391 4392 pptr->port_link_cnt++; 4393 4394 while (pptr->port_ipkt_cnt) { 4395 mutex_exit(&pptr->port_mutex); 4396 delay(drv_usectohz(1000000)); 4397 mutex_enter(&pptr->port_mutex); 4398 } 4399 4400 pptr->port_topology = port_top; 4401 4402 /* 4403 * The state of the targets and luns accessible through this 4404 * port is updated. 4405 */ 4406 fcp_update_state(pptr, FCP_LUN_BUSY | FCP_LUN_MARK, 4407 FCP_CAUSE_LINK_CHANGE); 4408 4409 pptr->port_state &= ~(FCP_STATE_INIT | FCP_STATE_OFFLINE); 4410 pptr->port_state |= FCP_STATE_ONLINING; 4411 pptr->port_tmp_cnt = dev_cnt; 4412 link_count = pptr->port_link_cnt; 4413 4414 pptr->port_deadline = fcp_watchdog_time + 4415 FCP_ICMD_DEADLINE; 4416 4417 if (!dev_cnt) { 4418 /* 4419 * We go directly to the online state if no remote 4420 * ports were discovered. 4421 */ 4422 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4423 fcp_trace, FCP_BUF_LEVEL_3, 0, 4424 "No remote ports discovered"); 4425 4426 pptr->port_state &= ~FCP_STATE_ONLINING; 4427 pptr->port_state |= FCP_STATE_ONLINE; 4428 } 4429 4430 switch (port_top) { 4431 case FC_TOP_FABRIC: 4432 case FC_TOP_PUBLIC_LOOP: 4433 case FC_TOP_PRIVATE_LOOP: 4434 case FC_TOP_PT_PT: 4435 4436 if (pptr->port_state & FCP_STATE_NS_REG_FAILED) { 4437 fcp_retry_ns_registry(pptr, port_sid); 4438 } 4439 4440 fcp_handle_devices(pptr, devlist, dev_cnt, link_count, 4441 map_tag, FCP_CAUSE_LINK_CHANGE); 4442 break; 4443 4444 default: 4445 /* 4446 * We got here because we were provided with an unknown 4447 * topology. 4448 */ 4449 if (pptr->port_state & FCP_STATE_NS_REG_FAILED) { 4450 pptr->port_state &= ~FCP_STATE_NS_REG_FAILED; 4451 } 4452 4453 pptr->port_tmp_cnt -= dev_cnt; 4454 fcp_log(CE_WARN, pptr->port_dip, 4455 "!unknown/unsupported topology (0x%x)", port_top); 4456 break; 4457 } 4458 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4459 fcp_trace, FCP_BUF_LEVEL_3, 0, 4460 "Notify ssd of the reset to reinstate the reservations"); 4461 4462 scsi_hba_reset_notify_callback(&pptr->port_mutex, 4463 &pptr->port_reset_notify_listf); 4464 4465 mutex_exit(&pptr->port_mutex); 4466 4467 break; 4468 4469 case FC_STATE_RESET: 4470 ASSERT(pptr->port_state & FCP_STATE_OFFLINE); 4471 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4472 fcp_trace, FCP_BUF_LEVEL_3, 0, 4473 "RESET state, waiting for Offline/Online state_cb"); 4474 mutex_exit(&pptr->port_mutex); 4475 break; 4476 4477 case FC_STATE_DEVICE_CHANGE: 4478 /* 4479 * We come here when an application has requested 4480 * Dynamic node creation/deletion in Fabric connectivity. 4481 */ 4482 if (pptr->port_state & (FCP_STATE_OFFLINE | 4483 FCP_STATE_INIT)) { 4484 /* 4485 * This case can happen when the FCTL is in the 4486 * process of giving us on online and the host on 4487 * the other side issues a PLOGI/PLOGO. Ideally 4488 * the state changes should be serialized unless 4489 * they are opposite (online-offline). 4490 * The transport will give us a final state change 4491 * so we can ignore this for the time being. 4492 */ 4493 pptr->port_state &= ~FCP_STATE_IN_CB_DEVC; 4494 mutex_exit(&pptr->port_mutex); 4495 break; 4496 } 4497 4498 if (pptr->port_state & FCP_STATE_NS_REG_FAILED) { 4499 fcp_retry_ns_registry(pptr, port_sid); 4500 } 4501 4502 /* 4503 * Extend the deadline under steady state conditions 4504 * to provide more time for the device-change-commands 4505 */ 4506 if (!pptr->port_ipkt_cnt) { 4507 pptr->port_deadline = fcp_watchdog_time + 4508 FCP_ICMD_DEADLINE; 4509 } 4510 4511 /* 4512 * There is another race condition here, where if we were 4513 * in ONLINEING state and a devices in the map logs out, 4514 * fp will give another state change as DEVICE_CHANGE 4515 * and OLD. This will result in that target being offlined. 4516 * The pd_handle is freed. If from the first statec callback 4517 * we were going to fire a PLOGI/PRLI, the system will 4518 * panic in fc_ulp_transport with invalid pd_handle. 4519 * The fix is to check for the link_cnt before issuing 4520 * any command down. 4521 */ 4522 fcp_update_targets(pptr, devlist, dev_cnt, 4523 FCP_LUN_BUSY | FCP_LUN_MARK, FCP_CAUSE_TGT_CHANGE); 4524 4525 link_count = pptr->port_link_cnt; 4526 4527 fcp_handle_devices(pptr, devlist, dev_cnt, 4528 link_count, map_tag, FCP_CAUSE_TGT_CHANGE); 4529 4530 pptr->port_state &= ~FCP_STATE_IN_CB_DEVC; 4531 4532 mutex_exit(&pptr->port_mutex); 4533 break; 4534 4535 case FC_STATE_TARGET_PORT_RESET: 4536 if (pptr->port_state & FCP_STATE_NS_REG_FAILED) { 4537 fcp_retry_ns_registry(pptr, port_sid); 4538 } 4539 4540 /* Do nothing else */ 4541 mutex_exit(&pptr->port_mutex); 4542 break; 4543 4544 default: 4545 fcp_log(CE_WARN, pptr->port_dip, 4546 "!Invalid state change=0x%x", port_state); 4547 mutex_exit(&pptr->port_mutex); 4548 break; 4549 } 4550 4551 if (map_tag) { 4552 kmem_free(map_tag, map_len); 4553 } 4554 } 4555 4556 /* 4557 * Function: fcp_handle_devices 4558 * 4559 * Description: This function updates the devices currently known by 4560 * walking the list provided by the caller. The list passed 4561 * by the caller is supposed to be the list of reachable 4562 * devices. 4563 * 4564 * Argument: *pptr Fcp port structure. 4565 * *devlist Pointer to the first entry of a table 4566 * containing the remote ports that can be 4567 * reached. 4568 * dev_cnt Number of entries pointed by devlist. 4569 * link_cnt Link state count. 4570 * *map_tag Array of fcp_map_tag_t structures. 4571 * cause What caused this function to be called. 4572 * 4573 * Return Value: None 4574 * 4575 * Notes: The pptr->port_mutex must be held. 4576 */ 4577 static void 4578 fcp_handle_devices(struct fcp_port *pptr, fc_portmap_t devlist[], 4579 uint32_t dev_cnt, int link_cnt, fcp_map_tag_t *map_tag, int cause) 4580 { 4581 int i; 4582 int check_finish_init = 0; 4583 fc_portmap_t *map_entry; 4584 struct fcp_tgt *ptgt = NULL; 4585 4586 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4587 fcp_trace, FCP_BUF_LEVEL_3, 0, 4588 "fcp_handle_devices: called for %d dev(s)", dev_cnt); 4589 4590 if (dev_cnt) { 4591 ASSERT(map_tag != NULL); 4592 } 4593 4594 /* 4595 * The following code goes through the list of remote ports that are 4596 * accessible through this (pptr) local port (The list walked is the 4597 * one provided by the caller which is the list of the remote ports 4598 * currently reachable). It checks if any of them was already 4599 * known by looking for the corresponding target structure based on 4600 * the world wide name. If a target is part of the list it is tagged 4601 * (ptgt->tgt_aux_state = FCP_TGT_TAGGED). 4602 * 4603 * Old comment 4604 * ----------- 4605 * Before we drop port mutex; we MUST get the tags updated; This 4606 * two step process is somewhat slow, but more reliable. 4607 */ 4608 for (i = 0; (i < dev_cnt) && (pptr->port_link_cnt == link_cnt); i++) { 4609 map_entry = &(devlist[i]); 4610 4611 /* 4612 * get ptr to this map entry in our port's 4613 * list (if any) 4614 */ 4615 ptgt = fcp_lookup_target(pptr, 4616 (uchar_t *)&(map_entry->map_pwwn)); 4617 4618 if (ptgt) { 4619 map_tag[i] = ptgt->tgt_change_cnt; 4620 if (cause == FCP_CAUSE_LINK_CHANGE) { 4621 ptgt->tgt_aux_state = FCP_TGT_TAGGED; 4622 } 4623 } 4624 } 4625 4626 /* 4627 * At this point we know which devices of the new list were already 4628 * known (The field tgt_aux_state of the target structure has been 4629 * set to FCP_TGT_TAGGED). 4630 * 4631 * The following code goes through the list of targets currently known 4632 * by the local port (the list is actually a hashing table). If a 4633 * target is found and is not tagged, it means the target cannot 4634 * be reached anymore through the local port (pptr). It is offlined. 4635 * The offlining only occurs if the cause is FCP_CAUSE_LINK_CHANGE. 4636 */ 4637 for (i = 0; i < FCP_NUM_HASH; i++) { 4638 for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL; 4639 ptgt = ptgt->tgt_next) { 4640 mutex_enter(&ptgt->tgt_mutex); 4641 if ((ptgt->tgt_aux_state != FCP_TGT_TAGGED) && 4642 (cause == FCP_CAUSE_LINK_CHANGE) && 4643 !(ptgt->tgt_state & FCP_TGT_OFFLINE)) { 4644 fcp_offline_target_now(pptr, ptgt, 4645 link_cnt, ptgt->tgt_change_cnt, 0); 4646 } 4647 mutex_exit(&ptgt->tgt_mutex); 4648 } 4649 } 4650 4651 /* 4652 * At this point, the devices that were known but cannot be reached 4653 * anymore, have most likely been offlined. 4654 * 4655 * The following section of code seems to go through the list of 4656 * remote ports that can now be reached. For every single one it 4657 * checks if it is already known or if it is a new port. 4658 */ 4659 for (i = 0; (i < dev_cnt) && (pptr->port_link_cnt == link_cnt); i++) { 4660 4661 if (check_finish_init) { 4662 ASSERT(i > 0); 4663 (void) fcp_call_finish_init_held(pptr, ptgt, link_cnt, 4664 map_tag[i - 1], cause); 4665 check_finish_init = 0; 4666 } 4667 4668 /* get a pointer to this map entry */ 4669 map_entry = &(devlist[i]); 4670 4671 /* 4672 * Check for the duplicate map entry flag. If we have marked 4673 * this entry as a duplicate we skip it since the correct 4674 * (perhaps even same) state change will be encountered 4675 * later in the list. 4676 */ 4677 if (map_entry->map_flags & PORT_DEVICE_DUPLICATE_MAP_ENTRY) { 4678 continue; 4679 } 4680 4681 /* get ptr to this map entry in our port's list (if any) */ 4682 ptgt = fcp_lookup_target(pptr, 4683 (uchar_t *)&(map_entry->map_pwwn)); 4684 4685 if (ptgt) { 4686 /* 4687 * This device was already known. The field 4688 * tgt_aux_state is reset (was probably set to 4689 * FCP_TGT_TAGGED previously in this routine). 4690 */ 4691 ptgt->tgt_aux_state = 0; 4692 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4693 fcp_trace, FCP_BUF_LEVEL_3, 0, 4694 "handle_devices: map did/state/type/flags = " 4695 "0x%x/0x%x/0x%x/0x%x, tgt_d_id=0x%x, " 4696 "tgt_state=%d", 4697 map_entry->map_did.port_id, map_entry->map_state, 4698 map_entry->map_type, map_entry->map_flags, 4699 ptgt->tgt_d_id, ptgt->tgt_state); 4700 } 4701 4702 if (map_entry->map_type == PORT_DEVICE_OLD || 4703 map_entry->map_type == PORT_DEVICE_NEW || 4704 map_entry->map_type == PORT_DEVICE_REPORTLUN_CHANGED || 4705 map_entry->map_type == PORT_DEVICE_CHANGED) { 4706 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4707 fcp_trace, FCP_BUF_LEVEL_2, 0, 4708 "map_type=%x, did = %x", 4709 map_entry->map_type, 4710 map_entry->map_did.port_id); 4711 } 4712 4713 switch (map_entry->map_type) { 4714 case PORT_DEVICE_NOCHANGE: 4715 case PORT_DEVICE_USER_CREATE: 4716 case PORT_DEVICE_USER_LOGIN: 4717 case PORT_DEVICE_NEW: 4718 case PORT_DEVICE_REPORTLUN_CHANGED: 4719 FCP_TGT_TRACE(ptgt, map_tag[i], FCP_TGT_TRACE_1); 4720 4721 if (fcp_handle_mapflags(pptr, ptgt, map_entry, 4722 link_cnt, (ptgt) ? map_tag[i] : 0, 4723 cause) == TRUE) { 4724 4725 FCP_TGT_TRACE(ptgt, map_tag[i], 4726 FCP_TGT_TRACE_2); 4727 check_finish_init++; 4728 } 4729 break; 4730 4731 case PORT_DEVICE_OLD: 4732 if (ptgt != NULL) { 4733 FCP_TGT_TRACE(ptgt, map_tag[i], 4734 FCP_TGT_TRACE_3); 4735 4736 mutex_enter(&ptgt->tgt_mutex); 4737 if (!(ptgt->tgt_state & FCP_TGT_OFFLINE)) { 4738 /* 4739 * Must do an in-line wait for I/Os 4740 * to get drained 4741 */ 4742 mutex_exit(&ptgt->tgt_mutex); 4743 mutex_exit(&pptr->port_mutex); 4744 4745 mutex_enter(&ptgt->tgt_mutex); 4746 while (ptgt->tgt_ipkt_cnt || 4747 fcp_outstanding_lun_cmds(ptgt) 4748 == FC_SUCCESS) { 4749 mutex_exit(&ptgt->tgt_mutex); 4750 delay(drv_usectohz(1000000)); 4751 mutex_enter(&ptgt->tgt_mutex); 4752 } 4753 mutex_exit(&ptgt->tgt_mutex); 4754 4755 mutex_enter(&pptr->port_mutex); 4756 mutex_enter(&ptgt->tgt_mutex); 4757 4758 (void) fcp_offline_target(pptr, ptgt, 4759 link_cnt, map_tag[i], 0, 0); 4760 } 4761 mutex_exit(&ptgt->tgt_mutex); 4762 } 4763 check_finish_init++; 4764 break; 4765 4766 case PORT_DEVICE_USER_DELETE: 4767 case PORT_DEVICE_USER_LOGOUT: 4768 if (ptgt != NULL) { 4769 FCP_TGT_TRACE(ptgt, map_tag[i], 4770 FCP_TGT_TRACE_4); 4771 4772 mutex_enter(&ptgt->tgt_mutex); 4773 if (!(ptgt->tgt_state & FCP_TGT_OFFLINE)) { 4774 (void) fcp_offline_target(pptr, ptgt, 4775 link_cnt, map_tag[i], 1, 0); 4776 } 4777 mutex_exit(&ptgt->tgt_mutex); 4778 } 4779 check_finish_init++; 4780 break; 4781 4782 case PORT_DEVICE_CHANGED: 4783 if (ptgt != NULL) { 4784 FCP_TGT_TRACE(ptgt, map_tag[i], 4785 FCP_TGT_TRACE_5); 4786 4787 if (fcp_device_changed(pptr, ptgt, 4788 map_entry, link_cnt, map_tag[i], 4789 cause) == TRUE) { 4790 check_finish_init++; 4791 } 4792 } else { 4793 if (fcp_handle_mapflags(pptr, ptgt, 4794 map_entry, link_cnt, 0, cause) == TRUE) { 4795 check_finish_init++; 4796 } 4797 } 4798 break; 4799 4800 default: 4801 fcp_log(CE_WARN, pptr->port_dip, 4802 "!Invalid map_type=0x%x", map_entry->map_type); 4803 check_finish_init++; 4804 break; 4805 } 4806 } 4807 4808 if (check_finish_init && pptr->port_link_cnt == link_cnt) { 4809 ASSERT(i > 0); 4810 (void) fcp_call_finish_init_held(pptr, ptgt, link_cnt, 4811 map_tag[i-1], cause); 4812 } else if (dev_cnt == 0 && pptr->port_link_cnt == link_cnt) { 4813 fcp_offline_all(pptr, link_cnt, cause); 4814 } 4815 } 4816 4817 static int 4818 fcp_handle_reportlun_changed(struct fcp_tgt *ptgt, int cause) 4819 { 4820 struct fcp_lun *plun; 4821 struct fcp_port *pptr; 4822 int rscn_count; 4823 int lun0_newalloc; 4824 int ret = TRUE; 4825 4826 ASSERT(ptgt); 4827 pptr = ptgt->tgt_port; 4828 lun0_newalloc = 0; 4829 if ((plun = fcp_get_lun(ptgt, 0)) == NULL) { 4830 /* 4831 * no LUN struct for LUN 0 yet exists, 4832 * so create one 4833 */ 4834 plun = fcp_alloc_lun(ptgt); 4835 if (plun == NULL) { 4836 fcp_log(CE_WARN, pptr->port_dip, 4837 "!Failed to allocate lun 0 for" 4838 " D_ID=%x", ptgt->tgt_d_id); 4839 return (ret); 4840 } 4841 lun0_newalloc = 1; 4842 } 4843 4844 mutex_enter(&ptgt->tgt_mutex); 4845 /* 4846 * consider lun 0 as device not connected if it is 4847 * offlined or newly allocated 4848 */ 4849 if ((plun->lun_state & FCP_LUN_OFFLINE) || lun0_newalloc) { 4850 plun->lun_state |= FCP_LUN_DEVICE_NOT_CONNECTED; 4851 } 4852 plun->lun_state |= (FCP_LUN_BUSY | FCP_LUN_MARK); 4853 plun->lun_state &= ~FCP_LUN_OFFLINE; 4854 ptgt->tgt_lun_cnt = 1; 4855 ptgt->tgt_report_lun_cnt = 0; 4856 mutex_exit(&ptgt->tgt_mutex); 4857 4858 rscn_count = fc_ulp_get_rscn_count(pptr->port_fp_handle); 4859 if (fcp_send_scsi(plun, SCMD_REPORT_LUN, 4860 sizeof (struct fcp_reportlun_resp), pptr->port_link_cnt, 4861 ptgt->tgt_change_cnt, cause, rscn_count) != DDI_SUCCESS) { 4862 FCP_TRACE(fcp_logq, pptr->port_instbuf, 4863 fcp_trace, FCP_BUF_LEVEL_3, 0, "!Failed to send REPORTLUN " 4864 "to D_ID=%x", ptgt->tgt_d_id); 4865 } else { 4866 ret = FALSE; 4867 } 4868 4869 return (ret); 4870 } 4871 4872 /* 4873 * Function: fcp_handle_mapflags 4874 * 4875 * Description: This function creates a target structure if the ptgt passed 4876 * is NULL. It also kicks off the PLOGI if we are not logged 4877 * into the target yet or the PRLI if we are logged into the 4878 * target already. The rest of the treatment is done in the 4879 * callbacks of the PLOGI or PRLI. 4880 * 4881 * Argument: *pptr FCP Port structure. 4882 * *ptgt Target structure. 4883 * *map_entry Array of fc_portmap_t structures. 4884 * link_cnt Link state count. 4885 * tgt_cnt Target state count. 4886 * cause What caused this function to be called. 4887 * 4888 * Return Value: TRUE Failed 4889 * FALSE Succeeded 4890 * 4891 * Notes: pptr->port_mutex must be owned. 4892 */ 4893 static int 4894 fcp_handle_mapflags(struct fcp_port *pptr, struct fcp_tgt *ptgt, 4895 fc_portmap_t *map_entry, int link_cnt, int tgt_cnt, int cause) 4896 { 4897 int lcount; 4898 int tcount; 4899 int ret = TRUE; 4900 int alloc; 4901 struct fcp_ipkt *icmd; 4902 struct fcp_lun *pseq_lun = NULL; 4903 uchar_t opcode; 4904 int valid_ptgt_was_passed = FALSE; 4905 4906 ASSERT(mutex_owned(&pptr->port_mutex)); 4907 4908 /* 4909 * This case is possible where the FCTL has come up and done discovery 4910 * before FCP was loaded and attached. FCTL would have discovered the 4911 * devices and later the ULP came online. In this case ULP's would get 4912 * PORT_DEVICE_NOCHANGE but target would be NULL. 4913 */ 4914 if (ptgt == NULL) { 4915 /* don't already have a target */ 4916 mutex_exit(&pptr->port_mutex); 4917 ptgt = fcp_alloc_tgt(pptr, map_entry, link_cnt); 4918 mutex_enter(&pptr->port_mutex); 4919 4920 if (ptgt == NULL) { 4921 fcp_log(CE_WARN, pptr->port_dip, 4922 "!FC target allocation failed"); 4923 return (ret); 4924 } 4925 mutex_enter(&ptgt->tgt_mutex); 4926 ptgt->tgt_statec_cause = cause; 4927 ptgt->tgt_tmp_cnt = 1; 4928 mutex_exit(&ptgt->tgt_mutex); 4929 } else { 4930 valid_ptgt_was_passed = TRUE; 4931 } 4932 4933 /* 4934 * Copy in the target parameters 4935 */ 4936 mutex_enter(&ptgt->tgt_mutex); 4937 ptgt->tgt_d_id = map_entry->map_did.port_id; 4938 ptgt->tgt_hard_addr = map_entry->map_hard_addr.hard_addr; 4939 ptgt->tgt_pd_handle = map_entry->map_pd; 4940 ptgt->tgt_fca_dev = NULL; 4941 4942 /* Copy port and node WWNs */ 4943 bcopy(&map_entry->map_nwwn, &ptgt->tgt_node_wwn.raw_wwn[0], 4944 FC_WWN_SIZE); 4945 bcopy(&map_entry->map_pwwn, &ptgt->tgt_port_wwn.raw_wwn[0], 4946 FC_WWN_SIZE); 4947 4948 if (!(map_entry->map_flags & PORT_DEVICE_NO_SKIP_DEVICE_DISCOVERY) && 4949 (map_entry->map_type == PORT_DEVICE_NOCHANGE) && 4950 (map_entry->map_state == PORT_DEVICE_LOGGED_IN) && 4951 valid_ptgt_was_passed) { 4952 /* 4953 * determine if there are any tape LUNs on this target 4954 */ 4955 for (pseq_lun = ptgt->tgt_lun; 4956 pseq_lun != NULL; 4957 pseq_lun = pseq_lun->lun_next) { 4958 if ((pseq_lun->lun_type == DTYPE_SEQUENTIAL) && 4959 !(pseq_lun->lun_state & FCP_LUN_OFFLINE)) { 4960 fcp_update_tgt_state(ptgt, FCP_RESET, 4961 FCP_LUN_MARK); 4962 mutex_exit(&ptgt->tgt_mutex); 4963 return (ret); 4964 } 4965 } 4966 } 4967 4968 /* 4969 * if UA'REPORT_LUN_CHANGED received, 4970 * send out REPORT LUN promptly, skip PLOGI/PRLI process 4971 */ 4972 if (map_entry->map_type == PORT_DEVICE_REPORTLUN_CHANGED) { 4973 ptgt->tgt_state &= ~(FCP_TGT_OFFLINE | FCP_TGT_MARK); 4974 mutex_exit(&ptgt->tgt_mutex); 4975 mutex_exit(&pptr->port_mutex); 4976 4977 ret = fcp_handle_reportlun_changed(ptgt, cause); 4978 4979 mutex_enter(&pptr->port_mutex); 4980 return (ret); 4981 } 4982 4983 /* 4984 * If ptgt was NULL when this function was entered, then tgt_node_state 4985 * was never specifically initialized but zeroed out which means 4986 * FCP_TGT_NODE_NONE. 4987 */ 4988 switch (ptgt->tgt_node_state) { 4989 case FCP_TGT_NODE_NONE: 4990 case FCP_TGT_NODE_ON_DEMAND: 4991 if (FC_TOP_EXTERNAL(pptr->port_topology) && 4992 !fcp_enable_auto_configuration && 4993 map_entry->map_type != PORT_DEVICE_USER_CREATE) { 4994 ptgt->tgt_node_state = FCP_TGT_NODE_ON_DEMAND; 4995 } else if (FC_TOP_EXTERNAL(pptr->port_topology) && 4996 fcp_enable_auto_configuration && 4997 (ptgt->tgt_manual_config_only == 1) && 4998 map_entry->map_type != PORT_DEVICE_USER_CREATE) { 4999 /* 5000 * If auto configuration is set and 5001 * the tgt_manual_config_only flag is set then 5002 * we only want the user to be able to change 5003 * the state through create_on_demand. 5004 */ 5005 ptgt->tgt_node_state = FCP_TGT_NODE_ON_DEMAND; 5006 } else { 5007 ptgt->tgt_node_state = FCP_TGT_NODE_NONE; 5008 } 5009 break; 5010 5011 case FCP_TGT_NODE_PRESENT: 5012 break; 5013 } 5014 /* 5015 * If we are booting from a fabric device, make sure we 5016 * mark the node state appropriately for this target to be 5017 * enumerated 5018 */ 5019 if (FC_TOP_EXTERNAL(pptr->port_topology) && pptr->port_boot_wwn[0]) { 5020 if (bcmp((caddr_t)pptr->port_boot_wwn, 5021 (caddr_t)&ptgt->tgt_port_wwn.raw_wwn[0], 5022 sizeof (ptgt->tgt_port_wwn)) == 0) { 5023 ptgt->tgt_node_state = FCP_TGT_NODE_NONE; 5024 } 5025 } 5026 mutex_exit(&ptgt->tgt_mutex); 5027 5028 FCP_TRACE(fcp_logq, pptr->port_instbuf, 5029 fcp_trace, FCP_BUF_LEVEL_3, 0, 5030 "map_pd=%p, map_type=%x, did = %x, ulp_rscn_count=0x%x", 5031 map_entry->map_pd, map_entry->map_type, map_entry->map_did.port_id, 5032 map_entry->map_rscn_info.ulp_rscn_count); 5033 5034 mutex_enter(&ptgt->tgt_mutex); 5035 5036 /* 5037 * Reset target OFFLINE state and mark the target BUSY 5038 */ 5039 ptgt->tgt_state &= ~FCP_TGT_OFFLINE; 5040 ptgt->tgt_state |= (FCP_TGT_BUSY | FCP_TGT_MARK); 5041 5042 tcount = tgt_cnt ? tgt_cnt : ptgt->tgt_change_cnt; 5043 lcount = link_cnt; 5044 5045 mutex_exit(&ptgt->tgt_mutex); 5046 mutex_exit(&pptr->port_mutex); 5047 5048 /* 5049 * if we are already logged in, then we do a PRLI, else 5050 * we do a PLOGI first (to get logged in) 5051 * 5052 * We will not check if we are the PLOGI initiator 5053 */ 5054 opcode = (map_entry->map_state == PORT_DEVICE_LOGGED_IN && 5055 map_entry->map_pd != NULL) ? LA_ELS_PRLI : LA_ELS_PLOGI; 5056 5057 alloc = FCP_MAX(sizeof (la_els_logi_t), sizeof (la_els_prli_t)); 5058 5059 icmd = fcp_icmd_alloc(pptr, ptgt, alloc, alloc, 0, 0, lcount, tcount, 5060 cause, map_entry->map_rscn_info.ulp_rscn_count); 5061 5062 if (icmd == NULL) { 5063 FCP_TGT_TRACE(ptgt, tgt_cnt, FCP_TGT_TRACE_29); 5064 /* 5065 * We've exited port_mutex before calling fcp_icmd_alloc, 5066 * we need to make sure we reacquire it before returning. 5067 */ 5068 mutex_enter(&pptr->port_mutex); 5069 return (FALSE); 5070 } 5071 5072 /* TRUE is only returned while target is intended skipped */ 5073 ret = FALSE; 5074 /* discover info about this target */ 5075 if ((fcp_send_els(pptr, ptgt, icmd, opcode, 5076 lcount, tcount, cause)) == DDI_SUCCESS) { 5077 FCP_TGT_TRACE(ptgt, tgt_cnt, FCP_TGT_TRACE_9); 5078 } else { 5079 fcp_icmd_free(pptr, icmd); 5080 ret = TRUE; 5081 } 5082 mutex_enter(&pptr->port_mutex); 5083 5084 return (ret); 5085 } 5086 5087 /* 5088 * Function: fcp_send_els 5089 * 5090 * Description: Sends an ELS to the target specified by the caller. Supports 5091 * PLOGI and PRLI. 5092 * 5093 * Argument: *pptr Fcp port. 5094 * *ptgt Target to send the ELS to. 5095 * *icmd Internal packet 5096 * opcode ELS opcode 5097 * lcount Link state change counter 5098 * tcount Target state change counter 5099 * cause What caused the call 5100 * 5101 * Return Value: DDI_SUCCESS 5102 * Others 5103 */ 5104 static int 5105 fcp_send_els(struct fcp_port *pptr, struct fcp_tgt *ptgt, 5106 struct fcp_ipkt *icmd, uchar_t opcode, int lcount, int tcount, int cause) 5107 { 5108 fc_packet_t *fpkt; 5109 fc_frame_hdr_t *hp; 5110 int internal = 0; 5111 int alloc; 5112 int cmd_len; 5113 int resp_len; 5114 int res = DDI_FAILURE; /* default result */ 5115 int rval = DDI_FAILURE; 5116 5117 ASSERT(opcode == LA_ELS_PLOGI || opcode == LA_ELS_PRLI); 5118 ASSERT(ptgt->tgt_port == pptr); 5119 5120 FCP_TRACE(fcp_logq, pptr->port_instbuf, 5121 fcp_trace, FCP_BUF_LEVEL_5, 0, 5122 "fcp_send_els: d_id=0x%x ELS 0x%x (%s)", ptgt->tgt_d_id, opcode, 5123 (opcode == LA_ELS_PLOGI) ? "PLOGI" : "PRLI"); 5124 5125 if (opcode == LA_ELS_PLOGI) { 5126 cmd_len = sizeof (la_els_logi_t); 5127 resp_len = sizeof (la_els_logi_t); 5128 } else { 5129 ASSERT(opcode == LA_ELS_PRLI); 5130 cmd_len = sizeof (la_els_prli_t); 5131 resp_len = sizeof (la_els_prli_t); 5132 } 5133 5134 if (icmd == NULL) { 5135 alloc = FCP_MAX(sizeof (la_els_logi_t), 5136 sizeof (la_els_prli_t)); 5137 icmd = fcp_icmd_alloc(pptr, ptgt, alloc, alloc, 0, 0, 5138 lcount, tcount, cause, FC_INVALID_RSCN_COUNT); 5139 if (icmd == NULL) { 5140 FCP_TGT_TRACE(ptgt, tcount, FCP_TGT_TRACE_10); 5141 return (res); 5142 } 5143 internal++; 5144 } 5145 fpkt = icmd->ipkt_fpkt; 5146 5147 fpkt->pkt_cmdlen = cmd_len; 5148 fpkt->pkt_rsplen = resp_len; 5149 fpkt->pkt_datalen = 0; 5150 icmd->ipkt_retries = 0; 5151 5152 /* fill in fpkt info */ 5153 fpkt->pkt_tran_flags = FC_TRAN_CLASS3 | FC_TRAN_INTR; 5154 fpkt->pkt_tran_type = FC_PKT_EXCHANGE; 5155 fpkt->pkt_timeout = FCP_ELS_TIMEOUT; 5156 5157 /* get ptr to frame hdr in fpkt */ 5158 hp = &fpkt->pkt_cmd_fhdr; 5159 5160 /* 5161 * fill in frame hdr 5162 */ 5163 hp->r_ctl = R_CTL_ELS_REQ; 5164 hp->s_id = pptr->port_id; /* source ID */ 5165 hp->d_id = ptgt->tgt_d_id; /* dest ID */ 5166 hp->type = FC_TYPE_EXTENDED_LS; 5167 hp->f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ; 5168 hp->seq_id = 0; 5169 hp->rsvd = 0; 5170 hp->df_ctl = 0; 5171 hp->seq_cnt = 0; 5172 hp->ox_id = 0xffff; /* i.e. none */ 5173 hp->rx_id = 0xffff; /* i.e. none */ 5174 hp->ro = 0; 5175 5176 /* 5177 * at this point we have a filled in cmd pkt 5178 * 5179 * fill in the respective info, then use the transport to send 5180 * the packet 5181 * 5182 * for a PLOGI call fc_ulp_login(), and 5183 * for a PRLI call fc_ulp_issue_els() 5184 */ 5185 switch (opcode) { 5186 case LA_ELS_PLOGI: { 5187 struct la_els_logi logi; 5188 5189 bzero(&logi, sizeof (struct la_els_logi)); 5190 5191 hp = &fpkt->pkt_cmd_fhdr; 5192 hp->r_ctl = R_CTL_ELS_REQ; 5193 logi.ls_code.ls_code = LA_ELS_PLOGI; 5194 logi.ls_code.mbz = 0; 5195 5196 FCP_CP_OUT((uint8_t *)&logi, fpkt->pkt_cmd, 5197 fpkt->pkt_cmd_acc, sizeof (struct la_els_logi)); 5198 5199 icmd->ipkt_opcode = LA_ELS_PLOGI; 5200 5201 mutex_enter(&pptr->port_mutex); 5202 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 5203 5204 mutex_exit(&pptr->port_mutex); 5205 5206 rval = fc_ulp_login(pptr->port_fp_handle, &fpkt, 1); 5207 if (rval == FC_SUCCESS) { 5208 res = DDI_SUCCESS; 5209 break; 5210 } 5211 5212 FCP_TGT_TRACE(ptgt, tcount, FCP_TGT_TRACE_11); 5213 5214 res = fcp_handle_ipkt_errors(pptr, ptgt, icmd, 5215 rval, "PLOGI"); 5216 } else { 5217 FCP_TRACE(fcp_logq, pptr->port_instbuf, 5218 fcp_trace, FCP_BUF_LEVEL_5, 0, 5219 "fcp_send_els1: state change occured" 5220 " for D_ID=0x%x", ptgt->tgt_d_id); 5221 mutex_exit(&pptr->port_mutex); 5222 FCP_TGT_TRACE(ptgt, tcount, FCP_TGT_TRACE_12); 5223 } 5224 break; 5225 } 5226 5227 case LA_ELS_PRLI: { 5228 struct la_els_prli prli; 5229 struct fcp_prli *fprli; 5230 5231 bzero(&prli, sizeof (struct la_els_prli)); 5232 5233 hp = &fpkt->pkt_cmd_fhdr; 5234 hp->r_ctl = R_CTL_ELS_REQ; 5235 5236 /* fill in PRLI cmd ELS fields */ 5237 prli.ls_code = LA_ELS_PRLI; 5238 prli.page_length = 0x10; /* huh? */ 5239 prli.payload_length = sizeof (struct la_els_prli); 5240 5241 icmd->ipkt_opcode = LA_ELS_PRLI; 5242 5243 /* get ptr to PRLI service params */ 5244 fprli = (struct fcp_prli *)prli.service_params; 5245 5246 /* fill in service params */ 5247 fprli->type = 0x08; 5248 fprli->resvd1 = 0; 5249 fprli->orig_process_assoc_valid = 0; 5250 fprli->resp_process_assoc_valid = 0; 5251 fprli->establish_image_pair = 1; 5252 fprli->resvd2 = 0; 5253 fprli->resvd3 = 0; 5254 fprli->obsolete_1 = 0; 5255 fprli->obsolete_2 = 0; 5256 fprli->data_overlay_allowed = 0; 5257 fprli->initiator_fn = 1; 5258 fprli->confirmed_compl_allowed = 1; 5259 5260 if (fc_ulp_is_name_present("ltct") == FC_SUCCESS) { 5261 fprli->target_fn = 1; 5262 } else { 5263 fprli->target_fn = 0; 5264 } 5265 5266 fprli->retry = 1; 5267 fprli->read_xfer_rdy_disabled = 1; 5268 fprli->write_xfer_rdy_disabled = 0; 5269 5270 FCP_CP_OUT((uint8_t *)&prli, fpkt->pkt_cmd, 5271 fpkt->pkt_cmd_acc, sizeof (struct la_els_prli)); 5272 5273 /* issue the PRLI request */ 5274 5275 mutex_enter(&pptr->port_mutex); 5276 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 5277 5278 mutex_exit(&pptr->port_mutex); 5279 5280 rval = fc_ulp_issue_els(pptr->port_fp_handle, fpkt); 5281 if (rval == FC_SUCCESS) { 5282 res = DDI_SUCCESS; 5283 break; 5284 } 5285 5286 FCP_TGT_TRACE(ptgt, tcount, FCP_TGT_TRACE_13); 5287 5288 res = fcp_handle_ipkt_errors(pptr, ptgt, icmd, 5289 rval, "PRLI"); 5290 } else { 5291 mutex_exit(&pptr->port_mutex); 5292 FCP_TGT_TRACE(ptgt, tcount, FCP_TGT_TRACE_14); 5293 } 5294 break; 5295 } 5296 5297 default: 5298 fcp_log(CE_WARN, NULL, "!invalid ELS opcode=0x%x", opcode); 5299 break; 5300 } 5301 5302 FCP_TRACE(fcp_logq, pptr->port_instbuf, 5303 fcp_trace, FCP_BUF_LEVEL_5, 0, 5304 "fcp_send_els: returning %d", res); 5305 5306 if (res != DDI_SUCCESS) { 5307 if (internal) { 5308 fcp_icmd_free(pptr, icmd); 5309 } 5310 } 5311 5312 return (res); 5313 } 5314 5315 5316 /* 5317 * called internally update the state of all of the tgts and each LUN 5318 * for this port (i.e. each target known to be attached to this port) 5319 * if they are not already offline 5320 * 5321 * must be called with the port mutex owned 5322 * 5323 * acquires and releases the target mutexes for each target attached 5324 * to this port 5325 */ 5326 void 5327 fcp_update_state(struct fcp_port *pptr, uint32_t state, int cause) 5328 { 5329 int i; 5330 struct fcp_tgt *ptgt; 5331 5332 ASSERT(mutex_owned(&pptr->port_mutex)); 5333 5334 for (i = 0; i < FCP_NUM_HASH; i++) { 5335 for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL; 5336 ptgt = ptgt->tgt_next) { 5337 mutex_enter(&ptgt->tgt_mutex); 5338 fcp_update_tgt_state(ptgt, FCP_SET, state); 5339 ptgt->tgt_change_cnt++; 5340 ptgt->tgt_statec_cause = cause; 5341 ptgt->tgt_tmp_cnt = 1; 5342 ptgt->tgt_done = 0; 5343 mutex_exit(&ptgt->tgt_mutex); 5344 } 5345 } 5346 } 5347 5348 5349 static void 5350 fcp_offline_all(struct fcp_port *pptr, int lcount, int cause) 5351 { 5352 int i; 5353 int ndevs; 5354 struct fcp_tgt *ptgt; 5355 5356 ASSERT(mutex_owned(&pptr->port_mutex)); 5357 5358 for (ndevs = 0, i = 0; i < FCP_NUM_HASH; i++) { 5359 for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL; 5360 ptgt = ptgt->tgt_next) { 5361 ndevs++; 5362 } 5363 } 5364 5365 if (ndevs == 0) { 5366 return; 5367 } 5368 pptr->port_tmp_cnt = ndevs; 5369 5370 for (i = 0; i < FCP_NUM_HASH; i++) { 5371 for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL; 5372 ptgt = ptgt->tgt_next) { 5373 (void) fcp_call_finish_init_held(pptr, ptgt, 5374 lcount, ptgt->tgt_change_cnt, cause); 5375 } 5376 } 5377 } 5378 5379 /* 5380 * Function: fcp_update_tgt_state 5381 * 5382 * Description: This function updates the field tgt_state of a target. That 5383 * field is a bitmap and which bit can be set or reset 5384 * individually. The action applied to the target state is also 5385 * applied to all the LUNs belonging to the target (provided the 5386 * LUN is not offline). A side effect of applying the state 5387 * modification to the target and the LUNs is the field tgt_trace 5388 * of the target and lun_trace of the LUNs is set to zero. 5389 * 5390 * 5391 * Argument: *ptgt Target structure. 5392 * flag Flag indication what action to apply (set/reset). 5393 * state State bits to update. 5394 * 5395 * Return Value: None 5396 * 5397 * Context: Interrupt, Kernel or User context. 5398 * The mutex of the target (ptgt->tgt_mutex) must be owned when 5399 * calling this function. 5400 */ 5401 void 5402 fcp_update_tgt_state(struct fcp_tgt *ptgt, int flag, uint32_t state) 5403 { 5404 struct fcp_lun *plun; 5405 5406 ASSERT(mutex_owned(&ptgt->tgt_mutex)); 5407 5408 if (!(ptgt->tgt_state & FCP_TGT_OFFLINE)) { 5409 /* The target is not offline. */ 5410 if (flag == FCP_SET) { 5411 ptgt->tgt_state |= state; 5412 ptgt->tgt_trace = 0; 5413 } else { 5414 ptgt->tgt_state &= ~state; 5415 } 5416 5417 for (plun = ptgt->tgt_lun; plun != NULL; 5418 plun = plun->lun_next) { 5419 if (!(plun->lun_state & FCP_LUN_OFFLINE)) { 5420 /* The LUN is not offline. */ 5421 if (flag == FCP_SET) { 5422 plun->lun_state |= state; 5423 plun->lun_trace = 0; 5424 } else { 5425 plun->lun_state &= ~state; 5426 } 5427 } 5428 } 5429 } 5430 } 5431 5432 /* 5433 * Function: fcp_update_tgt_state 5434 * 5435 * Description: This function updates the field lun_state of a LUN. That 5436 * field is a bitmap and which bit can be set or reset 5437 * individually. 5438 * 5439 * Argument: *plun LUN structure. 5440 * flag Flag indication what action to apply (set/reset). 5441 * state State bits to update. 5442 * 5443 * Return Value: None 5444 * 5445 * Context: Interrupt, Kernel or User context. 5446 * The mutex of the target (ptgt->tgt_mutex) must be owned when 5447 * calling this function. 5448 */ 5449 void 5450 fcp_update_lun_state(struct fcp_lun *plun, int flag, uint32_t state) 5451 { 5452 struct fcp_tgt *ptgt = plun->lun_tgt; 5453 5454 ASSERT(mutex_owned(&ptgt->tgt_mutex)); 5455 5456 if (!(plun->lun_state & FCP_TGT_OFFLINE)) { 5457 if (flag == FCP_SET) { 5458 plun->lun_state |= state; 5459 } else { 5460 plun->lun_state &= ~state; 5461 } 5462 } 5463 } 5464 5465 /* 5466 * Function: fcp_get_port 5467 * 5468 * Description: This function returns the fcp_port structure from the opaque 5469 * handle passed by the caller. That opaque handle is the handle 5470 * used by fp/fctl to identify a particular local port. That 5471 * handle has been stored in the corresponding fcp_port 5472 * structure. This function is going to walk the global list of 5473 * fcp_port structures till one has a port_fp_handle that matches 5474 * the handle passed by the caller. This function enters the 5475 * mutex fcp_global_mutex while walking the global list and then 5476 * releases it. 5477 * 5478 * Argument: port_handle Opaque handle that fp/fctl uses to identify a 5479 * particular port. 5480 * 5481 * Return Value: NULL Not found. 5482 * Not NULL Pointer to the fcp_port structure. 5483 * 5484 * Context: Interrupt, Kernel or User context. 5485 */ 5486 static struct fcp_port * 5487 fcp_get_port(opaque_t port_handle) 5488 { 5489 struct fcp_port *pptr; 5490 5491 ASSERT(port_handle != NULL); 5492 5493 mutex_enter(&fcp_global_mutex); 5494 for (pptr = fcp_port_head; pptr != NULL; pptr = pptr->port_next) { 5495 if (pptr->port_fp_handle == port_handle) { 5496 break; 5497 } 5498 } 5499 mutex_exit(&fcp_global_mutex); 5500 5501 return (pptr); 5502 } 5503 5504 5505 static void 5506 fcp_unsol_callback(fc_packet_t *fpkt) 5507 { 5508 struct fcp_ipkt *icmd = (struct fcp_ipkt *)fpkt->pkt_ulp_private; 5509 struct fcp_port *pptr = icmd->ipkt_port; 5510 5511 if (fpkt->pkt_state != FC_PKT_SUCCESS) { 5512 caddr_t state, reason, action, expln; 5513 5514 (void) fc_ulp_pkt_error(fpkt, &state, &reason, 5515 &action, &expln); 5516 5517 fcp_log(CE_WARN, pptr->port_dip, 5518 "!couldn't post response to unsolicited request: " 5519 " state=%s reason=%s rx_id=%x ox_id=%x", 5520 state, reason, fpkt->pkt_cmd_fhdr.ox_id, 5521 fpkt->pkt_cmd_fhdr.rx_id); 5522 } 5523 fcp_icmd_free(pptr, icmd); 5524 } 5525 5526 5527 /* 5528 * Perform general purpose preparation of a response to an unsolicited request 5529 */ 5530 static void 5531 fcp_unsol_resp_init(fc_packet_t *pkt, fc_unsol_buf_t *buf, 5532 uchar_t r_ctl, uchar_t type) 5533 { 5534 pkt->pkt_cmd_fhdr.r_ctl = r_ctl; 5535 pkt->pkt_cmd_fhdr.d_id = buf->ub_frame.s_id; 5536 pkt->pkt_cmd_fhdr.s_id = buf->ub_frame.d_id; 5537 pkt->pkt_cmd_fhdr.type = type; 5538 pkt->pkt_cmd_fhdr.f_ctl = F_CTL_LAST_SEQ | F_CTL_XCHG_CONTEXT; 5539 pkt->pkt_cmd_fhdr.seq_id = buf->ub_frame.seq_id; 5540 pkt->pkt_cmd_fhdr.df_ctl = buf->ub_frame.df_ctl; 5541 pkt->pkt_cmd_fhdr.seq_cnt = buf->ub_frame.seq_cnt; 5542 pkt->pkt_cmd_fhdr.ox_id = buf->ub_frame.ox_id; 5543 pkt->pkt_cmd_fhdr.rx_id = buf->ub_frame.rx_id; 5544 pkt->pkt_cmd_fhdr.ro = 0; 5545 pkt->pkt_cmd_fhdr.rsvd = 0; 5546 pkt->pkt_comp = fcp_unsol_callback; 5547 pkt->pkt_pd = NULL; 5548 } 5549 5550 5551 /*ARGSUSED*/ 5552 static int 5553 fcp_unsol_prli(struct fcp_port *pptr, fc_unsol_buf_t *buf) 5554 { 5555 fc_packet_t *fpkt; 5556 struct la_els_prli prli; 5557 struct fcp_prli *fprli; 5558 struct fcp_ipkt *icmd; 5559 struct la_els_prli *from; 5560 struct fcp_prli *orig; 5561 struct fcp_tgt *ptgt; 5562 int tcount = 0; 5563 int lcount; 5564 5565 from = (struct la_els_prli *)buf->ub_buffer; 5566 orig = (struct fcp_prli *)from->service_params; 5567 5568 if ((ptgt = fcp_get_target_by_did(pptr, buf->ub_frame.s_id)) != 5569 NULL) { 5570 mutex_enter(&ptgt->tgt_mutex); 5571 tcount = ptgt->tgt_change_cnt; 5572 mutex_exit(&ptgt->tgt_mutex); 5573 } 5574 mutex_enter(&pptr->port_mutex); 5575 lcount = pptr->port_link_cnt; 5576 mutex_exit(&pptr->port_mutex); 5577 5578 if ((icmd = fcp_icmd_alloc(pptr, ptgt, sizeof (la_els_prli_t), 5579 sizeof (la_els_prli_t), 0, 0, lcount, tcount, 0, 5580 FC_INVALID_RSCN_COUNT)) == NULL) { 5581 return (FC_FAILURE); 5582 } 5583 fpkt = icmd->ipkt_fpkt; 5584 fpkt->pkt_tran_flags = FC_TRAN_CLASS3 | FC_TRAN_INTR; 5585 fpkt->pkt_tran_type = FC_PKT_OUTBOUND; 5586 fpkt->pkt_timeout = FCP_ELS_TIMEOUT; 5587 fpkt->pkt_cmdlen = sizeof (la_els_prli_t); 5588 fpkt->pkt_rsplen = 0; 5589 fpkt->pkt_datalen = 0; 5590 5591 icmd->ipkt_opcode = LA_ELS_PRLI; 5592 5593 bzero(&prli, sizeof (struct la_els_prli)); 5594 fprli = (struct fcp_prli *)prli.service_params; 5595 prli.ls_code = LA_ELS_ACC; 5596 prli.page_length = 0x10; 5597 prli.payload_length = sizeof (struct la_els_prli); 5598 5599 /* fill in service params */ 5600 fprli->type = 0x08; 5601 fprli->resvd1 = 0; 5602 fprli->orig_process_assoc_valid = orig->orig_process_assoc_valid; 5603 fprli->orig_process_associator = orig->orig_process_associator; 5604 fprli->resp_process_assoc_valid = 0; 5605 fprli->establish_image_pair = 1; 5606 fprli->resvd2 = 0; 5607 fprli->resvd3 = 0; 5608 fprli->obsolete_1 = 0; 5609 fprli->obsolete_2 = 0; 5610 fprli->data_overlay_allowed = 0; 5611 fprli->initiator_fn = 1; 5612 fprli->confirmed_compl_allowed = 1; 5613 5614 if (fc_ulp_is_name_present("ltct") == FC_SUCCESS) { 5615 fprli->target_fn = 1; 5616 } else { 5617 fprli->target_fn = 0; 5618 } 5619 5620 fprli->retry = 1; 5621 fprli->read_xfer_rdy_disabled = 1; 5622 fprli->write_xfer_rdy_disabled = 0; 5623 5624 /* save the unsol prli payload first */ 5625 FCP_CP_OUT((uint8_t *)from, fpkt->pkt_resp, 5626 fpkt->pkt_resp_acc, sizeof (struct la_els_prli)); 5627 5628 FCP_CP_OUT((uint8_t *)&prli, fpkt->pkt_cmd, 5629 fpkt->pkt_cmd_acc, sizeof (struct la_els_prli)); 5630 5631 fcp_unsol_resp_init(fpkt, buf, R_CTL_ELS_RSP, FC_TYPE_EXTENDED_LS); 5632 5633 mutex_enter(&pptr->port_mutex); 5634 if (!FCP_LINK_STATE_CHANGED(pptr, icmd)) { 5635 int rval; 5636 mutex_exit(&pptr->port_mutex); 5637 5638 if ((rval = fc_ulp_issue_els(pptr->port_fp_handle, fpkt)) != 5639 FC_SUCCESS) { 5640 if (rval == FC_STATEC_BUSY || rval == FC_OFFLINE) { 5641 fcp_queue_ipkt(pptr, fpkt); 5642 return (FC_SUCCESS); 5643 } 5644 /* Let it timeout */ 5645 fcp_icmd_free(pptr, icmd); 5646 return (FC_FAILURE); 5647 } 5648 } else { 5649 mutex_exit(&pptr->port_mutex); 5650 fcp_icmd_free(pptr, icmd); 5651 return (FC_FAILURE); 5652 } 5653 5654 (void) fc_ulp_ubrelease(pptr->port_fp_handle, 1, &buf->ub_token); 5655 5656 return (FC_SUCCESS); 5657 } 5658 5659 /* 5660 * Function: fcp_icmd_alloc 5661 * 5662 * Description: This function allocated a fcp_ipkt structure. The pkt_comp 5663 * field is initialized to fcp_icmd_callback. Sometimes it is 5664 * modified by the caller (such as fcp_send_scsi). The 5665 * structure is also tied to the state of the line and of the 5666 * target at a particular time. That link is established by 5667 * setting the fields ipkt_link_cnt and ipkt_change_cnt to lcount 5668 * and tcount which came respectively from pptr->link_cnt and 5669 * ptgt->tgt_change_cnt. 5670 * 5671 * Argument: *pptr Fcp port. 5672 * *ptgt Target (destination of the command). 5673 * cmd_len Length of the command. 5674 * resp_len Length of the expected response. 5675 * data_len Length of the data. 5676 * nodma Indicates weither the command and response. 5677 * will be transfer through DMA or not. 5678 * lcount Link state change counter. 5679 * tcount Target state change counter. 5680 * cause Reason that lead to this call. 5681 * 5682 * Return Value: NULL Failed. 5683 * Not NULL Internal packet address. 5684 */ 5685 static struct fcp_ipkt * 5686 fcp_icmd_alloc(struct fcp_port *pptr, struct fcp_tgt *ptgt, int cmd_len, 5687 int resp_len, int data_len, int nodma, int lcount, int tcount, int cause, 5688 uint32_t rscn_count) 5689 { 5690 int dma_setup = 0; 5691 fc_packet_t *fpkt; 5692 struct fcp_ipkt *icmd = NULL; 5693 5694 icmd = kmem_zalloc(sizeof (struct fcp_ipkt) + 5695 pptr->port_dmacookie_sz + pptr->port_priv_pkt_len, 5696 KM_NOSLEEP); 5697 if (icmd == NULL) { 5698 fcp_log(CE_WARN, pptr->port_dip, 5699 "!internal packet allocation failed"); 5700 return (NULL); 5701 } 5702 5703 /* 5704 * initialize the allocated packet 5705 */ 5706 icmd->ipkt_nodma = nodma; 5707 icmd->ipkt_next = icmd->ipkt_prev = NULL; 5708 icmd->ipkt_lun = NULL; 5709 5710 icmd->ipkt_link_cnt = lcount; 5711 icmd->ipkt_change_cnt = tcount; 5712 icmd->ipkt_cause = cause; 5713 5714 mutex_enter(&pptr->port_mutex); 5715 icmd->ipkt_port = pptr; 5716 mutex_exit(&pptr->port_mutex); 5717 5718 /* keep track of amt of data to be sent in pkt */ 5719 icmd->ipkt_cmdlen = cmd_len; 5720 icmd->ipkt_resplen = resp_len; 5721 icmd->ipkt_datalen = data_len; 5722 5723 /* set up pkt's ptr to the fc_packet_t struct, just after the ipkt */ 5724 icmd->ipkt_fpkt = (fc_packet_t *)(&icmd->ipkt_fc_packet); 5725 5726 /* set pkt's private ptr to point to cmd pkt */ 5727 icmd->ipkt_fpkt->pkt_ulp_private = (opaque_t)icmd; 5728 5729 /* set FCA private ptr to memory just beyond */ 5730 icmd->ipkt_fpkt->pkt_fca_private = (opaque_t) 5731 ((char *)icmd + sizeof (struct fcp_ipkt) + 5732 pptr->port_dmacookie_sz); 5733 5734 /* get ptr to fpkt substruct and fill it in */ 5735 fpkt = icmd->ipkt_fpkt; 5736 fpkt->pkt_data_cookie = (ddi_dma_cookie_t *)((caddr_t)icmd + 5737 sizeof (struct fcp_ipkt)); 5738 5739 if (ptgt != NULL) { 5740 icmd->ipkt_tgt = ptgt; 5741 fpkt->pkt_fca_device = ptgt->tgt_fca_dev; 5742 } 5743 5744 fpkt->pkt_comp = fcp_icmd_callback; 5745 fpkt->pkt_tran_flags = (FC_TRAN_CLASS3 | FC_TRAN_INTR); 5746 fpkt->pkt_cmdlen = cmd_len; 5747 fpkt->pkt_rsplen = resp_len; 5748 fpkt->pkt_datalen = data_len; 5749 5750 /* 5751 * The pkt_ulp_rscn_infop (aka pkt_ulp_rsvd1) field is used to pass the 5752 * rscn_count as fcp knows down to the transport. If a valid count was 5753 * passed into this function, we allocate memory to actually pass down 5754 * this info. 5755 * 5756 * BTW, if the kmem_zalloc fails, we won't try too hard. This will 5757 * basically mean that fcp will not be able to help transport 5758 * distinguish if a new RSCN has come after fcp was last informed about 5759 * it. In such cases, it might lead to the problem mentioned in CR/bug # 5760 * 5068068 where the device might end up going offline in case of RSCN 5761 * storms. 5762 */ 5763 fpkt->pkt_ulp_rscn_infop = NULL; 5764 if (rscn_count != FC_INVALID_RSCN_COUNT) { 5765 fpkt->pkt_ulp_rscn_infop = kmem_zalloc( 5766 sizeof (fc_ulp_rscn_info_t), KM_NOSLEEP); 5767 if (fpkt->pkt_ulp_rscn_infop == NULL) { 5768 FCP_TRACE(fcp_logq, pptr->port_instbuf, 5769 fcp_trace, FCP_BUF_LEVEL_6, 0, 5770 "Failed to alloc memory to pass rscn info"); 5771 } 5772 } 5773 5774 if (fpkt->pkt_ulp_rscn_infop != NULL) { 5775 fc_ulp_rscn_info_t *rscnp; 5776 5777 rscnp = (fc_ulp_rscn_info_t *)fpkt->pkt_ulp_rscn_infop; 5778 rscnp->ulp_rscn_count = rscn_count; 5779 } 5780 5781 if (fcp_alloc_dma(pptr, icmd, nodma, KM_NOSLEEP) != FC_SUCCESS) { 5782 goto fail; 5783 } 5784 dma_setup++; 5785 5786 /* 5787 * Must hold target mutex across setting of pkt_pd and call to 5788 * fc_ulp_init_packet to ensure the handle to the target doesn't go 5789 * away while we're not looking. 5790 */ 5791 if (ptgt != NULL) { 5792 mutex_enter(&ptgt->tgt_mutex); 5793 fpkt->pkt_pd = ptgt->tgt_pd_handle; 5794 5795 /* ask transport to do its initialization on this pkt */ 5796 if (fc_ulp_init_packet(pptr->port_fp_handle, fpkt, KM_NOSLEEP) 5797 != FC_SUCCESS) { 5798 FCP_TRACE(fcp_logq, pptr->port_instbuf, 5799 fcp_trace, FCP_BUF_LEVEL_6, 0, 5800 "fc_ulp_init_packet failed"); 5801 mutex_exit(&ptgt->tgt_mutex); 5802 goto fail; 5803 } 5804 mutex_exit(&ptgt->tgt_mutex); 5805 } else { 5806 if (fc_ulp_init_packet(pptr->port_fp_handle, fpkt, KM_NOSLEEP) 5807 != FC_SUCCESS) { 5808 FCP_TRACE(fcp_logq, pptr->port_instbuf, 5809 fcp_trace, FCP_BUF_LEVEL_6, 0, 5810 "fc_ulp_init_packet failed"); 5811 goto fail; 5812 } 5813 } 5814 5815 mutex_enter(&pptr->port_mutex); 5816 if (pptr->port_state & (FCP_STATE_DETACHING | 5817 FCP_STATE_SUSPENDED | FCP_STATE_POWER_DOWN)) { 5818 int rval; 5819 5820 mutex_exit(&pptr->port_mutex); 5821 5822 rval = fc_ulp_uninit_packet(pptr->port_fp_handle, fpkt); 5823 ASSERT(rval == FC_SUCCESS); 5824 5825 goto fail; 5826 } 5827 5828 if (ptgt != NULL) { 5829 mutex_enter(&ptgt->tgt_mutex); 5830 ptgt->tgt_ipkt_cnt++; 5831 mutex_exit(&ptgt->tgt_mutex); 5832 } 5833 5834 pptr->port_ipkt_cnt++; 5835 5836 mutex_exit(&pptr->port_mutex); 5837 5838 return (icmd); 5839 5840 fail: 5841 if (fpkt->pkt_ulp_rscn_infop != NULL) { 5842 kmem_free(fpkt->pkt_ulp_rscn_infop, 5843 sizeof (fc_ulp_rscn_info_t)); 5844 fpkt->pkt_ulp_rscn_infop = NULL; 5845 } 5846 5847 if (dma_setup) { 5848 fcp_free_dma(pptr, icmd); 5849 } 5850 kmem_free(icmd, sizeof (struct fcp_ipkt) + pptr->port_priv_pkt_len + 5851 (size_t)pptr->port_dmacookie_sz); 5852 5853 return (NULL); 5854 } 5855 5856 /* 5857 * Function: fcp_icmd_free 5858 * 5859 * Description: Frees the internal command passed by the caller. 5860 * 5861 * Argument: *pptr Fcp port. 5862 * *icmd Internal packet to free. 5863 * 5864 * Return Value: None 5865 */ 5866 static void 5867 fcp_icmd_free(struct fcp_port *pptr, struct fcp_ipkt *icmd) 5868 { 5869 struct fcp_tgt *ptgt = icmd->ipkt_tgt; 5870 5871 /* Let the underlying layers do their cleanup. */ 5872 (void) fc_ulp_uninit_packet(pptr->port_fp_handle, 5873 icmd->ipkt_fpkt); 5874 5875 if (icmd->ipkt_fpkt->pkt_ulp_rscn_infop) { 5876 kmem_free(icmd->ipkt_fpkt->pkt_ulp_rscn_infop, 5877 sizeof (fc_ulp_rscn_info_t)); 5878 } 5879 5880 fcp_free_dma(pptr, icmd); 5881 5882 kmem_free(icmd, sizeof (struct fcp_ipkt) + pptr->port_priv_pkt_len + 5883 (size_t)pptr->port_dmacookie_sz); 5884 5885 mutex_enter(&pptr->port_mutex); 5886 5887 if (ptgt) { 5888 mutex_enter(&ptgt->tgt_mutex); 5889 ptgt->tgt_ipkt_cnt--; 5890 mutex_exit(&ptgt->tgt_mutex); 5891 } 5892 5893 pptr->port_ipkt_cnt--; 5894 mutex_exit(&pptr->port_mutex); 5895 } 5896 5897 /* 5898 * Function: fcp_alloc_dma 5899 * 5900 * Description: Allocated the DMA resources required for the internal 5901 * packet. 5902 * 5903 * Argument: *pptr FCP port. 5904 * *icmd Internal FCP packet. 5905 * nodma Indicates if the Cmd and Resp will be DMAed. 5906 * flags Allocation flags (Sleep or NoSleep). 5907 * 5908 * Return Value: FC_SUCCESS 5909 * FC_NOMEM 5910 */ 5911 static int 5912 fcp_alloc_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd, 5913 int nodma, int flags) 5914 { 5915 int rval; 5916 size_t real_size; 5917 uint_t ccount; 5918 int bound = 0; 5919 int cmd_resp = 0; 5920 fc_packet_t *fpkt; 5921 ddi_dma_cookie_t pkt_data_cookie; 5922 ddi_dma_cookie_t *cp; 5923 uint32_t cnt; 5924 5925 fpkt = &icmd->ipkt_fc_packet; 5926 5927 ASSERT(fpkt->pkt_cmd_dma == NULL && fpkt->pkt_data_dma == NULL && 5928 fpkt->pkt_resp_dma == NULL); 5929 5930 icmd->ipkt_nodma = nodma; 5931 5932 if (nodma) { 5933 fpkt->pkt_cmd = kmem_zalloc(fpkt->pkt_cmdlen, flags); 5934 if (fpkt->pkt_cmd == NULL) { 5935 goto fail; 5936 } 5937 5938 fpkt->pkt_resp = kmem_zalloc(fpkt->pkt_rsplen, flags); 5939 if (fpkt->pkt_resp == NULL) { 5940 goto fail; 5941 } 5942 } else { 5943 ASSERT(fpkt->pkt_cmdlen && fpkt->pkt_rsplen); 5944 5945 rval = fcp_alloc_cmd_resp(pptr, fpkt, flags); 5946 if (rval == FC_FAILURE) { 5947 ASSERT(fpkt->pkt_cmd_dma == NULL && 5948 fpkt->pkt_resp_dma == NULL); 5949 goto fail; 5950 } 5951 cmd_resp++; 5952 } 5953 5954 if (fpkt->pkt_datalen != 0) { 5955 /* 5956 * set up DMA handle and memory for the data in this packet 5957 */ 5958 if (ddi_dma_alloc_handle(pptr->port_dip, 5959 &pptr->port_data_dma_attr, DDI_DMA_DONTWAIT, 5960 NULL, &fpkt->pkt_data_dma) != DDI_SUCCESS) { 5961 goto fail; 5962 } 5963 5964 if (ddi_dma_mem_alloc(fpkt->pkt_data_dma, fpkt->pkt_datalen, 5965 &pptr->port_dma_acc_attr, DDI_DMA_CONSISTENT, 5966 DDI_DMA_DONTWAIT, NULL, &fpkt->pkt_data, 5967 &real_size, &fpkt->pkt_data_acc) != DDI_SUCCESS) { 5968 goto fail; 5969 } 5970 5971 /* was DMA mem size gotten < size asked for/needed ?? */ 5972 if (real_size < fpkt->pkt_datalen) { 5973 goto fail; 5974 } 5975 5976 /* bind DMA address and handle together */ 5977 if (ddi_dma_addr_bind_handle(fpkt->pkt_data_dma, 5978 NULL, fpkt->pkt_data, real_size, DDI_DMA_READ | 5979 DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, 5980 &pkt_data_cookie, &ccount) != DDI_DMA_MAPPED) { 5981 goto fail; 5982 } 5983 bound++; 5984 5985 if (ccount > pptr->port_data_dma_attr.dma_attr_sgllen) { 5986 goto fail; 5987 } 5988 5989 fpkt->pkt_data_cookie_cnt = ccount; 5990 5991 cp = fpkt->pkt_data_cookie; 5992 *cp = pkt_data_cookie; 5993 cp++; 5994 5995 for (cnt = 1; cnt < ccount; cnt++, cp++) { 5996 ddi_dma_nextcookie(fpkt->pkt_data_dma, 5997 &pkt_data_cookie); 5998 *cp = pkt_data_cookie; 5999 } 6000 6001 } 6002 6003 return (FC_SUCCESS); 6004 6005 fail: 6006 if (bound) { 6007 (void) ddi_dma_unbind_handle(fpkt->pkt_data_dma); 6008 } 6009 6010 if (fpkt->pkt_data_dma) { 6011 if (fpkt->pkt_data) { 6012 ddi_dma_mem_free(&fpkt->pkt_data_acc); 6013 } 6014 ddi_dma_free_handle(&fpkt->pkt_data_dma); 6015 } 6016 6017 if (nodma) { 6018 if (fpkt->pkt_cmd) { 6019 kmem_free(fpkt->pkt_cmd, fpkt->pkt_cmdlen); 6020 } 6021 if (fpkt->pkt_resp) { 6022 kmem_free(fpkt->pkt_resp, fpkt->pkt_rsplen); 6023 } 6024 } else { 6025 if (cmd_resp) { 6026 fcp_free_cmd_resp(pptr, fpkt); 6027 } 6028 } 6029 6030 return (FC_NOMEM); 6031 } 6032 6033 6034 static void 6035 fcp_free_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd) 6036 { 6037 fc_packet_t *fpkt = icmd->ipkt_fpkt; 6038 6039 if (fpkt->pkt_data_dma) { 6040 (void) ddi_dma_unbind_handle(fpkt->pkt_data_dma); 6041 if (fpkt->pkt_data) { 6042 ddi_dma_mem_free(&fpkt->pkt_data_acc); 6043 } 6044 ddi_dma_free_handle(&fpkt->pkt_data_dma); 6045 } 6046 6047 if (icmd->ipkt_nodma) { 6048 if (fpkt->pkt_cmd) { 6049 kmem_free(fpkt->pkt_cmd, icmd->ipkt_cmdlen); 6050 } 6051 if (fpkt->pkt_resp) { 6052 kmem_free(fpkt->pkt_resp, icmd->ipkt_resplen); 6053 } 6054 } else { 6055 ASSERT(fpkt->pkt_resp_dma != NULL && fpkt->pkt_cmd_dma != NULL); 6056 6057 fcp_free_cmd_resp(pptr, fpkt); 6058 } 6059 } 6060 6061 /* 6062 * Function: fcp_lookup_target 6063 * 6064 * Description: Finds a target given a WWN. 6065 * 6066 * Argument: *pptr FCP port. 6067 * *wwn World Wide Name of the device to look for. 6068 * 6069 * Return Value: NULL No target found 6070 * Not NULL Target structure 6071 * 6072 * Context: Interrupt context. 6073 * The mutex pptr->port_mutex must be owned. 6074 */ 6075 /* ARGSUSED */ 6076 static struct fcp_tgt * 6077 fcp_lookup_target(struct fcp_port *pptr, uchar_t *wwn) 6078 { 6079 int hash; 6080 struct fcp_tgt *ptgt; 6081 6082 ASSERT(mutex_owned(&pptr->port_mutex)); 6083 6084 hash = FCP_HASH(wwn); 6085 6086 for (ptgt = pptr->port_tgt_hash_table[hash]; ptgt != NULL; 6087 ptgt = ptgt->tgt_next) { 6088 if (!(ptgt->tgt_state & FCP_TGT_ORPHAN) && 6089 bcmp((caddr_t)wwn, (caddr_t)&ptgt->tgt_port_wwn.raw_wwn[0], 6090 sizeof (ptgt->tgt_port_wwn)) == 0) { 6091 break; 6092 } 6093 } 6094 6095 return (ptgt); 6096 } 6097 6098 6099 /* 6100 * Find target structure given a port identifier 6101 */ 6102 static struct fcp_tgt * 6103 fcp_get_target_by_did(struct fcp_port *pptr, uint32_t d_id) 6104 { 6105 fc_portid_t port_id; 6106 la_wwn_t pwwn; 6107 struct fcp_tgt *ptgt = NULL; 6108 6109 port_id.priv_lilp_posit = 0; 6110 port_id.port_id = d_id; 6111 if (fc_ulp_get_pwwn_by_did(pptr->port_fp_handle, port_id, 6112 &pwwn) == FC_SUCCESS) { 6113 mutex_enter(&pptr->port_mutex); 6114 ptgt = fcp_lookup_target(pptr, pwwn.raw_wwn); 6115 mutex_exit(&pptr->port_mutex); 6116 } 6117 6118 return (ptgt); 6119 } 6120 6121 6122 /* 6123 * the packet completion callback routine for info cmd pkts 6124 * 6125 * this means fpkt pts to a response to either a PLOGI or a PRLI 6126 * 6127 * if there is an error an attempt is made to call a routine to resend 6128 * the command that failed 6129 */ 6130 static void 6131 fcp_icmd_callback(fc_packet_t *fpkt) 6132 { 6133 struct fcp_ipkt *icmd; 6134 struct fcp_port *pptr; 6135 struct fcp_tgt *ptgt; 6136 struct la_els_prli *prli; 6137 struct la_els_prli prli_s; 6138 struct fcp_prli *fprli; 6139 struct fcp_lun *plun; 6140 int free_pkt = 1; 6141 int rval; 6142 ls_code_t resp; 6143 uchar_t prli_acc = 0; 6144 uint32_t rscn_count = FC_INVALID_RSCN_COUNT; 6145 int lun0_newalloc; 6146 6147 icmd = (struct fcp_ipkt *)fpkt->pkt_ulp_private; 6148 6149 /* get ptrs to the port and target structs for the cmd */ 6150 pptr = icmd->ipkt_port; 6151 ptgt = icmd->ipkt_tgt; 6152 6153 FCP_CP_IN(fpkt->pkt_resp, &resp, fpkt->pkt_resp_acc, sizeof (resp)); 6154 6155 if (icmd->ipkt_opcode == LA_ELS_PRLI) { 6156 FCP_CP_IN(fpkt->pkt_cmd, &prli_s, fpkt->pkt_cmd_acc, 6157 sizeof (prli_s)); 6158 prli_acc = (prli_s.ls_code == LA_ELS_ACC); 6159 } 6160 6161 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6162 fcp_trace, FCP_BUF_LEVEL_2, 0, 6163 "ELS (%x) callback state=0x%x reason=0x%x for %x", 6164 icmd->ipkt_opcode, fpkt->pkt_state, fpkt->pkt_reason, 6165 ptgt->tgt_d_id); 6166 6167 if ((fpkt->pkt_state == FC_PKT_SUCCESS) && 6168 ((resp.ls_code == LA_ELS_ACC) || prli_acc)) { 6169 6170 mutex_enter(&ptgt->tgt_mutex); 6171 if (ptgt->tgt_pd_handle == NULL) { 6172 /* 6173 * in a fabric environment the port device handles 6174 * get created only after successful LOGIN into the 6175 * transport, so the transport makes this port 6176 * device (pd) handle available in this packet, so 6177 * save it now 6178 */ 6179 ASSERT(fpkt->pkt_pd != NULL); 6180 ptgt->tgt_pd_handle = fpkt->pkt_pd; 6181 } 6182 mutex_exit(&ptgt->tgt_mutex); 6183 6184 /* which ELS cmd is this response for ?? */ 6185 switch (icmd->ipkt_opcode) { 6186 case LA_ELS_PLOGI: 6187 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6188 fcp_trace, FCP_BUF_LEVEL_5, 0, 6189 "PLOGI to d_id=0x%x succeeded, wwn=%08x%08x", 6190 ptgt->tgt_d_id, 6191 *((int *)&ptgt->tgt_port_wwn.raw_wwn[0]), 6192 *((int *)&ptgt->tgt_port_wwn.raw_wwn[4])); 6193 6194 FCP_TGT_TRACE(ptgt, icmd->ipkt_change_cnt, 6195 FCP_TGT_TRACE_15); 6196 6197 /* Note that we are not allocating a new icmd */ 6198 if (fcp_send_els(pptr, ptgt, icmd, LA_ELS_PRLI, 6199 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 6200 icmd->ipkt_cause) != DDI_SUCCESS) { 6201 FCP_TGT_TRACE(ptgt, icmd->ipkt_change_cnt, 6202 FCP_TGT_TRACE_16); 6203 goto fail; 6204 } 6205 break; 6206 6207 case LA_ELS_PRLI: 6208 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6209 fcp_trace, FCP_BUF_LEVEL_5, 0, 6210 "PRLI to d_id=0x%x succeeded", ptgt->tgt_d_id); 6211 6212 FCP_TGT_TRACE(ptgt, icmd->ipkt_change_cnt, 6213 FCP_TGT_TRACE_17); 6214 6215 prli = &prli_s; 6216 6217 FCP_CP_IN(fpkt->pkt_resp, prli, fpkt->pkt_resp_acc, 6218 sizeof (prli_s)); 6219 6220 fprli = (struct fcp_prli *)prli->service_params; 6221 6222 mutex_enter(&ptgt->tgt_mutex); 6223 ptgt->tgt_icap = fprli->initiator_fn; 6224 ptgt->tgt_tcap = fprli->target_fn; 6225 mutex_exit(&ptgt->tgt_mutex); 6226 6227 if ((fprli->type != 0x08) || (fprli->target_fn != 1)) { 6228 /* 6229 * this FCP device does not support target mode 6230 */ 6231 FCP_TGT_TRACE(ptgt, icmd->ipkt_change_cnt, 6232 FCP_TGT_TRACE_18); 6233 goto fail; 6234 } 6235 if (fprli->retry == 1) { 6236 fc_ulp_disable_relogin(pptr->port_fp_handle, 6237 &ptgt->tgt_port_wwn); 6238 } 6239 6240 /* target is no longer offline */ 6241 mutex_enter(&pptr->port_mutex); 6242 mutex_enter(&ptgt->tgt_mutex); 6243 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 6244 ptgt->tgt_state &= ~(FCP_TGT_OFFLINE | 6245 FCP_TGT_MARK); 6246 } else { 6247 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6248 fcp_trace, FCP_BUF_LEVEL_2, 0, 6249 "fcp_icmd_callback,1: state change " 6250 " occured for D_ID=0x%x", ptgt->tgt_d_id); 6251 mutex_exit(&ptgt->tgt_mutex); 6252 mutex_exit(&pptr->port_mutex); 6253 goto fail; 6254 } 6255 mutex_exit(&ptgt->tgt_mutex); 6256 mutex_exit(&pptr->port_mutex); 6257 6258 /* 6259 * lun 0 should always respond to inquiry, so 6260 * get the LUN struct for LUN 0 6261 * 6262 * Currently we deal with first level of addressing. 6263 * If / when we start supporting 0x device types 6264 * (DTYPE_ARRAY_CTRL, i.e. array controllers) 6265 * this logic will need revisiting. 6266 */ 6267 lun0_newalloc = 0; 6268 if ((plun = fcp_get_lun(ptgt, 0)) == NULL) { 6269 /* 6270 * no LUN struct for LUN 0 yet exists, 6271 * so create one 6272 */ 6273 plun = fcp_alloc_lun(ptgt); 6274 if (plun == NULL) { 6275 fcp_log(CE_WARN, pptr->port_dip, 6276 "!Failed to allocate lun 0 for" 6277 " D_ID=%x", ptgt->tgt_d_id); 6278 goto fail; 6279 } 6280 lun0_newalloc = 1; 6281 } 6282 6283 /* fill in LUN info */ 6284 mutex_enter(&ptgt->tgt_mutex); 6285 /* 6286 * consider lun 0 as device not connected if it is 6287 * offlined or newly allocated 6288 */ 6289 if ((plun->lun_state & FCP_LUN_OFFLINE) || 6290 lun0_newalloc) { 6291 plun->lun_state |= FCP_LUN_DEVICE_NOT_CONNECTED; 6292 } 6293 plun->lun_state |= (FCP_LUN_BUSY | FCP_LUN_MARK); 6294 plun->lun_state &= ~FCP_LUN_OFFLINE; 6295 ptgt->tgt_lun_cnt = 1; 6296 ptgt->tgt_report_lun_cnt = 0; 6297 mutex_exit(&ptgt->tgt_mutex); 6298 6299 /* Retrieve the rscn count (if a valid one exists) */ 6300 if (icmd->ipkt_fpkt->pkt_ulp_rscn_infop != NULL) { 6301 rscn_count = ((fc_ulp_rscn_info_t *) 6302 (icmd->ipkt_fpkt->pkt_ulp_rscn_infop)) 6303 ->ulp_rscn_count; 6304 } else { 6305 rscn_count = FC_INVALID_RSCN_COUNT; 6306 } 6307 6308 /* send Report Lun request to target */ 6309 if (fcp_send_scsi(plun, SCMD_REPORT_LUN, 6310 sizeof (struct fcp_reportlun_resp), 6311 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 6312 icmd->ipkt_cause, rscn_count) != DDI_SUCCESS) { 6313 mutex_enter(&pptr->port_mutex); 6314 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 6315 fcp_log(CE_WARN, pptr->port_dip, 6316 "!Failed to send REPORT LUN to" 6317 " D_ID=%x", ptgt->tgt_d_id); 6318 } else { 6319 FCP_TRACE(fcp_logq, 6320 pptr->port_instbuf, fcp_trace, 6321 FCP_BUF_LEVEL_5, 0, 6322 "fcp_icmd_callback,2:state change" 6323 " occured for D_ID=0x%x", 6324 ptgt->tgt_d_id); 6325 } 6326 mutex_exit(&pptr->port_mutex); 6327 6328 FCP_TGT_TRACE(ptgt, icmd->ipkt_change_cnt, 6329 FCP_TGT_TRACE_19); 6330 6331 goto fail; 6332 } else { 6333 free_pkt = 0; 6334 fcp_icmd_free(pptr, icmd); 6335 } 6336 break; 6337 6338 default: 6339 fcp_log(CE_WARN, pptr->port_dip, 6340 "!fcp_icmd_callback Invalid opcode"); 6341 goto fail; 6342 } 6343 6344 return; 6345 } 6346 6347 6348 /* 6349 * Other PLOGI failures are not retried as the 6350 * transport does it already 6351 */ 6352 if (icmd->ipkt_opcode != LA_ELS_PLOGI) { 6353 if (fcp_is_retryable(icmd) && 6354 icmd->ipkt_retries++ < FCP_MAX_RETRIES) { 6355 6356 if (FCP_MUST_RETRY(fpkt)) { 6357 fcp_queue_ipkt(pptr, fpkt); 6358 return; 6359 } 6360 6361 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6362 fcp_trace, FCP_BUF_LEVEL_2, 0, 6363 "ELS PRLI is retried for d_id=0x%x, state=%x," 6364 " reason= %x", ptgt->tgt_d_id, fpkt->pkt_state, 6365 fpkt->pkt_reason); 6366 6367 /* 6368 * Retry by recalling the routine that 6369 * originally queued this packet 6370 */ 6371 mutex_enter(&pptr->port_mutex); 6372 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 6373 caddr_t msg; 6374 6375 mutex_exit(&pptr->port_mutex); 6376 6377 ASSERT(icmd->ipkt_opcode != LA_ELS_PLOGI); 6378 6379 if (fpkt->pkt_state == FC_PKT_TIMEOUT) { 6380 fpkt->pkt_timeout += 6381 FCP_TIMEOUT_DELTA; 6382 } 6383 6384 rval = fc_ulp_issue_els(pptr->port_fp_handle, 6385 fpkt); 6386 if (rval == FC_SUCCESS) { 6387 return; 6388 } 6389 6390 if (rval == FC_STATEC_BUSY || 6391 rval == FC_OFFLINE) { 6392 fcp_queue_ipkt(pptr, fpkt); 6393 return; 6394 } 6395 (void) fc_ulp_error(rval, &msg); 6396 6397 fcp_log(CE_NOTE, pptr->port_dip, 6398 "!ELS 0x%x failed to d_id=0x%x;" 6399 " %s", icmd->ipkt_opcode, 6400 ptgt->tgt_d_id, msg); 6401 } else { 6402 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6403 fcp_trace, FCP_BUF_LEVEL_2, 0, 6404 "fcp_icmd_callback,3: state change " 6405 " occured for D_ID=0x%x", ptgt->tgt_d_id); 6406 mutex_exit(&pptr->port_mutex); 6407 } 6408 } 6409 } else { 6410 if (fcp_is_retryable(icmd) && 6411 icmd->ipkt_retries++ < FCP_MAX_RETRIES) { 6412 if (FCP_MUST_RETRY(fpkt)) { 6413 fcp_queue_ipkt(pptr, fpkt); 6414 return; 6415 } 6416 } 6417 mutex_enter(&pptr->port_mutex); 6418 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd) && 6419 fpkt->pkt_state != FC_PKT_PORT_OFFLINE) { 6420 mutex_exit(&pptr->port_mutex); 6421 fcp_print_error(fpkt); 6422 } else { 6423 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6424 fcp_trace, FCP_BUF_LEVEL_2, 0, 6425 "fcp_icmd_callback,4: state change occured" 6426 " for D_ID=0x%x", ptgt->tgt_d_id); 6427 mutex_exit(&pptr->port_mutex); 6428 } 6429 } 6430 6431 fail: 6432 if (free_pkt) { 6433 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 6434 icmd->ipkt_change_cnt, icmd->ipkt_cause); 6435 fcp_icmd_free(pptr, icmd); 6436 } 6437 } 6438 6439 6440 /* 6441 * called internally to send an info cmd using the transport 6442 * 6443 * sends either an INQ or a REPORT_LUN 6444 * 6445 * when the packet is completed fcp_scsi_callback is called 6446 */ 6447 static int 6448 fcp_send_scsi(struct fcp_lun *plun, uchar_t opcode, int alloc_len, 6449 int lcount, int tcount, int cause, uint32_t rscn_count) 6450 { 6451 int nodma; 6452 struct fcp_ipkt *icmd; 6453 struct fcp_tgt *ptgt; 6454 struct fcp_port *pptr; 6455 fc_frame_hdr_t *hp; 6456 fc_packet_t *fpkt; 6457 struct fcp_cmd fcp_cmd; 6458 struct fcp_cmd *fcmd; 6459 union scsi_cdb *scsi_cdb; 6460 6461 ASSERT(plun != NULL); 6462 6463 ptgt = plun->lun_tgt; 6464 ASSERT(ptgt != NULL); 6465 6466 pptr = ptgt->tgt_port; 6467 ASSERT(pptr != NULL); 6468 6469 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6470 fcp_trace, FCP_BUF_LEVEL_5, 0, 6471 "fcp_send_scsi: d_id=0x%x opcode=0x%x", ptgt->tgt_d_id, opcode); 6472 6473 nodma = (pptr->port_fcp_dma == FC_NO_DVMA_SPACE) ? 1 : 0; 6474 6475 icmd = fcp_icmd_alloc(pptr, ptgt, sizeof (struct fcp_cmd), 6476 FCP_MAX_RSP_IU_SIZE, alloc_len, nodma, lcount, tcount, cause, 6477 rscn_count); 6478 6479 if (icmd == NULL) { 6480 return (DDI_FAILURE); 6481 } 6482 6483 fpkt = icmd->ipkt_fpkt; 6484 fpkt->pkt_tran_flags = FC_TRAN_CLASS3 | FC_TRAN_INTR; 6485 icmd->ipkt_retries = 0; 6486 icmd->ipkt_opcode = opcode; 6487 icmd->ipkt_lun = plun; 6488 6489 if (nodma) { 6490 fcmd = (struct fcp_cmd *)fpkt->pkt_cmd; 6491 } else { 6492 fcmd = &fcp_cmd; 6493 } 6494 bzero(fcmd, sizeof (struct fcp_cmd)); 6495 6496 fpkt->pkt_timeout = FCP_SCSI_CMD_TIMEOUT; 6497 6498 hp = &fpkt->pkt_cmd_fhdr; 6499 6500 hp->s_id = pptr->port_id; 6501 hp->d_id = ptgt->tgt_d_id; 6502 hp->r_ctl = R_CTL_COMMAND; 6503 hp->type = FC_TYPE_SCSI_FCP; 6504 hp->f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ; 6505 hp->rsvd = 0; 6506 hp->seq_id = 0; 6507 hp->seq_cnt = 0; 6508 hp->ox_id = 0xffff; 6509 hp->rx_id = 0xffff; 6510 hp->ro = 0; 6511 6512 bcopy(&(plun->lun_addr), &(fcmd->fcp_ent_addr), FCP_LUN_SIZE); 6513 6514 /* 6515 * Request SCSI target for expedited processing 6516 */ 6517 6518 /* 6519 * Set up for untagged queuing because we do not 6520 * know if the fibre device supports queuing. 6521 */ 6522 fcmd->fcp_cntl.cntl_reserved_0 = 0; 6523 fcmd->fcp_cntl.cntl_reserved_1 = 0; 6524 fcmd->fcp_cntl.cntl_reserved_2 = 0; 6525 fcmd->fcp_cntl.cntl_reserved_3 = 0; 6526 fcmd->fcp_cntl.cntl_reserved_4 = 0; 6527 fcmd->fcp_cntl.cntl_qtype = FCP_QTYPE_UNTAGGED; 6528 scsi_cdb = (union scsi_cdb *)fcmd->fcp_cdb; 6529 6530 switch (opcode) { 6531 case SCMD_INQUIRY_PAGE83: 6532 /* 6533 * Prepare to get the Inquiry VPD page 83 information 6534 */ 6535 fcmd->fcp_cntl.cntl_read_data = 1; 6536 fcmd->fcp_cntl.cntl_write_data = 0; 6537 fcmd->fcp_data_len = alloc_len; 6538 6539 fpkt->pkt_tran_type = FC_PKT_FCP_READ; 6540 fpkt->pkt_comp = fcp_scsi_callback; 6541 6542 scsi_cdb->scc_cmd = SCMD_INQUIRY; 6543 scsi_cdb->g0_addr2 = 0x01; 6544 scsi_cdb->g0_addr1 = 0x83; 6545 scsi_cdb->g0_count0 = (uchar_t)alloc_len; 6546 break; 6547 6548 case SCMD_INQUIRY: 6549 fcmd->fcp_cntl.cntl_read_data = 1; 6550 fcmd->fcp_cntl.cntl_write_data = 0; 6551 fcmd->fcp_data_len = alloc_len; 6552 6553 fpkt->pkt_tran_type = FC_PKT_FCP_READ; 6554 fpkt->pkt_comp = fcp_scsi_callback; 6555 6556 scsi_cdb->scc_cmd = SCMD_INQUIRY; 6557 scsi_cdb->g0_count0 = SUN_INQSIZE; 6558 break; 6559 6560 case SCMD_REPORT_LUN: { 6561 fc_portid_t d_id; 6562 opaque_t fca_dev; 6563 6564 ASSERT(alloc_len >= 16); 6565 6566 d_id.priv_lilp_posit = 0; 6567 d_id.port_id = ptgt->tgt_d_id; 6568 6569 fca_dev = fc_ulp_get_fca_device(pptr->port_fp_handle, d_id); 6570 6571 mutex_enter(&ptgt->tgt_mutex); 6572 ptgt->tgt_fca_dev = fca_dev; 6573 mutex_exit(&ptgt->tgt_mutex); 6574 6575 fcmd->fcp_cntl.cntl_read_data = 1; 6576 fcmd->fcp_cntl.cntl_write_data = 0; 6577 fcmd->fcp_data_len = alloc_len; 6578 6579 fpkt->pkt_tran_type = FC_PKT_FCP_READ; 6580 fpkt->pkt_comp = fcp_scsi_callback; 6581 6582 scsi_cdb->scc_cmd = SCMD_REPORT_LUN; 6583 scsi_cdb->scc5_count0 = alloc_len & 0xff; 6584 scsi_cdb->scc5_count1 = (alloc_len >> 8) & 0xff; 6585 scsi_cdb->scc5_count2 = (alloc_len >> 16) & 0xff; 6586 scsi_cdb->scc5_count3 = (alloc_len >> 24) & 0xff; 6587 break; 6588 } 6589 6590 default: 6591 fcp_log(CE_WARN, pptr->port_dip, 6592 "!fcp_send_scsi Invalid opcode"); 6593 break; 6594 } 6595 6596 if (!nodma) { 6597 FCP_CP_OUT((uint8_t *)fcmd, fpkt->pkt_cmd, 6598 fpkt->pkt_cmd_acc, sizeof (struct fcp_cmd)); 6599 } 6600 6601 mutex_enter(&pptr->port_mutex); 6602 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 6603 6604 mutex_exit(&pptr->port_mutex); 6605 if (fcp_transport(pptr->port_fp_handle, fpkt, 1) != 6606 FC_SUCCESS) { 6607 fcp_icmd_free(pptr, icmd); 6608 return (DDI_FAILURE); 6609 } 6610 return (DDI_SUCCESS); 6611 } else { 6612 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6613 fcp_trace, FCP_BUF_LEVEL_2, 0, 6614 "fcp_send_scsi,1: state change occured" 6615 " for D_ID=0x%x", ptgt->tgt_d_id); 6616 mutex_exit(&pptr->port_mutex); 6617 fcp_icmd_free(pptr, icmd); 6618 return (DDI_FAILURE); 6619 } 6620 } 6621 6622 6623 /* 6624 * called by fcp_scsi_callback to check to handle the case where 6625 * REPORT_LUN returns ILLEGAL REQUEST or a UNIT ATTENTION 6626 */ 6627 static int 6628 fcp_check_reportlun(struct fcp_rsp *rsp, fc_packet_t *fpkt) 6629 { 6630 uchar_t rqlen; 6631 int rval = DDI_FAILURE; 6632 struct scsi_extended_sense sense_info, *sense; 6633 struct fcp_ipkt *icmd = (struct fcp_ipkt *) 6634 fpkt->pkt_ulp_private; 6635 struct fcp_tgt *ptgt = icmd->ipkt_tgt; 6636 struct fcp_port *pptr = ptgt->tgt_port; 6637 6638 ASSERT(icmd->ipkt_opcode == SCMD_REPORT_LUN); 6639 6640 if (rsp->fcp_u.fcp_status.scsi_status == STATUS_RESERVATION_CONFLICT) { 6641 /* 6642 * SCSI-II Reserve Release support. Some older FC drives return 6643 * Reservation conflict for Report Luns command. 6644 */ 6645 if (icmd->ipkt_nodma) { 6646 rsp->fcp_u.fcp_status.rsp_len_set = 0; 6647 rsp->fcp_u.fcp_status.sense_len_set = 0; 6648 rsp->fcp_u.fcp_status.scsi_status = STATUS_GOOD; 6649 } else { 6650 fcp_rsp_t new_resp; 6651 6652 FCP_CP_IN(fpkt->pkt_resp, &new_resp, 6653 fpkt->pkt_resp_acc, sizeof (new_resp)); 6654 6655 new_resp.fcp_u.fcp_status.rsp_len_set = 0; 6656 new_resp.fcp_u.fcp_status.sense_len_set = 0; 6657 new_resp.fcp_u.fcp_status.scsi_status = STATUS_GOOD; 6658 6659 FCP_CP_OUT(&new_resp, fpkt->pkt_resp, 6660 fpkt->pkt_resp_acc, sizeof (new_resp)); 6661 } 6662 6663 FCP_CP_OUT(fcp_dummy_lun, fpkt->pkt_data, 6664 fpkt->pkt_data_acc, sizeof (fcp_dummy_lun)); 6665 6666 return (DDI_SUCCESS); 6667 } 6668 6669 sense = &sense_info; 6670 if (!rsp->fcp_u.fcp_status.sense_len_set) { 6671 /* no need to continue if sense length is not set */ 6672 return (rval); 6673 } 6674 6675 /* casting 64-bit integer to 8-bit */ 6676 rqlen = (uchar_t)min(rsp->fcp_sense_len, 6677 sizeof (struct scsi_extended_sense)); 6678 6679 if (rqlen < 14) { 6680 /* no need to continue if request length isn't long enough */ 6681 return (rval); 6682 } 6683 6684 if (icmd->ipkt_nodma) { 6685 /* 6686 * We can safely use fcp_response_len here since the 6687 * only path that calls fcp_check_reportlun, 6688 * fcp_scsi_callback, has already called 6689 * fcp_validate_fcp_response. 6690 */ 6691 sense = (struct scsi_extended_sense *)(fpkt->pkt_resp + 6692 sizeof (struct fcp_rsp) + rsp->fcp_response_len); 6693 } else { 6694 FCP_CP_IN(fpkt->pkt_resp + sizeof (struct fcp_rsp) + 6695 rsp->fcp_response_len, sense, fpkt->pkt_resp_acc, 6696 sizeof (struct scsi_extended_sense)); 6697 } 6698 6699 if (!FCP_SENSE_NO_LUN(sense)) { 6700 mutex_enter(&ptgt->tgt_mutex); 6701 /* clear the flag if any */ 6702 ptgt->tgt_state &= ~FCP_TGT_ILLREQ; 6703 mutex_exit(&ptgt->tgt_mutex); 6704 } 6705 6706 if ((sense->es_key == KEY_ILLEGAL_REQUEST) && 6707 (sense->es_add_code == 0x20)) { 6708 if (icmd->ipkt_nodma) { 6709 rsp->fcp_u.fcp_status.rsp_len_set = 0; 6710 rsp->fcp_u.fcp_status.sense_len_set = 0; 6711 rsp->fcp_u.fcp_status.scsi_status = STATUS_GOOD; 6712 } else { 6713 fcp_rsp_t new_resp; 6714 6715 FCP_CP_IN(fpkt->pkt_resp, &new_resp, 6716 fpkt->pkt_resp_acc, sizeof (new_resp)); 6717 6718 new_resp.fcp_u.fcp_status.rsp_len_set = 0; 6719 new_resp.fcp_u.fcp_status.sense_len_set = 0; 6720 new_resp.fcp_u.fcp_status.scsi_status = STATUS_GOOD; 6721 6722 FCP_CP_OUT(&new_resp, fpkt->pkt_resp, 6723 fpkt->pkt_resp_acc, sizeof (new_resp)); 6724 } 6725 6726 FCP_CP_OUT(fcp_dummy_lun, fpkt->pkt_data, 6727 fpkt->pkt_data_acc, sizeof (fcp_dummy_lun)); 6728 6729 return (DDI_SUCCESS); 6730 } 6731 6732 /* 6733 * This is for the STK library which returns a check condition, 6734 * to indicate device is not ready, manual assistance needed. 6735 * This is to a report lun command when the door is open. 6736 */ 6737 if ((sense->es_key == KEY_NOT_READY) && (sense->es_add_code == 0x04)) { 6738 if (icmd->ipkt_nodma) { 6739 rsp->fcp_u.fcp_status.rsp_len_set = 0; 6740 rsp->fcp_u.fcp_status.sense_len_set = 0; 6741 rsp->fcp_u.fcp_status.scsi_status = STATUS_GOOD; 6742 } else { 6743 fcp_rsp_t new_resp; 6744 6745 FCP_CP_IN(fpkt->pkt_resp, &new_resp, 6746 fpkt->pkt_resp_acc, sizeof (new_resp)); 6747 6748 new_resp.fcp_u.fcp_status.rsp_len_set = 0; 6749 new_resp.fcp_u.fcp_status.sense_len_set = 0; 6750 new_resp.fcp_u.fcp_status.scsi_status = STATUS_GOOD; 6751 6752 FCP_CP_OUT(&new_resp, fpkt->pkt_resp, 6753 fpkt->pkt_resp_acc, sizeof (new_resp)); 6754 } 6755 6756 FCP_CP_OUT(fcp_dummy_lun, fpkt->pkt_data, 6757 fpkt->pkt_data_acc, sizeof (fcp_dummy_lun)); 6758 6759 return (DDI_SUCCESS); 6760 } 6761 6762 if ((FCP_SENSE_REPORTLUN_CHANGED(sense)) || 6763 (FCP_SENSE_NO_LUN(sense))) { 6764 mutex_enter(&ptgt->tgt_mutex); 6765 if ((FCP_SENSE_NO_LUN(sense)) && 6766 (ptgt->tgt_state & FCP_TGT_ILLREQ)) { 6767 ptgt->tgt_state &= ~FCP_TGT_ILLREQ; 6768 mutex_exit(&ptgt->tgt_mutex); 6769 /* 6770 * reconfig was triggred by ILLEGAL REQUEST but 6771 * got ILLEGAL REQUEST again 6772 */ 6773 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6774 fcp_trace, FCP_BUF_LEVEL_3, 0, 6775 "!FCP: Unable to obtain Report Lun data" 6776 " target=%x", ptgt->tgt_d_id); 6777 } else { 6778 if (ptgt->tgt_tid == NULL) { 6779 timeout_id_t tid; 6780 /* 6781 * REPORT LUN data has changed. Kick off 6782 * rediscovery 6783 */ 6784 tid = timeout(fcp_reconfigure_luns, 6785 (caddr_t)ptgt, (clock_t)drv_usectohz(1)); 6786 6787 ptgt->tgt_tid = tid; 6788 ptgt->tgt_state |= FCP_TGT_BUSY; 6789 } 6790 if (FCP_SENSE_NO_LUN(sense)) { 6791 ptgt->tgt_state |= FCP_TGT_ILLREQ; 6792 } 6793 mutex_exit(&ptgt->tgt_mutex); 6794 if (FCP_SENSE_REPORTLUN_CHANGED(sense)) { 6795 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6796 fcp_trace, FCP_BUF_LEVEL_3, 0, 6797 "!FCP:Report Lun Has Changed" 6798 " target=%x", ptgt->tgt_d_id); 6799 } else if (FCP_SENSE_NO_LUN(sense)) { 6800 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6801 fcp_trace, FCP_BUF_LEVEL_3, 0, 6802 "!FCP:LU Not Supported" 6803 " target=%x", ptgt->tgt_d_id); 6804 } 6805 } 6806 rval = DDI_SUCCESS; 6807 } 6808 6809 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6810 fcp_trace, FCP_BUF_LEVEL_5, 0, 6811 "D_ID=%x, sense=%x, status=%x", 6812 fpkt->pkt_cmd_fhdr.d_id, sense->es_key, 6813 rsp->fcp_u.fcp_status.scsi_status); 6814 6815 return (rval); 6816 } 6817 6818 /* 6819 * Function: fcp_scsi_callback 6820 * 6821 * Description: This is the callback routine set by fcp_send_scsi() after 6822 * it calls fcp_icmd_alloc(). The SCSI command completed here 6823 * and autogenerated by FCP are: REPORT_LUN, INQUIRY and 6824 * INQUIRY_PAGE83. 6825 * 6826 * Argument: *fpkt FC packet used to convey the command 6827 * 6828 * Return Value: None 6829 */ 6830 static void 6831 fcp_scsi_callback(fc_packet_t *fpkt) 6832 { 6833 struct fcp_ipkt *icmd = (struct fcp_ipkt *) 6834 fpkt->pkt_ulp_private; 6835 struct fcp_rsp_info fcp_rsp_err, *bep; 6836 struct fcp_port *pptr; 6837 struct fcp_tgt *ptgt; 6838 struct fcp_lun *plun; 6839 struct fcp_rsp response, *rsp; 6840 6841 if (icmd->ipkt_nodma) { 6842 rsp = (struct fcp_rsp *)fpkt->pkt_resp; 6843 } else { 6844 rsp = &response; 6845 FCP_CP_IN(fpkt->pkt_resp, rsp, fpkt->pkt_resp_acc, 6846 sizeof (struct fcp_rsp)); 6847 } 6848 6849 ptgt = icmd->ipkt_tgt; 6850 pptr = ptgt->tgt_port; 6851 plun = icmd->ipkt_lun; 6852 6853 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6854 fcp_trace, FCP_BUF_LEVEL_2, 0, 6855 "SCSI callback state=0x%x for %x, op_code=0x%x, " 6856 "status=%x, lun num=%x", 6857 fpkt->pkt_state, ptgt->tgt_d_id, icmd->ipkt_opcode, 6858 rsp->fcp_u.fcp_status.scsi_status, plun->lun_num); 6859 6860 /* 6861 * Pre-init LUN GUID with NWWN if it is not a device that 6862 * supports multiple luns and we know it's not page83 6863 * compliant. Although using a NWWN is not lun unique, 6864 * we will be fine since there is only one lun behind the taget 6865 * in this case. 6866 */ 6867 if ((plun->lun_guid_size == 0) && 6868 (icmd->ipkt_opcode == SCMD_INQUIRY_PAGE83) && 6869 (fcp_symmetric_device_probe(plun) == 0)) { 6870 6871 char ascii_wwn[FC_WWN_SIZE*2+1]; 6872 fcp_wwn_to_ascii(&ptgt->tgt_node_wwn.raw_wwn[0], ascii_wwn); 6873 (void) fcp_copy_guid_2_lun_block(plun, ascii_wwn); 6874 } 6875 6876 /* 6877 * Some old FC tapes and FC <-> SCSI bridge devices return overrun 6878 * when thay have more data than what is asked in CDB. An overrun 6879 * is really when FCP_DL is smaller than the data length in CDB. 6880 * In the case here we know that REPORT LUN command we formed within 6881 * this binary has correct FCP_DL. So this OVERRUN is due to bad device 6882 * behavior. In reality this is FC_SUCCESS. 6883 */ 6884 if ((fpkt->pkt_state != FC_PKT_SUCCESS) && 6885 (fpkt->pkt_reason == FC_REASON_OVERRUN) && 6886 (icmd->ipkt_opcode == SCMD_REPORT_LUN)) { 6887 fpkt->pkt_state = FC_PKT_SUCCESS; 6888 } 6889 6890 if (fpkt->pkt_state != FC_PKT_SUCCESS) { 6891 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6892 fcp_trace, FCP_BUF_LEVEL_2, 0, 6893 "icmd failed with state=0x%x for %x", fpkt->pkt_state, 6894 ptgt->tgt_d_id); 6895 6896 if (fpkt->pkt_reason == FC_REASON_CRC_ERROR) { 6897 /* 6898 * Inquiry VPD page command on A5K SES devices would 6899 * result in data CRC errors. 6900 */ 6901 if (icmd->ipkt_opcode == SCMD_INQUIRY_PAGE83) { 6902 (void) fcp_handle_page83(fpkt, icmd, 1); 6903 return; 6904 } 6905 } 6906 if (fpkt->pkt_state == FC_PKT_TIMEOUT || 6907 FCP_MUST_RETRY(fpkt)) { 6908 fpkt->pkt_timeout += FCP_TIMEOUT_DELTA; 6909 fcp_retry_scsi_cmd(fpkt); 6910 return; 6911 } 6912 6913 FCP_TGT_TRACE(ptgt, icmd->ipkt_change_cnt, 6914 FCP_TGT_TRACE_20); 6915 6916 mutex_enter(&pptr->port_mutex); 6917 mutex_enter(&ptgt->tgt_mutex); 6918 if (!FCP_STATE_CHANGED(pptr, ptgt, icmd)) { 6919 mutex_exit(&ptgt->tgt_mutex); 6920 mutex_exit(&pptr->port_mutex); 6921 fcp_print_error(fpkt); 6922 } else { 6923 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6924 fcp_trace, FCP_BUF_LEVEL_2, 0, 6925 "fcp_scsi_callback,1: state change occured" 6926 " for D_ID=0x%x", ptgt->tgt_d_id); 6927 mutex_exit(&ptgt->tgt_mutex); 6928 mutex_exit(&pptr->port_mutex); 6929 } 6930 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 6931 icmd->ipkt_change_cnt, icmd->ipkt_cause); 6932 fcp_icmd_free(pptr, icmd); 6933 return; 6934 } 6935 6936 FCP_TGT_TRACE(ptgt, icmd->ipkt_change_cnt, FCP_TGT_TRACE_21); 6937 6938 mutex_enter(&pptr->port_mutex); 6939 mutex_enter(&ptgt->tgt_mutex); 6940 if (FCP_STATE_CHANGED(pptr, ptgt, icmd)) { 6941 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6942 fcp_trace, FCP_BUF_LEVEL_2, 0, 6943 "fcp_scsi_callback,2: state change occured" 6944 " for D_ID=0x%x", ptgt->tgt_d_id); 6945 mutex_exit(&ptgt->tgt_mutex); 6946 mutex_exit(&pptr->port_mutex); 6947 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 6948 icmd->ipkt_change_cnt, icmd->ipkt_cause); 6949 fcp_icmd_free(pptr, icmd); 6950 return; 6951 } 6952 ASSERT((ptgt->tgt_state & FCP_TGT_MARK) == 0); 6953 6954 mutex_exit(&ptgt->tgt_mutex); 6955 mutex_exit(&pptr->port_mutex); 6956 6957 if (icmd->ipkt_nodma) { 6958 bep = (struct fcp_rsp_info *)(fpkt->pkt_resp + 6959 sizeof (struct fcp_rsp)); 6960 } else { 6961 bep = &fcp_rsp_err; 6962 FCP_CP_IN(fpkt->pkt_resp + sizeof (struct fcp_rsp), bep, 6963 fpkt->pkt_resp_acc, sizeof (struct fcp_rsp_info)); 6964 } 6965 6966 if (fcp_validate_fcp_response(rsp, pptr) != FC_SUCCESS) { 6967 fcp_retry_scsi_cmd(fpkt); 6968 return; 6969 } 6970 6971 if (rsp->fcp_u.fcp_status.rsp_len_set && bep->rsp_code != 6972 FCP_NO_FAILURE) { 6973 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6974 fcp_trace, FCP_BUF_LEVEL_2, 0, 6975 "rsp_code=0x%x, rsp_len_set=0x%x", 6976 bep->rsp_code, rsp->fcp_u.fcp_status.rsp_len_set); 6977 fcp_retry_scsi_cmd(fpkt); 6978 return; 6979 } 6980 6981 if (rsp->fcp_u.fcp_status.scsi_status == STATUS_QFULL || 6982 rsp->fcp_u.fcp_status.scsi_status == STATUS_BUSY) { 6983 fcp_queue_ipkt(pptr, fpkt); 6984 return; 6985 } 6986 6987 /* 6988 * Devices that do not support INQUIRY_PAGE83, return check condition 6989 * with illegal request as per SCSI spec. 6990 * Crossbridge is one such device and Daktari's SES node is another. 6991 * We want to ideally enumerate these devices as a non-mpxio devices. 6992 * SES nodes (Daktari only currently) are an exception to this. 6993 */ 6994 if ((icmd->ipkt_opcode == SCMD_INQUIRY_PAGE83) && 6995 (rsp->fcp_u.fcp_status.scsi_status & STATUS_CHECK)) { 6996 6997 FCP_TRACE(fcp_logq, pptr->port_instbuf, 6998 fcp_trace, FCP_BUF_LEVEL_3, 0, 6999 "INQUIRY_PAGE83 for d_id %x (dtype:0x%x) failed with " 7000 "check condition. May enumerate as non-mpxio device", 7001 ptgt->tgt_d_id, plun->lun_type); 7002 7003 /* 7004 * If we let Daktari's SES be enumerated as a non-mpxio 7005 * device, there will be a discrepency in that the other 7006 * internal FC disks will get enumerated as mpxio devices. 7007 * Applications like luxadm expect this to be consistent. 7008 * 7009 * So, we put in a hack here to check if this is an SES device 7010 * and handle it here. 7011 */ 7012 if (plun->lun_type == DTYPE_ESI) { 7013 /* 7014 * Since, pkt_state is actually FC_PKT_SUCCESS 7015 * at this stage, we fake a failure here so that 7016 * fcp_handle_page83 will create a device path using 7017 * the WWN instead of the GUID which is not there anyway 7018 */ 7019 fpkt->pkt_state = FC_PKT_LOCAL_RJT; 7020 (void) fcp_handle_page83(fpkt, icmd, 1); 7021 return; 7022 } 7023 7024 mutex_enter(&ptgt->tgt_mutex); 7025 plun->lun_state &= ~(FCP_LUN_OFFLINE | 7026 FCP_LUN_MARK | FCP_LUN_BUSY); 7027 mutex_exit(&ptgt->tgt_mutex); 7028 7029 (void) fcp_call_finish_init(pptr, ptgt, 7030 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7031 icmd->ipkt_cause); 7032 fcp_icmd_free(pptr, icmd); 7033 return; 7034 } 7035 7036 if (rsp->fcp_u.fcp_status.scsi_status != STATUS_GOOD) { 7037 int rval = DDI_FAILURE; 7038 7039 /* 7040 * handle cases where report lun isn't supported 7041 * by faking up our own REPORT_LUN response or 7042 * UNIT ATTENTION 7043 */ 7044 if (icmd->ipkt_opcode == SCMD_REPORT_LUN) { 7045 rval = fcp_check_reportlun(rsp, fpkt); 7046 7047 /* 7048 * fcp_check_reportlun might have modified the 7049 * FCP response. Copy it in again to get an updated 7050 * FCP response 7051 */ 7052 if (rval == DDI_SUCCESS && icmd->ipkt_nodma == 0) { 7053 rsp = &response; 7054 7055 FCP_CP_IN(fpkt->pkt_resp, rsp, 7056 fpkt->pkt_resp_acc, 7057 sizeof (struct fcp_rsp)); 7058 } 7059 } 7060 7061 if (rsp->fcp_u.fcp_status.scsi_status != STATUS_GOOD) { 7062 if (rval == DDI_SUCCESS) { 7063 (void) fcp_call_finish_init(pptr, ptgt, 7064 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7065 icmd->ipkt_cause); 7066 fcp_icmd_free(pptr, icmd); 7067 } else { 7068 fcp_retry_scsi_cmd(fpkt); 7069 } 7070 7071 return; 7072 } 7073 } else { 7074 if (icmd->ipkt_opcode == SCMD_REPORT_LUN) { 7075 mutex_enter(&ptgt->tgt_mutex); 7076 ptgt->tgt_state &= ~FCP_TGT_ILLREQ; 7077 mutex_exit(&ptgt->tgt_mutex); 7078 } 7079 } 7080 7081 ASSERT(rsp->fcp_u.fcp_status.scsi_status == STATUS_GOOD); 7082 7083 (void) ddi_dma_sync(fpkt->pkt_data_dma, 0, 0, DDI_DMA_SYNC_FORCPU); 7084 7085 switch (icmd->ipkt_opcode) { 7086 case SCMD_INQUIRY: 7087 FCP_LUN_TRACE(plun, FCP_LUN_TRACE_1); 7088 fcp_handle_inquiry(fpkt, icmd); 7089 break; 7090 7091 case SCMD_REPORT_LUN: 7092 FCP_TGT_TRACE(ptgt, icmd->ipkt_change_cnt, 7093 FCP_TGT_TRACE_22); 7094 fcp_handle_reportlun(fpkt, icmd); 7095 break; 7096 7097 case SCMD_INQUIRY_PAGE83: 7098 FCP_LUN_TRACE(plun, FCP_LUN_TRACE_2); 7099 (void) fcp_handle_page83(fpkt, icmd, 0); 7100 break; 7101 7102 default: 7103 fcp_log(CE_WARN, NULL, "!Invalid SCSI opcode"); 7104 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 7105 icmd->ipkt_change_cnt, icmd->ipkt_cause); 7106 fcp_icmd_free(pptr, icmd); 7107 break; 7108 } 7109 } 7110 7111 7112 static void 7113 fcp_retry_scsi_cmd(fc_packet_t *fpkt) 7114 { 7115 struct fcp_ipkt *icmd = (struct fcp_ipkt *) 7116 fpkt->pkt_ulp_private; 7117 struct fcp_tgt *ptgt = icmd->ipkt_tgt; 7118 struct fcp_port *pptr = ptgt->tgt_port; 7119 7120 if (icmd->ipkt_retries < FCP_MAX_RETRIES && 7121 fcp_is_retryable(icmd)) { 7122 mutex_enter(&pptr->port_mutex); 7123 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 7124 mutex_exit(&pptr->port_mutex); 7125 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7126 fcp_trace, FCP_BUF_LEVEL_3, 0, 7127 "Retrying %s to %x; state=%x, reason=%x", 7128 (icmd->ipkt_opcode == SCMD_REPORT_LUN) ? 7129 "Report LUN" : "INQUIRY", ptgt->tgt_d_id, 7130 fpkt->pkt_state, fpkt->pkt_reason); 7131 7132 fcp_queue_ipkt(pptr, fpkt); 7133 } else { 7134 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7135 fcp_trace, FCP_BUF_LEVEL_3, 0, 7136 "fcp_retry_scsi_cmd,1: state change occured" 7137 " for D_ID=0x%x", ptgt->tgt_d_id); 7138 mutex_exit(&pptr->port_mutex); 7139 (void) fcp_call_finish_init(pptr, ptgt, 7140 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7141 icmd->ipkt_cause); 7142 fcp_icmd_free(pptr, icmd); 7143 } 7144 } else { 7145 fcp_print_error(fpkt); 7146 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 7147 icmd->ipkt_change_cnt, icmd->ipkt_cause); 7148 fcp_icmd_free(pptr, icmd); 7149 } 7150 } 7151 7152 /* 7153 * Function: fcp_handle_page83 7154 * 7155 * Description: Treats the response to INQUIRY_PAGE83. 7156 * 7157 * Argument: *fpkt FC packet used to convey the command. 7158 * *icmd Original fcp_ipkt structure. 7159 * ignore_page83_data 7160 * if it's 1, that means it's a special devices's 7161 * page83 response, it should be enumerated under mpxio 7162 * 7163 * Return Value: None 7164 */ 7165 static void 7166 fcp_handle_page83(fc_packet_t *fpkt, struct fcp_ipkt *icmd, 7167 int ignore_page83_data) 7168 { 7169 struct fcp_port *pptr; 7170 struct fcp_lun *plun; 7171 struct fcp_tgt *ptgt; 7172 uchar_t dev_id_page[SCMD_MAX_INQUIRY_PAGE83_SIZE]; 7173 int fail = 0; 7174 ddi_devid_t devid; 7175 char *guid = NULL; 7176 int ret; 7177 7178 ASSERT(icmd != NULL && fpkt != NULL); 7179 7180 pptr = icmd->ipkt_port; 7181 ptgt = icmd->ipkt_tgt; 7182 plun = icmd->ipkt_lun; 7183 7184 if (fpkt->pkt_state == FC_PKT_SUCCESS) { 7185 FCP_LUN_TRACE(plun, FCP_LUN_TRACE_7); 7186 7187 FCP_CP_IN(fpkt->pkt_data, dev_id_page, fpkt->pkt_data_acc, 7188 SCMD_MAX_INQUIRY_PAGE83_SIZE); 7189 7190 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7191 fcp_trace, FCP_BUF_LEVEL_5, 0, 7192 "fcp_handle_page83: port=%d, tgt D_ID=0x%x, " 7193 "dtype=0x%x, lun num=%x", 7194 pptr->port_instance, ptgt->tgt_d_id, 7195 dev_id_page[0], plun->lun_num); 7196 7197 ret = ddi_devid_scsi_encode( 7198 DEVID_SCSI_ENCODE_VERSION_LATEST, 7199 NULL, /* driver name */ 7200 (unsigned char *) &plun->lun_inq, /* standard inquiry */ 7201 sizeof (plun->lun_inq), /* size of standard inquiry */ 7202 NULL, /* page 80 data */ 7203 0, /* page 80 len */ 7204 dev_id_page, /* page 83 data */ 7205 SCMD_MAX_INQUIRY_PAGE83_SIZE, /* page 83 data len */ 7206 &devid); 7207 7208 if (ret == DDI_SUCCESS) { 7209 7210 guid = ddi_devid_to_guid(devid); 7211 7212 if (guid) { 7213 /* 7214 * Check our current guid. If it's non null 7215 * and it has changed, we need to copy it into 7216 * lun_old_guid since we might still need it. 7217 */ 7218 if (plun->lun_guid && 7219 strcmp(guid, plun->lun_guid)) { 7220 unsigned int len; 7221 7222 /* 7223 * If the guid of the LUN changes, 7224 * reconfiguration should be triggered 7225 * to reflect the changes. 7226 * i.e. we should offline the LUN with 7227 * the old guid, and online the LUN with 7228 * the new guid. 7229 */ 7230 plun->lun_state |= FCP_LUN_CHANGED; 7231 7232 if (plun->lun_old_guid) { 7233 kmem_free(plun->lun_old_guid, 7234 plun->lun_old_guid_size); 7235 } 7236 7237 len = plun->lun_guid_size; 7238 plun->lun_old_guid_size = len; 7239 7240 plun->lun_old_guid = kmem_zalloc(len, 7241 KM_NOSLEEP); 7242 7243 if (plun->lun_old_guid) { 7244 /* 7245 * The alloc was successful then 7246 * let's do the copy. 7247 */ 7248 bcopy(plun->lun_guid, 7249 plun->lun_old_guid, len); 7250 } else { 7251 fail = 1; 7252 plun->lun_old_guid_size = 0; 7253 } 7254 } 7255 if (!fail) { 7256 if (fcp_copy_guid_2_lun_block( 7257 plun, guid)) { 7258 fail = 1; 7259 } 7260 } 7261 ddi_devid_free_guid(guid); 7262 7263 } else { 7264 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7265 fcp_trace, FCP_BUF_LEVEL_2, 0, 7266 "fcp_handle_page83: unable to create " 7267 "GUID"); 7268 7269 /* couldn't create good guid from devid */ 7270 fail = 1; 7271 } 7272 ddi_devid_free(devid); 7273 7274 } else if (ret == DDI_NOT_WELL_FORMED) { 7275 /* NULL filled data for page 83 */ 7276 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7277 fcp_trace, FCP_BUF_LEVEL_2, 0, 7278 "fcp_handle_page83: retry GUID"); 7279 7280 icmd->ipkt_retries = 0; 7281 fcp_retry_scsi_cmd(fpkt); 7282 return; 7283 } else { 7284 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7285 fcp_trace, FCP_BUF_LEVEL_2, 0, 7286 "fcp_handle_page83: bad ddi_devid_scsi_encode %x", 7287 ret); 7288 /* 7289 * Since the page83 validation 7290 * introduced late, we are being 7291 * tolerant to the existing devices 7292 * that already found to be working 7293 * under mpxio, like A5200's SES device, 7294 * its page83 response will not be standard-compliant, 7295 * but we still want it to be enumerated under mpxio. 7296 */ 7297 if (fcp_symmetric_device_probe(plun) != 0) { 7298 fail = 1; 7299 } 7300 } 7301 7302 } else { 7303 /* bad packet state */ 7304 FCP_LUN_TRACE(plun, FCP_LUN_TRACE_8); 7305 7306 /* 7307 * For some special devices (A5K SES and Daktari's SES devices), 7308 * they should be enumerated under mpxio 7309 * or "luxadm dis" will fail 7310 */ 7311 if (ignore_page83_data) { 7312 fail = 0; 7313 } else { 7314 fail = 1; 7315 } 7316 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7317 fcp_trace, FCP_BUF_LEVEL_2, 0, 7318 "!Devid page cmd failed. " 7319 "fpkt_state: %x fpkt_reason: %x", 7320 "ignore_page83: %d", 7321 fpkt->pkt_state, fpkt->pkt_reason, 7322 ignore_page83_data); 7323 } 7324 7325 mutex_enter(&pptr->port_mutex); 7326 mutex_enter(&plun->lun_mutex); 7327 /* 7328 * If lun_cip is not NULL, then we needn't update lun_mpxio to avoid 7329 * mismatch between lun_cip and lun_mpxio. 7330 */ 7331 if (plun->lun_cip == NULL) { 7332 /* 7333 * If we don't have a guid for this lun it's because we were 7334 * unable to glean one from the page 83 response. Set the 7335 * control flag to 0 here to make sure that we don't attempt to 7336 * enumerate it under mpxio. 7337 */ 7338 if (fail || pptr->port_mpxio == 0) { 7339 plun->lun_mpxio = 0; 7340 } else { 7341 plun->lun_mpxio = 1; 7342 } 7343 } 7344 mutex_exit(&plun->lun_mutex); 7345 mutex_exit(&pptr->port_mutex); 7346 7347 mutex_enter(&ptgt->tgt_mutex); 7348 plun->lun_state &= 7349 ~(FCP_LUN_OFFLINE | FCP_LUN_MARK | FCP_LUN_BUSY); 7350 mutex_exit(&ptgt->tgt_mutex); 7351 7352 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 7353 icmd->ipkt_change_cnt, icmd->ipkt_cause); 7354 7355 fcp_icmd_free(pptr, icmd); 7356 } 7357 7358 /* 7359 * Function: fcp_handle_inquiry 7360 * 7361 * Description: Called by fcp_scsi_callback to handle the response to an 7362 * INQUIRY request. 7363 * 7364 * Argument: *fpkt FC packet used to convey the command. 7365 * *icmd Original fcp_ipkt structure. 7366 * 7367 * Return Value: None 7368 */ 7369 static void 7370 fcp_handle_inquiry(fc_packet_t *fpkt, struct fcp_ipkt *icmd) 7371 { 7372 struct fcp_port *pptr; 7373 struct fcp_lun *plun; 7374 struct fcp_tgt *ptgt; 7375 uchar_t dtype; 7376 uchar_t pqual; 7377 uint32_t rscn_count = FC_INVALID_RSCN_COUNT; 7378 7379 ASSERT(icmd != NULL && fpkt != NULL); 7380 7381 pptr = icmd->ipkt_port; 7382 ptgt = icmd->ipkt_tgt; 7383 plun = icmd->ipkt_lun; 7384 7385 FCP_CP_IN(fpkt->pkt_data, &plun->lun_inq, fpkt->pkt_data_acc, 7386 sizeof (struct scsi_inquiry)); 7387 7388 dtype = plun->lun_inq.inq_dtype & DTYPE_MASK; 7389 pqual = plun->lun_inq.inq_dtype >> 5; 7390 7391 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7392 fcp_trace, FCP_BUF_LEVEL_5, 0, 7393 "fcp_handle_inquiry: port=%d, tgt D_ID=0x%x, lun=0x%x, " 7394 "dtype=0x%x pqual: 0x%x", pptr->port_instance, ptgt->tgt_d_id, 7395 plun->lun_num, dtype, pqual); 7396 7397 if (pqual != 0) { 7398 /* 7399 * Non-zero peripheral qualifier 7400 */ 7401 fcp_log(CE_CONT, pptr->port_dip, 7402 "!Target 0x%x lun 0x%x: Nonzero peripheral qualifier: " 7403 "Device type=0x%x Peripheral qual=0x%x\n", 7404 ptgt->tgt_d_id, plun->lun_num, dtype, pqual); 7405 7406 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7407 fcp_trace, FCP_BUF_LEVEL_5, 0, 7408 "!Target 0x%x lun 0x%x: Nonzero peripheral qualifier: " 7409 "Device type=0x%x Peripheral qual=0x%x\n", 7410 ptgt->tgt_d_id, plun->lun_num, dtype, pqual); 7411 7412 FCP_LUN_TRACE(plun, FCP_LUN_TRACE_3); 7413 7414 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 7415 icmd->ipkt_change_cnt, icmd->ipkt_cause); 7416 fcp_icmd_free(pptr, icmd); 7417 return; 7418 } 7419 7420 /* 7421 * If the device is already initialized, check the dtype 7422 * for a change. If it has changed then update the flags 7423 * so the create_luns will offline the old device and 7424 * create the new device. Refer to bug: 4764752 7425 */ 7426 if ((plun->lun_state & FCP_LUN_INIT) && dtype != plun->lun_type) { 7427 plun->lun_state |= FCP_LUN_CHANGED; 7428 } 7429 plun->lun_type = plun->lun_inq.inq_dtype; 7430 7431 /* 7432 * This code is setting/initializing the throttling in the FCA 7433 * driver. 7434 */ 7435 mutex_enter(&pptr->port_mutex); 7436 if (!pptr->port_notify) { 7437 if (bcmp(plun->lun_inq.inq_pid, pid, strlen(pid)) == 0) { 7438 uint32_t cmd = 0; 7439 cmd = ((cmd & 0xFF | FC_NOTIFY_THROTTLE) | 7440 ((cmd & 0xFFFFFF00 >> 8) | 7441 FCP_SVE_THROTTLE << 8)); 7442 pptr->port_notify = 1; 7443 mutex_exit(&pptr->port_mutex); 7444 (void) fc_ulp_port_notify(pptr->port_fp_handle, cmd); 7445 mutex_enter(&pptr->port_mutex); 7446 } 7447 } 7448 7449 if (FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 7450 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7451 fcp_trace, FCP_BUF_LEVEL_2, 0, 7452 "fcp_handle_inquiry,1:state change occured" 7453 " for D_ID=0x%x", ptgt->tgt_d_id); 7454 mutex_exit(&pptr->port_mutex); 7455 7456 FCP_LUN_TRACE(plun, FCP_LUN_TRACE_5); 7457 (void) fcp_call_finish_init(pptr, ptgt, 7458 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7459 icmd->ipkt_cause); 7460 fcp_icmd_free(pptr, icmd); 7461 return; 7462 } 7463 ASSERT((ptgt->tgt_state & FCP_TGT_MARK) == 0); 7464 mutex_exit(&pptr->port_mutex); 7465 7466 /* Retrieve the rscn count (if a valid one exists) */ 7467 if (icmd->ipkt_fpkt->pkt_ulp_rscn_infop != NULL) { 7468 rscn_count = ((fc_ulp_rscn_info_t *) 7469 (icmd->ipkt_fpkt->pkt_ulp_rscn_infop))->ulp_rscn_count; 7470 } else { 7471 rscn_count = FC_INVALID_RSCN_COUNT; 7472 } 7473 7474 if (fcp_send_scsi(plun, SCMD_INQUIRY_PAGE83, 7475 SCMD_MAX_INQUIRY_PAGE83_SIZE, 7476 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7477 icmd->ipkt_cause, rscn_count) != DDI_SUCCESS) { 7478 fcp_log(CE_WARN, NULL, "!failed to send page 83"); 7479 FCP_LUN_TRACE(plun, FCP_LUN_TRACE_6); 7480 (void) fcp_call_finish_init(pptr, ptgt, 7481 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7482 icmd->ipkt_cause); 7483 } 7484 7485 /* 7486 * Read Inquiry VPD Page 0x83 to uniquely 7487 * identify this logical unit. 7488 */ 7489 fcp_icmd_free(pptr, icmd); 7490 } 7491 7492 /* 7493 * Function: fcp_handle_reportlun 7494 * 7495 * Description: Called by fcp_scsi_callback to handle the response to a 7496 * REPORT_LUN request. 7497 * 7498 * Argument: *fpkt FC packet used to convey the command. 7499 * *icmd Original fcp_ipkt structure. 7500 * 7501 * Return Value: None 7502 */ 7503 static void 7504 fcp_handle_reportlun(fc_packet_t *fpkt, struct fcp_ipkt *icmd) 7505 { 7506 int i; 7507 int nluns_claimed; 7508 int nluns_bufmax; 7509 int len; 7510 uint16_t lun_num; 7511 uint32_t rscn_count = FC_INVALID_RSCN_COUNT; 7512 struct fcp_port *pptr; 7513 struct fcp_tgt *ptgt; 7514 struct fcp_lun *plun; 7515 struct fcp_reportlun_resp *report_lun; 7516 7517 pptr = icmd->ipkt_port; 7518 ptgt = icmd->ipkt_tgt; 7519 len = fpkt->pkt_datalen; 7520 7521 if ((len < FCP_LUN_HEADER) || 7522 ((report_lun = kmem_zalloc(len, KM_NOSLEEP)) == NULL)) { 7523 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 7524 icmd->ipkt_change_cnt, icmd->ipkt_cause); 7525 fcp_icmd_free(pptr, icmd); 7526 return; 7527 } 7528 7529 FCP_CP_IN(fpkt->pkt_data, report_lun, fpkt->pkt_data_acc, 7530 fpkt->pkt_datalen); 7531 7532 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7533 fcp_trace, FCP_BUF_LEVEL_5, 0, 7534 "fcp_handle_reportlun: port=%d, tgt D_ID=0x%x", 7535 pptr->port_instance, ptgt->tgt_d_id); 7536 7537 /* 7538 * Get the number of luns (which is supplied as LUNS * 8) the 7539 * device claims it has. 7540 */ 7541 nluns_claimed = BE_32(report_lun->num_lun) >> 3; 7542 7543 /* 7544 * Get the maximum number of luns the buffer submitted can hold. 7545 */ 7546 nluns_bufmax = (fpkt->pkt_datalen - FCP_LUN_HEADER) / FCP_LUN_SIZE; 7547 7548 /* 7549 * Due to limitations of certain hardware, we support only 16 bit LUNs 7550 */ 7551 if (nluns_claimed > FCP_MAX_LUNS_SUPPORTED) { 7552 kmem_free(report_lun, len); 7553 7554 fcp_log(CE_NOTE, pptr->port_dip, "!Can not support" 7555 " 0x%x number of LUNs for target=%x", nluns_claimed, 7556 ptgt->tgt_d_id); 7557 7558 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 7559 icmd->ipkt_change_cnt, icmd->ipkt_cause); 7560 fcp_icmd_free(pptr, icmd); 7561 return; 7562 } 7563 7564 /* 7565 * If there are more LUNs than we have allocated memory for, 7566 * allocate more space and send down yet another report lun if 7567 * the maximum number of attempts hasn't been reached. 7568 */ 7569 mutex_enter(&ptgt->tgt_mutex); 7570 7571 if ((nluns_claimed > nluns_bufmax) && 7572 (ptgt->tgt_report_lun_cnt < FCP_MAX_REPORTLUNS_ATTEMPTS)) { 7573 7574 struct fcp_lun *plun; 7575 7576 ptgt->tgt_report_lun_cnt++; 7577 plun = ptgt->tgt_lun; 7578 ASSERT(plun != NULL); 7579 mutex_exit(&ptgt->tgt_mutex); 7580 7581 kmem_free(report_lun, len); 7582 7583 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7584 fcp_trace, FCP_BUF_LEVEL_5, 0, 7585 "!Dynamically discovered %d LUNs for D_ID=%x", 7586 nluns_claimed, ptgt->tgt_d_id); 7587 7588 /* Retrieve the rscn count (if a valid one exists) */ 7589 if (icmd->ipkt_fpkt->pkt_ulp_rscn_infop != NULL) { 7590 rscn_count = ((fc_ulp_rscn_info_t *) 7591 (icmd->ipkt_fpkt->pkt_ulp_rscn_infop))-> 7592 ulp_rscn_count; 7593 } else { 7594 rscn_count = FC_INVALID_RSCN_COUNT; 7595 } 7596 7597 if (fcp_send_scsi(icmd->ipkt_lun, SCMD_REPORT_LUN, 7598 FCP_LUN_HEADER + (nluns_claimed * FCP_LUN_SIZE), 7599 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7600 icmd->ipkt_cause, rscn_count) != DDI_SUCCESS) { 7601 (void) fcp_call_finish_init(pptr, ptgt, 7602 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7603 icmd->ipkt_cause); 7604 } 7605 7606 fcp_icmd_free(pptr, icmd); 7607 return; 7608 } 7609 7610 if (nluns_claimed > nluns_bufmax) { 7611 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7612 fcp_trace, FCP_BUF_LEVEL_5, 0, 7613 "Target=%x:%x:%x:%x:%x:%x:%x:%x" 7614 " Number of LUNs lost=%x", 7615 ptgt->tgt_port_wwn.raw_wwn[0], 7616 ptgt->tgt_port_wwn.raw_wwn[1], 7617 ptgt->tgt_port_wwn.raw_wwn[2], 7618 ptgt->tgt_port_wwn.raw_wwn[3], 7619 ptgt->tgt_port_wwn.raw_wwn[4], 7620 ptgt->tgt_port_wwn.raw_wwn[5], 7621 ptgt->tgt_port_wwn.raw_wwn[6], 7622 ptgt->tgt_port_wwn.raw_wwn[7], 7623 nluns_claimed - nluns_bufmax); 7624 7625 nluns_claimed = nluns_bufmax; 7626 } 7627 ptgt->tgt_lun_cnt = nluns_claimed; 7628 7629 /* 7630 * Identify missing LUNs and print warning messages 7631 */ 7632 for (plun = ptgt->tgt_lun; plun; plun = plun->lun_next) { 7633 int offline; 7634 int exists = 0; 7635 7636 offline = (plun->lun_state & FCP_LUN_OFFLINE) ? 1 : 0; 7637 7638 for (i = 0; i < nluns_claimed && exists == 0; i++) { 7639 uchar_t *lun_string; 7640 7641 lun_string = (uchar_t *)&(report_lun->lun_string[i]); 7642 7643 switch (lun_string[0] & 0xC0) { 7644 case FCP_LUN_ADDRESSING: 7645 case FCP_PD_ADDRESSING: 7646 case FCP_VOLUME_ADDRESSING: 7647 lun_num = ((lun_string[0] & 0x3F) << 8) | 7648 lun_string[1]; 7649 if (plun->lun_num == lun_num) { 7650 exists++; 7651 break; 7652 } 7653 break; 7654 7655 default: 7656 break; 7657 } 7658 } 7659 7660 if (!exists && !offline) { 7661 mutex_exit(&ptgt->tgt_mutex); 7662 7663 mutex_enter(&pptr->port_mutex); 7664 mutex_enter(&ptgt->tgt_mutex); 7665 if (!FCP_STATE_CHANGED(pptr, ptgt, icmd)) { 7666 /* 7667 * set disappear flag when device was connected 7668 */ 7669 if (!(plun->lun_state & 7670 FCP_LUN_DEVICE_NOT_CONNECTED)) { 7671 plun->lun_state |= FCP_LUN_DISAPPEARED; 7672 } 7673 mutex_exit(&ptgt->tgt_mutex); 7674 mutex_exit(&pptr->port_mutex); 7675 if (!(plun->lun_state & 7676 FCP_LUN_DEVICE_NOT_CONNECTED)) { 7677 fcp_log(CE_NOTE, pptr->port_dip, 7678 "!Lun=%x for target=%x disappeared", 7679 plun->lun_num, ptgt->tgt_d_id); 7680 } 7681 mutex_enter(&ptgt->tgt_mutex); 7682 } else { 7683 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7684 fcp_trace, FCP_BUF_LEVEL_5, 0, 7685 "fcp_handle_reportlun,1: state change" 7686 " occured for D_ID=0x%x", ptgt->tgt_d_id); 7687 mutex_exit(&ptgt->tgt_mutex); 7688 mutex_exit(&pptr->port_mutex); 7689 kmem_free(report_lun, len); 7690 (void) fcp_call_finish_init(pptr, ptgt, 7691 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7692 icmd->ipkt_cause); 7693 fcp_icmd_free(pptr, icmd); 7694 return; 7695 } 7696 } else if (exists) { 7697 /* 7698 * clear FCP_LUN_DEVICE_NOT_CONNECTED when lun 0 7699 * actually exists in REPORT_LUN response 7700 */ 7701 if (plun->lun_state & FCP_LUN_DEVICE_NOT_CONNECTED) { 7702 plun->lun_state &= 7703 ~FCP_LUN_DEVICE_NOT_CONNECTED; 7704 } 7705 if (offline || plun->lun_num == 0) { 7706 if (plun->lun_state & FCP_LUN_DISAPPEARED) { 7707 plun->lun_state &= ~FCP_LUN_DISAPPEARED; 7708 mutex_exit(&ptgt->tgt_mutex); 7709 fcp_log(CE_NOTE, pptr->port_dip, 7710 "!Lun=%x for target=%x reappeared", 7711 plun->lun_num, ptgt->tgt_d_id); 7712 mutex_enter(&ptgt->tgt_mutex); 7713 } 7714 } 7715 } 7716 } 7717 7718 ptgt->tgt_tmp_cnt = nluns_claimed ? nluns_claimed : 1; 7719 mutex_exit(&ptgt->tgt_mutex); 7720 7721 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7722 fcp_trace, FCP_BUF_LEVEL_5, 0, 7723 "fcp_handle_reportlun: port=%d, tgt D_ID=0x%x, %d LUN(s)", 7724 pptr->port_instance, ptgt->tgt_d_id, nluns_claimed); 7725 7726 /* scan each lun */ 7727 for (i = 0; i < nluns_claimed; i++) { 7728 uchar_t *lun_string; 7729 7730 lun_string = (uchar_t *)&(report_lun->lun_string[i]); 7731 7732 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7733 fcp_trace, FCP_BUF_LEVEL_5, 0, 7734 "handle_reportlun: d_id=%x, LUN ind=%d, LUN=%d," 7735 " addr=0x%x", ptgt->tgt_d_id, i, lun_string[1], 7736 lun_string[0]); 7737 7738 switch (lun_string[0] & 0xC0) { 7739 case FCP_LUN_ADDRESSING: 7740 case FCP_PD_ADDRESSING: 7741 case FCP_VOLUME_ADDRESSING: 7742 lun_num = ((lun_string[0] & 0x3F) << 8) | lun_string[1]; 7743 7744 /* We will skip masked LUNs because of the blacklist. */ 7745 if (fcp_lun_blacklist != NULL) { 7746 mutex_enter(&ptgt->tgt_mutex); 7747 if (fcp_should_mask(&ptgt->tgt_port_wwn, 7748 lun_num) == TRUE) { 7749 ptgt->tgt_lun_cnt--; 7750 mutex_exit(&ptgt->tgt_mutex); 7751 break; 7752 } 7753 mutex_exit(&ptgt->tgt_mutex); 7754 } 7755 7756 /* see if this LUN is already allocated */ 7757 if ((plun = fcp_get_lun(ptgt, lun_num)) == NULL) { 7758 plun = fcp_alloc_lun(ptgt); 7759 if (plun == NULL) { 7760 fcp_log(CE_NOTE, pptr->port_dip, 7761 "!Lun allocation failed" 7762 " target=%x lun=%x", 7763 ptgt->tgt_d_id, lun_num); 7764 break; 7765 } 7766 } 7767 7768 mutex_enter(&plun->lun_tgt->tgt_mutex); 7769 /* convert to LUN */ 7770 plun->lun_addr.ent_addr_0 = 7771 BE_16(*(uint16_t *)&(lun_string[0])); 7772 plun->lun_addr.ent_addr_1 = 7773 BE_16(*(uint16_t *)&(lun_string[2])); 7774 plun->lun_addr.ent_addr_2 = 7775 BE_16(*(uint16_t *)&(lun_string[4])); 7776 plun->lun_addr.ent_addr_3 = 7777 BE_16(*(uint16_t *)&(lun_string[6])); 7778 7779 plun->lun_num = lun_num; 7780 plun->lun_state |= FCP_LUN_BUSY | FCP_LUN_MARK; 7781 plun->lun_state &= ~FCP_LUN_OFFLINE; 7782 mutex_exit(&plun->lun_tgt->tgt_mutex); 7783 7784 /* Retrieve the rscn count (if a valid one exists) */ 7785 if (icmd->ipkt_fpkt->pkt_ulp_rscn_infop != NULL) { 7786 rscn_count = ((fc_ulp_rscn_info_t *) 7787 (icmd->ipkt_fpkt->pkt_ulp_rscn_infop))-> 7788 ulp_rscn_count; 7789 } else { 7790 rscn_count = FC_INVALID_RSCN_COUNT; 7791 } 7792 7793 if (fcp_send_scsi(plun, SCMD_INQUIRY, SUN_INQSIZE, 7794 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 7795 icmd->ipkt_cause, rscn_count) != DDI_SUCCESS) { 7796 mutex_enter(&pptr->port_mutex); 7797 mutex_enter(&plun->lun_tgt->tgt_mutex); 7798 if (!FCP_STATE_CHANGED(pptr, ptgt, icmd)) { 7799 fcp_log(CE_NOTE, pptr->port_dip, 7800 "!failed to send INQUIRY" 7801 " target=%x lun=%x", 7802 ptgt->tgt_d_id, plun->lun_num); 7803 } else { 7804 FCP_TRACE(fcp_logq, 7805 pptr->port_instbuf, fcp_trace, 7806 FCP_BUF_LEVEL_5, 0, 7807 "fcp_handle_reportlun,2: state" 7808 " change occured for D_ID=0x%x", 7809 ptgt->tgt_d_id); 7810 } 7811 mutex_exit(&plun->lun_tgt->tgt_mutex); 7812 mutex_exit(&pptr->port_mutex); 7813 } else { 7814 continue; 7815 } 7816 break; 7817 7818 default: 7819 fcp_log(CE_WARN, NULL, 7820 "!Unsupported LUN Addressing method %x " 7821 "in response to REPORT_LUN", lun_string[0]); 7822 break; 7823 } 7824 7825 /* 7826 * each time through this loop we should decrement 7827 * the tmp_cnt by one -- since we go through this loop 7828 * one time for each LUN, the tmp_cnt should never be <=0 7829 */ 7830 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 7831 icmd->ipkt_change_cnt, icmd->ipkt_cause); 7832 } 7833 7834 if (i == 0) { 7835 fcp_log(CE_WARN, pptr->port_dip, 7836 "!FCP: target=%x reported NO Luns", ptgt->tgt_d_id); 7837 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 7838 icmd->ipkt_change_cnt, icmd->ipkt_cause); 7839 } 7840 7841 kmem_free(report_lun, len); 7842 fcp_icmd_free(pptr, icmd); 7843 } 7844 7845 7846 /* 7847 * called internally to return a LUN given a target and a LUN number 7848 */ 7849 static struct fcp_lun * 7850 fcp_get_lun(struct fcp_tgt *ptgt, uint16_t lun_num) 7851 { 7852 struct fcp_lun *plun; 7853 7854 mutex_enter(&ptgt->tgt_mutex); 7855 for (plun = ptgt->tgt_lun; plun != NULL; plun = plun->lun_next) { 7856 if (plun->lun_num == lun_num) { 7857 mutex_exit(&ptgt->tgt_mutex); 7858 return (plun); 7859 } 7860 } 7861 mutex_exit(&ptgt->tgt_mutex); 7862 7863 return (NULL); 7864 } 7865 7866 7867 /* 7868 * handle finishing one target for fcp_finish_init 7869 * 7870 * return true (non-zero) if we want finish_init to continue with the 7871 * next target 7872 * 7873 * called with the port mutex held 7874 */ 7875 /*ARGSUSED*/ 7876 static int 7877 fcp_finish_tgt(struct fcp_port *pptr, struct fcp_tgt *ptgt, 7878 int link_cnt, int tgt_cnt, int cause) 7879 { 7880 int rval = 1; 7881 ASSERT(pptr != NULL); 7882 ASSERT(ptgt != NULL); 7883 7884 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7885 fcp_trace, FCP_BUF_LEVEL_5, 0, 7886 "finish_tgt: D_ID/state = 0x%x/0x%x", ptgt->tgt_d_id, 7887 ptgt->tgt_state); 7888 7889 ASSERT(mutex_owned(&pptr->port_mutex)); 7890 7891 if ((pptr->port_link_cnt != link_cnt) || 7892 (tgt_cnt && ptgt->tgt_change_cnt != tgt_cnt)) { 7893 /* 7894 * oh oh -- another link reset or target change 7895 * must have occurred while we are in here 7896 */ 7897 FCP_TGT_TRACE(ptgt, tgt_cnt, FCP_TGT_TRACE_23); 7898 7899 return (0); 7900 } else { 7901 FCP_TGT_TRACE(ptgt, tgt_cnt, FCP_TGT_TRACE_24); 7902 } 7903 7904 mutex_enter(&ptgt->tgt_mutex); 7905 7906 if (!(ptgt->tgt_state & FCP_TGT_OFFLINE)) { 7907 /* 7908 * tgt is not offline -- is it marked (i.e. needs 7909 * to be offlined) ?? 7910 */ 7911 if (ptgt->tgt_state & FCP_TGT_MARK) { 7912 /* 7913 * this target not offline *and* 7914 * marked 7915 */ 7916 ptgt->tgt_state &= ~FCP_TGT_MARK; 7917 rval = fcp_offline_target(pptr, ptgt, link_cnt, 7918 tgt_cnt, 0, 0); 7919 } else { 7920 ptgt->tgt_state &= ~FCP_TGT_BUSY; 7921 7922 /* create the LUNs */ 7923 if (ptgt->tgt_node_state != FCP_TGT_NODE_ON_DEMAND) { 7924 ptgt->tgt_node_state = FCP_TGT_NODE_PRESENT; 7925 fcp_create_luns(ptgt, link_cnt, tgt_cnt, 7926 cause); 7927 ptgt->tgt_device_created = 1; 7928 } else { 7929 fcp_update_tgt_state(ptgt, FCP_RESET, 7930 FCP_LUN_BUSY); 7931 } 7932 } 7933 } 7934 7935 mutex_exit(&ptgt->tgt_mutex); 7936 7937 return (rval); 7938 } 7939 7940 7941 /* 7942 * this routine is called to finish port initialization 7943 * 7944 * Each port has a "temp" counter -- when a state change happens (e.g. 7945 * port online), the temp count is set to the number of devices in the map. 7946 * Then, as each device gets "discovered", the temp counter is decremented 7947 * by one. When this count reaches zero we know that all of the devices 7948 * in the map have been discovered (or an error has occurred), so we can 7949 * then finish initialization -- which is done by this routine (well, this 7950 * and fcp-finish_tgt()) 7951 * 7952 * acquires and releases the global mutex 7953 * 7954 * called with the port mutex owned 7955 */ 7956 static void 7957 fcp_finish_init(struct fcp_port *pptr) 7958 { 7959 #ifdef DEBUG 7960 bzero(pptr->port_finish_stack, sizeof (pptr->port_finish_stack)); 7961 pptr->port_finish_depth = getpcstack(pptr->port_finish_stack, 7962 FCP_STACK_DEPTH); 7963 #endif /* DEBUG */ 7964 7965 ASSERT(mutex_owned(&pptr->port_mutex)); 7966 7967 FCP_TRACE(fcp_logq, pptr->port_instbuf, 7968 fcp_trace, FCP_BUF_LEVEL_2, 0, "finish_init:" 7969 " entering; ipkt count=%d", pptr->port_ipkt_cnt); 7970 7971 if ((pptr->port_state & FCP_STATE_ONLINING) && 7972 !(pptr->port_state & (FCP_STATE_SUSPENDED | 7973 FCP_STATE_DETACHING | FCP_STATE_POWER_DOWN))) { 7974 pptr->port_state &= ~FCP_STATE_ONLINING; 7975 pptr->port_state |= FCP_STATE_ONLINE; 7976 } 7977 7978 /* Wake up threads waiting on config done */ 7979 cv_broadcast(&pptr->port_config_cv); 7980 } 7981 7982 7983 /* 7984 * called from fcp_finish_init to create the LUNs for a target 7985 * 7986 * called with the port mutex owned 7987 */ 7988 static void 7989 fcp_create_luns(struct fcp_tgt *ptgt, int link_cnt, int tgt_cnt, int cause) 7990 { 7991 struct fcp_lun *plun; 7992 struct fcp_port *pptr; 7993 child_info_t *cip = NULL; 7994 7995 ASSERT(ptgt != NULL); 7996 ASSERT(mutex_owned(&ptgt->tgt_mutex)); 7997 7998 pptr = ptgt->tgt_port; 7999 8000 ASSERT(pptr != NULL); 8001 8002 /* scan all LUNs for this target */ 8003 for (plun = ptgt->tgt_lun; plun != NULL; plun = plun->lun_next) { 8004 if (plun->lun_state & FCP_LUN_OFFLINE) { 8005 continue; 8006 } 8007 8008 if (plun->lun_state & FCP_LUN_MARK) { 8009 FCP_TRACE(fcp_logq, pptr->port_instbuf, 8010 fcp_trace, FCP_BUF_LEVEL_2, 0, 8011 "fcp_create_luns: offlining marked LUN!"); 8012 fcp_offline_lun(plun, link_cnt, tgt_cnt, 1, 0); 8013 continue; 8014 } 8015 8016 plun->lun_state &= ~FCP_LUN_BUSY; 8017 8018 /* 8019 * There are conditions in which FCP_LUN_INIT flag is cleared 8020 * but we have a valid plun->lun_cip. To cover this case also 8021 * CLEAR_BUSY whenever we have a valid lun_cip. 8022 */ 8023 if (plun->lun_mpxio && plun->lun_cip && 8024 (!fcp_pass_to_hp(pptr, plun, plun->lun_cip, 8025 FCP_MPXIO_PATH_CLEAR_BUSY, link_cnt, tgt_cnt, 8026 0, 0))) { 8027 FCP_TRACE(fcp_logq, pptr->port_instbuf, 8028 fcp_trace, FCP_BUF_LEVEL_2, 0, 8029 "fcp_create_luns: enable lun %p failed!", 8030 plun); 8031 } 8032 8033 if (plun->lun_state & FCP_LUN_INIT && 8034 !(plun->lun_state & FCP_LUN_CHANGED)) { 8035 continue; 8036 } 8037 8038 if (cause == FCP_CAUSE_USER_CREATE) { 8039 continue; 8040 } 8041 8042 FCP_TRACE(fcp_logq, pptr->port_instbuf, 8043 fcp_trace, FCP_BUF_LEVEL_6, 0, 8044 "create_luns: passing ONLINE elem to HP thread"); 8045 8046 /* 8047 * If lun has changed, prepare for offlining the old path. 8048 * Do not offline the old path right now, since it may be 8049 * still opened. 8050 */ 8051 if (plun->lun_cip && (plun->lun_state & FCP_LUN_CHANGED)) { 8052 fcp_prepare_offline_lun(plun, link_cnt, tgt_cnt); 8053 } 8054 8055 /* pass an ONLINE element to the hotplug thread */ 8056 if (!fcp_pass_to_hp(pptr, plun, cip, FCP_ONLINE, 8057 link_cnt, tgt_cnt, NDI_ONLINE_ATTACH, 0)) { 8058 8059 /* 8060 * We can not synchronous attach (i.e pass 8061 * NDI_ONLINE_ATTACH) here as we might be 8062 * coming from an interrupt or callback 8063 * thread. 8064 */ 8065 if (!fcp_pass_to_hp(pptr, plun, cip, FCP_ONLINE, 8066 link_cnt, tgt_cnt, 0, 0)) { 8067 fcp_log(CE_CONT, pptr->port_dip, 8068 "Can not ONLINE LUN; D_ID=%x, LUN=%x\n", 8069 plun->lun_tgt->tgt_d_id, plun->lun_num); 8070 } 8071 } 8072 } 8073 } 8074 8075 8076 /* 8077 * function to online/offline devices 8078 */ 8079 static int 8080 fcp_trigger_lun(struct fcp_lun *plun, child_info_t *cip, int old_mpxio, 8081 int online, int lcount, int tcount, int flags) 8082 { 8083 int rval = NDI_FAILURE; 8084 int circ; 8085 child_info_t *ccip; 8086 struct fcp_port *pptr = plun->lun_tgt->tgt_port; 8087 int is_mpxio = pptr->port_mpxio; 8088 dev_info_t *cdip, *pdip; 8089 char *devname; 8090 8091 if ((old_mpxio != 0) && (plun->lun_mpxio != old_mpxio)) { 8092 /* 8093 * When this event gets serviced, lun_cip and lun_mpxio 8094 * has changed, so it should be invalidated now. 8095 */ 8096 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 8097 FCP_BUF_LEVEL_2, 0, "fcp_trigger_lun: lun_mpxio changed: " 8098 "plun: %p, cip: %p, what:%d", plun, cip, online); 8099 return (rval); 8100 } 8101 8102 FCP_TRACE(fcp_logq, pptr->port_instbuf, 8103 fcp_trace, FCP_BUF_LEVEL_2, 0, 8104 "fcp_trigger_lun: plun=%p target=%x lun=%d cip=%p what=%x " 8105 "flags=%x mpxio=%x\n", 8106 plun, LUN_TGT->tgt_d_id, plun->lun_num, cip, online, flags, 8107 plun->lun_mpxio); 8108 8109 /* 8110 * lun_mpxio needs checking here because we can end up in a race 8111 * condition where this task has been dispatched while lun_mpxio is 8112 * set, but an earlier FCP_ONLINE task for the same LUN tried to 8113 * enable MPXIO for the LUN, but was unable to, and hence cleared 8114 * the flag. We rely on the serialization of the tasks here. We return 8115 * NDI_SUCCESS so any callers continue without reporting spurious 8116 * errors, and the still think we're an MPXIO LUN. 8117 */ 8118 8119 if (online == FCP_MPXIO_PATH_CLEAR_BUSY || 8120 online == FCP_MPXIO_PATH_SET_BUSY) { 8121 if (plun->lun_mpxio) { 8122 rval = fcp_update_mpxio_path(plun, cip, online); 8123 } else { 8124 rval = NDI_SUCCESS; 8125 } 8126 return (rval); 8127 } 8128 8129 /* 8130 * Explicit devfs_clean() due to ndi_devi_offline() not 8131 * executing devfs_clean() if parent lock is held. 8132 */ 8133 ASSERT(!servicing_interrupt()); 8134 if (online == FCP_OFFLINE) { 8135 if (plun->lun_mpxio == 0) { 8136 if (plun->lun_cip == cip) { 8137 cdip = DIP(plun->lun_cip); 8138 } else { 8139 cdip = DIP(cip); 8140 } 8141 } else if ((plun->lun_cip == cip) && plun->lun_cip) { 8142 cdip = mdi_pi_get_client(PIP(plun->lun_cip)); 8143 } else if ((plun->lun_cip != cip) && cip) { 8144 /* 8145 * This means a DTYPE/GUID change, we shall get the 8146 * dip of the old cip instead of the current lun_cip. 8147 */ 8148 cdip = mdi_pi_get_client(PIP(cip)); 8149 } 8150 if (cdip) { 8151 if (i_ddi_devi_attached(cdip)) { 8152 pdip = ddi_get_parent(cdip); 8153 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 8154 ndi_devi_enter(pdip, &circ); 8155 (void) ddi_deviname(cdip, devname); 8156 ndi_devi_exit(pdip, circ); 8157 /* 8158 * Release parent lock before calling 8159 * devfs_clean(). 8160 */ 8161 rval = devfs_clean(pdip, devname + 1, 8162 DV_CLEAN_FORCE); 8163 kmem_free(devname, MAXNAMELEN + 1); 8164 /* 8165 * Return if devfs_clean() fails for 8166 * non-MPXIO case. 8167 * For MPXIO case, another path could be 8168 * offlined. 8169 */ 8170 if (rval && plun->lun_mpxio == 0) { 8171 FCP_TRACE(fcp_logq, pptr->port_instbuf, 8172 fcp_trace, FCP_BUF_LEVEL_3, 0, 8173 "fcp_trigger_lun: devfs_clean " 8174 "failed rval=%x dip=%p", 8175 rval, pdip); 8176 return (NDI_FAILURE); 8177 } 8178 } 8179 } 8180 } 8181 8182 if (fc_ulp_busy_port(pptr->port_fp_handle) != 0) { 8183 return (NDI_FAILURE); 8184 } 8185 8186 if (is_mpxio) { 8187 mdi_devi_enter(pptr->port_dip, &circ); 8188 } else { 8189 ndi_devi_enter(pptr->port_dip, &circ); 8190 } 8191 8192 mutex_enter(&pptr->port_mutex); 8193 mutex_enter(&plun->lun_mutex); 8194 8195 if (online == FCP_ONLINE) { 8196 ccip = fcp_get_cip(plun, cip, lcount, tcount); 8197 if (ccip == NULL) { 8198 goto fail; 8199 } 8200 } else { 8201 if (fcp_is_child_present(plun, cip) != FC_SUCCESS) { 8202 goto fail; 8203 } 8204 ccip = cip; 8205 } 8206 8207 if (online == FCP_ONLINE) { 8208 rval = fcp_online_child(plun, ccip, lcount, tcount, flags, 8209 &circ); 8210 fc_ulp_log_device_event(pptr->port_fp_handle, 8211 FC_ULP_DEVICE_ONLINE); 8212 } else { 8213 rval = fcp_offline_child(plun, ccip, lcount, tcount, flags, 8214 &circ); 8215 fc_ulp_log_device_event(pptr->port_fp_handle, 8216 FC_ULP_DEVICE_OFFLINE); 8217 } 8218 8219 fail: mutex_exit(&plun->lun_mutex); 8220 mutex_exit(&pptr->port_mutex); 8221 8222 if (is_mpxio) { 8223 mdi_devi_exit(pptr->port_dip, circ); 8224 } else { 8225 ndi_devi_exit(pptr->port_dip, circ); 8226 } 8227 8228 fc_ulp_idle_port(pptr->port_fp_handle); 8229 8230 return (rval); 8231 } 8232 8233 8234 /* 8235 * take a target offline by taking all of its LUNs offline 8236 */ 8237 /*ARGSUSED*/ 8238 static int 8239 fcp_offline_target(struct fcp_port *pptr, struct fcp_tgt *ptgt, 8240 int link_cnt, int tgt_cnt, int nowait, int flags) 8241 { 8242 struct fcp_tgt_elem *elem; 8243 8244 ASSERT(mutex_owned(&pptr->port_mutex)); 8245 ASSERT(mutex_owned(&ptgt->tgt_mutex)); 8246 8247 ASSERT(!(ptgt->tgt_state & FCP_TGT_OFFLINE)); 8248 8249 if (link_cnt != pptr->port_link_cnt || (tgt_cnt && tgt_cnt != 8250 ptgt->tgt_change_cnt)) { 8251 mutex_exit(&ptgt->tgt_mutex); 8252 FCP_TGT_TRACE(ptgt, tgt_cnt, FCP_TGT_TRACE_25); 8253 mutex_enter(&ptgt->tgt_mutex); 8254 8255 return (0); 8256 } 8257 8258 ptgt->tgt_pd_handle = NULL; 8259 mutex_exit(&ptgt->tgt_mutex); 8260 FCP_TGT_TRACE(ptgt, tgt_cnt, FCP_TGT_TRACE_26); 8261 mutex_enter(&ptgt->tgt_mutex); 8262 8263 tgt_cnt = tgt_cnt ? tgt_cnt : ptgt->tgt_change_cnt; 8264 8265 if (ptgt->tgt_tcap && 8266 (elem = kmem_zalloc(sizeof (*elem), KM_NOSLEEP)) != NULL) { 8267 elem->flags = flags; 8268 elem->time = fcp_watchdog_time; 8269 if (nowait == 0) { 8270 elem->time += fcp_offline_delay; 8271 } 8272 elem->ptgt = ptgt; 8273 elem->link_cnt = link_cnt; 8274 elem->tgt_cnt = tgt_cnt; 8275 elem->next = pptr->port_offline_tgts; 8276 pptr->port_offline_tgts = elem; 8277 } else { 8278 fcp_offline_target_now(pptr, ptgt, link_cnt, tgt_cnt, flags); 8279 } 8280 8281 return (1); 8282 } 8283 8284 8285 static void 8286 fcp_offline_target_now(struct fcp_port *pptr, struct fcp_tgt *ptgt, 8287 int link_cnt, int tgt_cnt, int flags) 8288 { 8289 ASSERT(mutex_owned(&pptr->port_mutex)); 8290 ASSERT(mutex_owned(&ptgt->tgt_mutex)); 8291 8292 fc_ulp_enable_relogin(pptr->port_fp_handle, &ptgt->tgt_port_wwn); 8293 ptgt->tgt_state = FCP_TGT_OFFLINE; 8294 ptgt->tgt_pd_handle = NULL; 8295 fcp_offline_tgt_luns(ptgt, link_cnt, tgt_cnt, flags); 8296 } 8297 8298 8299 static void 8300 fcp_offline_tgt_luns(struct fcp_tgt *ptgt, int link_cnt, int tgt_cnt, 8301 int flags) 8302 { 8303 struct fcp_lun *plun; 8304 8305 ASSERT(mutex_owned(&ptgt->tgt_port->port_mutex)); 8306 ASSERT(mutex_owned(&ptgt->tgt_mutex)); 8307 8308 for (plun = ptgt->tgt_lun; plun != NULL; plun = plun->lun_next) { 8309 if (!(plun->lun_state & FCP_LUN_OFFLINE)) { 8310 fcp_offline_lun(plun, link_cnt, tgt_cnt, 1, flags); 8311 } 8312 } 8313 } 8314 8315 8316 /* 8317 * take a LUN offline 8318 * 8319 * enters and leaves with the target mutex held, releasing it in the process 8320 * 8321 * allocates memory in non-sleep mode 8322 */ 8323 static void 8324 fcp_offline_lun(struct fcp_lun *plun, int link_cnt, int tgt_cnt, 8325 int nowait, int flags) 8326 { 8327 struct fcp_port *pptr = plun->lun_tgt->tgt_port; 8328 struct fcp_lun_elem *elem; 8329 8330 ASSERT(plun != NULL); 8331 ASSERT(mutex_owned(&LUN_TGT->tgt_mutex)); 8332 8333 if (nowait) { 8334 fcp_offline_lun_now(plun, link_cnt, tgt_cnt, flags); 8335 return; 8336 } 8337 8338 if ((elem = kmem_zalloc(sizeof (*elem), KM_NOSLEEP)) != NULL) { 8339 elem->flags = flags; 8340 elem->time = fcp_watchdog_time; 8341 if (nowait == 0) { 8342 elem->time += fcp_offline_delay; 8343 } 8344 elem->plun = plun; 8345 elem->link_cnt = link_cnt; 8346 elem->tgt_cnt = plun->lun_tgt->tgt_change_cnt; 8347 elem->next = pptr->port_offline_luns; 8348 pptr->port_offline_luns = elem; 8349 } else { 8350 fcp_offline_lun_now(plun, link_cnt, tgt_cnt, flags); 8351 } 8352 } 8353 8354 8355 static void 8356 fcp_prepare_offline_lun(struct fcp_lun *plun, int link_cnt, int tgt_cnt) 8357 { 8358 struct fcp_pkt *head = NULL; 8359 8360 ASSERT(mutex_owned(&LUN_TGT->tgt_mutex)); 8361 8362 mutex_exit(&LUN_TGT->tgt_mutex); 8363 8364 head = fcp_scan_commands(plun); 8365 if (head != NULL) { 8366 fcp_abort_commands(head, LUN_PORT); 8367 } 8368 8369 mutex_enter(&LUN_TGT->tgt_mutex); 8370 8371 if (plun->lun_cip && plun->lun_mpxio) { 8372 /* 8373 * Intimate MPxIO lun busy is cleared 8374 */ 8375 if (!fcp_pass_to_hp(LUN_PORT, plun, plun->lun_cip, 8376 FCP_MPXIO_PATH_CLEAR_BUSY, link_cnt, tgt_cnt, 8377 0, 0)) { 8378 fcp_log(CE_NOTE, LUN_PORT->port_dip, 8379 "Can not ENABLE LUN; D_ID=%x, LUN=%x", 8380 LUN_TGT->tgt_d_id, plun->lun_num); 8381 } 8382 /* 8383 * Intimate MPxIO that the lun is now marked for offline 8384 */ 8385 mutex_exit(&LUN_TGT->tgt_mutex); 8386 (void) mdi_pi_disable_path(PIP(plun->lun_cip), DRIVER_DISABLE); 8387 mutex_enter(&LUN_TGT->tgt_mutex); 8388 } 8389 } 8390 8391 static void 8392 fcp_offline_lun_now(struct fcp_lun *plun, int link_cnt, int tgt_cnt, 8393 int flags) 8394 { 8395 ASSERT(mutex_owned(&LUN_TGT->tgt_mutex)); 8396 8397 mutex_exit(&LUN_TGT->tgt_mutex); 8398 fcp_update_offline_flags(plun); 8399 mutex_enter(&LUN_TGT->tgt_mutex); 8400 8401 fcp_prepare_offline_lun(plun, link_cnt, tgt_cnt); 8402 8403 FCP_TRACE(fcp_logq, LUN_PORT->port_instbuf, 8404 fcp_trace, FCP_BUF_LEVEL_4, 0, 8405 "offline_lun: passing OFFLINE elem to HP thread"); 8406 8407 if (plun->lun_cip) { 8408 fcp_log(CE_NOTE, LUN_PORT->port_dip, 8409 "!offlining lun=%x (trace=%x), target=%x (trace=%x)", 8410 plun->lun_num, plun->lun_trace, LUN_TGT->tgt_d_id, 8411 LUN_TGT->tgt_trace); 8412 8413 if (!fcp_pass_to_hp(LUN_PORT, plun, plun->lun_cip, FCP_OFFLINE, 8414 link_cnt, tgt_cnt, flags, 0)) { 8415 fcp_log(CE_CONT, LUN_PORT->port_dip, 8416 "Can not OFFLINE LUN; D_ID=%x, LUN=%x\n", 8417 LUN_TGT->tgt_d_id, plun->lun_num); 8418 } 8419 } 8420 } 8421 8422 static void 8423 fcp_scan_offline_luns(struct fcp_port *pptr) 8424 { 8425 struct fcp_lun_elem *elem; 8426 struct fcp_lun_elem *prev; 8427 struct fcp_lun_elem *next; 8428 8429 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 8430 8431 prev = NULL; 8432 elem = pptr->port_offline_luns; 8433 while (elem) { 8434 next = elem->next; 8435 if (elem->time <= fcp_watchdog_time) { 8436 int changed = 1; 8437 struct fcp_tgt *ptgt = elem->plun->lun_tgt; 8438 8439 mutex_enter(&ptgt->tgt_mutex); 8440 if (pptr->port_link_cnt == elem->link_cnt && 8441 ptgt->tgt_change_cnt == elem->tgt_cnt) { 8442 changed = 0; 8443 } 8444 8445 if (!changed && 8446 !(elem->plun->lun_state & FCP_TGT_OFFLINE)) { 8447 fcp_offline_lun_now(elem->plun, 8448 elem->link_cnt, elem->tgt_cnt, elem->flags); 8449 } 8450 mutex_exit(&ptgt->tgt_mutex); 8451 8452 kmem_free(elem, sizeof (*elem)); 8453 8454 if (prev) { 8455 prev->next = next; 8456 } else { 8457 pptr->port_offline_luns = next; 8458 } 8459 } else { 8460 prev = elem; 8461 } 8462 elem = next; 8463 } 8464 } 8465 8466 8467 static void 8468 fcp_scan_offline_tgts(struct fcp_port *pptr) 8469 { 8470 struct fcp_tgt_elem *elem; 8471 struct fcp_tgt_elem *prev; 8472 struct fcp_tgt_elem *next; 8473 8474 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 8475 8476 prev = NULL; 8477 elem = pptr->port_offline_tgts; 8478 while (elem) { 8479 next = elem->next; 8480 if (elem->time <= fcp_watchdog_time) { 8481 int changed = 1; 8482 struct fcp_tgt *ptgt = elem->ptgt; 8483 8484 if (ptgt->tgt_change_cnt == elem->tgt_cnt) { 8485 changed = 0; 8486 } 8487 8488 mutex_enter(&ptgt->tgt_mutex); 8489 if (!changed && !(ptgt->tgt_state & 8490 FCP_TGT_OFFLINE)) { 8491 fcp_offline_target_now(pptr, 8492 ptgt, elem->link_cnt, elem->tgt_cnt, 8493 elem->flags); 8494 } 8495 mutex_exit(&ptgt->tgt_mutex); 8496 8497 kmem_free(elem, sizeof (*elem)); 8498 8499 if (prev) { 8500 prev->next = next; 8501 } else { 8502 pptr->port_offline_tgts = next; 8503 } 8504 } else { 8505 prev = elem; 8506 } 8507 elem = next; 8508 } 8509 } 8510 8511 8512 static void 8513 fcp_update_offline_flags(struct fcp_lun *plun) 8514 { 8515 struct fcp_port *pptr = LUN_PORT; 8516 ASSERT(plun != NULL); 8517 8518 mutex_enter(&LUN_TGT->tgt_mutex); 8519 plun->lun_state |= FCP_LUN_OFFLINE; 8520 plun->lun_state &= ~(FCP_LUN_INIT | FCP_LUN_BUSY | FCP_LUN_MARK); 8521 8522 mutex_enter(&plun->lun_mutex); 8523 if (plun->lun_cip && plun->lun_state & FCP_SCSI_LUN_TGT_INIT) { 8524 dev_info_t *cdip = NULL; 8525 8526 mutex_exit(&LUN_TGT->tgt_mutex); 8527 8528 if (plun->lun_mpxio == 0) { 8529 cdip = DIP(plun->lun_cip); 8530 } else if (plun->lun_cip) { 8531 cdip = mdi_pi_get_client(PIP(plun->lun_cip)); 8532 } 8533 8534 mutex_exit(&plun->lun_mutex); 8535 if (cdip) { 8536 (void) ndi_event_retrieve_cookie( 8537 pptr->port_ndi_event_hdl, cdip, FCAL_REMOVE_EVENT, 8538 &fcp_remove_eid, NDI_EVENT_NOPASS); 8539 (void) ndi_event_run_callbacks( 8540 pptr->port_ndi_event_hdl, cdip, 8541 fcp_remove_eid, NULL); 8542 } 8543 } else { 8544 mutex_exit(&plun->lun_mutex); 8545 mutex_exit(&LUN_TGT->tgt_mutex); 8546 } 8547 } 8548 8549 8550 /* 8551 * Scan all of the command pkts for this port, moving pkts that 8552 * match our LUN onto our own list (headed by "head") 8553 */ 8554 static struct fcp_pkt * 8555 fcp_scan_commands(struct fcp_lun *plun) 8556 { 8557 struct fcp_port *pptr = LUN_PORT; 8558 8559 struct fcp_pkt *cmd = NULL; /* pkt cmd ptr */ 8560 struct fcp_pkt *ncmd = NULL; /* next pkt ptr */ 8561 struct fcp_pkt *pcmd = NULL; /* the previous command */ 8562 8563 struct fcp_pkt *head = NULL; /* head of our list */ 8564 struct fcp_pkt *tail = NULL; /* tail of our list */ 8565 8566 int cmds_found = 0; 8567 8568 mutex_enter(&pptr->port_pkt_mutex); 8569 for (cmd = pptr->port_pkt_head; cmd != NULL; cmd = ncmd) { 8570 struct fcp_lun *tlun = 8571 ADDR2LUN(&cmd->cmd_pkt->pkt_address); 8572 8573 ncmd = cmd->cmd_next; /* set next command */ 8574 8575 /* 8576 * if this pkt is for a different LUN or the 8577 * command is sent down, skip it. 8578 */ 8579 if (tlun != plun || cmd->cmd_state == FCP_PKT_ISSUED || 8580 (cmd->cmd_pkt->pkt_flags & FLAG_NOINTR)) { 8581 pcmd = cmd; 8582 continue; 8583 } 8584 cmds_found++; 8585 if (pcmd != NULL) { 8586 ASSERT(pptr->port_pkt_head != cmd); 8587 pcmd->cmd_next = cmd->cmd_next; 8588 } else { 8589 ASSERT(cmd == pptr->port_pkt_head); 8590 pptr->port_pkt_head = cmd->cmd_next; 8591 } 8592 8593 if (cmd == pptr->port_pkt_tail) { 8594 pptr->port_pkt_tail = pcmd; 8595 if (pcmd) { 8596 pcmd->cmd_next = NULL; 8597 } 8598 } 8599 8600 if (head == NULL) { 8601 head = tail = cmd; 8602 } else { 8603 ASSERT(tail != NULL); 8604 8605 tail->cmd_next = cmd; 8606 tail = cmd; 8607 } 8608 cmd->cmd_next = NULL; 8609 } 8610 mutex_exit(&pptr->port_pkt_mutex); 8611 8612 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 8613 fcp_trace, FCP_BUF_LEVEL_8, 0, 8614 "scan commands: %d cmd(s) found", cmds_found); 8615 8616 return (head); 8617 } 8618 8619 8620 /* 8621 * Abort all the commands in the command queue 8622 */ 8623 static void 8624 fcp_abort_commands(struct fcp_pkt *head, struct fcp_port *pptr) 8625 { 8626 struct fcp_pkt *cmd = NULL; /* pkt cmd ptr */ 8627 struct fcp_pkt *ncmd = NULL; /* next pkt ptr */ 8628 8629 ASSERT(mutex_owned(&pptr->port_mutex)); 8630 8631 /* scan through the pkts and invalid them */ 8632 for (cmd = head; cmd != NULL; cmd = ncmd) { 8633 struct scsi_pkt *pkt = cmd->cmd_pkt; 8634 8635 ncmd = cmd->cmd_next; 8636 ASSERT(pkt != NULL); 8637 8638 /* 8639 * The lun is going to be marked offline. Indicate 8640 * the target driver not to requeue or retry this command 8641 * as the device is going to be offlined pretty soon. 8642 */ 8643 pkt->pkt_reason = CMD_DEV_GONE; 8644 pkt->pkt_statistics = 0; 8645 pkt->pkt_state = 0; 8646 8647 /* reset cmd flags/state */ 8648 cmd->cmd_flags &= ~CFLAG_IN_QUEUE; 8649 cmd->cmd_state = FCP_PKT_IDLE; 8650 8651 /* 8652 * ensure we have a packet completion routine, 8653 * then call it. 8654 */ 8655 ASSERT(pkt->pkt_comp != NULL); 8656 8657 mutex_exit(&pptr->port_mutex); 8658 fcp_post_callback(cmd); 8659 mutex_enter(&pptr->port_mutex); 8660 } 8661 } 8662 8663 8664 /* 8665 * the pkt_comp callback for command packets 8666 */ 8667 static void 8668 fcp_cmd_callback(fc_packet_t *fpkt) 8669 { 8670 struct fcp_pkt *cmd = (struct fcp_pkt *)fpkt->pkt_ulp_private; 8671 struct scsi_pkt *pkt = cmd->cmd_pkt; 8672 struct fcp_port *pptr = ADDR2FCP(&pkt->pkt_address); 8673 8674 ASSERT(cmd->cmd_state != FCP_PKT_IDLE); 8675 8676 if (cmd->cmd_state == FCP_PKT_IDLE) { 8677 cmn_err(CE_PANIC, "Packet already completed %p", 8678 (void *)cmd); 8679 } 8680 8681 /* 8682 * Watch thread should be freeing the packet, ignore the pkt. 8683 */ 8684 if (cmd->cmd_state == FCP_PKT_ABORTING) { 8685 fcp_log(CE_CONT, pptr->port_dip, 8686 "!FCP: Pkt completed while aborting\n"); 8687 return; 8688 } 8689 cmd->cmd_state = FCP_PKT_IDLE; 8690 8691 fcp_complete_pkt(fpkt); 8692 8693 #ifdef DEBUG 8694 mutex_enter(&pptr->port_pkt_mutex); 8695 pptr->port_npkts--; 8696 mutex_exit(&pptr->port_pkt_mutex); 8697 #endif /* DEBUG */ 8698 8699 fcp_post_callback(cmd); 8700 } 8701 8702 8703 static void 8704 fcp_complete_pkt(fc_packet_t *fpkt) 8705 { 8706 int error = 0; 8707 struct fcp_pkt *cmd = (struct fcp_pkt *) 8708 fpkt->pkt_ulp_private; 8709 struct scsi_pkt *pkt = cmd->cmd_pkt; 8710 struct fcp_port *pptr = ADDR2FCP(&pkt->pkt_address); 8711 struct fcp_lun *plun; 8712 struct fcp_tgt *ptgt; 8713 struct fcp_rsp *rsp; 8714 struct scsi_address save; 8715 8716 #ifdef DEBUG 8717 save = pkt->pkt_address; 8718 #endif /* DEBUG */ 8719 8720 rsp = (struct fcp_rsp *)cmd->cmd_fcp_rsp; 8721 8722 if (fpkt->pkt_state == FC_PKT_SUCCESS) { 8723 if (pptr->port_fcp_dma != FC_NO_DVMA_SPACE) { 8724 FCP_CP_IN(fpkt->pkt_resp, rsp, fpkt->pkt_resp_acc, 8725 sizeof (struct fcp_rsp)); 8726 } 8727 8728 pkt->pkt_state = STATE_GOT_BUS | STATE_GOT_TARGET | 8729 STATE_SENT_CMD | STATE_GOT_STATUS; 8730 8731 pkt->pkt_resid = 0; 8732 8733 if (cmd->cmd_pkt->pkt_numcookies) { 8734 pkt->pkt_state |= STATE_XFERRED_DATA; 8735 if (fpkt->pkt_data_resid) { 8736 error++; 8737 } 8738 } 8739 8740 if ((pkt->pkt_scbp != NULL) && ((*(pkt->pkt_scbp) = 8741 rsp->fcp_u.fcp_status.scsi_status) != STATUS_GOOD)) { 8742 /* 8743 * The next two checks make sure that if there 8744 * is no sense data or a valid response and 8745 * the command came back with check condition, 8746 * the command should be retried. 8747 */ 8748 if (!rsp->fcp_u.fcp_status.rsp_len_set && 8749 !rsp->fcp_u.fcp_status.sense_len_set) { 8750 pkt->pkt_state &= ~STATE_XFERRED_DATA; 8751 pkt->pkt_resid = cmd->cmd_dmacount; 8752 } 8753 } 8754 8755 if ((error | rsp->fcp_u.i_fcp_status | rsp->fcp_resid) == 0) { 8756 return; 8757 } 8758 8759 plun = ADDR2LUN(&pkt->pkt_address); 8760 ptgt = plun->lun_tgt; 8761 ASSERT(ptgt != NULL); 8762 8763 /* 8764 * Update the transfer resid, if appropriate 8765 */ 8766 if (rsp->fcp_u.fcp_status.resid_over || 8767 rsp->fcp_u.fcp_status.resid_under) { 8768 pkt->pkt_resid = rsp->fcp_resid; 8769 } 8770 8771 /* 8772 * First see if we got a FCP protocol error. 8773 */ 8774 if (rsp->fcp_u.fcp_status.rsp_len_set) { 8775 struct fcp_rsp_info *bep; 8776 bep = (struct fcp_rsp_info *)(cmd->cmd_fcp_rsp + 8777 sizeof (struct fcp_rsp)); 8778 8779 if (fcp_validate_fcp_response(rsp, pptr) != 8780 FC_SUCCESS) { 8781 pkt->pkt_reason = CMD_CMPLT; 8782 *(pkt->pkt_scbp) = STATUS_CHECK; 8783 8784 fcp_log(CE_WARN, pptr->port_dip, 8785 "!SCSI command to d_id=0x%x lun=0x%x" 8786 " failed, Bad FCP response values:" 8787 " rsvd1=%x, rsvd2=%x, sts-rsvd1=%x," 8788 " sts-rsvd2=%x, rsplen=%x, senselen=%x", 8789 ptgt->tgt_d_id, plun->lun_num, 8790 rsp->reserved_0, rsp->reserved_1, 8791 rsp->fcp_u.fcp_status.reserved_0, 8792 rsp->fcp_u.fcp_status.reserved_1, 8793 rsp->fcp_response_len, rsp->fcp_sense_len); 8794 8795 return; 8796 } 8797 8798 if (pptr->port_fcp_dma != FC_NO_DVMA_SPACE) { 8799 FCP_CP_IN(fpkt->pkt_resp + 8800 sizeof (struct fcp_rsp), bep, 8801 fpkt->pkt_resp_acc, 8802 sizeof (struct fcp_rsp_info)); 8803 } 8804 8805 if (bep->rsp_code != FCP_NO_FAILURE) { 8806 child_info_t *cip; 8807 8808 pkt->pkt_reason = CMD_TRAN_ERR; 8809 8810 mutex_enter(&plun->lun_mutex); 8811 cip = plun->lun_cip; 8812 mutex_exit(&plun->lun_mutex); 8813 8814 FCP_TRACE(fcp_logq, pptr->port_instbuf, 8815 fcp_trace, FCP_BUF_LEVEL_2, 0, 8816 "FCP response error on cmd=%p" 8817 " target=0x%x, cip=%p", cmd, 8818 ptgt->tgt_d_id, cip); 8819 } 8820 } 8821 8822 /* 8823 * See if we got a SCSI error with sense data 8824 */ 8825 if (rsp->fcp_u.fcp_status.sense_len_set) { 8826 uchar_t rqlen; 8827 caddr_t sense_from; 8828 child_info_t *cip; 8829 timeout_id_t tid; 8830 struct scsi_arq_status *arq; 8831 struct scsi_extended_sense *sense_to; 8832 8833 arq = (struct scsi_arq_status *)pkt->pkt_scbp; 8834 sense_to = &arq->sts_sensedata; 8835 8836 rqlen = (uchar_t)min(rsp->fcp_sense_len, 8837 sizeof (struct scsi_extended_sense)); 8838 8839 sense_from = (caddr_t)fpkt->pkt_resp + 8840 sizeof (struct fcp_rsp) + rsp->fcp_response_len; 8841 8842 if (fcp_validate_fcp_response(rsp, pptr) != 8843 FC_SUCCESS) { 8844 pkt->pkt_reason = CMD_CMPLT; 8845 *(pkt->pkt_scbp) = STATUS_CHECK; 8846 8847 fcp_log(CE_WARN, pptr->port_dip, 8848 "!SCSI command to d_id=0x%x lun=0x%x" 8849 " failed, Bad FCP response values:" 8850 " rsvd1=%x, rsvd2=%x, sts-rsvd1=%x," 8851 " sts-rsvd2=%x, rsplen=%x, senselen=%x", 8852 ptgt->tgt_d_id, plun->lun_num, 8853 rsp->reserved_0, rsp->reserved_1, 8854 rsp->fcp_u.fcp_status.reserved_0, 8855 rsp->fcp_u.fcp_status.reserved_1, 8856 rsp->fcp_response_len, rsp->fcp_sense_len); 8857 8858 return; 8859 } 8860 8861 /* 8862 * copy in sense information 8863 */ 8864 if (pptr->port_fcp_dma != FC_NO_DVMA_SPACE) { 8865 FCP_CP_IN(sense_from, sense_to, 8866 fpkt->pkt_resp_acc, rqlen); 8867 } else { 8868 bcopy(sense_from, sense_to, rqlen); 8869 } 8870 8871 if ((FCP_SENSE_REPORTLUN_CHANGED(sense_to)) || 8872 (FCP_SENSE_NO_LUN(sense_to))) { 8873 mutex_enter(&ptgt->tgt_mutex); 8874 if (ptgt->tgt_tid == NULL) { 8875 /* 8876 * Kick off rediscovery 8877 */ 8878 tid = timeout(fcp_reconfigure_luns, 8879 (caddr_t)ptgt, drv_usectohz(1)); 8880 8881 ptgt->tgt_tid = tid; 8882 ptgt->tgt_state |= FCP_TGT_BUSY; 8883 } 8884 mutex_exit(&ptgt->tgt_mutex); 8885 if (FCP_SENSE_REPORTLUN_CHANGED(sense_to)) { 8886 FCP_TRACE(fcp_logq, pptr->port_instbuf, 8887 fcp_trace, FCP_BUF_LEVEL_3, 0, 8888 "!FCP: Report Lun Has Changed" 8889 " target=%x", ptgt->tgt_d_id); 8890 } else if (FCP_SENSE_NO_LUN(sense_to)) { 8891 FCP_TRACE(fcp_logq, pptr->port_instbuf, 8892 fcp_trace, FCP_BUF_LEVEL_3, 0, 8893 "!FCP: LU Not Supported" 8894 " target=%x", ptgt->tgt_d_id); 8895 } 8896 } 8897 ASSERT(pkt->pkt_scbp != NULL); 8898 8899 pkt->pkt_state |= STATE_ARQ_DONE; 8900 8901 arq->sts_rqpkt_resid = SENSE_LENGTH - rqlen; 8902 8903 *((uchar_t *)&arq->sts_rqpkt_status) = STATUS_GOOD; 8904 arq->sts_rqpkt_reason = 0; 8905 arq->sts_rqpkt_statistics = 0; 8906 8907 arq->sts_rqpkt_state = STATE_GOT_BUS | 8908 STATE_GOT_TARGET | STATE_SENT_CMD | 8909 STATE_GOT_STATUS | STATE_ARQ_DONE | 8910 STATE_XFERRED_DATA; 8911 8912 mutex_enter(&plun->lun_mutex); 8913 cip = plun->lun_cip; 8914 mutex_exit(&plun->lun_mutex); 8915 8916 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 8917 fcp_trace, FCP_BUF_LEVEL_8, 0, 8918 "SCSI Check condition on cmd=%p target=0x%x" 8919 " LUN=%p, cmd=%x SCSI status=%x, es key=%x" 8920 " ASC=%x ASCQ=%x", cmd, ptgt->tgt_d_id, cip, 8921 cmd->cmd_fcp_cmd.fcp_cdb[0], 8922 rsp->fcp_u.fcp_status.scsi_status, 8923 sense_to->es_key, sense_to->es_add_code, 8924 sense_to->es_qual_code); 8925 } 8926 } else { 8927 plun = ADDR2LUN(&pkt->pkt_address); 8928 ptgt = plun->lun_tgt; 8929 ASSERT(ptgt != NULL); 8930 8931 /* 8932 * Work harder to translate errors into target driver 8933 * understandable ones. Note with despair that the target 8934 * drivers don't decode pkt_state and pkt_reason exhaustively 8935 * They resort to using the big hammer most often, which 8936 * may not get fixed in the life time of this driver. 8937 */ 8938 pkt->pkt_state = 0; 8939 pkt->pkt_statistics = 0; 8940 8941 switch (fpkt->pkt_state) { 8942 case FC_PKT_TRAN_ERROR: 8943 switch (fpkt->pkt_reason) { 8944 case FC_REASON_OVERRUN: 8945 pkt->pkt_reason = CMD_CMD_OVR; 8946 pkt->pkt_statistics |= STAT_ABORTED; 8947 break; 8948 8949 case FC_REASON_XCHG_BSY: { 8950 caddr_t ptr; 8951 8952 pkt->pkt_reason = CMD_CMPLT; /* Lie */ 8953 8954 ptr = (caddr_t)pkt->pkt_scbp; 8955 if (ptr) { 8956 *ptr = STATUS_BUSY; 8957 } 8958 break; 8959 } 8960 8961 case FC_REASON_ABORTED: 8962 pkt->pkt_reason = CMD_TRAN_ERR; 8963 pkt->pkt_statistics |= STAT_ABORTED; 8964 break; 8965 8966 case FC_REASON_ABORT_FAILED: 8967 pkt->pkt_reason = CMD_ABORT_FAIL; 8968 break; 8969 8970 case FC_REASON_NO_SEQ_INIT: 8971 case FC_REASON_CRC_ERROR: 8972 pkt->pkt_reason = CMD_TRAN_ERR; 8973 pkt->pkt_statistics |= STAT_ABORTED; 8974 break; 8975 default: 8976 pkt->pkt_reason = CMD_TRAN_ERR; 8977 break; 8978 } 8979 break; 8980 8981 case FC_PKT_PORT_OFFLINE: { 8982 dev_info_t *cdip = NULL; 8983 caddr_t ptr; 8984 8985 if (fpkt->pkt_reason == FC_REASON_LOGIN_REQUIRED) { 8986 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 8987 fcp_trace, FCP_BUF_LEVEL_8, 0, 8988 "SCSI cmd; LOGIN REQUIRED from FCA for %x", 8989 ptgt->tgt_d_id); 8990 } 8991 8992 mutex_enter(&plun->lun_mutex); 8993 if (plun->lun_mpxio == 0) { 8994 cdip = DIP(plun->lun_cip); 8995 } else if (plun->lun_cip) { 8996 cdip = mdi_pi_get_client(PIP(plun->lun_cip)); 8997 } 8998 8999 mutex_exit(&plun->lun_mutex); 9000 9001 if (cdip) { 9002 (void) ndi_event_retrieve_cookie( 9003 pptr->port_ndi_event_hdl, cdip, 9004 FCAL_REMOVE_EVENT, &fcp_remove_eid, 9005 NDI_EVENT_NOPASS); 9006 (void) ndi_event_run_callbacks( 9007 pptr->port_ndi_event_hdl, cdip, 9008 fcp_remove_eid, NULL); 9009 } 9010 9011 /* 9012 * If the link goes off-line for a lip, 9013 * this will cause a error to the ST SG 9014 * SGEN drivers. By setting BUSY we will 9015 * give the drivers the chance to retry 9016 * before it blows of the job. ST will 9017 * remember how many times it has retried. 9018 */ 9019 9020 if ((plun->lun_type == DTYPE_SEQUENTIAL) || 9021 (plun->lun_type == DTYPE_CHANGER)) { 9022 pkt->pkt_reason = CMD_CMPLT; /* Lie */ 9023 ptr = (caddr_t)pkt->pkt_scbp; 9024 if (ptr) { 9025 *ptr = STATUS_BUSY; 9026 } 9027 } else { 9028 pkt->pkt_reason = CMD_TRAN_ERR; 9029 pkt->pkt_statistics |= STAT_BUS_RESET; 9030 } 9031 break; 9032 } 9033 9034 case FC_PKT_TRAN_BSY: 9035 /* 9036 * Use the ssd Qfull handling here. 9037 */ 9038 *pkt->pkt_scbp = STATUS_INTERMEDIATE; 9039 pkt->pkt_state = STATE_GOT_BUS; 9040 break; 9041 9042 case FC_PKT_TIMEOUT: 9043 pkt->pkt_reason = CMD_TIMEOUT; 9044 if (fpkt->pkt_reason == FC_REASON_ABORT_FAILED) { 9045 pkt->pkt_statistics |= STAT_TIMEOUT; 9046 } else { 9047 pkt->pkt_statistics |= STAT_ABORTED; 9048 } 9049 break; 9050 9051 case FC_PKT_LOCAL_RJT: 9052 switch (fpkt->pkt_reason) { 9053 case FC_REASON_OFFLINE: { 9054 dev_info_t *cdip = NULL; 9055 9056 mutex_enter(&plun->lun_mutex); 9057 if (plun->lun_mpxio == 0) { 9058 cdip = DIP(plun->lun_cip); 9059 } else if (plun->lun_cip) { 9060 cdip = mdi_pi_get_client( 9061 PIP(plun->lun_cip)); 9062 } 9063 mutex_exit(&plun->lun_mutex); 9064 9065 if (cdip) { 9066 (void) ndi_event_retrieve_cookie( 9067 pptr->port_ndi_event_hdl, cdip, 9068 FCAL_REMOVE_EVENT, 9069 &fcp_remove_eid, 9070 NDI_EVENT_NOPASS); 9071 (void) ndi_event_run_callbacks( 9072 pptr->port_ndi_event_hdl, 9073 cdip, fcp_remove_eid, NULL); 9074 } 9075 9076 pkt->pkt_reason = CMD_TRAN_ERR; 9077 pkt->pkt_statistics |= STAT_BUS_RESET; 9078 9079 break; 9080 } 9081 9082 case FC_REASON_NOMEM: 9083 case FC_REASON_QFULL: { 9084 caddr_t ptr; 9085 9086 pkt->pkt_reason = CMD_CMPLT; /* Lie */ 9087 ptr = (caddr_t)pkt->pkt_scbp; 9088 if (ptr) { 9089 *ptr = STATUS_BUSY; 9090 } 9091 break; 9092 } 9093 9094 case FC_REASON_DMA_ERROR: 9095 pkt->pkt_reason = CMD_DMA_DERR; 9096 pkt->pkt_statistics |= STAT_ABORTED; 9097 break; 9098 9099 case FC_REASON_CRC_ERROR: 9100 case FC_REASON_UNDERRUN: { 9101 uchar_t status; 9102 /* 9103 * Work around for Bugid: 4240945. 9104 * IB on A5k doesn't set the Underrun bit 9105 * in the fcp status, when it is transferring 9106 * less than requested amount of data. Work 9107 * around the ses problem to keep luxadm 9108 * happy till ibfirmware is fixed. 9109 */ 9110 if (pptr->port_fcp_dma != FC_NO_DVMA_SPACE) { 9111 FCP_CP_IN(fpkt->pkt_resp, rsp, 9112 fpkt->pkt_resp_acc, 9113 sizeof (struct fcp_rsp)); 9114 } 9115 status = rsp->fcp_u.fcp_status.scsi_status; 9116 if (((plun->lun_type & DTYPE_MASK) == 9117 DTYPE_ESI) && (status == STATUS_GOOD)) { 9118 pkt->pkt_reason = CMD_CMPLT; 9119 *pkt->pkt_scbp = status; 9120 pkt->pkt_resid = 0; 9121 } else { 9122 pkt->pkt_reason = CMD_TRAN_ERR; 9123 pkt->pkt_statistics |= STAT_ABORTED; 9124 } 9125 break; 9126 } 9127 9128 case FC_REASON_NO_CONNECTION: 9129 case FC_REASON_UNSUPPORTED: 9130 case FC_REASON_ILLEGAL_REQ: 9131 case FC_REASON_BAD_SID: 9132 case FC_REASON_DIAG_BUSY: 9133 case FC_REASON_FCAL_OPN_FAIL: 9134 case FC_REASON_BAD_XID: 9135 default: 9136 pkt->pkt_reason = CMD_TRAN_ERR; 9137 pkt->pkt_statistics |= STAT_ABORTED; 9138 break; 9139 9140 } 9141 break; 9142 9143 case FC_PKT_NPORT_RJT: 9144 case FC_PKT_FABRIC_RJT: 9145 case FC_PKT_NPORT_BSY: 9146 case FC_PKT_FABRIC_BSY: 9147 default: 9148 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 9149 fcp_trace, FCP_BUF_LEVEL_8, 0, 9150 "FC Status 0x%x, reason 0x%x", 9151 fpkt->pkt_state, fpkt->pkt_reason); 9152 pkt->pkt_reason = CMD_TRAN_ERR; 9153 pkt->pkt_statistics |= STAT_ABORTED; 9154 break; 9155 } 9156 9157 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 9158 fcp_trace, FCP_BUF_LEVEL_9, 0, 9159 "!FC error on cmd=%p target=0x%x: pkt state=0x%x " 9160 " pkt reason=0x%x", cmd, ptgt->tgt_d_id, fpkt->pkt_state, 9161 fpkt->pkt_reason); 9162 } 9163 9164 ASSERT(save.a_hba_tran == pkt->pkt_address.a_hba_tran); 9165 } 9166 9167 9168 static int 9169 fcp_validate_fcp_response(struct fcp_rsp *rsp, struct fcp_port *pptr) 9170 { 9171 if (rsp->reserved_0 || rsp->reserved_1 || 9172 rsp->fcp_u.fcp_status.reserved_0 || 9173 rsp->fcp_u.fcp_status.reserved_1) { 9174 /* 9175 * These reserved fields should ideally be zero. FCP-2 does say 9176 * that the recipient need not check for reserved fields to be 9177 * zero. If they are not zero, we will not make a fuss about it 9178 * - just log it (in debug to both trace buffer and messages 9179 * file and to trace buffer only in non-debug) and move on. 9180 * 9181 * Non-zero reserved fields were seen with minnows. 9182 * 9183 * qlc takes care of some of this but we cannot assume that all 9184 * FCAs will do so. 9185 */ 9186 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 9187 FCP_BUF_LEVEL_5, 0, 9188 "Got fcp response packet with non-zero reserved fields " 9189 "rsp->reserved_0:0x%x, rsp_reserved_1:0x%x, " 9190 "status.reserved_0:0x%x, status.reserved_1:0x%x", 9191 rsp->reserved_0, rsp->reserved_1, 9192 rsp->fcp_u.fcp_status.reserved_0, 9193 rsp->fcp_u.fcp_status.reserved_1); 9194 } 9195 9196 if (rsp->fcp_u.fcp_status.rsp_len_set && (rsp->fcp_response_len > 9197 (FCP_MAX_RSP_IU_SIZE - sizeof (struct fcp_rsp)))) { 9198 return (FC_FAILURE); 9199 } 9200 9201 if (rsp->fcp_u.fcp_status.sense_len_set && rsp->fcp_sense_len > 9202 (FCP_MAX_RSP_IU_SIZE - rsp->fcp_response_len - 9203 sizeof (struct fcp_rsp))) { 9204 return (FC_FAILURE); 9205 } 9206 9207 return (FC_SUCCESS); 9208 } 9209 9210 9211 /* 9212 * This is called when there is a change the in device state. The case we're 9213 * handling here is, if the d_id s does not match, offline this tgt and online 9214 * a new tgt with the new d_id. called from fcp_handle_devices with 9215 * port_mutex held. 9216 */ 9217 static int 9218 fcp_device_changed(struct fcp_port *pptr, struct fcp_tgt *ptgt, 9219 fc_portmap_t *map_entry, int link_cnt, int tgt_cnt, int cause) 9220 { 9221 ASSERT(mutex_owned(&pptr->port_mutex)); 9222 9223 FCP_TRACE(fcp_logq, pptr->port_instbuf, 9224 fcp_trace, FCP_BUF_LEVEL_3, 0, 9225 "Starting fcp_device_changed..."); 9226 9227 /* 9228 * The two cases where the port_device_changed is called is 9229 * either it changes it's d_id or it's hard address. 9230 */ 9231 if ((ptgt->tgt_d_id != map_entry->map_did.port_id) || 9232 (FC_TOP_EXTERNAL(pptr->port_topology) && 9233 (ptgt->tgt_hard_addr != map_entry->map_hard_addr.hard_addr))) { 9234 9235 /* offline this target */ 9236 mutex_enter(&ptgt->tgt_mutex); 9237 if (!(ptgt->tgt_state & FCP_TGT_OFFLINE)) { 9238 (void) fcp_offline_target(pptr, ptgt, link_cnt, 9239 0, 1, NDI_DEVI_REMOVE); 9240 } 9241 mutex_exit(&ptgt->tgt_mutex); 9242 9243 fcp_log(CE_NOTE, pptr->port_dip, 9244 "Change in target properties: Old D_ID=%x New D_ID=%x" 9245 " Old HA=%x New HA=%x", ptgt->tgt_d_id, 9246 map_entry->map_did.port_id, ptgt->tgt_hard_addr, 9247 map_entry->map_hard_addr.hard_addr); 9248 } 9249 9250 return (fcp_handle_mapflags(pptr, ptgt, map_entry, 9251 link_cnt, tgt_cnt, cause)); 9252 } 9253 9254 /* 9255 * Function: fcp_alloc_lun 9256 * 9257 * Description: Creates a new lun structure and adds it to the list 9258 * of luns of the target. 9259 * 9260 * Argument: ptgt Target the lun will belong to. 9261 * 9262 * Return Value: NULL Failed 9263 * Not NULL Succeeded 9264 * 9265 * Context: Kernel context 9266 */ 9267 static struct fcp_lun * 9268 fcp_alloc_lun(struct fcp_tgt *ptgt) 9269 { 9270 struct fcp_lun *plun; 9271 9272 plun = kmem_zalloc(sizeof (struct fcp_lun), KM_NOSLEEP); 9273 if (plun != NULL) { 9274 /* 9275 * Initialize the mutex before putting in the target list 9276 * especially before releasing the target mutex. 9277 */ 9278 mutex_init(&plun->lun_mutex, NULL, MUTEX_DRIVER, NULL); 9279 plun->lun_tgt = ptgt; 9280 9281 mutex_enter(&ptgt->tgt_mutex); 9282 plun->lun_next = ptgt->tgt_lun; 9283 ptgt->tgt_lun = plun; 9284 plun->lun_old_guid = NULL; 9285 plun->lun_old_guid_size = 0; 9286 mutex_exit(&ptgt->tgt_mutex); 9287 } 9288 9289 return (plun); 9290 } 9291 9292 /* 9293 * Function: fcp_dealloc_lun 9294 * 9295 * Description: Frees the LUN structure passed by the caller. 9296 * 9297 * Argument: plun LUN structure to free. 9298 * 9299 * Return Value: None 9300 * 9301 * Context: Kernel context. 9302 */ 9303 static void 9304 fcp_dealloc_lun(struct fcp_lun *plun) 9305 { 9306 mutex_enter(&plun->lun_mutex); 9307 if (plun->lun_cip) { 9308 fcp_remove_child(plun); 9309 } 9310 mutex_exit(&plun->lun_mutex); 9311 9312 mutex_destroy(&plun->lun_mutex); 9313 if (plun->lun_guid) { 9314 kmem_free(plun->lun_guid, plun->lun_guid_size); 9315 } 9316 if (plun->lun_old_guid) { 9317 kmem_free(plun->lun_old_guid, plun->lun_old_guid_size); 9318 } 9319 kmem_free(plun, sizeof (*plun)); 9320 } 9321 9322 /* 9323 * Function: fcp_alloc_tgt 9324 * 9325 * Description: Creates a new target structure and adds it to the port 9326 * hash list. 9327 * 9328 * Argument: pptr fcp port structure 9329 * *map_entry entry describing the target to create 9330 * link_cnt Link state change counter 9331 * 9332 * Return Value: NULL Failed 9333 * Not NULL Succeeded 9334 * 9335 * Context: Kernel context. 9336 */ 9337 static struct fcp_tgt * 9338 fcp_alloc_tgt(struct fcp_port *pptr, fc_portmap_t *map_entry, int link_cnt) 9339 { 9340 int hash; 9341 uchar_t *wwn; 9342 struct fcp_tgt *ptgt; 9343 9344 ptgt = kmem_zalloc(sizeof (*ptgt), KM_NOSLEEP); 9345 if (ptgt != NULL) { 9346 mutex_enter(&pptr->port_mutex); 9347 if (link_cnt != pptr->port_link_cnt) { 9348 /* 9349 * oh oh -- another link reset 9350 * in progress -- give up 9351 */ 9352 mutex_exit(&pptr->port_mutex); 9353 kmem_free(ptgt, sizeof (*ptgt)); 9354 ptgt = NULL; 9355 } else { 9356 /* 9357 * initialize the mutex before putting in the port 9358 * wwn list, especially before releasing the port 9359 * mutex. 9360 */ 9361 mutex_init(&ptgt->tgt_mutex, NULL, MUTEX_DRIVER, NULL); 9362 9363 /* add new target entry to the port's hash list */ 9364 wwn = (uchar_t *)&map_entry->map_pwwn; 9365 hash = FCP_HASH(wwn); 9366 9367 ptgt->tgt_next = pptr->port_tgt_hash_table[hash]; 9368 pptr->port_tgt_hash_table[hash] = ptgt; 9369 9370 /* save cross-ptr */ 9371 ptgt->tgt_port = pptr; 9372 9373 ptgt->tgt_change_cnt = 1; 9374 9375 /* initialize the target manual_config_only flag */ 9376 if (fcp_enable_auto_configuration) { 9377 ptgt->tgt_manual_config_only = 0; 9378 } else { 9379 ptgt->tgt_manual_config_only = 1; 9380 } 9381 9382 mutex_exit(&pptr->port_mutex); 9383 } 9384 } 9385 9386 return (ptgt); 9387 } 9388 9389 /* 9390 * Function: fcp_dealloc_tgt 9391 * 9392 * Description: Frees the target structure passed by the caller. 9393 * 9394 * Argument: ptgt Target structure to free. 9395 * 9396 * Return Value: None 9397 * 9398 * Context: Kernel context. 9399 */ 9400 static void 9401 fcp_dealloc_tgt(struct fcp_tgt *ptgt) 9402 { 9403 mutex_destroy(&ptgt->tgt_mutex); 9404 kmem_free(ptgt, sizeof (*ptgt)); 9405 } 9406 9407 9408 /* 9409 * Handle STATUS_QFULL and STATUS_BUSY by performing delayed retry 9410 * 9411 * Device discovery commands will not be retried for-ever as 9412 * this will have repercussions on other devices that need to 9413 * be submitted to the hotplug thread. After a quick glance 9414 * at the SCSI-3 spec, it was found that the spec doesn't 9415 * mandate a forever retry, rather recommends a delayed retry. 9416 * 9417 * Since Photon IB is single threaded, STATUS_BUSY is common 9418 * in a 4+initiator environment. Make sure the total time 9419 * spent on retries (including command timeout) does not 9420 * 60 seconds 9421 */ 9422 static void 9423 fcp_queue_ipkt(struct fcp_port *pptr, fc_packet_t *fpkt) 9424 { 9425 struct fcp_ipkt *icmd = (struct fcp_ipkt *)fpkt->pkt_ulp_private; 9426 struct fcp_tgt *ptgt = icmd->ipkt_tgt; 9427 9428 mutex_enter(&pptr->port_mutex); 9429 mutex_enter(&ptgt->tgt_mutex); 9430 if (FCP_STATE_CHANGED(pptr, ptgt, icmd)) { 9431 FCP_TRACE(fcp_logq, pptr->port_instbuf, 9432 fcp_trace, FCP_BUF_LEVEL_2, 0, 9433 "fcp_queue_ipkt,1:state change occured" 9434 " for D_ID=0x%x", ptgt->tgt_d_id); 9435 mutex_exit(&ptgt->tgt_mutex); 9436 mutex_exit(&pptr->port_mutex); 9437 (void) fcp_call_finish_init(pptr, ptgt, icmd->ipkt_link_cnt, 9438 icmd->ipkt_change_cnt, icmd->ipkt_cause); 9439 fcp_icmd_free(pptr, icmd); 9440 return; 9441 } 9442 mutex_exit(&ptgt->tgt_mutex); 9443 9444 icmd->ipkt_restart = fcp_watchdog_time + icmd->ipkt_retries++; 9445 9446 if (pptr->port_ipkt_list != NULL) { 9447 /* add pkt to front of doubly-linked list */ 9448 pptr->port_ipkt_list->ipkt_prev = icmd; 9449 icmd->ipkt_next = pptr->port_ipkt_list; 9450 pptr->port_ipkt_list = icmd; 9451 icmd->ipkt_prev = NULL; 9452 } else { 9453 /* this is the first/only pkt on the list */ 9454 pptr->port_ipkt_list = icmd; 9455 icmd->ipkt_next = NULL; 9456 icmd->ipkt_prev = NULL; 9457 } 9458 mutex_exit(&pptr->port_mutex); 9459 } 9460 9461 /* 9462 * Function: fcp_transport 9463 * 9464 * Description: This function submits the Fibre Channel packet to the transort 9465 * layer by calling fc_ulp_transport(). If fc_ulp_transport() 9466 * fails the submission, the treatment depends on the value of 9467 * the variable internal. 9468 * 9469 * Argument: port_handle fp/fctl port handle. 9470 * *fpkt Packet to submit to the transport layer. 9471 * internal Not zero when it's an internal packet. 9472 * 9473 * Return Value: FC_TRAN_BUSY 9474 * FC_STATEC_BUSY 9475 * FC_OFFLINE 9476 * FC_LOGINREQ 9477 * FC_DEVICE_BUSY 9478 * FC_SUCCESS 9479 */ 9480 static int 9481 fcp_transport(opaque_t port_handle, fc_packet_t *fpkt, int internal) 9482 { 9483 int rval; 9484 9485 rval = fc_ulp_transport(port_handle, fpkt); 9486 if (rval == FC_SUCCESS) { 9487 return (rval); 9488 } 9489 9490 /* 9491 * LUN isn't marked BUSY or OFFLINE, so we got here to transport 9492 * a command, if the underlying modules see that there is a state 9493 * change, or if a port is OFFLINE, that means, that state change 9494 * hasn't reached FCP yet, so re-queue the command for deferred 9495 * submission. 9496 */ 9497 if ((rval == FC_STATEC_BUSY) || (rval == FC_OFFLINE) || 9498 (rval == FC_LOGINREQ) || (rval == FC_DEVICE_BUSY) || 9499 (rval == FC_DEVICE_BUSY_NEW_RSCN) || (rval == FC_TRAN_BUSY)) { 9500 /* 9501 * Defer packet re-submission. Life hang is possible on 9502 * internal commands if the port driver sends FC_STATEC_BUSY 9503 * for ever, but that shouldn't happen in a good environment. 9504 * Limiting re-transport for internal commands is probably a 9505 * good idea.. 9506 * A race condition can happen when a port sees barrage of 9507 * link transitions offline to online. If the FCTL has 9508 * returned FC_STATEC_BUSY or FC_OFFLINE then none of the 9509 * internal commands should be queued to do the discovery. 9510 * The race condition is when an online comes and FCP starts 9511 * its internal discovery and the link goes offline. It is 9512 * possible that the statec_callback has not reached FCP 9513 * and FCP is carrying on with its internal discovery. 9514 * FC_STATEC_BUSY or FC_OFFLINE will be the first indication 9515 * that the link has gone offline. At this point FCP should 9516 * drop all the internal commands and wait for the 9517 * statec_callback. It will be facilitated by incrementing 9518 * port_link_cnt. 9519 * 9520 * For external commands, the (FC)pkt_timeout is decremented 9521 * by the QUEUE Delay added by our driver, Care is taken to 9522 * ensure that it doesn't become zero (zero means no timeout) 9523 * If the time expires right inside driver queue itself, 9524 * the watch thread will return it to the original caller 9525 * indicating that the command has timed-out. 9526 */ 9527 if (internal) { 9528 char *op; 9529 struct fcp_ipkt *icmd; 9530 9531 icmd = (struct fcp_ipkt *)fpkt->pkt_ulp_private; 9532 switch (icmd->ipkt_opcode) { 9533 case SCMD_REPORT_LUN: 9534 op = "REPORT LUN"; 9535 break; 9536 9537 case SCMD_INQUIRY: 9538 op = "INQUIRY"; 9539 break; 9540 9541 case SCMD_INQUIRY_PAGE83: 9542 op = "INQUIRY-83"; 9543 break; 9544 9545 default: 9546 op = "Internal SCSI COMMAND"; 9547 break; 9548 } 9549 9550 if (fcp_handle_ipkt_errors(icmd->ipkt_port, 9551 icmd->ipkt_tgt, icmd, rval, op) == DDI_SUCCESS) { 9552 rval = FC_SUCCESS; 9553 } 9554 } else { 9555 struct fcp_pkt *cmd; 9556 struct fcp_port *pptr; 9557 9558 cmd = (struct fcp_pkt *)fpkt->pkt_ulp_private; 9559 cmd->cmd_state = FCP_PKT_IDLE; 9560 pptr = ADDR2FCP(&cmd->cmd_pkt->pkt_address); 9561 9562 if (cmd->cmd_pkt->pkt_flags & FLAG_NOQUEUE) { 9563 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 9564 fcp_trace, FCP_BUF_LEVEL_9, 0, 9565 "fcp_transport: xport busy for pkt %p", 9566 cmd->cmd_pkt); 9567 rval = FC_TRAN_BUSY; 9568 } else { 9569 fcp_queue_pkt(pptr, cmd); 9570 rval = FC_SUCCESS; 9571 } 9572 } 9573 } 9574 9575 return (rval); 9576 } 9577 9578 /*VARARGS3*/ 9579 static void 9580 fcp_log(int level, dev_info_t *dip, const char *fmt, ...) 9581 { 9582 char buf[256]; 9583 va_list ap; 9584 9585 if (dip == NULL) { 9586 dip = fcp_global_dip; 9587 } 9588 9589 va_start(ap, fmt); 9590 (void) vsprintf(buf, fmt, ap); 9591 va_end(ap); 9592 9593 scsi_log(dip, "fcp", level, buf); 9594 } 9595 9596 /* 9597 * This function retries NS registry of FC4 type. 9598 * It assumes that fcp_mutex is held. 9599 * The function does nothing if topology is not fabric 9600 * So, the topology has to be set before this function can be called 9601 */ 9602 static void 9603 fcp_retry_ns_registry(struct fcp_port *pptr, uint32_t s_id) 9604 { 9605 int rval; 9606 9607 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 9608 9609 if (((pptr->port_state & FCP_STATE_NS_REG_FAILED) == 0) || 9610 ((pptr->port_topology != FC_TOP_FABRIC) && 9611 (pptr->port_topology != FC_TOP_PUBLIC_LOOP))) { 9612 if (pptr->port_state & FCP_STATE_NS_REG_FAILED) { 9613 pptr->port_state &= ~FCP_STATE_NS_REG_FAILED; 9614 } 9615 return; 9616 } 9617 mutex_exit(&pptr->port_mutex); 9618 rval = fcp_do_ns_registry(pptr, s_id); 9619 mutex_enter(&pptr->port_mutex); 9620 9621 if (rval == 0) { 9622 /* Registry successful. Reset flag */ 9623 pptr->port_state &= ~(FCP_STATE_NS_REG_FAILED); 9624 } 9625 } 9626 9627 /* 9628 * This function registers the ULP with the switch by calling transport i/f 9629 */ 9630 static int 9631 fcp_do_ns_registry(struct fcp_port *pptr, uint32_t s_id) 9632 { 9633 fc_ns_cmd_t ns_cmd; 9634 ns_rfc_type_t rfc; 9635 uint32_t types[8]; 9636 9637 /* 9638 * Prepare the Name server structure to 9639 * register with the transport in case of 9640 * Fabric configuration. 9641 */ 9642 bzero(&rfc, sizeof (rfc)); 9643 bzero(types, sizeof (types)); 9644 9645 types[FC4_TYPE_WORD_POS(FC_TYPE_SCSI_FCP)] = 9646 (1 << FC4_TYPE_BIT_POS(FC_TYPE_SCSI_FCP)); 9647 9648 rfc.rfc_port_id.port_id = s_id; 9649 bcopy(types, rfc.rfc_types, sizeof (types)); 9650 9651 ns_cmd.ns_flags = 0; 9652 ns_cmd.ns_cmd = NS_RFT_ID; 9653 ns_cmd.ns_req_len = sizeof (rfc); 9654 ns_cmd.ns_req_payload = (caddr_t)&rfc; 9655 ns_cmd.ns_resp_len = 0; 9656 ns_cmd.ns_resp_payload = NULL; 9657 9658 /* 9659 * Perform the Name Server Registration for SCSI_FCP FC4 Type. 9660 */ 9661 if (fc_ulp_port_ns(pptr->port_fp_handle, NULL, &ns_cmd)) { 9662 fcp_log(CE_WARN, pptr->port_dip, 9663 "!ns_registry: failed name server registration"); 9664 return (1); 9665 } 9666 9667 return (0); 9668 } 9669 9670 /* 9671 * Function: fcp_handle_port_attach 9672 * 9673 * Description: This function is called from fcp_port_attach() to attach a 9674 * new port. This routine does the following: 9675 * 9676 * 1) Allocates an fcp_port structure and initializes it. 9677 * 2) Tries to register the new FC-4 (FCP) capablity with the name 9678 * server. 9679 * 3) Kicks off the enumeration of the targets/luns visible 9680 * through this new port. That is done by calling 9681 * fcp_statec_callback() if the port is online. 9682 * 9683 * Argument: ulph fp/fctl port handle. 9684 * *pinfo Port information. 9685 * s_id Port ID. 9686 * instance Device instance number for the local port 9687 * (returned by ddi_get_instance()). 9688 * 9689 * Return Value: DDI_SUCCESS 9690 * DDI_FAILURE 9691 * 9692 * Context: User and Kernel context. 9693 */ 9694 /*ARGSUSED*/ 9695 int 9696 fcp_handle_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo, 9697 uint32_t s_id, int instance) 9698 { 9699 int res = DDI_FAILURE; 9700 scsi_hba_tran_t *tran; 9701 int mutex_initted = FALSE; 9702 int hba_attached = FALSE; 9703 int soft_state_linked = FALSE; 9704 int event_bind = FALSE; 9705 struct fcp_port *pptr; 9706 fc_portmap_t *tmp_list = NULL; 9707 uint32_t max_cnt, alloc_cnt; 9708 uchar_t *boot_wwn = NULL; 9709 uint_t nbytes; 9710 int manual_cfg; 9711 9712 /* 9713 * this port instance attaching for the first time (or after 9714 * being detached before) 9715 */ 9716 FCP_TRACE(fcp_logq, "fcp", fcp_trace, 9717 FCP_BUF_LEVEL_3, 0, "port attach: for port %d", instance); 9718 9719 if (ddi_soft_state_zalloc(fcp_softstate, instance) != DDI_SUCCESS) { 9720 cmn_err(CE_WARN, "fcp: Softstate struct alloc failed" 9721 "parent dip: %p; instance: %d", (void *)pinfo->port_dip, 9722 instance); 9723 return (res); 9724 } 9725 9726 if ((pptr = ddi_get_soft_state(fcp_softstate, instance)) == NULL) { 9727 /* this shouldn't happen */ 9728 ddi_soft_state_free(fcp_softstate, instance); 9729 cmn_err(CE_WARN, "fcp: bad soft state"); 9730 return (res); 9731 } 9732 9733 (void) sprintf(pptr->port_instbuf, "fcp(%d)", instance); 9734 9735 /* 9736 * Make a copy of ulp_port_info as fctl allocates 9737 * a temp struct. 9738 */ 9739 (void) fcp_cp_pinfo(pptr, pinfo); 9740 9741 /* 9742 * Check for manual_configuration_only property. 9743 * Enable manual configurtion if the property is 9744 * set to 1, otherwise disable manual configuration. 9745 */ 9746 if ((manual_cfg = ddi_prop_get_int(DDI_DEV_T_ANY, pptr->port_dip, 9747 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 9748 MANUAL_CFG_ONLY, 9749 -1)) != -1) { 9750 if (manual_cfg == 1) { 9751 char *pathname; 9752 pathname = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 9753 (void) ddi_pathname(pptr->port_dip, pathname); 9754 cmn_err(CE_NOTE, 9755 "%s (%s%d) %s is enabled via %s.conf.", 9756 pathname, 9757 ddi_driver_name(pptr->port_dip), 9758 ddi_get_instance(pptr->port_dip), 9759 MANUAL_CFG_ONLY, 9760 ddi_driver_name(pptr->port_dip)); 9761 fcp_enable_auto_configuration = 0; 9762 kmem_free(pathname, MAXPATHLEN); 9763 } 9764 } 9765 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(pptr->port_link_cnt)) 9766 pptr->port_link_cnt = 1; 9767 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(pptr->port_link_cnt)) 9768 pptr->port_id = s_id; 9769 pptr->port_instance = instance; 9770 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(pptr->port_state)) 9771 pptr->port_state = FCP_STATE_INIT; 9772 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(pptr->port_state)) 9773 9774 pptr->port_dmacookie_sz = (pptr->port_data_dma_attr.dma_attr_sgllen * 9775 sizeof (ddi_dma_cookie_t)); 9776 9777 /* 9778 * The two mutexes of fcp_port are initialized. The variable 9779 * mutex_initted is incremented to remember that fact. That variable 9780 * is checked when the routine fails and the mutexes have to be 9781 * destroyed. 9782 */ 9783 mutex_init(&pptr->port_mutex, NULL, MUTEX_DRIVER, NULL); 9784 mutex_init(&pptr->port_pkt_mutex, NULL, MUTEX_DRIVER, NULL); 9785 mutex_initted++; 9786 9787 /* 9788 * The SCSI tran structure is allocate and initialized now. 9789 */ 9790 if ((tran = scsi_hba_tran_alloc(pptr->port_dip, 0)) == NULL) { 9791 fcp_log(CE_WARN, pptr->port_dip, 9792 "!fcp%d: scsi_hba_tran_alloc failed", instance); 9793 goto fail; 9794 } 9795 9796 /* link in the transport structure then fill it in */ 9797 pptr->port_tran = tran; 9798 tran->tran_hba_private = pptr; 9799 tran->tran_tgt_init = fcp_scsi_tgt_init; 9800 tran->tran_tgt_probe = NULL; 9801 tran->tran_tgt_free = fcp_scsi_tgt_free; 9802 tran->tran_start = fcp_scsi_start; 9803 tran->tran_reset = fcp_scsi_reset; 9804 tran->tran_abort = fcp_scsi_abort; 9805 tran->tran_getcap = fcp_scsi_getcap; 9806 tran->tran_setcap = fcp_scsi_setcap; 9807 tran->tran_init_pkt = NULL; 9808 tran->tran_destroy_pkt = NULL; 9809 tran->tran_dmafree = NULL; 9810 tran->tran_sync_pkt = NULL; 9811 tran->tran_reset_notify = fcp_scsi_reset_notify; 9812 tran->tran_get_bus_addr = fcp_scsi_get_bus_addr; 9813 tran->tran_get_name = fcp_scsi_get_name; 9814 tran->tran_clear_aca = NULL; 9815 tran->tran_clear_task_set = NULL; 9816 tran->tran_terminate_task = NULL; 9817 tran->tran_get_eventcookie = fcp_scsi_bus_get_eventcookie; 9818 tran->tran_add_eventcall = fcp_scsi_bus_add_eventcall; 9819 tran->tran_remove_eventcall = fcp_scsi_bus_remove_eventcall; 9820 tran->tran_post_event = fcp_scsi_bus_post_event; 9821 tran->tran_quiesce = NULL; 9822 tran->tran_unquiesce = NULL; 9823 tran->tran_bus_reset = NULL; 9824 tran->tran_bus_config = fcp_scsi_bus_config; 9825 tran->tran_bus_unconfig = fcp_scsi_bus_unconfig; 9826 tran->tran_bus_power = NULL; 9827 tran->tran_interconnect_type = INTERCONNECT_FABRIC; 9828 9829 tran->tran_pkt_constructor = fcp_kmem_cache_constructor; 9830 tran->tran_pkt_destructor = fcp_kmem_cache_destructor; 9831 tran->tran_setup_pkt = fcp_pkt_setup; 9832 tran->tran_teardown_pkt = fcp_pkt_teardown; 9833 tran->tran_hba_len = pptr->port_priv_pkt_len + 9834 sizeof (struct fcp_pkt) + pptr->port_dmacookie_sz; 9835 9836 /* 9837 * Allocate an ndi event handle 9838 */ 9839 pptr->port_ndi_event_defs = (ndi_event_definition_t *) 9840 kmem_zalloc(sizeof (fcp_ndi_event_defs), KM_SLEEP); 9841 9842 bcopy(fcp_ndi_event_defs, pptr->port_ndi_event_defs, 9843 sizeof (fcp_ndi_event_defs)); 9844 9845 (void) ndi_event_alloc_hdl(pptr->port_dip, NULL, 9846 &pptr->port_ndi_event_hdl, NDI_SLEEP); 9847 9848 pptr->port_ndi_events.ndi_events_version = NDI_EVENTS_REV1; 9849 pptr->port_ndi_events.ndi_n_events = FCP_N_NDI_EVENTS; 9850 pptr->port_ndi_events.ndi_event_defs = pptr->port_ndi_event_defs; 9851 9852 if (DEVI_IS_ATTACHING(pptr->port_dip) && 9853 (ndi_event_bind_set(pptr->port_ndi_event_hdl, 9854 &pptr->port_ndi_events, NDI_SLEEP) != NDI_SUCCESS)) { 9855 goto fail; 9856 } 9857 event_bind++; /* Checked in fail case */ 9858 9859 if (scsi_hba_attach_setup(pptr->port_dip, &pptr->port_data_dma_attr, 9860 tran, SCSI_HBA_ADDR_COMPLEX | SCSI_HBA_TRAN_SCB) 9861 != DDI_SUCCESS) { 9862 fcp_log(CE_WARN, pptr->port_dip, 9863 "!fcp%d: scsi_hba_attach_setup failed", instance); 9864 goto fail; 9865 } 9866 hba_attached++; /* Checked in fail case */ 9867 9868 pptr->port_mpxio = 0; 9869 if (mdi_phci_register(MDI_HCI_CLASS_SCSI, pptr->port_dip, 0) == 9870 MDI_SUCCESS) { 9871 pptr->port_mpxio++; 9872 } 9873 9874 /* 9875 * The following code is putting the new port structure in the global 9876 * list of ports and, if it is the first port to attach, it start the 9877 * fcp_watchdog_tick. 9878 * 9879 * Why put this new port in the global before we are done attaching it? 9880 * We are actually making the structure globally known before we are 9881 * done attaching it. The reason for that is: because of the code that 9882 * follows. At this point the resources to handle the port are 9883 * allocated. This function is now going to do the following: 9884 * 9885 * 1) It is going to try to register with the name server advertizing 9886 * the new FCP capability of the port. 9887 * 2) It is going to play the role of the fp/fctl layer by building 9888 * a list of worlwide names reachable through this port and call 9889 * itself on fcp_statec_callback(). That requires the port to 9890 * be part of the global list. 9891 */ 9892 mutex_enter(&fcp_global_mutex); 9893 if (fcp_port_head == NULL) { 9894 fcp_read_blacklist(pinfo->port_dip, &fcp_lun_blacklist); 9895 } 9896 pptr->port_next = fcp_port_head; 9897 fcp_port_head = pptr; 9898 soft_state_linked++; 9899 9900 if (fcp_watchdog_init++ == 0) { 9901 fcp_watchdog_tick = fcp_watchdog_timeout * 9902 drv_usectohz(1000000); 9903 fcp_watchdog_id = timeout(fcp_watch, NULL, 9904 fcp_watchdog_tick); 9905 } 9906 mutex_exit(&fcp_global_mutex); 9907 9908 /* 9909 * Here an attempt is made to register with the name server, the new 9910 * FCP capability. That is done using an RTF_ID to the name server. 9911 * It is done synchronously. The function fcp_do_ns_registry() 9912 * doesn't return till the name server responded. 9913 * On failures, just ignore it for now and it will get retried during 9914 * state change callbacks. We'll set a flag to show this failure 9915 */ 9916 if (fcp_do_ns_registry(pptr, s_id)) { 9917 mutex_enter(&pptr->port_mutex); 9918 pptr->port_state |= FCP_STATE_NS_REG_FAILED; 9919 mutex_exit(&pptr->port_mutex); 9920 } else { 9921 mutex_enter(&pptr->port_mutex); 9922 pptr->port_state &= ~(FCP_STATE_NS_REG_FAILED); 9923 mutex_exit(&pptr->port_mutex); 9924 } 9925 9926 /* 9927 * Lookup for boot WWN property 9928 */ 9929 if (modrootloaded != 1) { 9930 if ((ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, 9931 ddi_get_parent(pinfo->port_dip), 9932 DDI_PROP_DONTPASS, OBP_BOOT_WWN, 9933 &boot_wwn, &nbytes) == DDI_PROP_SUCCESS) && 9934 (nbytes == FC_WWN_SIZE)) { 9935 bcopy(boot_wwn, pptr->port_boot_wwn, FC_WWN_SIZE); 9936 } 9937 if (boot_wwn) { 9938 ddi_prop_free(boot_wwn); 9939 } 9940 } 9941 9942 /* 9943 * Handle various topologies and link states. 9944 */ 9945 switch (FC_PORT_STATE_MASK(pptr->port_phys_state)) { 9946 case FC_STATE_OFFLINE: 9947 9948 /* 9949 * we're attaching a port where the link is offline 9950 * 9951 * Wait for ONLINE, at which time a state 9952 * change will cause a statec_callback 9953 * 9954 * in the mean time, do not do anything 9955 */ 9956 res = DDI_SUCCESS; 9957 pptr->port_state |= FCP_STATE_OFFLINE; 9958 break; 9959 9960 case FC_STATE_ONLINE: { 9961 if (pptr->port_topology == FC_TOP_UNKNOWN) { 9962 (void) fcp_linkreset(pptr, NULL, KM_NOSLEEP); 9963 res = DDI_SUCCESS; 9964 break; 9965 } 9966 /* 9967 * discover devices and create nodes (a private 9968 * loop or point-to-point) 9969 */ 9970 ASSERT(pptr->port_topology != FC_TOP_UNKNOWN); 9971 9972 /* 9973 * At this point we are going to build a list of all the ports 9974 * that can be reached through this local port. It looks like 9975 * we cannot handle more than FCP_MAX_DEVICES per local port 9976 * (128). 9977 */ 9978 if ((tmp_list = (fc_portmap_t *)kmem_zalloc( 9979 sizeof (fc_portmap_t) * FCP_MAX_DEVICES, 9980 KM_NOSLEEP)) == NULL) { 9981 fcp_log(CE_WARN, pptr->port_dip, 9982 "!fcp%d: failed to allocate portmap", 9983 instance); 9984 goto fail; 9985 } 9986 9987 /* 9988 * fc_ulp_getportmap() is going to provide us with the list of 9989 * remote ports in the buffer we just allocated. The way the 9990 * list is going to be retrieved depends on the topology. 9991 * However, if we are connected to a Fabric, a name server 9992 * request may be sent to get the list of FCP capable ports. 9993 * It should be noted that is the case the request is 9994 * synchronous. This means we are stuck here till the name 9995 * server replies. A lot of things can change during that time 9996 * and including, may be, being called on 9997 * fcp_statec_callback() for different reasons. I'm not sure 9998 * the code can handle that. 9999 */ 10000 max_cnt = FCP_MAX_DEVICES; 10001 alloc_cnt = FCP_MAX_DEVICES; 10002 if ((res = fc_ulp_getportmap(pptr->port_fp_handle, 10003 &tmp_list, &max_cnt, FC_ULP_PLOGI_PRESERVE)) != 10004 FC_SUCCESS) { 10005 caddr_t msg; 10006 10007 (void) fc_ulp_error(res, &msg); 10008 10009 /* 10010 * this just means the transport is 10011 * busy perhaps building a portmap so, 10012 * for now, succeed this port attach 10013 * when the transport has a new map, 10014 * it'll send us a state change then 10015 */ 10016 fcp_log(CE_WARN, pptr->port_dip, 10017 "!failed to get port map : %s", msg); 10018 10019 res = DDI_SUCCESS; 10020 break; /* go return result */ 10021 } 10022 if (max_cnt > alloc_cnt) { 10023 alloc_cnt = max_cnt; 10024 } 10025 10026 /* 10027 * We are now going to call fcp_statec_callback() ourselves. 10028 * By issuing this call we are trying to kick off the enumera- 10029 * tion process. 10030 */ 10031 /* 10032 * let the state change callback do the SCSI device 10033 * discovery and create the devinfos 10034 */ 10035 fcp_statec_callback(ulph, pptr->port_fp_handle, 10036 pptr->port_phys_state, pptr->port_topology, tmp_list, 10037 max_cnt, pptr->port_id); 10038 10039 res = DDI_SUCCESS; 10040 break; 10041 } 10042 10043 default: 10044 /* unknown port state */ 10045 fcp_log(CE_WARN, pptr->port_dip, 10046 "!fcp%d: invalid port state at attach=0x%x", 10047 instance, pptr->port_phys_state); 10048 10049 mutex_enter(&pptr->port_mutex); 10050 pptr->port_phys_state = FCP_STATE_OFFLINE; 10051 mutex_exit(&pptr->port_mutex); 10052 10053 res = DDI_SUCCESS; 10054 break; 10055 } 10056 10057 /* free temp list if used */ 10058 if (tmp_list != NULL) { 10059 kmem_free(tmp_list, sizeof (fc_portmap_t) * alloc_cnt); 10060 } 10061 10062 /* note the attach time */ 10063 pptr->port_attach_time = lbolt64; 10064 10065 /* all done */ 10066 return (res); 10067 10068 /* a failure we have to clean up after */ 10069 fail: 10070 fcp_log(CE_WARN, pptr->port_dip, "!failed to attach to port"); 10071 10072 if (soft_state_linked) { 10073 /* remove this fcp_port from the linked list */ 10074 (void) fcp_soft_state_unlink(pptr); 10075 } 10076 10077 /* unbind and free event set */ 10078 if (pptr->port_ndi_event_hdl) { 10079 if (event_bind) { 10080 (void) ndi_event_unbind_set(pptr->port_ndi_event_hdl, 10081 &pptr->port_ndi_events, NDI_SLEEP); 10082 } 10083 (void) ndi_event_free_hdl(pptr->port_ndi_event_hdl); 10084 } 10085 10086 if (pptr->port_ndi_event_defs) { 10087 (void) kmem_free(pptr->port_ndi_event_defs, 10088 sizeof (fcp_ndi_event_defs)); 10089 } 10090 10091 /* 10092 * Clean up mpxio stuff 10093 */ 10094 if (pptr->port_mpxio) { 10095 (void) mdi_phci_unregister(pptr->port_dip, 0); 10096 pptr->port_mpxio--; 10097 } 10098 10099 /* undo SCSI HBA setup */ 10100 if (hba_attached) { 10101 (void) scsi_hba_detach(pptr->port_dip); 10102 } 10103 if (pptr->port_tran != NULL) { 10104 scsi_hba_tran_free(pptr->port_tran); 10105 } 10106 10107 mutex_enter(&fcp_global_mutex); 10108 10109 /* 10110 * We check soft_state_linked, because it is incremented right before 10111 * we call increment fcp_watchdog_init. Therefore, we know if 10112 * soft_state_linked is still FALSE, we do not want to decrement 10113 * fcp_watchdog_init or possibly call untimeout. 10114 */ 10115 10116 if (soft_state_linked) { 10117 if (--fcp_watchdog_init == 0) { 10118 timeout_id_t tid = fcp_watchdog_id; 10119 10120 mutex_exit(&fcp_global_mutex); 10121 (void) untimeout(tid); 10122 } else { 10123 mutex_exit(&fcp_global_mutex); 10124 } 10125 } else { 10126 mutex_exit(&fcp_global_mutex); 10127 } 10128 10129 if (mutex_initted) { 10130 mutex_destroy(&pptr->port_mutex); 10131 mutex_destroy(&pptr->port_pkt_mutex); 10132 } 10133 10134 if (tmp_list != NULL) { 10135 kmem_free(tmp_list, sizeof (fc_portmap_t) * alloc_cnt); 10136 } 10137 10138 /* this makes pptr invalid */ 10139 ddi_soft_state_free(fcp_softstate, instance); 10140 10141 return (DDI_FAILURE); 10142 } 10143 10144 10145 static int 10146 fcp_handle_port_detach(struct fcp_port *pptr, int flag, int instance) 10147 { 10148 int count = 0; 10149 10150 mutex_enter(&pptr->port_mutex); 10151 10152 /* 10153 * if the port is powered down or suspended, nothing else 10154 * to do; just return. 10155 */ 10156 if (flag != FCP_STATE_DETACHING) { 10157 if (pptr->port_state & (FCP_STATE_POWER_DOWN | 10158 FCP_STATE_SUSPENDED)) { 10159 pptr->port_state |= flag; 10160 mutex_exit(&pptr->port_mutex); 10161 return (FC_SUCCESS); 10162 } 10163 } 10164 10165 if (pptr->port_state & FCP_STATE_IN_MDI) { 10166 mutex_exit(&pptr->port_mutex); 10167 return (FC_FAILURE); 10168 } 10169 10170 FCP_TRACE(fcp_logq, pptr->port_instbuf, 10171 fcp_trace, FCP_BUF_LEVEL_2, 0, 10172 "fcp_handle_port_detach: port is detaching"); 10173 10174 pptr->port_state |= flag; 10175 10176 /* 10177 * Wait for any ongoing reconfig/ipkt to complete, that 10178 * ensures the freeing to targets/luns is safe. 10179 * No more ref to this port should happen from statec/ioctl 10180 * after that as it was removed from the global port list. 10181 */ 10182 while (pptr->port_tmp_cnt || pptr->port_ipkt_cnt || 10183 (pptr->port_state & FCP_STATE_IN_WATCHDOG)) { 10184 /* 10185 * Let's give sufficient time for reconfig/ipkt 10186 * to complete. 10187 */ 10188 if (count++ >= FCP_ICMD_DEADLINE) { 10189 break; 10190 } 10191 mutex_exit(&pptr->port_mutex); 10192 delay(drv_usectohz(1000000)); 10193 mutex_enter(&pptr->port_mutex); 10194 } 10195 10196 /* 10197 * if the driver is still busy then fail to 10198 * suspend/power down. 10199 */ 10200 if (pptr->port_tmp_cnt || pptr->port_ipkt_cnt || 10201 (pptr->port_state & FCP_STATE_IN_WATCHDOG)) { 10202 pptr->port_state &= ~flag; 10203 mutex_exit(&pptr->port_mutex); 10204 return (FC_FAILURE); 10205 } 10206 10207 if (flag == FCP_STATE_DETACHING) { 10208 pptr = fcp_soft_state_unlink(pptr); 10209 ASSERT(pptr != NULL); 10210 } 10211 10212 pptr->port_link_cnt++; 10213 pptr->port_state |= FCP_STATE_OFFLINE; 10214 pptr->port_state &= ~(FCP_STATE_ONLINING | FCP_STATE_ONLINE); 10215 10216 fcp_update_state(pptr, (FCP_LUN_BUSY | FCP_LUN_MARK), 10217 FCP_CAUSE_LINK_DOWN); 10218 mutex_exit(&pptr->port_mutex); 10219 10220 /* kill watch dog timer if we're the last */ 10221 mutex_enter(&fcp_global_mutex); 10222 if (--fcp_watchdog_init == 0) { 10223 timeout_id_t tid = fcp_watchdog_id; 10224 mutex_exit(&fcp_global_mutex); 10225 (void) untimeout(tid); 10226 } else { 10227 mutex_exit(&fcp_global_mutex); 10228 } 10229 10230 /* clean up the port structures */ 10231 if (flag == FCP_STATE_DETACHING) { 10232 fcp_cleanup_port(pptr, instance); 10233 } 10234 10235 return (FC_SUCCESS); 10236 } 10237 10238 10239 static void 10240 fcp_cleanup_port(struct fcp_port *pptr, int instance) 10241 { 10242 ASSERT(pptr != NULL); 10243 10244 /* unbind and free event set */ 10245 if (pptr->port_ndi_event_hdl) { 10246 (void) ndi_event_unbind_set(pptr->port_ndi_event_hdl, 10247 &pptr->port_ndi_events, NDI_SLEEP); 10248 (void) ndi_event_free_hdl(pptr->port_ndi_event_hdl); 10249 } 10250 10251 if (pptr->port_ndi_event_defs) { 10252 (void) kmem_free(pptr->port_ndi_event_defs, 10253 sizeof (fcp_ndi_event_defs)); 10254 } 10255 10256 /* free the lun/target structures and devinfos */ 10257 fcp_free_targets(pptr); 10258 10259 /* 10260 * Clean up mpxio stuff 10261 */ 10262 if (pptr->port_mpxio) { 10263 (void) mdi_phci_unregister(pptr->port_dip, 0); 10264 pptr->port_mpxio--; 10265 } 10266 10267 /* clean up SCSA stuff */ 10268 (void) scsi_hba_detach(pptr->port_dip); 10269 if (pptr->port_tran != NULL) { 10270 scsi_hba_tran_free(pptr->port_tran); 10271 } 10272 10273 #ifdef KSTATS_CODE 10274 /* clean up kstats */ 10275 if (pptr->fcp_ksp != NULL) { 10276 kstat_delete(pptr->fcp_ksp); 10277 } 10278 #endif 10279 10280 /* clean up soft state mutexes/condition variables */ 10281 mutex_destroy(&pptr->port_mutex); 10282 mutex_destroy(&pptr->port_pkt_mutex); 10283 10284 /* all done with soft state */ 10285 ddi_soft_state_free(fcp_softstate, instance); 10286 } 10287 10288 /* 10289 * Function: fcp_kmem_cache_constructor 10290 * 10291 * Description: This function allocates and initializes the resources required 10292 * to build a scsi_pkt structure the target driver. The result 10293 * of the allocation and initialization will be cached in the 10294 * memory cache. As DMA resources may be allocated here, that 10295 * means DMA resources will be tied up in the cache manager. 10296 * This is a tradeoff that has been made for performance reasons. 10297 * 10298 * Argument: *buf Memory to preinitialize. 10299 * *arg FCP port structure (fcp_port). 10300 * kmflags Value passed to kmem_cache_alloc() and 10301 * propagated to the constructor. 10302 * 10303 * Return Value: 0 Allocation/Initialization was successful. 10304 * -1 Allocation or Initialization failed. 10305 * 10306 * 10307 * If the returned value is 0, the buffer is initialized like this: 10308 * 10309 * +================================+ 10310 * +----> | struct scsi_pkt | 10311 * | | | 10312 * | +--- | pkt_ha_private | 10313 * | | | | 10314 * | | +================================+ 10315 * | | 10316 * | | +================================+ 10317 * | +--> | struct fcp_pkt | <---------+ 10318 * | | | | 10319 * +----- | cmd_pkt | | 10320 * | cmd_fp_pkt | ---+ | 10321 * +-------->| cmd_fcp_rsp[] | | | 10322 * | +--->| cmd_fcp_cmd[] | | | 10323 * | | |--------------------------------| | | 10324 * | | | struct fc_packet | <--+ | 10325 * | | | | | 10326 * | | | pkt_ulp_private | ----------+ 10327 * | | | pkt_fca_private | -----+ 10328 * | | | pkt_data_cookie | ---+ | 10329 * | | | pkt_cmdlen | | | 10330 * | |(a) | pkt_rsplen | | | 10331 * | +----| .......... pkt_cmd ........... | ---|-|---------------+ 10332 * | (b) | pkt_cmd_cookie | ---|-|----------+ | 10333 * +---------| .......... pkt_resp .......... | ---|-|------+ | | 10334 * | pkt_resp_cookie | ---|-|--+ | | | 10335 * | pkt_cmd_dma | | | | | | | 10336 * | pkt_cmd_acc | | | | | | | 10337 * +================================+ | | | | | | 10338 * | dma_cookies | <--+ | | | | | 10339 * | | | | | | | 10340 * +================================+ | | | | | 10341 * | fca_private | <----+ | | | | 10342 * | | | | | | 10343 * +================================+ | | | | 10344 * | | | | 10345 * | | | | 10346 * +================================+ (d) | | | | 10347 * | fcp_resp cookies | <-------+ | | | 10348 * | | | | | 10349 * +================================+ | | | 10350 * | | | 10351 * +================================+ (d) | | | 10352 * | fcp_resp | <-----------+ | | 10353 * | (DMA resources associated) | | | 10354 * +================================+ | | 10355 * | | 10356 * | | 10357 * | | 10358 * +================================+ (c) | | 10359 * | fcp_cmd cookies | <---------------+ | 10360 * | | | 10361 * +================================+ | 10362 * | 10363 * +================================+ (c) | 10364 * | fcp_cmd | <--------------------+ 10365 * | (DMA resources associated) | 10366 * +================================+ 10367 * 10368 * (a) Only if DMA is NOT used for the FCP_CMD buffer. 10369 * (b) Only if DMA is NOT used for the FCP_RESP buffer 10370 * (c) Only if DMA is used for the FCP_CMD buffer. 10371 * (d) Only if DMA is used for the FCP_RESP buffer 10372 */ 10373 static int 10374 fcp_kmem_cache_constructor(struct scsi_pkt *pkt, scsi_hba_tran_t *tran, 10375 int kmflags) 10376 { 10377 struct fcp_pkt *cmd; 10378 struct fcp_port *pptr; 10379 fc_packet_t *fpkt; 10380 10381 pptr = (struct fcp_port *)tran->tran_hba_private; 10382 cmd = (struct fcp_pkt *)pkt->pkt_ha_private; 10383 bzero(cmd, tran->tran_hba_len); 10384 10385 cmd->cmd_pkt = pkt; 10386 pkt->pkt_cdbp = cmd->cmd_fcp_cmd.fcp_cdb; 10387 fpkt = (fc_packet_t *)&cmd->cmd_fc_packet; 10388 cmd->cmd_fp_pkt = fpkt; 10389 10390 cmd->cmd_pkt->pkt_ha_private = (opaque_t)cmd; 10391 cmd->cmd_fp_pkt->pkt_ulp_private = (opaque_t)cmd; 10392 cmd->cmd_fp_pkt->pkt_fca_private = (opaque_t)((caddr_t)cmd + 10393 sizeof (struct fcp_pkt) + pptr->port_dmacookie_sz); 10394 10395 fpkt->pkt_data_cookie = (ddi_dma_cookie_t *)((caddr_t)cmd + 10396 sizeof (struct fcp_pkt)); 10397 10398 fpkt->pkt_cmdlen = sizeof (struct fcp_cmd); 10399 fpkt->pkt_rsplen = FCP_MAX_RSP_IU_SIZE; 10400 10401 if (pptr->port_fcp_dma == FC_NO_DVMA_SPACE) { 10402 /* 10403 * The underlying HBA doesn't want to DMA the fcp_cmd or 10404 * fcp_resp. The transfer of information will be done by 10405 * bcopy. 10406 * The naming of the flags (that is actually a value) is 10407 * unfortunate. FC_NO_DVMA_SPACE doesn't mean "NO VIRTUAL 10408 * DMA" but instead "NO DMA". 10409 */ 10410 fpkt->pkt_resp_acc = fpkt->pkt_cmd_acc = NULL; 10411 fpkt->pkt_cmd = (caddr_t)&cmd->cmd_fcp_cmd; 10412 fpkt->pkt_resp = cmd->cmd_fcp_rsp; 10413 } else { 10414 /* 10415 * The underlying HBA will dma the fcp_cmd buffer and fcp_resp 10416 * buffer. A buffer is allocated for each one the ddi_dma_* 10417 * interfaces. 10418 */ 10419 if (fcp_alloc_cmd_resp(pptr, fpkt, kmflags) != FC_SUCCESS) { 10420 return (-1); 10421 } 10422 } 10423 10424 return (0); 10425 } 10426 10427 /* 10428 * Function: fcp_kmem_cache_destructor 10429 * 10430 * Description: Called by the destructor of the cache managed by SCSA. 10431 * All the resources pre-allocated in fcp_pkt_constructor 10432 * and the data also pre-initialized in fcp_pkt_constructor 10433 * are freed and uninitialized here. 10434 * 10435 * Argument: *buf Memory to uninitialize. 10436 * *arg FCP port structure (fcp_port). 10437 * 10438 * Return Value: None 10439 * 10440 * Context: kernel 10441 */ 10442 static void 10443 fcp_kmem_cache_destructor(struct scsi_pkt *pkt, scsi_hba_tran_t *tran) 10444 { 10445 struct fcp_pkt *cmd; 10446 struct fcp_port *pptr; 10447 10448 pptr = (struct fcp_port *)(tran->tran_hba_private); 10449 cmd = pkt->pkt_ha_private; 10450 10451 if (pptr->port_fcp_dma != FC_NO_DVMA_SPACE) { 10452 /* 10453 * If DMA was used to transfer the FCP_CMD and FCP_RESP, the 10454 * buffer and DMA resources allocated to do so are released. 10455 */ 10456 fcp_free_cmd_resp(pptr, cmd->cmd_fp_pkt); 10457 } 10458 } 10459 10460 /* 10461 * Function: fcp_alloc_cmd_resp 10462 * 10463 * Description: This function allocated an FCP_CMD and FCP_RESP buffer that 10464 * will be DMAed by the HBA. The buffer is allocated applying 10465 * the DMA requirements for the HBA. The buffers allocated will 10466 * also be bound. DMA resources are allocated in the process. 10467 * They will be released by fcp_free_cmd_resp(). 10468 * 10469 * Argument: *pptr FCP port. 10470 * *fpkt fc packet for which the cmd and resp packet should be 10471 * allocated. 10472 * flags Allocation flags. 10473 * 10474 * Return Value: FC_FAILURE 10475 * FC_SUCCESS 10476 * 10477 * Context: User or Kernel context only if flags == KM_SLEEP. 10478 * Interrupt context if the KM_SLEEP is not specified. 10479 */ 10480 static int 10481 fcp_alloc_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt, int flags) 10482 { 10483 int rval; 10484 int cmd_len; 10485 int resp_len; 10486 ulong_t real_len; 10487 int (*cb) (caddr_t); 10488 ddi_dma_cookie_t pkt_cookie; 10489 ddi_dma_cookie_t *cp; 10490 uint32_t cnt; 10491 10492 cb = (flags == KM_SLEEP) ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT; 10493 10494 cmd_len = fpkt->pkt_cmdlen; 10495 resp_len = fpkt->pkt_rsplen; 10496 10497 ASSERT(fpkt->pkt_cmd_dma == NULL); 10498 10499 /* Allocation of a DMA handle used in subsequent calls. */ 10500 if (ddi_dma_alloc_handle(pptr->port_dip, &pptr->port_cmd_dma_attr, 10501 cb, NULL, &fpkt->pkt_cmd_dma) != DDI_SUCCESS) { 10502 return (FC_FAILURE); 10503 } 10504 10505 /* A buffer is allocated that satisfies the DMA requirements. */ 10506 rval = ddi_dma_mem_alloc(fpkt->pkt_cmd_dma, cmd_len, 10507 &pptr->port_dma_acc_attr, DDI_DMA_CONSISTENT, cb, NULL, 10508 (caddr_t *)&fpkt->pkt_cmd, &real_len, &fpkt->pkt_cmd_acc); 10509 10510 if (rval != DDI_SUCCESS) { 10511 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10512 return (FC_FAILURE); 10513 } 10514 10515 if (real_len < cmd_len) { 10516 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10517 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10518 return (FC_FAILURE); 10519 } 10520 10521 /* The buffer allocated is DMA bound. */ 10522 rval = ddi_dma_addr_bind_handle(fpkt->pkt_cmd_dma, NULL, 10523 fpkt->pkt_cmd, real_len, DDI_DMA_WRITE | DDI_DMA_CONSISTENT, 10524 cb, NULL, &pkt_cookie, &fpkt->pkt_cmd_cookie_cnt); 10525 10526 if (rval != DDI_DMA_MAPPED) { 10527 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10528 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10529 return (FC_FAILURE); 10530 } 10531 10532 if (fpkt->pkt_cmd_cookie_cnt > 10533 pptr->port_cmd_dma_attr.dma_attr_sgllen) { 10534 (void) ddi_dma_unbind_handle(fpkt->pkt_cmd_dma); 10535 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10536 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10537 return (FC_FAILURE); 10538 } 10539 10540 ASSERT(fpkt->pkt_cmd_cookie_cnt != 0); 10541 10542 /* 10543 * The buffer where the scatter/gather list is going to be built is 10544 * allocated. 10545 */ 10546 cp = fpkt->pkt_cmd_cookie = (ddi_dma_cookie_t *)kmem_alloc( 10547 fpkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie), 10548 KM_NOSLEEP); 10549 10550 if (cp == NULL) { 10551 (void) ddi_dma_unbind_handle(fpkt->pkt_cmd_dma); 10552 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10553 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10554 return (FC_FAILURE); 10555 } 10556 10557 /* 10558 * The scatter/gather list for the buffer we just allocated is built 10559 * here. 10560 */ 10561 *cp = pkt_cookie; 10562 cp++; 10563 10564 for (cnt = 1; cnt < fpkt->pkt_cmd_cookie_cnt; cnt++, cp++) { 10565 ddi_dma_nextcookie(fpkt->pkt_cmd_dma, 10566 &pkt_cookie); 10567 *cp = pkt_cookie; 10568 } 10569 10570 ASSERT(fpkt->pkt_resp_dma == NULL); 10571 if (ddi_dma_alloc_handle(pptr->port_dip, &pptr->port_resp_dma_attr, 10572 cb, NULL, &fpkt->pkt_resp_dma) != DDI_SUCCESS) { 10573 (void) ddi_dma_unbind_handle(fpkt->pkt_cmd_dma); 10574 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10575 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10576 return (FC_FAILURE); 10577 } 10578 10579 rval = ddi_dma_mem_alloc(fpkt->pkt_resp_dma, resp_len, 10580 &pptr->port_dma_acc_attr, DDI_DMA_CONSISTENT, cb, NULL, 10581 (caddr_t *)&fpkt->pkt_resp, &real_len, 10582 &fpkt->pkt_resp_acc); 10583 10584 if (rval != DDI_SUCCESS) { 10585 ddi_dma_free_handle(&fpkt->pkt_resp_dma); 10586 (void) ddi_dma_unbind_handle(fpkt->pkt_cmd_dma); 10587 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10588 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10589 kmem_free(fpkt->pkt_cmd_cookie, 10590 fpkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie)); 10591 return (FC_FAILURE); 10592 } 10593 10594 if (real_len < resp_len) { 10595 ddi_dma_mem_free(&fpkt->pkt_resp_acc); 10596 ddi_dma_free_handle(&fpkt->pkt_resp_dma); 10597 (void) ddi_dma_unbind_handle(fpkt->pkt_cmd_dma); 10598 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10599 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10600 kmem_free(fpkt->pkt_cmd_cookie, 10601 fpkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie)); 10602 return (FC_FAILURE); 10603 } 10604 10605 rval = ddi_dma_addr_bind_handle(fpkt->pkt_resp_dma, NULL, 10606 fpkt->pkt_resp, real_len, DDI_DMA_READ | DDI_DMA_CONSISTENT, 10607 cb, NULL, &pkt_cookie, &fpkt->pkt_resp_cookie_cnt); 10608 10609 if (rval != DDI_DMA_MAPPED) { 10610 ddi_dma_mem_free(&fpkt->pkt_resp_acc); 10611 ddi_dma_free_handle(&fpkt->pkt_resp_dma); 10612 (void) ddi_dma_unbind_handle(fpkt->pkt_cmd_dma); 10613 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10614 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10615 kmem_free(fpkt->pkt_cmd_cookie, 10616 fpkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie)); 10617 return (FC_FAILURE); 10618 } 10619 10620 if (fpkt->pkt_resp_cookie_cnt > 10621 pptr->port_resp_dma_attr.dma_attr_sgllen) { 10622 ddi_dma_mem_free(&fpkt->pkt_resp_acc); 10623 ddi_dma_free_handle(&fpkt->pkt_resp_dma); 10624 (void) ddi_dma_unbind_handle(fpkt->pkt_cmd_dma); 10625 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10626 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10627 kmem_free(fpkt->pkt_cmd_cookie, 10628 fpkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie)); 10629 return (FC_FAILURE); 10630 } 10631 10632 ASSERT(fpkt->pkt_resp_cookie_cnt != 0); 10633 10634 cp = fpkt->pkt_resp_cookie = (ddi_dma_cookie_t *)kmem_alloc( 10635 fpkt->pkt_resp_cookie_cnt * sizeof (pkt_cookie), 10636 KM_NOSLEEP); 10637 10638 if (cp == NULL) { 10639 ddi_dma_mem_free(&fpkt->pkt_resp_acc); 10640 ddi_dma_free_handle(&fpkt->pkt_resp_dma); 10641 (void) ddi_dma_unbind_handle(fpkt->pkt_cmd_dma); 10642 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10643 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10644 kmem_free(fpkt->pkt_cmd_cookie, 10645 fpkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie)); 10646 return (FC_FAILURE); 10647 } 10648 10649 *cp = pkt_cookie; 10650 cp++; 10651 10652 for (cnt = 1; cnt < fpkt->pkt_resp_cookie_cnt; cnt++, cp++) { 10653 ddi_dma_nextcookie(fpkt->pkt_resp_dma, 10654 &pkt_cookie); 10655 *cp = pkt_cookie; 10656 } 10657 10658 return (FC_SUCCESS); 10659 } 10660 10661 /* 10662 * Function: fcp_free_cmd_resp 10663 * 10664 * Description: This function releases the FCP_CMD and FCP_RESP buffer 10665 * allocated by fcp_alloc_cmd_resp() and all the resources 10666 * associated with them. That includes the DMA resources and the 10667 * buffer allocated for the cookies of each one of them. 10668 * 10669 * Argument: *pptr FCP port context. 10670 * *fpkt fc packet containing the cmd and resp packet 10671 * to be released. 10672 * 10673 * Return Value: None 10674 * 10675 * Context: Interrupt, User and Kernel context. 10676 */ 10677 /* ARGSUSED */ 10678 static void 10679 fcp_free_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt) 10680 { 10681 ASSERT(fpkt->pkt_resp_dma != NULL && fpkt->pkt_cmd_dma != NULL); 10682 10683 if (fpkt->pkt_resp_dma) { 10684 (void) ddi_dma_unbind_handle(fpkt->pkt_resp_dma); 10685 ddi_dma_mem_free(&fpkt->pkt_resp_acc); 10686 ddi_dma_free_handle(&fpkt->pkt_resp_dma); 10687 } 10688 10689 if (fpkt->pkt_resp_cookie) { 10690 kmem_free(fpkt->pkt_resp_cookie, 10691 fpkt->pkt_resp_cookie_cnt * sizeof (ddi_dma_cookie_t)); 10692 fpkt->pkt_resp_cookie = NULL; 10693 } 10694 10695 if (fpkt->pkt_cmd_dma) { 10696 (void) ddi_dma_unbind_handle(fpkt->pkt_cmd_dma); 10697 ddi_dma_mem_free(&fpkt->pkt_cmd_acc); 10698 ddi_dma_free_handle(&fpkt->pkt_cmd_dma); 10699 } 10700 10701 if (fpkt->pkt_cmd_cookie) { 10702 kmem_free(fpkt->pkt_cmd_cookie, 10703 fpkt->pkt_cmd_cookie_cnt * sizeof (ddi_dma_cookie_t)); 10704 fpkt->pkt_cmd_cookie = NULL; 10705 } 10706 } 10707 10708 10709 /* 10710 * called by the transport to do our own target initialization 10711 * 10712 * can acquire and release the global mutex 10713 */ 10714 /* ARGSUSED */ 10715 static int 10716 fcp_phys_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 10717 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 10718 { 10719 uchar_t *bytes; 10720 uint_t nbytes; 10721 uint16_t lun_num; 10722 struct fcp_tgt *ptgt; 10723 struct fcp_lun *plun; 10724 struct fcp_port *pptr = (struct fcp_port *) 10725 hba_tran->tran_hba_private; 10726 10727 ASSERT(pptr != NULL); 10728 10729 FCP_DTRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 10730 FCP_BUF_LEVEL_8, 0, 10731 "fcp_phys_tgt_init: called for %s (instance %d)", 10732 ddi_get_name(tgt_dip), ddi_get_instance(tgt_dip)); 10733 10734 /* get our port WWN property */ 10735 bytes = NULL; 10736 if ((scsi_device_prop_lookup_byte_array(sd, SCSI_DEVICE_PROP_PATH, 10737 PORT_WWN_PROP, &bytes, &nbytes) != DDI_PROP_SUCCESS) || 10738 (nbytes != FC_WWN_SIZE)) { 10739 /* no port WWN property */ 10740 FCP_DTRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 10741 FCP_BUF_LEVEL_8, 0, 10742 "fcp_phys_tgt_init: Returning DDI_NOT_WELL_FORMED" 10743 " for %s (instance %d): bytes=%p nbytes=%x", 10744 ddi_get_name(tgt_dip), ddi_get_instance(tgt_dip), bytes, 10745 nbytes); 10746 10747 if (bytes != NULL) { 10748 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, bytes); 10749 } 10750 10751 return (DDI_NOT_WELL_FORMED); 10752 } 10753 ASSERT(bytes != NULL); 10754 10755 lun_num = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH, 10756 LUN_PROP, 0xFFFF); 10757 if (lun_num == 0xFFFF) { 10758 FCP_DTRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 10759 FCP_BUF_LEVEL_8, 0, 10760 "fcp_phys_tgt_init: Returning DDI_FAILURE:lun" 10761 " for %s (instance %d)", ddi_get_name(tgt_dip), 10762 ddi_get_instance(tgt_dip)); 10763 10764 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, bytes); 10765 return (DDI_NOT_WELL_FORMED); 10766 } 10767 10768 mutex_enter(&pptr->port_mutex); 10769 if ((plun = fcp_lookup_lun(pptr, bytes, lun_num)) == NULL) { 10770 mutex_exit(&pptr->port_mutex); 10771 FCP_DTRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 10772 FCP_BUF_LEVEL_8, 0, 10773 "fcp_phys_tgt_init: Returning DDI_FAILURE: No Lun" 10774 " for %s (instance %d)", ddi_get_name(tgt_dip), 10775 ddi_get_instance(tgt_dip)); 10776 10777 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, bytes); 10778 return (DDI_FAILURE); 10779 } 10780 10781 ASSERT(bcmp(plun->lun_tgt->tgt_port_wwn.raw_wwn, bytes, 10782 FC_WWN_SIZE) == 0); 10783 ASSERT(plun->lun_num == lun_num); 10784 10785 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, bytes); 10786 10787 ptgt = plun->lun_tgt; 10788 10789 mutex_enter(&ptgt->tgt_mutex); 10790 plun->lun_tgt_count++; 10791 scsi_device_hba_private_set(sd, plun); 10792 plun->lun_state |= FCP_SCSI_LUN_TGT_INIT; 10793 plun->lun_sd = sd; 10794 mutex_exit(&ptgt->tgt_mutex); 10795 mutex_exit(&pptr->port_mutex); 10796 10797 return (DDI_SUCCESS); 10798 } 10799 10800 /*ARGSUSED*/ 10801 static int 10802 fcp_virt_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 10803 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 10804 { 10805 uchar_t *bytes; 10806 uint_t nbytes; 10807 uint16_t lun_num; 10808 struct fcp_tgt *ptgt; 10809 struct fcp_lun *plun; 10810 struct fcp_port *pptr = (struct fcp_port *) 10811 hba_tran->tran_hba_private; 10812 child_info_t *cip; 10813 10814 ASSERT(pptr != NULL); 10815 10816 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 10817 fcp_trace, FCP_BUF_LEVEL_8, 0, 10818 "fcp_virt_tgt_init: called for %s (instance %d) (hba_dip %p)," 10819 " (tgt_dip %p)", ddi_get_name(tgt_dip), 10820 ddi_get_instance(tgt_dip), hba_dip, tgt_dip); 10821 10822 cip = (child_info_t *)sd->sd_pathinfo; 10823 if (cip == NULL) { 10824 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 10825 fcp_trace, FCP_BUF_LEVEL_8, 0, 10826 "fcp_virt_tgt_init: Returning DDI_NOT_WELL_FORMED" 10827 " for %s (instance %d)", ddi_get_name(tgt_dip), 10828 ddi_get_instance(tgt_dip)); 10829 10830 return (DDI_NOT_WELL_FORMED); 10831 } 10832 10833 /* get our port WWN property */ 10834 bytes = NULL; 10835 if ((scsi_device_prop_lookup_byte_array(sd, SCSI_DEVICE_PROP_PATH, 10836 PORT_WWN_PROP, &bytes, &nbytes) != DDI_PROP_SUCCESS) || 10837 (nbytes != FC_WWN_SIZE)) { 10838 if (bytes) { 10839 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, bytes); 10840 } 10841 return (DDI_NOT_WELL_FORMED); 10842 } 10843 10844 ASSERT(bytes != NULL); 10845 10846 lun_num = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH, 10847 LUN_PROP, 0xFFFF); 10848 if (lun_num == 0xFFFF) { 10849 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 10850 fcp_trace, FCP_BUF_LEVEL_8, 0, 10851 "fcp_virt_tgt_init: Returning DDI_FAILURE:lun" 10852 " for %s (instance %d)", ddi_get_name(tgt_dip), 10853 ddi_get_instance(tgt_dip)); 10854 10855 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, bytes); 10856 return (DDI_NOT_WELL_FORMED); 10857 } 10858 10859 mutex_enter(&pptr->port_mutex); 10860 if ((plun = fcp_lookup_lun(pptr, bytes, lun_num)) == NULL) { 10861 mutex_exit(&pptr->port_mutex); 10862 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 10863 fcp_trace, FCP_BUF_LEVEL_8, 0, 10864 "fcp_virt_tgt_init: Returning DDI_FAILURE: No Lun" 10865 " for %s (instance %d)", ddi_get_name(tgt_dip), 10866 ddi_get_instance(tgt_dip)); 10867 10868 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, bytes); 10869 return (DDI_FAILURE); 10870 } 10871 10872 ASSERT(bcmp(plun->lun_tgt->tgt_port_wwn.raw_wwn, bytes, 10873 FC_WWN_SIZE) == 0); 10874 ASSERT(plun->lun_num == lun_num); 10875 10876 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, bytes); 10877 10878 ptgt = plun->lun_tgt; 10879 10880 mutex_enter(&ptgt->tgt_mutex); 10881 plun->lun_tgt_count++; 10882 scsi_device_hba_private_set(sd, plun); 10883 plun->lun_state |= FCP_SCSI_LUN_TGT_INIT; 10884 plun->lun_sd = sd; 10885 mutex_exit(&ptgt->tgt_mutex); 10886 mutex_exit(&pptr->port_mutex); 10887 10888 return (DDI_SUCCESS); 10889 } 10890 10891 10892 /* 10893 * called by the transport to do our own target initialization 10894 * 10895 * can acquire and release the global mutex 10896 */ 10897 /* ARGSUSED */ 10898 static int 10899 fcp_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 10900 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 10901 { 10902 struct fcp_port *pptr = (struct fcp_port *) 10903 hba_tran->tran_hba_private; 10904 int rval; 10905 10906 ASSERT(pptr != NULL); 10907 10908 /* 10909 * Child node is getting initialized. Look at the mpxio component 10910 * type on the child device to see if this device is mpxio managed 10911 * or not. 10912 */ 10913 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 10914 rval = fcp_virt_tgt_init(hba_dip, tgt_dip, hba_tran, sd); 10915 } else { 10916 rval = fcp_phys_tgt_init(hba_dip, tgt_dip, hba_tran, sd); 10917 } 10918 10919 return (rval); 10920 } 10921 10922 10923 /* ARGSUSED */ 10924 static void 10925 fcp_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 10926 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 10927 { 10928 struct fcp_lun *plun = scsi_device_hba_private_get(sd); 10929 struct fcp_tgt *ptgt; 10930 10931 FCP_DTRACE(fcp_logq, LUN_PORT->port_instbuf, 10932 fcp_trace, FCP_BUF_LEVEL_8, 0, 10933 "fcp_scsi_tgt_free: called for tran %s%d, dev %s%d", 10934 ddi_get_name(hba_dip), ddi_get_instance(hba_dip), 10935 ddi_get_name(tgt_dip), ddi_get_instance(tgt_dip)); 10936 10937 if (plun == NULL) { 10938 return; 10939 } 10940 ptgt = plun->lun_tgt; 10941 10942 ASSERT(ptgt != NULL); 10943 10944 mutex_enter(&ptgt->tgt_mutex); 10945 ASSERT(plun->lun_tgt_count > 0); 10946 10947 if (--plun->lun_tgt_count == 0) { 10948 plun->lun_state &= ~FCP_SCSI_LUN_TGT_INIT; 10949 } 10950 plun->lun_sd = NULL; 10951 mutex_exit(&ptgt->tgt_mutex); 10952 } 10953 10954 /* 10955 * Function: fcp_scsi_start 10956 * 10957 * Description: This function is called by the target driver to request a 10958 * command to be sent. 10959 * 10960 * Argument: *ap SCSI address of the device. 10961 * *pkt SCSI packet containing the cmd to send. 10962 * 10963 * Return Value: TRAN_ACCEPT 10964 * TRAN_BUSY 10965 * TRAN_BADPKT 10966 * TRAN_FATAL_ERROR 10967 */ 10968 static int 10969 fcp_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 10970 { 10971 struct fcp_port *pptr = ADDR2FCP(ap); 10972 struct fcp_lun *plun = ADDR2LUN(ap); 10973 struct fcp_pkt *cmd = PKT2CMD(pkt); 10974 struct fcp_tgt *ptgt = plun->lun_tgt; 10975 int rval; 10976 10977 /* ensure command isn't already issued */ 10978 ASSERT(cmd->cmd_state != FCP_PKT_ISSUED); 10979 10980 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 10981 fcp_trace, FCP_BUF_LEVEL_9, 0, 10982 "fcp_transport Invoked for %x", plun->lun_tgt->tgt_d_id); 10983 10984 /* 10985 * It is strange that we enter the fcp_port mutex and the target 10986 * mutex to check the lun state (which has a mutex of its own). 10987 */ 10988 mutex_enter(&pptr->port_mutex); 10989 mutex_enter(&ptgt->tgt_mutex); 10990 10991 /* 10992 * If the device is offline and is not in the process of coming 10993 * online, fail the request. 10994 */ 10995 10996 if ((plun->lun_state & FCP_LUN_OFFLINE) && 10997 !(plun->lun_state & FCP_LUN_ONLINING)) { 10998 mutex_exit(&ptgt->tgt_mutex); 10999 mutex_exit(&pptr->port_mutex); 11000 11001 if (cmd->cmd_fp_pkt->pkt_pd == NULL) { 11002 pkt->pkt_reason = CMD_DEV_GONE; 11003 } 11004 11005 return (TRAN_FATAL_ERROR); 11006 } 11007 cmd->cmd_fp_pkt->pkt_timeout = pkt->pkt_time; 11008 11009 /* 11010 * If we are suspended, kernel is trying to dump, so don't 11011 * block, fail or defer requests - send them down right away. 11012 * NOTE: If we are in panic (i.e. trying to dump), we can't 11013 * assume we have been suspended. There is hardware such as 11014 * the v880 that doesn't do PM. Thus, the check for 11015 * ddi_in_panic. 11016 * 11017 * If FCP_STATE_IN_CB_DEVC is set, devices are in the process 11018 * of changing. So, if we can queue the packet, do it. Eventually, 11019 * either the device will have gone away or changed and we can fail 11020 * the request, or we can proceed if the device didn't change. 11021 * 11022 * If the pd in the target or the packet is NULL it's probably 11023 * because the device has gone away, we allow the request to be 11024 * put on the internal queue here in case the device comes back within 11025 * the offline timeout. fctl will fix up the pd's if the tgt_pd_handle 11026 * has gone NULL, while fcp deals cases where pkt_pd is NULL. pkt_pd 11027 * could be NULL because the device was disappearing during or since 11028 * packet initialization. 11029 */ 11030 11031 if (((plun->lun_state & FCP_LUN_BUSY) && (!(pptr->port_state & 11032 FCP_STATE_SUSPENDED)) && !ddi_in_panic()) || 11033 (pptr->port_state & (FCP_STATE_ONLINING | FCP_STATE_IN_CB_DEVC)) || 11034 (ptgt->tgt_pd_handle == NULL) || 11035 (cmd->cmd_fp_pkt->pkt_pd == NULL)) { 11036 /* 11037 * If ((LUN is busy AND 11038 * LUN not suspended AND 11039 * The system is not in panic state) OR 11040 * (The port is coming up)) 11041 * 11042 * We check to see if the any of the flags FLAG_NOINTR or 11043 * FLAG_NOQUEUE is set. If one of them is set the value 11044 * returned will be TRAN_BUSY. If not, the request is queued. 11045 */ 11046 mutex_exit(&ptgt->tgt_mutex); 11047 mutex_exit(&pptr->port_mutex); 11048 11049 /* see if using interrupts is allowed (so queueing'll work) */ 11050 if (pkt->pkt_flags & FLAG_NOINTR) { 11051 pkt->pkt_resid = 0; 11052 return (TRAN_BUSY); 11053 } 11054 if (pkt->pkt_flags & FLAG_NOQUEUE) { 11055 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 11056 fcp_trace, FCP_BUF_LEVEL_9, 0, 11057 "fcp_scsi_start: lun busy for pkt %p", pkt); 11058 return (TRAN_BUSY); 11059 } 11060 #ifdef DEBUG 11061 mutex_enter(&pptr->port_pkt_mutex); 11062 pptr->port_npkts++; 11063 mutex_exit(&pptr->port_pkt_mutex); 11064 #endif /* DEBUG */ 11065 11066 /* got queue up the pkt for later */ 11067 fcp_queue_pkt(pptr, cmd); 11068 return (TRAN_ACCEPT); 11069 } 11070 cmd->cmd_state = FCP_PKT_ISSUED; 11071 11072 mutex_exit(&ptgt->tgt_mutex); 11073 mutex_exit(&pptr->port_mutex); 11074 11075 /* 11076 * Now that we released the mutexes, what was protected by them can 11077 * change. 11078 */ 11079 11080 /* 11081 * If there is a reconfiguration in progress, wait for it to complete. 11082 */ 11083 fcp_reconfig_wait(pptr); 11084 11085 cmd->cmd_timeout = pkt->pkt_time ? fcp_watchdog_time + 11086 pkt->pkt_time : 0; 11087 11088 /* prepare the packet */ 11089 11090 fcp_prepare_pkt(pptr, cmd, plun); 11091 11092 if (cmd->cmd_pkt->pkt_time) { 11093 cmd->cmd_fp_pkt->pkt_timeout = cmd->cmd_pkt->pkt_time; 11094 } else { 11095 cmd->cmd_fp_pkt->pkt_timeout = 5 * 60 * 60; 11096 } 11097 11098 /* 11099 * if interrupts aren't allowed (e.g. at dump time) then we'll 11100 * have to do polled I/O 11101 */ 11102 if (pkt->pkt_flags & FLAG_NOINTR) { 11103 cmd->cmd_state &= ~FCP_PKT_ISSUED; 11104 return (fcp_dopoll(pptr, cmd)); 11105 } 11106 11107 #ifdef DEBUG 11108 mutex_enter(&pptr->port_pkt_mutex); 11109 pptr->port_npkts++; 11110 mutex_exit(&pptr->port_pkt_mutex); 11111 #endif /* DEBUG */ 11112 11113 rval = fcp_transport(pptr->port_fp_handle, cmd->cmd_fp_pkt, 0); 11114 if (rval == FC_SUCCESS) { 11115 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 11116 fcp_trace, FCP_BUF_LEVEL_9, 0, 11117 "fcp_transport success for %x", plun->lun_tgt->tgt_d_id); 11118 return (TRAN_ACCEPT); 11119 } 11120 11121 cmd->cmd_state = FCP_PKT_IDLE; 11122 11123 #ifdef DEBUG 11124 mutex_enter(&pptr->port_pkt_mutex); 11125 pptr->port_npkts--; 11126 mutex_exit(&pptr->port_pkt_mutex); 11127 #endif /* DEBUG */ 11128 11129 /* 11130 * For lack of clearer definitions, choose 11131 * between TRAN_BUSY and TRAN_FATAL_ERROR. 11132 */ 11133 11134 if (rval == FC_TRAN_BUSY) { 11135 pkt->pkt_resid = 0; 11136 rval = TRAN_BUSY; 11137 } else { 11138 mutex_enter(&ptgt->tgt_mutex); 11139 if (plun->lun_state & FCP_LUN_OFFLINE) { 11140 child_info_t *cip; 11141 11142 mutex_enter(&plun->lun_mutex); 11143 cip = plun->lun_cip; 11144 mutex_exit(&plun->lun_mutex); 11145 11146 FCP_TRACE(fcp_logq, pptr->port_instbuf, 11147 fcp_trace, FCP_BUF_LEVEL_6, 0, 11148 "fcp_transport failed 2 for %x: %x; dip=%p", 11149 plun->lun_tgt->tgt_d_id, rval, cip); 11150 11151 rval = TRAN_FATAL_ERROR; 11152 } else { 11153 if (pkt->pkt_flags & FLAG_NOQUEUE) { 11154 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 11155 fcp_trace, FCP_BUF_LEVEL_9, 0, 11156 "fcp_scsi_start: FC_BUSY for pkt %p", 11157 pkt); 11158 rval = TRAN_BUSY; 11159 } else { 11160 rval = TRAN_ACCEPT; 11161 fcp_queue_pkt(pptr, cmd); 11162 } 11163 } 11164 mutex_exit(&ptgt->tgt_mutex); 11165 } 11166 11167 return (rval); 11168 } 11169 11170 /* 11171 * called by the transport to abort a packet 11172 */ 11173 /*ARGSUSED*/ 11174 static int 11175 fcp_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 11176 { 11177 int tgt_cnt; 11178 struct fcp_port *pptr = ADDR2FCP(ap); 11179 struct fcp_lun *plun = ADDR2LUN(ap); 11180 struct fcp_tgt *ptgt = plun->lun_tgt; 11181 11182 if (pkt == NULL) { 11183 if (ptgt) { 11184 mutex_enter(&ptgt->tgt_mutex); 11185 tgt_cnt = ptgt->tgt_change_cnt; 11186 mutex_exit(&ptgt->tgt_mutex); 11187 fcp_abort_all(pptr, ptgt, plun, tgt_cnt); 11188 return (TRUE); 11189 } 11190 } 11191 return (FALSE); 11192 } 11193 11194 11195 /* 11196 * Perform reset 11197 */ 11198 int 11199 fcp_scsi_reset(struct scsi_address *ap, int level) 11200 { 11201 int rval = 0; 11202 struct fcp_port *pptr = ADDR2FCP(ap); 11203 struct fcp_lun *plun = ADDR2LUN(ap); 11204 struct fcp_tgt *ptgt = plun->lun_tgt; 11205 11206 if (level == RESET_ALL) { 11207 if (fcp_linkreset(pptr, ap, KM_NOSLEEP) == FC_SUCCESS) { 11208 rval = 1; 11209 } 11210 } else if (level == RESET_TARGET || level == RESET_LUN) { 11211 /* 11212 * If we are in the middle of discovery, return 11213 * SUCCESS as this target will be rediscovered 11214 * anyway 11215 */ 11216 mutex_enter(&ptgt->tgt_mutex); 11217 if (ptgt->tgt_state & (FCP_TGT_OFFLINE | FCP_TGT_BUSY)) { 11218 mutex_exit(&ptgt->tgt_mutex); 11219 return (1); 11220 } 11221 mutex_exit(&ptgt->tgt_mutex); 11222 11223 if (fcp_reset_target(ap, level) == FC_SUCCESS) { 11224 rval = 1; 11225 } 11226 } 11227 return (rval); 11228 } 11229 11230 11231 /* 11232 * called by the framework to get a SCSI capability 11233 */ 11234 static int 11235 fcp_scsi_getcap(struct scsi_address *ap, char *cap, int whom) 11236 { 11237 return (fcp_commoncap(ap, cap, 0, whom, 0)); 11238 } 11239 11240 11241 /* 11242 * called by the framework to set a SCSI capability 11243 */ 11244 static int 11245 fcp_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom) 11246 { 11247 return (fcp_commoncap(ap, cap, value, whom, 1)); 11248 } 11249 11250 /* 11251 * Function: fcp_pkt_setup 11252 * 11253 * Description: This function sets up the scsi_pkt structure passed by the 11254 * caller. This function assumes fcp_pkt_constructor has been 11255 * called previously for the packet passed by the caller. If 11256 * successful this call will have the following results: 11257 * 11258 * - The resources needed that will be constant through out 11259 * the whole transaction are allocated. 11260 * - The fields that will be constant through out the whole 11261 * transaction are initialized. 11262 * - The scsi packet will be linked to the LUN structure 11263 * addressed by the transaction. 11264 * 11265 * Argument: 11266 * *pkt Pointer to a scsi_pkt structure. 11267 * callback 11268 * arg 11269 * 11270 * Return Value: 0 Success 11271 * !0 Failure 11272 * 11273 * Context: Kernel context or interrupt context 11274 */ 11275 /* ARGSUSED */ 11276 static int 11277 fcp_pkt_setup(struct scsi_pkt *pkt, 11278 int (*callback)(caddr_t arg), 11279 caddr_t arg) 11280 { 11281 struct fcp_pkt *cmd; 11282 struct fcp_port *pptr; 11283 struct fcp_lun *plun; 11284 struct fcp_tgt *ptgt; 11285 int kf; 11286 fc_packet_t *fpkt; 11287 fc_frame_hdr_t *hp; 11288 11289 pptr = ADDR2FCP(&pkt->pkt_address); 11290 plun = ADDR2LUN(&pkt->pkt_address); 11291 ptgt = plun->lun_tgt; 11292 11293 cmd = (struct fcp_pkt *)pkt->pkt_ha_private; 11294 fpkt = cmd->cmd_fp_pkt; 11295 11296 /* 11297 * this request is for dma allocation only 11298 */ 11299 /* 11300 * First step of fcp_scsi_init_pkt: pkt allocation 11301 * We determine if the caller is willing to wait for the 11302 * resources. 11303 */ 11304 kf = (callback == SLEEP_FUNC) ? KM_SLEEP: KM_NOSLEEP; 11305 11306 /* 11307 * Selective zeroing of the pkt. 11308 */ 11309 cmd->cmd_back = NULL; 11310 cmd->cmd_next = NULL; 11311 11312 /* 11313 * Zero out fcp command 11314 */ 11315 bzero(&cmd->cmd_fcp_cmd, sizeof (cmd->cmd_fcp_cmd)); 11316 11317 cmd->cmd_state = FCP_PKT_IDLE; 11318 11319 fpkt = cmd->cmd_fp_pkt; 11320 fpkt->pkt_data_acc = NULL; 11321 11322 /* 11323 * When port_state is FCP_STATE_OFFLINE, remote_port (tgt_pd_handle) 11324 * could be destroyed. We need fail pkt_setup. 11325 */ 11326 if (pptr->port_state & FCP_STATE_OFFLINE) { 11327 return (-1); 11328 } 11329 11330 mutex_enter(&ptgt->tgt_mutex); 11331 fpkt->pkt_pd = ptgt->tgt_pd_handle; 11332 11333 if (fc_ulp_init_packet(pptr->port_fp_handle, fpkt, kf) 11334 != FC_SUCCESS) { 11335 mutex_exit(&ptgt->tgt_mutex); 11336 return (-1); 11337 } 11338 11339 mutex_exit(&ptgt->tgt_mutex); 11340 11341 /* Fill in the Fabric Channel Header */ 11342 hp = &fpkt->pkt_cmd_fhdr; 11343 hp->r_ctl = R_CTL_COMMAND; 11344 hp->rsvd = 0; 11345 hp->type = FC_TYPE_SCSI_FCP; 11346 hp->f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ; 11347 hp->seq_id = 0; 11348 hp->df_ctl = 0; 11349 hp->seq_cnt = 0; 11350 hp->ox_id = 0xffff; 11351 hp->rx_id = 0xffff; 11352 hp->ro = 0; 11353 11354 /* 11355 * A doubly linked list (cmd_forw, cmd_back) is built 11356 * out of every allocated packet on a per-lun basis 11357 * 11358 * The packets are maintained in the list so as to satisfy 11359 * scsi_abort() requests. At present (which is unlikely to 11360 * change in the future) nobody performs a real scsi_abort 11361 * in the SCSI target drivers (as they don't keep the packets 11362 * after doing scsi_transport - so they don't know how to 11363 * abort a packet other than sending a NULL to abort all 11364 * outstanding packets) 11365 */ 11366 mutex_enter(&plun->lun_mutex); 11367 if ((cmd->cmd_forw = plun->lun_pkt_head) != NULL) { 11368 plun->lun_pkt_head->cmd_back = cmd; 11369 } else { 11370 plun->lun_pkt_tail = cmd; 11371 } 11372 plun->lun_pkt_head = cmd; 11373 mutex_exit(&plun->lun_mutex); 11374 return (0); 11375 } 11376 11377 /* 11378 * Function: fcp_pkt_teardown 11379 * 11380 * Description: This function releases a scsi_pkt structure and all the 11381 * resources attached to it. 11382 * 11383 * Argument: *pkt Pointer to a scsi_pkt structure. 11384 * 11385 * Return Value: None 11386 * 11387 * Context: User, Kernel or Interrupt context. 11388 */ 11389 static void 11390 fcp_pkt_teardown(struct scsi_pkt *pkt) 11391 { 11392 struct fcp_port *pptr = ADDR2FCP(&pkt->pkt_address); 11393 struct fcp_lun *plun = ADDR2LUN(&pkt->pkt_address); 11394 struct fcp_pkt *cmd = (struct fcp_pkt *)pkt->pkt_ha_private; 11395 11396 /* 11397 * Remove the packet from the per-lun list 11398 */ 11399 mutex_enter(&plun->lun_mutex); 11400 if (cmd->cmd_back) { 11401 ASSERT(cmd != plun->lun_pkt_head); 11402 cmd->cmd_back->cmd_forw = cmd->cmd_forw; 11403 } else { 11404 ASSERT(cmd == plun->lun_pkt_head); 11405 plun->lun_pkt_head = cmd->cmd_forw; 11406 } 11407 11408 if (cmd->cmd_forw) { 11409 cmd->cmd_forw->cmd_back = cmd->cmd_back; 11410 } else { 11411 ASSERT(cmd == plun->lun_pkt_tail); 11412 plun->lun_pkt_tail = cmd->cmd_back; 11413 } 11414 11415 mutex_exit(&plun->lun_mutex); 11416 11417 (void) fc_ulp_uninit_packet(pptr->port_fp_handle, cmd->cmd_fp_pkt); 11418 } 11419 11420 /* 11421 * Routine for reset notification setup, to register or cancel. 11422 * This function is called by SCSA 11423 */ 11424 /*ARGSUSED*/ 11425 static int 11426 fcp_scsi_reset_notify(struct scsi_address *ap, int flag, 11427 void (*callback)(caddr_t), caddr_t arg) 11428 { 11429 struct fcp_port *pptr = ADDR2FCP(ap); 11430 11431 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg, 11432 &pptr->port_mutex, &pptr->port_reset_notify_listf)); 11433 } 11434 11435 11436 static int 11437 fcp_scsi_bus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip, char *name, 11438 ddi_eventcookie_t *event_cookiep) 11439 { 11440 struct fcp_port *pptr = fcp_dip2port(dip); 11441 11442 if (pptr == NULL) { 11443 return (DDI_FAILURE); 11444 } 11445 11446 return (ndi_event_retrieve_cookie(pptr->port_ndi_event_hdl, rdip, name, 11447 event_cookiep, NDI_EVENT_NOPASS)); 11448 } 11449 11450 11451 static int 11452 fcp_scsi_bus_add_eventcall(dev_info_t *dip, dev_info_t *rdip, 11453 ddi_eventcookie_t eventid, void (*callback)(), void *arg, 11454 ddi_callback_id_t *cb_id) 11455 { 11456 struct fcp_port *pptr = fcp_dip2port(dip); 11457 11458 if (pptr == NULL) { 11459 return (DDI_FAILURE); 11460 } 11461 11462 return (ndi_event_add_callback(pptr->port_ndi_event_hdl, rdip, 11463 eventid, callback, arg, NDI_SLEEP, cb_id)); 11464 } 11465 11466 11467 static int 11468 fcp_scsi_bus_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id) 11469 { 11470 11471 struct fcp_port *pptr = fcp_dip2port(dip); 11472 11473 if (pptr == NULL) { 11474 return (DDI_FAILURE); 11475 } 11476 return (ndi_event_remove_callback(pptr->port_ndi_event_hdl, cb_id)); 11477 } 11478 11479 11480 /* 11481 * called by the transport to post an event 11482 */ 11483 static int 11484 fcp_scsi_bus_post_event(dev_info_t *dip, dev_info_t *rdip, 11485 ddi_eventcookie_t eventid, void *impldata) 11486 { 11487 struct fcp_port *pptr = fcp_dip2port(dip); 11488 11489 if (pptr == NULL) { 11490 return (DDI_FAILURE); 11491 } 11492 11493 return (ndi_event_run_callbacks(pptr->port_ndi_event_hdl, rdip, 11494 eventid, impldata)); 11495 } 11496 11497 11498 /* 11499 * A target in in many cases in Fibre Channel has a one to one relation 11500 * with a port identifier (which is also known as D_ID and also as AL_PA 11501 * in private Loop) On Fibre Channel-to-SCSI bridge boxes a target reset 11502 * will most likely result in resetting all LUNs (which means a reset will 11503 * occur on all the SCSI devices connected at the other end of the bridge) 11504 * That is the latest favorite topic for discussion, for, one can debate as 11505 * hot as one likes and come up with arguably a best solution to one's 11506 * satisfaction 11507 * 11508 * To stay on track and not digress much, here are the problems stated 11509 * briefly: 11510 * 11511 * SCSA doesn't define RESET_LUN, It defines RESET_TARGET, but the 11512 * target drivers use RESET_TARGET even if their instance is on a 11513 * LUN. Doesn't that sound a bit broken ? 11514 * 11515 * FCP SCSI (the current spec) only defines RESET TARGET in the 11516 * control fields of an FCP_CMND structure. It should have been 11517 * fixed right there, giving flexibility to the initiators to 11518 * minimize havoc that could be caused by resetting a target. 11519 */ 11520 static int 11521 fcp_reset_target(struct scsi_address *ap, int level) 11522 { 11523 int rval = FC_FAILURE; 11524 char lun_id[25]; 11525 struct fcp_port *pptr = ADDR2FCP(ap); 11526 struct fcp_lun *plun = ADDR2LUN(ap); 11527 struct fcp_tgt *ptgt = plun->lun_tgt; 11528 struct scsi_pkt *pkt; 11529 struct fcp_pkt *cmd; 11530 struct fcp_rsp *rsp; 11531 uint32_t tgt_cnt; 11532 struct fcp_rsp_info *rsp_info; 11533 struct fcp_reset_elem *p; 11534 int bval; 11535 11536 if ((p = kmem_alloc(sizeof (struct fcp_reset_elem), 11537 KM_NOSLEEP)) == NULL) { 11538 return (rval); 11539 } 11540 11541 mutex_enter(&ptgt->tgt_mutex); 11542 if (level == RESET_TARGET) { 11543 if (ptgt->tgt_state & (FCP_TGT_OFFLINE | FCP_TGT_BUSY)) { 11544 mutex_exit(&ptgt->tgt_mutex); 11545 kmem_free(p, sizeof (struct fcp_reset_elem)); 11546 return (rval); 11547 } 11548 fcp_update_tgt_state(ptgt, FCP_SET, FCP_LUN_BUSY); 11549 (void) strcpy(lun_id, " "); 11550 } else { 11551 if (plun->lun_state & (FCP_LUN_OFFLINE | FCP_LUN_BUSY)) { 11552 mutex_exit(&ptgt->tgt_mutex); 11553 kmem_free(p, sizeof (struct fcp_reset_elem)); 11554 return (rval); 11555 } 11556 fcp_update_lun_state(plun, FCP_SET, FCP_LUN_BUSY); 11557 11558 (void) sprintf(lun_id, ", LUN=%d", plun->lun_num); 11559 } 11560 tgt_cnt = ptgt->tgt_change_cnt; 11561 11562 mutex_exit(&ptgt->tgt_mutex); 11563 11564 if ((pkt = scsi_init_pkt(ap, NULL, NULL, 0, 0, 11565 0, 0, NULL, 0)) == NULL) { 11566 kmem_free(p, sizeof (struct fcp_reset_elem)); 11567 mutex_enter(&ptgt->tgt_mutex); 11568 fcp_update_tgt_state(ptgt, FCP_RESET, FCP_LUN_BUSY); 11569 mutex_exit(&ptgt->tgt_mutex); 11570 return (rval); 11571 } 11572 pkt->pkt_time = FCP_POLL_TIMEOUT; 11573 11574 /* fill in cmd part of packet */ 11575 cmd = PKT2CMD(pkt); 11576 if (level == RESET_TARGET) { 11577 cmd->cmd_fcp_cmd.fcp_cntl.cntl_reset_tgt = 1; 11578 } else { 11579 cmd->cmd_fcp_cmd.fcp_cntl.cntl_reset_lun = 1; 11580 } 11581 cmd->cmd_fp_pkt->pkt_comp = NULL; 11582 cmd->cmd_pkt->pkt_flags |= FLAG_NOINTR; 11583 11584 /* prepare a packet for transport */ 11585 fcp_prepare_pkt(pptr, cmd, plun); 11586 11587 if (cmd->cmd_pkt->pkt_time) { 11588 cmd->cmd_fp_pkt->pkt_timeout = cmd->cmd_pkt->pkt_time; 11589 } else { 11590 cmd->cmd_fp_pkt->pkt_timeout = 5 * 60 * 60; 11591 } 11592 11593 (void) fc_ulp_busy_port(pptr->port_fp_handle); 11594 bval = fcp_dopoll(pptr, cmd); 11595 fc_ulp_idle_port(pptr->port_fp_handle); 11596 11597 /* submit the packet */ 11598 if (bval == TRAN_ACCEPT) { 11599 int error = 3; 11600 11601 rsp = (struct fcp_rsp *)cmd->cmd_fcp_rsp; 11602 rsp_info = (struct fcp_rsp_info *)(cmd->cmd_fcp_rsp + 11603 sizeof (struct fcp_rsp)); 11604 11605 if (rsp->fcp_u.fcp_status.rsp_len_set) { 11606 if (fcp_validate_fcp_response(rsp, pptr) == 11607 FC_SUCCESS) { 11608 if (pptr->port_fcp_dma != FC_NO_DVMA_SPACE) { 11609 FCP_CP_IN(cmd->cmd_fp_pkt->pkt_resp + 11610 sizeof (struct fcp_rsp), rsp_info, 11611 cmd->cmd_fp_pkt->pkt_resp_acc, 11612 sizeof (struct fcp_rsp_info)); 11613 } 11614 if (rsp_info->rsp_code == FCP_NO_FAILURE) { 11615 rval = FC_SUCCESS; 11616 error = 0; 11617 } else { 11618 error = 1; 11619 } 11620 } else { 11621 error = 2; 11622 } 11623 } 11624 11625 switch (error) { 11626 case 0: 11627 fcp_log(CE_WARN, pptr->port_dip, 11628 "!FCP: WWN 0x%08x%08x %s reset successfully", 11629 *((int *)&ptgt->tgt_port_wwn.raw_wwn[0]), 11630 *((int *)&ptgt->tgt_port_wwn.raw_wwn[4]), lun_id); 11631 break; 11632 11633 case 1: 11634 fcp_log(CE_WARN, pptr->port_dip, 11635 "!FCP: Reset to WWN 0x%08x%08x %s failed," 11636 " response code=%x", 11637 *((int *)&ptgt->tgt_port_wwn.raw_wwn[0]), 11638 *((int *)&ptgt->tgt_port_wwn.raw_wwn[4]), lun_id, 11639 rsp_info->rsp_code); 11640 break; 11641 11642 case 2: 11643 fcp_log(CE_WARN, pptr->port_dip, 11644 "!FCP: Reset to WWN 0x%08x%08x %s failed," 11645 " Bad FCP response values: rsvd1=%x," 11646 " rsvd2=%x, sts-rsvd1=%x, sts-rsvd2=%x," 11647 " rsplen=%x, senselen=%x", 11648 *((int *)&ptgt->tgt_port_wwn.raw_wwn[0]), 11649 *((int *)&ptgt->tgt_port_wwn.raw_wwn[4]), lun_id, 11650 rsp->reserved_0, rsp->reserved_1, 11651 rsp->fcp_u.fcp_status.reserved_0, 11652 rsp->fcp_u.fcp_status.reserved_1, 11653 rsp->fcp_response_len, rsp->fcp_sense_len); 11654 break; 11655 11656 default: 11657 fcp_log(CE_WARN, pptr->port_dip, 11658 "!FCP: Reset to WWN 0x%08x%08x %s failed", 11659 *((int *)&ptgt->tgt_port_wwn.raw_wwn[0]), 11660 *((int *)&ptgt->tgt_port_wwn.raw_wwn[4]), lun_id); 11661 break; 11662 } 11663 } 11664 scsi_destroy_pkt(pkt); 11665 11666 if (rval == FC_FAILURE) { 11667 mutex_enter(&ptgt->tgt_mutex); 11668 if (level == RESET_TARGET) { 11669 fcp_update_tgt_state(ptgt, FCP_RESET, FCP_LUN_BUSY); 11670 } else { 11671 fcp_update_lun_state(plun, FCP_RESET, FCP_LUN_BUSY); 11672 } 11673 mutex_exit(&ptgt->tgt_mutex); 11674 kmem_free(p, sizeof (struct fcp_reset_elem)); 11675 return (rval); 11676 } 11677 11678 mutex_enter(&pptr->port_mutex); 11679 if (level == RESET_TARGET) { 11680 p->tgt = ptgt; 11681 p->lun = NULL; 11682 } else { 11683 p->tgt = NULL; 11684 p->lun = plun; 11685 } 11686 p->tgt = ptgt; 11687 p->tgt_cnt = tgt_cnt; 11688 p->timeout = fcp_watchdog_time + FCP_RESET_DELAY; 11689 p->next = pptr->port_reset_list; 11690 pptr->port_reset_list = p; 11691 11692 FCP_TRACE(fcp_logq, pptr->port_instbuf, 11693 fcp_trace, FCP_BUF_LEVEL_3, 0, 11694 "Notify ssd of the reset to reinstate the reservations"); 11695 11696 scsi_hba_reset_notify_callback(&pptr->port_mutex, 11697 &pptr->port_reset_notify_listf); 11698 11699 mutex_exit(&pptr->port_mutex); 11700 11701 return (rval); 11702 } 11703 11704 11705 /* 11706 * called by fcp_getcap and fcp_setcap to get and set (respectively) 11707 * SCSI capabilities 11708 */ 11709 /* ARGSUSED */ 11710 static int 11711 fcp_commoncap(struct scsi_address *ap, char *cap, 11712 int val, int tgtonly, int doset) 11713 { 11714 struct fcp_port *pptr = ADDR2FCP(ap); 11715 struct fcp_lun *plun = ADDR2LUN(ap); 11716 struct fcp_tgt *ptgt = plun->lun_tgt; 11717 int cidx; 11718 int rval = FALSE; 11719 11720 if (cap == (char *)0) { 11721 FCP_TRACE(fcp_logq, pptr->port_instbuf, 11722 fcp_trace, FCP_BUF_LEVEL_3, 0, 11723 "fcp_commoncap: invalid arg"); 11724 return (rval); 11725 } 11726 11727 if ((cidx = scsi_hba_lookup_capstr(cap)) == -1) { 11728 return (UNDEFINED); 11729 } 11730 11731 /* 11732 * Process setcap request. 11733 */ 11734 if (doset) { 11735 /* 11736 * At present, we can only set binary (0/1) values 11737 */ 11738 switch (cidx) { 11739 case SCSI_CAP_ARQ: 11740 if (val == 0) { 11741 rval = FALSE; 11742 } else { 11743 rval = TRUE; 11744 } 11745 break; 11746 11747 case SCSI_CAP_LUN_RESET: 11748 if (val) { 11749 plun->lun_cap |= FCP_LUN_CAP_RESET; 11750 } else { 11751 plun->lun_cap &= ~FCP_LUN_CAP_RESET; 11752 } 11753 rval = TRUE; 11754 break; 11755 11756 case SCSI_CAP_SECTOR_SIZE: 11757 rval = TRUE; 11758 break; 11759 default: 11760 FCP_TRACE(fcp_logq, pptr->port_instbuf, 11761 fcp_trace, FCP_BUF_LEVEL_4, 0, 11762 "fcp_setcap: unsupported %d", cidx); 11763 rval = UNDEFINED; 11764 break; 11765 } 11766 11767 FCP_TRACE(fcp_logq, pptr->port_instbuf, 11768 fcp_trace, FCP_BUF_LEVEL_5, 0, 11769 "set cap: cap=%s, val/tgtonly/doset/rval = " 11770 "0x%x/0x%x/0x%x/%d", 11771 cap, val, tgtonly, doset, rval); 11772 11773 } else { 11774 /* 11775 * Process getcap request. 11776 */ 11777 switch (cidx) { 11778 case SCSI_CAP_DMA_MAX: 11779 rval = (int)pptr->port_data_dma_attr.dma_attr_maxxfer; 11780 11781 /* 11782 * Need to make an adjustment qlc is uint_t 64 11783 * st is int, so we will make the adjustment here 11784 * being as nobody wants to touch this. 11785 * It still leaves the max single block length 11786 * of 2 gig. This should last . 11787 */ 11788 11789 if (rval == -1) { 11790 rval = MAX_INT_DMA; 11791 } 11792 11793 break; 11794 11795 case SCSI_CAP_INITIATOR_ID: 11796 rval = pptr->port_id; 11797 break; 11798 11799 case SCSI_CAP_ARQ: 11800 case SCSI_CAP_RESET_NOTIFICATION: 11801 case SCSI_CAP_TAGGED_QING: 11802 rval = TRUE; 11803 break; 11804 11805 case SCSI_CAP_SCSI_VERSION: 11806 rval = 3; 11807 break; 11808 11809 case SCSI_CAP_INTERCONNECT_TYPE: 11810 if (FC_TOP_EXTERNAL(pptr->port_topology) || 11811 (ptgt->tgt_hard_addr == 0)) { 11812 rval = INTERCONNECT_FABRIC; 11813 } else { 11814 rval = INTERCONNECT_FIBRE; 11815 } 11816 break; 11817 11818 case SCSI_CAP_LUN_RESET: 11819 rval = ((plun->lun_cap & FCP_LUN_CAP_RESET) != 0) ? 11820 TRUE : FALSE; 11821 break; 11822 11823 default: 11824 FCP_TRACE(fcp_logq, pptr->port_instbuf, 11825 fcp_trace, FCP_BUF_LEVEL_4, 0, 11826 "fcp_getcap: unsupported %d", cidx); 11827 rval = UNDEFINED; 11828 break; 11829 } 11830 11831 FCP_TRACE(fcp_logq, pptr->port_instbuf, 11832 fcp_trace, FCP_BUF_LEVEL_8, 0, 11833 "get cap: cap=%s, val/tgtonly/doset/rval = " 11834 "0x%x/0x%x/0x%x/%d", 11835 cap, val, tgtonly, doset, rval); 11836 } 11837 11838 return (rval); 11839 } 11840 11841 /* 11842 * called by the transport to get the port-wwn and lun 11843 * properties of this device, and to create a "name" based on them 11844 * 11845 * these properties don't exist on sun4m 11846 * 11847 * return 1 for success else return 0 11848 */ 11849 /* ARGSUSED */ 11850 static int 11851 fcp_scsi_get_name(struct scsi_device *sd, char *name, int len) 11852 { 11853 int i; 11854 int *lun; 11855 int numChars; 11856 uint_t nlun; 11857 uint_t count; 11858 uint_t nbytes; 11859 uchar_t *bytes; 11860 uint16_t lun_num; 11861 uint32_t tgt_id; 11862 char **conf_wwn; 11863 char tbuf[(FC_WWN_SIZE << 1) + 1]; 11864 uchar_t barray[FC_WWN_SIZE]; 11865 dev_info_t *tgt_dip; 11866 struct fcp_tgt *ptgt; 11867 struct fcp_port *pptr; 11868 struct fcp_lun *plun; 11869 11870 ASSERT(sd != NULL); 11871 ASSERT(name != NULL); 11872 11873 tgt_dip = sd->sd_dev; 11874 pptr = ddi_get_soft_state(fcp_softstate, 11875 ddi_get_instance(ddi_get_parent(tgt_dip))); 11876 if (pptr == NULL) { 11877 return (0); 11878 } 11879 11880 ASSERT(tgt_dip != NULL); 11881 11882 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, sd->sd_dev, 11883 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 11884 LUN_PROP, &lun, &nlun) != DDI_SUCCESS) { 11885 name[0] = '\0'; 11886 return (0); 11887 } 11888 11889 if (nlun == 0) { 11890 ddi_prop_free(lun); 11891 return (0); 11892 } 11893 11894 lun_num = lun[0]; 11895 ddi_prop_free(lun); 11896 11897 /* 11898 * Lookup for .conf WWN property 11899 */ 11900 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, tgt_dip, 11901 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, CONF_WWN_PROP, 11902 &conf_wwn, &count) == DDI_PROP_SUCCESS) { 11903 ASSERT(count >= 1); 11904 11905 fcp_ascii_to_wwn(conf_wwn[0], barray, FC_WWN_SIZE); 11906 ddi_prop_free(conf_wwn); 11907 mutex_enter(&pptr->port_mutex); 11908 if ((plun = fcp_lookup_lun(pptr, barray, lun_num)) == NULL) { 11909 mutex_exit(&pptr->port_mutex); 11910 return (0); 11911 } 11912 ptgt = plun->lun_tgt; 11913 mutex_exit(&pptr->port_mutex); 11914 11915 (void) ndi_prop_update_byte_array(DDI_DEV_T_NONE, 11916 tgt_dip, PORT_WWN_PROP, barray, FC_WWN_SIZE); 11917 11918 if (!FC_TOP_EXTERNAL(pptr->port_topology) && 11919 ptgt->tgt_hard_addr != 0) { 11920 tgt_id = (uint32_t)fcp_alpa_to_switch[ 11921 ptgt->tgt_hard_addr]; 11922 } else { 11923 tgt_id = ptgt->tgt_d_id; 11924 } 11925 11926 (void) ndi_prop_update_int(DDI_DEV_T_NONE, tgt_dip, 11927 TARGET_PROP, tgt_id); 11928 } 11929 11930 /* get the our port-wwn property */ 11931 bytes = NULL; 11932 if ((ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, tgt_dip, 11933 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, PORT_WWN_PROP, &bytes, 11934 &nbytes) != DDI_PROP_SUCCESS) || nbytes != FC_WWN_SIZE) { 11935 if (bytes != NULL) { 11936 ddi_prop_free(bytes); 11937 } 11938 return (0); 11939 } 11940 11941 for (i = 0; i < FC_WWN_SIZE; i++) { 11942 (void) sprintf(&tbuf[i << 1], "%02x", *(bytes + i)); 11943 } 11944 11945 /* Stick in the address of the form "wWWN,LUN" */ 11946 numChars = snprintf(name, len, "w%s,%x", tbuf, lun_num); 11947 11948 ASSERT(numChars < len); 11949 if (numChars >= len) { 11950 fcp_log(CE_WARN, pptr->port_dip, 11951 "!fcp_scsi_get_name: " 11952 "name parameter length too small, it needs to be %d", 11953 numChars+1); 11954 } 11955 11956 ddi_prop_free(bytes); 11957 11958 return (1); 11959 } 11960 11961 11962 /* 11963 * called by the transport to get the SCSI target id value, returning 11964 * it in "name" 11965 * 11966 * this isn't needed/used on sun4m 11967 * 11968 * return 1 for success else return 0 11969 */ 11970 /* ARGSUSED */ 11971 static int 11972 fcp_scsi_get_bus_addr(struct scsi_device *sd, char *name, int len) 11973 { 11974 struct fcp_lun *plun = ADDR2LUN(&sd->sd_address); 11975 struct fcp_tgt *ptgt; 11976 int numChars; 11977 11978 if (plun == NULL) { 11979 return (0); 11980 } 11981 11982 if ((ptgt = plun->lun_tgt) == NULL) { 11983 return (0); 11984 } 11985 11986 numChars = snprintf(name, len, "%x", ptgt->tgt_d_id); 11987 11988 ASSERT(numChars < len); 11989 if (numChars >= len) { 11990 fcp_log(CE_WARN, NULL, 11991 "!fcp_scsi_get_bus_addr: " 11992 "name parameter length too small, it needs to be %d", 11993 numChars+1); 11994 } 11995 11996 return (1); 11997 } 11998 11999 12000 /* 12001 * called internally to reset the link where the specified port lives 12002 */ 12003 static int 12004 fcp_linkreset(struct fcp_port *pptr, struct scsi_address *ap, int sleep) 12005 { 12006 la_wwn_t wwn; 12007 struct fcp_lun *plun; 12008 struct fcp_tgt *ptgt; 12009 12010 /* disable restart of lip if we're suspended */ 12011 mutex_enter(&pptr->port_mutex); 12012 12013 if (pptr->port_state & (FCP_STATE_SUSPENDED | 12014 FCP_STATE_POWER_DOWN)) { 12015 mutex_exit(&pptr->port_mutex); 12016 FCP_TRACE(fcp_logq, pptr->port_instbuf, 12017 fcp_trace, FCP_BUF_LEVEL_2, 0, 12018 "fcp_linkreset, fcp%d: link reset " 12019 "disabled due to DDI_SUSPEND", 12020 ddi_get_instance(pptr->port_dip)); 12021 return (FC_FAILURE); 12022 } 12023 12024 if (pptr->port_state & (FCP_STATE_OFFLINE | FCP_STATE_ONLINING)) { 12025 mutex_exit(&pptr->port_mutex); 12026 return (FC_SUCCESS); 12027 } 12028 12029 FCP_DTRACE(fcp_logq, pptr->port_instbuf, 12030 fcp_trace, FCP_BUF_LEVEL_8, 0, "Forcing link reset"); 12031 12032 /* 12033 * If ap == NULL assume local link reset. 12034 */ 12035 if (FC_TOP_EXTERNAL(pptr->port_topology) && (ap != NULL)) { 12036 plun = ADDR2LUN(ap); 12037 ptgt = plun->lun_tgt; 12038 bcopy(&ptgt->tgt_port_wwn.raw_wwn[0], &wwn, sizeof (wwn)); 12039 } else { 12040 bzero((caddr_t)&wwn, sizeof (wwn)); 12041 } 12042 mutex_exit(&pptr->port_mutex); 12043 12044 return (fc_ulp_linkreset(pptr->port_fp_handle, &wwn, sleep)); 12045 } 12046 12047 12048 /* 12049 * called from fcp_port_attach() to resume a port 12050 * return DDI_* success/failure status 12051 * acquires and releases the global mutex 12052 * acquires and releases the port mutex 12053 */ 12054 /*ARGSUSED*/ 12055 12056 static int 12057 fcp_handle_port_resume(opaque_t ulph, fc_ulp_port_info_t *pinfo, 12058 uint32_t s_id, fc_attach_cmd_t cmd, int instance) 12059 { 12060 int res = DDI_FAILURE; /* default result */ 12061 struct fcp_port *pptr; /* port state ptr */ 12062 uint32_t alloc_cnt; 12063 uint32_t max_cnt; 12064 fc_portmap_t *tmp_list = NULL; 12065 12066 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 12067 FCP_BUF_LEVEL_8, 0, "port resume: for port %d", 12068 instance); 12069 12070 if ((pptr = ddi_get_soft_state(fcp_softstate, instance)) == NULL) { 12071 cmn_err(CE_WARN, "fcp: bad soft state"); 12072 return (res); 12073 } 12074 12075 mutex_enter(&pptr->port_mutex); 12076 switch (cmd) { 12077 case FC_CMD_RESUME: 12078 ASSERT((pptr->port_state & FCP_STATE_POWER_DOWN) == 0); 12079 pptr->port_state &= ~FCP_STATE_SUSPENDED; 12080 break; 12081 12082 case FC_CMD_POWER_UP: 12083 /* 12084 * If the port is DDI_SUSPENded, defer rediscovery 12085 * until DDI_RESUME occurs 12086 */ 12087 if (pptr->port_state & FCP_STATE_SUSPENDED) { 12088 pptr->port_state &= ~FCP_STATE_POWER_DOWN; 12089 mutex_exit(&pptr->port_mutex); 12090 return (DDI_SUCCESS); 12091 } 12092 pptr->port_state &= ~FCP_STATE_POWER_DOWN; 12093 } 12094 pptr->port_id = s_id; 12095 pptr->port_state = FCP_STATE_INIT; 12096 mutex_exit(&pptr->port_mutex); 12097 12098 /* 12099 * Make a copy of ulp_port_info as fctl allocates 12100 * a temp struct. 12101 */ 12102 (void) fcp_cp_pinfo(pptr, pinfo); 12103 12104 mutex_enter(&fcp_global_mutex); 12105 if (fcp_watchdog_init++ == 0) { 12106 fcp_watchdog_tick = fcp_watchdog_timeout * 12107 drv_usectohz(1000000); 12108 fcp_watchdog_id = timeout(fcp_watch, 12109 NULL, fcp_watchdog_tick); 12110 } 12111 mutex_exit(&fcp_global_mutex); 12112 12113 /* 12114 * Handle various topologies and link states. 12115 */ 12116 switch (FC_PORT_STATE_MASK(pptr->port_phys_state)) { 12117 case FC_STATE_OFFLINE: 12118 /* 12119 * Wait for ONLINE, at which time a state 12120 * change will cause a statec_callback 12121 */ 12122 res = DDI_SUCCESS; 12123 break; 12124 12125 case FC_STATE_ONLINE: 12126 12127 if (pptr->port_topology == FC_TOP_UNKNOWN) { 12128 (void) fcp_linkreset(pptr, NULL, KM_NOSLEEP); 12129 res = DDI_SUCCESS; 12130 break; 12131 } 12132 12133 if (FC_TOP_EXTERNAL(pptr->port_topology) && 12134 !fcp_enable_auto_configuration) { 12135 tmp_list = fcp_construct_map(pptr, &alloc_cnt); 12136 if (tmp_list == NULL) { 12137 if (!alloc_cnt) { 12138 res = DDI_SUCCESS; 12139 } 12140 break; 12141 } 12142 max_cnt = alloc_cnt; 12143 } else { 12144 ASSERT(pptr->port_topology != FC_TOP_UNKNOWN); 12145 12146 alloc_cnt = FCP_MAX_DEVICES; 12147 12148 if ((tmp_list = (fc_portmap_t *)kmem_zalloc( 12149 (sizeof (fc_portmap_t)) * alloc_cnt, 12150 KM_NOSLEEP)) == NULL) { 12151 fcp_log(CE_WARN, pptr->port_dip, 12152 "!fcp%d: failed to allocate portmap", 12153 instance); 12154 break; 12155 } 12156 12157 max_cnt = alloc_cnt; 12158 if ((res = fc_ulp_getportmap(pptr->port_fp_handle, 12159 &tmp_list, &max_cnt, FC_ULP_PLOGI_PRESERVE)) != 12160 FC_SUCCESS) { 12161 caddr_t msg; 12162 12163 (void) fc_ulp_error(res, &msg); 12164 12165 FCP_TRACE(fcp_logq, pptr->port_instbuf, 12166 fcp_trace, FCP_BUF_LEVEL_2, 0, 12167 "resume failed getportmap: reason=0x%x", 12168 res); 12169 12170 fcp_log(CE_WARN, pptr->port_dip, 12171 "!failed to get port map : %s", msg); 12172 break; 12173 } 12174 if (max_cnt > alloc_cnt) { 12175 alloc_cnt = max_cnt; 12176 } 12177 } 12178 12179 /* 12180 * do the SCSI device discovery and create 12181 * the devinfos 12182 */ 12183 fcp_statec_callback(ulph, pptr->port_fp_handle, 12184 pptr->port_phys_state, pptr->port_topology, tmp_list, 12185 max_cnt, pptr->port_id); 12186 12187 res = DDI_SUCCESS; 12188 break; 12189 12190 default: 12191 fcp_log(CE_WARN, pptr->port_dip, 12192 "!fcp%d: invalid port state at attach=0x%x", 12193 instance, pptr->port_phys_state); 12194 12195 mutex_enter(&pptr->port_mutex); 12196 pptr->port_phys_state = FCP_STATE_OFFLINE; 12197 mutex_exit(&pptr->port_mutex); 12198 res = DDI_SUCCESS; 12199 12200 break; 12201 } 12202 12203 if (tmp_list != NULL) { 12204 kmem_free(tmp_list, sizeof (fc_portmap_t) * alloc_cnt); 12205 } 12206 12207 return (res); 12208 } 12209 12210 12211 static void 12212 fcp_cp_pinfo(struct fcp_port *pptr, fc_ulp_port_info_t *pinfo) 12213 { 12214 pptr->port_fp_modlinkage = *pinfo->port_linkage; 12215 pptr->port_dip = pinfo->port_dip; 12216 pptr->port_fp_handle = pinfo->port_handle; 12217 pptr->port_data_dma_attr = *pinfo->port_data_dma_attr; 12218 pptr->port_cmd_dma_attr = *pinfo->port_cmd_dma_attr; 12219 pptr->port_resp_dma_attr = *pinfo->port_resp_dma_attr; 12220 pptr->port_dma_acc_attr = *pinfo->port_acc_attr; 12221 pptr->port_priv_pkt_len = pinfo->port_fca_pkt_size; 12222 pptr->port_max_exch = pinfo->port_fca_max_exch; 12223 pptr->port_phys_state = pinfo->port_state; 12224 pptr->port_topology = pinfo->port_flags; 12225 pptr->port_reset_action = pinfo->port_reset_action; 12226 pptr->port_cmds_dma_flags = pinfo->port_dma_behavior; 12227 pptr->port_fcp_dma = pinfo->port_fcp_dma; 12228 bcopy(&pinfo->port_nwwn, &pptr->port_nwwn, sizeof (la_wwn_t)); 12229 bcopy(&pinfo->port_pwwn, &pptr->port_pwwn, sizeof (la_wwn_t)); 12230 12231 /* Clear FMA caps to avoid fm-capability ereport */ 12232 if (pptr->port_cmd_dma_attr.dma_attr_flags & DDI_DMA_FLAGERR) 12233 pptr->port_cmd_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12234 if (pptr->port_data_dma_attr.dma_attr_flags & DDI_DMA_FLAGERR) 12235 pptr->port_data_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12236 if (pptr->port_resp_dma_attr.dma_attr_flags & DDI_DMA_FLAGERR) 12237 pptr->port_resp_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12238 } 12239 12240 /* 12241 * If the elements wait field is set to 1 then 12242 * another thread is waiting for the operation to complete. Once 12243 * it is complete, the waiting thread is signaled and the element is 12244 * freed by the waiting thread. If the elements wait field is set to 0 12245 * the element is freed. 12246 */ 12247 static void 12248 fcp_process_elem(struct fcp_hp_elem *elem, int result) 12249 { 12250 ASSERT(elem != NULL); 12251 mutex_enter(&elem->mutex); 12252 elem->result = result; 12253 if (elem->wait) { 12254 elem->wait = 0; 12255 cv_signal(&elem->cv); 12256 mutex_exit(&elem->mutex); 12257 } else { 12258 mutex_exit(&elem->mutex); 12259 cv_destroy(&elem->cv); 12260 mutex_destroy(&elem->mutex); 12261 kmem_free(elem, sizeof (struct fcp_hp_elem)); 12262 } 12263 } 12264 12265 /* 12266 * This function is invoked from the taskq thread to allocate 12267 * devinfo nodes and to online/offline them. 12268 */ 12269 static void 12270 fcp_hp_task(void *arg) 12271 { 12272 struct fcp_hp_elem *elem = (struct fcp_hp_elem *)arg; 12273 struct fcp_lun *plun = elem->lun; 12274 struct fcp_port *pptr = elem->port; 12275 int result; 12276 12277 ASSERT(elem->what == FCP_ONLINE || 12278 elem->what == FCP_OFFLINE || 12279 elem->what == FCP_MPXIO_PATH_CLEAR_BUSY || 12280 elem->what == FCP_MPXIO_PATH_SET_BUSY); 12281 12282 mutex_enter(&pptr->port_mutex); 12283 mutex_enter(&plun->lun_mutex); 12284 if (((elem->what == FCP_ONLINE || elem->what == FCP_OFFLINE) && 12285 plun->lun_event_count != elem->event_cnt) || 12286 pptr->port_state & (FCP_STATE_SUSPENDED | 12287 FCP_STATE_DETACHING | FCP_STATE_POWER_DOWN)) { 12288 mutex_exit(&plun->lun_mutex); 12289 mutex_exit(&pptr->port_mutex); 12290 fcp_process_elem(elem, NDI_FAILURE); 12291 return; 12292 } 12293 mutex_exit(&plun->lun_mutex); 12294 mutex_exit(&pptr->port_mutex); 12295 12296 result = fcp_trigger_lun(plun, elem->cip, elem->old_lun_mpxio, 12297 elem->what, elem->link_cnt, elem->tgt_cnt, elem->flags); 12298 fcp_process_elem(elem, result); 12299 } 12300 12301 12302 static child_info_t * 12303 fcp_get_cip(struct fcp_lun *plun, child_info_t *cip, int lcount, 12304 int tcount) 12305 { 12306 ASSERT(MUTEX_HELD(&plun->lun_mutex)); 12307 12308 if (fcp_is_child_present(plun, cip) == FC_FAILURE) { 12309 struct fcp_port *pptr = plun->lun_tgt->tgt_port; 12310 12311 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 12312 /* 12313 * Child has not been created yet. Create the child device 12314 * based on the per-Lun flags. 12315 */ 12316 if (pptr->port_mpxio == 0 || plun->lun_mpxio == 0) { 12317 plun->lun_cip = 12318 CIP(fcp_create_dip(plun, lcount, tcount)); 12319 plun->lun_mpxio = 0; 12320 } else { 12321 plun->lun_cip = 12322 CIP(fcp_create_pip(plun, lcount, tcount)); 12323 plun->lun_mpxio = 1; 12324 } 12325 } else { 12326 plun->lun_cip = cip; 12327 } 12328 12329 return (plun->lun_cip); 12330 } 12331 12332 12333 static int 12334 fcp_is_dip_present(struct fcp_lun *plun, dev_info_t *cdip) 12335 { 12336 int rval = FC_FAILURE; 12337 dev_info_t *pdip; 12338 struct dev_info *dip; 12339 int circular; 12340 12341 ASSERT(MUTEX_HELD(&plun->lun_mutex)); 12342 12343 pdip = plun->lun_tgt->tgt_port->port_dip; 12344 12345 if (plun->lun_cip == NULL) { 12346 FCP_TRACE(fcp_logq, LUN_PORT->port_instbuf, 12347 fcp_trace, FCP_BUF_LEVEL_3, 0, 12348 "fcp_is_dip_present: plun->lun_cip is NULL: " 12349 "plun: %p lun state: %x num: %d target state: %x", 12350 plun, plun->lun_state, plun->lun_num, 12351 plun->lun_tgt->tgt_port->port_state); 12352 return (rval); 12353 } 12354 ndi_devi_enter(pdip, &circular); 12355 dip = DEVI(pdip)->devi_child; 12356 while (dip) { 12357 if (dip == DEVI(cdip)) { 12358 rval = FC_SUCCESS; 12359 break; 12360 } 12361 dip = dip->devi_sibling; 12362 } 12363 ndi_devi_exit(pdip, circular); 12364 return (rval); 12365 } 12366 12367 static int 12368 fcp_is_child_present(struct fcp_lun *plun, child_info_t *cip) 12369 { 12370 int rval = FC_FAILURE; 12371 12372 ASSERT(plun != NULL); 12373 ASSERT(MUTEX_HELD(&plun->lun_mutex)); 12374 12375 if (plun->lun_mpxio == 0) { 12376 rval = fcp_is_dip_present(plun, DIP(cip)); 12377 } else { 12378 rval = fcp_is_pip_present(plun, PIP(cip)); 12379 } 12380 12381 return (rval); 12382 } 12383 12384 /* 12385 * Function: fcp_create_dip 12386 * 12387 * Description: Creates a dev_info_t structure for the LUN specified by the 12388 * caller. 12389 * 12390 * Argument: plun Lun structure 12391 * link_cnt Link state count. 12392 * tgt_cnt Target state change count. 12393 * 12394 * Return Value: NULL if it failed 12395 * dev_info_t structure address if it succeeded 12396 * 12397 * Context: Kernel context 12398 */ 12399 static dev_info_t * 12400 fcp_create_dip(struct fcp_lun *plun, int link_cnt, int tgt_cnt) 12401 { 12402 int failure = 0; 12403 uint32_t tgt_id; 12404 uint64_t sam_lun; 12405 struct fcp_tgt *ptgt = plun->lun_tgt; 12406 struct fcp_port *pptr = ptgt->tgt_port; 12407 dev_info_t *pdip = pptr->port_dip; 12408 dev_info_t *cdip = NULL; 12409 dev_info_t *old_dip = DIP(plun->lun_cip); 12410 char *nname = NULL; 12411 char **compatible = NULL; 12412 int ncompatible; 12413 char *scsi_binding_set; 12414 char t_pwwn[17]; 12415 12416 ASSERT(MUTEX_HELD(&plun->lun_mutex)); 12417 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 12418 12419 /* get the 'scsi-binding-set' property */ 12420 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip, 12421 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "scsi-binding-set", 12422 &scsi_binding_set) != DDI_PROP_SUCCESS) { 12423 scsi_binding_set = NULL; 12424 } 12425 12426 /* determine the node name and compatible */ 12427 scsi_hba_nodename_compatible_get(&plun->lun_inq, scsi_binding_set, 12428 plun->lun_inq.inq_dtype, NULL, &nname, &compatible, &ncompatible); 12429 if (scsi_binding_set) { 12430 ddi_prop_free(scsi_binding_set); 12431 } 12432 12433 if (nname == NULL) { 12434 #ifdef DEBUG 12435 cmn_err(CE_WARN, "%s%d: no driver for " 12436 "device @w%02x%02x%02x%02x%02x%02x%02x%02x,%d:" 12437 " compatible: %s", 12438 ddi_driver_name(pdip), ddi_get_instance(pdip), 12439 ptgt->tgt_port_wwn.raw_wwn[0], 12440 ptgt->tgt_port_wwn.raw_wwn[1], 12441 ptgt->tgt_port_wwn.raw_wwn[2], 12442 ptgt->tgt_port_wwn.raw_wwn[3], 12443 ptgt->tgt_port_wwn.raw_wwn[4], 12444 ptgt->tgt_port_wwn.raw_wwn[5], 12445 ptgt->tgt_port_wwn.raw_wwn[6], 12446 ptgt->tgt_port_wwn.raw_wwn[7], plun->lun_num, 12447 *compatible); 12448 #endif /* DEBUG */ 12449 failure++; 12450 goto end_of_fcp_create_dip; 12451 } 12452 12453 cdip = fcp_find_existing_dip(plun, pdip, nname); 12454 12455 /* 12456 * if the old_dip does not match the cdip, that means there is 12457 * some property change. since we'll be using the cdip, we need 12458 * to offline the old_dip. If the state contains FCP_LUN_CHANGED 12459 * then the dtype for the device has been updated. Offline the 12460 * the old device and create a new device with the new device type 12461 * Refer to bug: 4764752 12462 */ 12463 if (old_dip && (cdip != old_dip || 12464 plun->lun_state & FCP_LUN_CHANGED)) { 12465 plun->lun_state &= ~(FCP_LUN_INIT); 12466 mutex_exit(&plun->lun_mutex); 12467 mutex_exit(&pptr->port_mutex); 12468 12469 mutex_enter(&ptgt->tgt_mutex); 12470 (void) fcp_pass_to_hp(pptr, plun, CIP(old_dip), FCP_OFFLINE, 12471 link_cnt, tgt_cnt, NDI_DEVI_REMOVE, 0); 12472 mutex_exit(&ptgt->tgt_mutex); 12473 12474 #ifdef DEBUG 12475 if (cdip != NULL) { 12476 FCP_TRACE(fcp_logq, pptr->port_instbuf, 12477 fcp_trace, FCP_BUF_LEVEL_2, 0, 12478 "Old dip=%p; New dip=%p don't match", old_dip, 12479 cdip); 12480 } else { 12481 FCP_TRACE(fcp_logq, pptr->port_instbuf, 12482 fcp_trace, FCP_BUF_LEVEL_2, 0, 12483 "Old dip=%p; New dip=NULL don't match", old_dip); 12484 } 12485 #endif 12486 12487 mutex_enter(&pptr->port_mutex); 12488 mutex_enter(&plun->lun_mutex); 12489 } 12490 12491 if (cdip == NULL || plun->lun_state & FCP_LUN_CHANGED) { 12492 plun->lun_state &= ~(FCP_LUN_CHANGED); 12493 if (ndi_devi_alloc(pptr->port_dip, nname, 12494 DEVI_SID_NODEID, &cdip) != NDI_SUCCESS) { 12495 failure++; 12496 goto end_of_fcp_create_dip; 12497 } 12498 } 12499 12500 /* 12501 * Previously all the properties for the devinfo were destroyed here 12502 * with a call to ndi_prop_remove_all(). Since this may cause loss of 12503 * the devid property (and other properties established by the target 12504 * driver or framework) which the code does not always recreate, this 12505 * call was removed. 12506 * This opens a theoretical possibility that we may return with a 12507 * stale devid on the node if the scsi entity behind the fibre channel 12508 * lun has changed. 12509 */ 12510 12511 /* decorate the node with compatible */ 12512 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, cdip, 12513 "compatible", compatible, ncompatible) != DDI_PROP_SUCCESS) { 12514 failure++; 12515 goto end_of_fcp_create_dip; 12516 } 12517 12518 if (ndi_prop_update_byte_array(DDI_DEV_T_NONE, cdip, NODE_WWN_PROP, 12519 ptgt->tgt_node_wwn.raw_wwn, FC_WWN_SIZE) != DDI_PROP_SUCCESS) { 12520 failure++; 12521 goto end_of_fcp_create_dip; 12522 } 12523 12524 if (ndi_prop_update_byte_array(DDI_DEV_T_NONE, cdip, PORT_WWN_PROP, 12525 ptgt->tgt_port_wwn.raw_wwn, FC_WWN_SIZE) != DDI_PROP_SUCCESS) { 12526 failure++; 12527 goto end_of_fcp_create_dip; 12528 } 12529 12530 fcp_wwn_to_ascii(ptgt->tgt_port_wwn.raw_wwn, t_pwwn); 12531 t_pwwn[16] = '\0'; 12532 if (ndi_prop_update_string(DDI_DEV_T_NONE, cdip, TGT_PORT_PROP, t_pwwn) 12533 != DDI_PROP_SUCCESS) { 12534 failure++; 12535 goto end_of_fcp_create_dip; 12536 } 12537 12538 /* 12539 * If there is no hard address - We might have to deal with 12540 * that by using WWN - Having said that it is important to 12541 * recognize this problem early so ssd can be informed of 12542 * the right interconnect type. 12543 */ 12544 if (!FC_TOP_EXTERNAL(pptr->port_topology) && ptgt->tgt_hard_addr != 0) { 12545 tgt_id = (uint32_t)fcp_alpa_to_switch[ptgt->tgt_hard_addr]; 12546 } else { 12547 tgt_id = ptgt->tgt_d_id; 12548 } 12549 12550 if (ndi_prop_update_int(DDI_DEV_T_NONE, cdip, TARGET_PROP, 12551 tgt_id) != DDI_PROP_SUCCESS) { 12552 failure++; 12553 goto end_of_fcp_create_dip; 12554 } 12555 12556 if (ndi_prop_update_int(DDI_DEV_T_NONE, cdip, LUN_PROP, 12557 (int)plun->lun_num) != DDI_PROP_SUCCESS) { 12558 failure++; 12559 goto end_of_fcp_create_dip; 12560 } 12561 bcopy(&plun->lun_addr, &sam_lun, FCP_LUN_SIZE); 12562 if (ndi_prop_update_int64(DDI_DEV_T_NONE, cdip, SAM_LUN_PROP, 12563 sam_lun) != DDI_PROP_SUCCESS) { 12564 failure++; 12565 goto end_of_fcp_create_dip; 12566 } 12567 12568 end_of_fcp_create_dip: 12569 scsi_hba_nodename_compatible_free(nname, compatible); 12570 12571 if (cdip != NULL && failure) { 12572 (void) ndi_prop_remove_all(cdip); 12573 (void) ndi_devi_free(cdip); 12574 cdip = NULL; 12575 } 12576 12577 return (cdip); 12578 } 12579 12580 /* 12581 * Function: fcp_create_pip 12582 * 12583 * Description: Creates a Path Id for the LUN specified by the caller. 12584 * 12585 * Argument: plun Lun structure 12586 * link_cnt Link state count. 12587 * tgt_cnt Target state count. 12588 * 12589 * Return Value: NULL if it failed 12590 * mdi_pathinfo_t structure address if it succeeded 12591 * 12592 * Context: Kernel context 12593 */ 12594 static mdi_pathinfo_t * 12595 fcp_create_pip(struct fcp_lun *plun, int lcount, int tcount) 12596 { 12597 int i; 12598 char buf[MAXNAMELEN]; 12599 char uaddr[MAXNAMELEN]; 12600 int failure = 0; 12601 uint32_t tgt_id; 12602 uint64_t sam_lun; 12603 struct fcp_tgt *ptgt = plun->lun_tgt; 12604 struct fcp_port *pptr = ptgt->tgt_port; 12605 dev_info_t *pdip = pptr->port_dip; 12606 mdi_pathinfo_t *pip = NULL; 12607 mdi_pathinfo_t *old_pip = PIP(plun->lun_cip); 12608 char *nname = NULL; 12609 char **compatible = NULL; 12610 int ncompatible; 12611 char *scsi_binding_set; 12612 char t_pwwn[17]; 12613 12614 ASSERT(MUTEX_HELD(&plun->lun_mutex)); 12615 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 12616 12617 scsi_binding_set = "vhci"; 12618 12619 /* determine the node name and compatible */ 12620 scsi_hba_nodename_compatible_get(&plun->lun_inq, scsi_binding_set, 12621 plun->lun_inq.inq_dtype, NULL, &nname, &compatible, &ncompatible); 12622 12623 if (nname == NULL) { 12624 #ifdef DEBUG 12625 cmn_err(CE_WARN, "fcp_create_dip: %s%d: no driver for " 12626 "device @w%02x%02x%02x%02x%02x%02x%02x%02x,%d:" 12627 " compatible: %s", 12628 ddi_driver_name(pdip), ddi_get_instance(pdip), 12629 ptgt->tgt_port_wwn.raw_wwn[0], 12630 ptgt->tgt_port_wwn.raw_wwn[1], 12631 ptgt->tgt_port_wwn.raw_wwn[2], 12632 ptgt->tgt_port_wwn.raw_wwn[3], 12633 ptgt->tgt_port_wwn.raw_wwn[4], 12634 ptgt->tgt_port_wwn.raw_wwn[5], 12635 ptgt->tgt_port_wwn.raw_wwn[6], 12636 ptgt->tgt_port_wwn.raw_wwn[7], plun->lun_num, 12637 *compatible); 12638 #endif /* DEBUG */ 12639 failure++; 12640 goto end_of_fcp_create_pip; 12641 } 12642 12643 pip = fcp_find_existing_pip(plun, pdip); 12644 12645 /* 12646 * if the old_dip does not match the cdip, that means there is 12647 * some property change. since we'll be using the cdip, we need 12648 * to offline the old_dip. If the state contains FCP_LUN_CHANGED 12649 * then the dtype for the device has been updated. Offline the 12650 * the old device and create a new device with the new device type 12651 * Refer to bug: 4764752 12652 */ 12653 if (old_pip && (pip != old_pip || 12654 plun->lun_state & FCP_LUN_CHANGED)) { 12655 plun->lun_state &= ~(FCP_LUN_INIT); 12656 mutex_exit(&plun->lun_mutex); 12657 mutex_exit(&pptr->port_mutex); 12658 12659 mutex_enter(&ptgt->tgt_mutex); 12660 (void) fcp_pass_to_hp(pptr, plun, CIP(old_pip), 12661 FCP_OFFLINE, lcount, tcount, 12662 NDI_DEVI_REMOVE, 0); 12663 mutex_exit(&ptgt->tgt_mutex); 12664 12665 if (pip != NULL) { 12666 FCP_TRACE(fcp_logq, pptr->port_instbuf, 12667 fcp_trace, FCP_BUF_LEVEL_2, 0, 12668 "Old pip=%p; New pip=%p don't match", 12669 old_pip, pip); 12670 } else { 12671 FCP_TRACE(fcp_logq, pptr->port_instbuf, 12672 fcp_trace, FCP_BUF_LEVEL_2, 0, 12673 "Old pip=%p; New pip=NULL don't match", 12674 old_pip); 12675 } 12676 12677 mutex_enter(&pptr->port_mutex); 12678 mutex_enter(&plun->lun_mutex); 12679 } 12680 12681 /* 12682 * Since FC_WWN_SIZE is 8 bytes and its not like the 12683 * lun_guid_size which is dependent on the target, I don't 12684 * believe the same trancation happens here UNLESS the standards 12685 * change the FC_WWN_SIZE value to something larger than 12686 * MAXNAMELEN(currently 255 bytes). 12687 */ 12688 12689 for (i = 0; i < FC_WWN_SIZE; i++) { 12690 (void) sprintf(&buf[i << 1], "%02x", 12691 ptgt->tgt_port_wwn.raw_wwn[i]); 12692 } 12693 12694 (void) snprintf(uaddr, MAXNAMELEN, "w%s,%x", 12695 buf, plun->lun_num); 12696 12697 if (pip == NULL || plun->lun_state & FCP_LUN_CHANGED) { 12698 /* 12699 * Release the locks before calling into 12700 * mdi_pi_alloc_compatible() since this can result in a 12701 * callback into fcp which can result in a deadlock 12702 * (see bug # 4870272). 12703 * 12704 * Basically, what we are trying to avoid is the scenario where 12705 * one thread does ndi_devi_enter() and tries to grab 12706 * fcp_mutex and another does it the other way round. 12707 * 12708 * But before we do that, make sure that nobody releases the 12709 * port in the meantime. We can do this by setting a flag. 12710 */ 12711 plun->lun_state &= ~(FCP_LUN_CHANGED); 12712 pptr->port_state |= FCP_STATE_IN_MDI; 12713 mutex_exit(&plun->lun_mutex); 12714 mutex_exit(&pptr->port_mutex); 12715 if (mdi_pi_alloc_compatible(pdip, nname, plun->lun_guid, 12716 uaddr, compatible, ncompatible, 0, &pip) != MDI_SUCCESS) { 12717 fcp_log(CE_WARN, pptr->port_dip, 12718 "!path alloc failed:0x%x", plun); 12719 mutex_enter(&pptr->port_mutex); 12720 mutex_enter(&plun->lun_mutex); 12721 pptr->port_state &= ~FCP_STATE_IN_MDI; 12722 failure++; 12723 goto end_of_fcp_create_pip; 12724 } 12725 mutex_enter(&pptr->port_mutex); 12726 mutex_enter(&plun->lun_mutex); 12727 pptr->port_state &= ~FCP_STATE_IN_MDI; 12728 } else { 12729 (void) mdi_prop_remove(pip, NULL); 12730 } 12731 12732 mdi_pi_set_phci_private(pip, (caddr_t)plun); 12733 12734 if (mdi_prop_update_byte_array(pip, NODE_WWN_PROP, 12735 ptgt->tgt_node_wwn.raw_wwn, FC_WWN_SIZE) 12736 != DDI_PROP_SUCCESS) { 12737 failure++; 12738 goto end_of_fcp_create_pip; 12739 } 12740 12741 if (mdi_prop_update_byte_array(pip, PORT_WWN_PROP, 12742 ptgt->tgt_port_wwn.raw_wwn, FC_WWN_SIZE) 12743 != DDI_PROP_SUCCESS) { 12744 failure++; 12745 goto end_of_fcp_create_pip; 12746 } 12747 12748 fcp_wwn_to_ascii(ptgt->tgt_port_wwn.raw_wwn, t_pwwn); 12749 t_pwwn[16] = '\0'; 12750 if (mdi_prop_update_string(pip, TGT_PORT_PROP, t_pwwn) 12751 != DDI_PROP_SUCCESS) { 12752 failure++; 12753 goto end_of_fcp_create_pip; 12754 } 12755 12756 /* 12757 * If there is no hard address - We might have to deal with 12758 * that by using WWN - Having said that it is important to 12759 * recognize this problem early so ssd can be informed of 12760 * the right interconnect type. 12761 */ 12762 if (!FC_TOP_EXTERNAL(pptr->port_topology) && 12763 ptgt->tgt_hard_addr != 0) { 12764 tgt_id = (uint32_t) 12765 fcp_alpa_to_switch[ptgt->tgt_hard_addr]; 12766 } else { 12767 tgt_id = ptgt->tgt_d_id; 12768 } 12769 12770 if (mdi_prop_update_int(pip, TARGET_PROP, tgt_id) 12771 != DDI_PROP_SUCCESS) { 12772 failure++; 12773 goto end_of_fcp_create_pip; 12774 } 12775 12776 if (mdi_prop_update_int(pip, LUN_PROP, (int)plun->lun_num) 12777 != DDI_PROP_SUCCESS) { 12778 failure++; 12779 goto end_of_fcp_create_pip; 12780 } 12781 bcopy(&plun->lun_addr, &sam_lun, FCP_LUN_SIZE); 12782 if (mdi_prop_update_int64(pip, SAM_LUN_PROP, sam_lun) 12783 != DDI_PROP_SUCCESS) { 12784 failure++; 12785 goto end_of_fcp_create_pip; 12786 } 12787 12788 end_of_fcp_create_pip: 12789 scsi_hba_nodename_compatible_free(nname, compatible); 12790 12791 if (pip != NULL && failure) { 12792 (void) mdi_prop_remove(pip, NULL); 12793 mutex_exit(&plun->lun_mutex); 12794 mutex_exit(&pptr->port_mutex); 12795 (void) mdi_pi_free(pip, 0); 12796 mutex_enter(&pptr->port_mutex); 12797 mutex_enter(&plun->lun_mutex); 12798 pip = NULL; 12799 } 12800 12801 return (pip); 12802 } 12803 12804 static dev_info_t * 12805 fcp_find_existing_dip(struct fcp_lun *plun, dev_info_t *pdip, caddr_t name) 12806 { 12807 uint_t nbytes; 12808 uchar_t *bytes; 12809 uint_t nwords; 12810 uint32_t tgt_id; 12811 int *words; 12812 dev_info_t *cdip; 12813 dev_info_t *ndip; 12814 struct fcp_tgt *ptgt = plun->lun_tgt; 12815 struct fcp_port *pptr = ptgt->tgt_port; 12816 int circular; 12817 12818 ndi_devi_enter(pdip, &circular); 12819 12820 ndip = (dev_info_t *)DEVI(pdip)->devi_child; 12821 while ((cdip = ndip) != NULL) { 12822 ndip = (dev_info_t *)DEVI(cdip)->devi_sibling; 12823 12824 if (strcmp(DEVI(cdip)->devi_node_name, name)) { 12825 continue; 12826 } 12827 12828 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, cdip, 12829 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, NODE_WWN_PROP, &bytes, 12830 &nbytes) != DDI_PROP_SUCCESS) { 12831 continue; 12832 } 12833 12834 if (nbytes != FC_WWN_SIZE || bytes == NULL) { 12835 if (bytes != NULL) { 12836 ddi_prop_free(bytes); 12837 } 12838 continue; 12839 } 12840 ASSERT(bytes != NULL); 12841 12842 if (bcmp(bytes, ptgt->tgt_node_wwn.raw_wwn, nbytes) != 0) { 12843 ddi_prop_free(bytes); 12844 continue; 12845 } 12846 12847 ddi_prop_free(bytes); 12848 12849 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, cdip, 12850 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, PORT_WWN_PROP, &bytes, 12851 &nbytes) != DDI_PROP_SUCCESS) { 12852 continue; 12853 } 12854 12855 if (nbytes != FC_WWN_SIZE || bytes == NULL) { 12856 if (bytes != NULL) { 12857 ddi_prop_free(bytes); 12858 } 12859 continue; 12860 } 12861 ASSERT(bytes != NULL); 12862 12863 if (bcmp(bytes, ptgt->tgt_port_wwn.raw_wwn, nbytes) != 0) { 12864 ddi_prop_free(bytes); 12865 continue; 12866 } 12867 12868 ddi_prop_free(bytes); 12869 12870 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, cdip, 12871 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, TARGET_PROP, &words, 12872 &nwords) != DDI_PROP_SUCCESS) { 12873 continue; 12874 } 12875 12876 if (nwords != 1 || words == NULL) { 12877 if (words != NULL) { 12878 ddi_prop_free(words); 12879 } 12880 continue; 12881 } 12882 ASSERT(words != NULL); 12883 12884 /* 12885 * If there is no hard address - We might have to deal with 12886 * that by using WWN - Having said that it is important to 12887 * recognize this problem early so ssd can be informed of 12888 * the right interconnect type. 12889 */ 12890 if (!FC_TOP_EXTERNAL(pptr->port_topology) && 12891 ptgt->tgt_hard_addr != 0) { 12892 tgt_id = 12893 (uint32_t)fcp_alpa_to_switch[ptgt->tgt_hard_addr]; 12894 } else { 12895 tgt_id = ptgt->tgt_d_id; 12896 } 12897 12898 if (tgt_id != (uint32_t)*words) { 12899 ddi_prop_free(words); 12900 continue; 12901 } 12902 ddi_prop_free(words); 12903 12904 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, cdip, 12905 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, LUN_PROP, &words, 12906 &nwords) != DDI_PROP_SUCCESS) { 12907 continue; 12908 } 12909 12910 if (nwords != 1 || words == NULL) { 12911 if (words != NULL) { 12912 ddi_prop_free(words); 12913 } 12914 continue; 12915 } 12916 ASSERT(words != NULL); 12917 12918 if (plun->lun_num == (uint16_t)*words) { 12919 ddi_prop_free(words); 12920 break; 12921 } 12922 ddi_prop_free(words); 12923 } 12924 ndi_devi_exit(pdip, circular); 12925 12926 return (cdip); 12927 } 12928 12929 12930 static int 12931 fcp_is_pip_present(struct fcp_lun *plun, mdi_pathinfo_t *pip) 12932 { 12933 dev_info_t *pdip; 12934 char buf[MAXNAMELEN]; 12935 char uaddr[MAXNAMELEN]; 12936 int rval = FC_FAILURE; 12937 12938 ASSERT(MUTEX_HELD(&plun->lun_mutex)); 12939 12940 pdip = plun->lun_tgt->tgt_port->port_dip; 12941 12942 /* 12943 * Check if pip (and not plun->lun_cip) is NULL. plun->lun_cip can be 12944 * non-NULL even when the LUN is not there as in the case when a LUN is 12945 * configured and then deleted on the device end (for T3/T4 case). In 12946 * such cases, pip will be NULL. 12947 * 12948 * If the device generates an RSCN, it will end up getting offlined when 12949 * it disappeared and a new LUN will get created when it is rediscovered 12950 * on the device. If we check for lun_cip here, the LUN will not end 12951 * up getting onlined since this function will end up returning a 12952 * FC_SUCCESS. 12953 * 12954 * The behavior is different on other devices. For instance, on a HDS, 12955 * there was no RSCN generated by the device but the next I/O generated 12956 * a check condition and rediscovery got triggered that way. So, in 12957 * such cases, this path will not be exercised 12958 */ 12959 if (pip == NULL) { 12960 FCP_TRACE(fcp_logq, LUN_PORT->port_instbuf, 12961 fcp_trace, FCP_BUF_LEVEL_4, 0, 12962 "fcp_is_pip_present: plun->lun_cip is NULL: " 12963 "plun: %p lun state: %x num: %d target state: %x", 12964 plun, plun->lun_state, plun->lun_num, 12965 plun->lun_tgt->tgt_port->port_state); 12966 return (rval); 12967 } 12968 12969 fcp_wwn_to_ascii(plun->lun_tgt->tgt_port_wwn.raw_wwn, buf); 12970 12971 (void) snprintf(uaddr, MAXNAMELEN, "w%s,%x", buf, plun->lun_num); 12972 12973 if (plun->lun_old_guid) { 12974 if (mdi_pi_find(pdip, plun->lun_old_guid, uaddr) == pip) { 12975 rval = FC_SUCCESS; 12976 } 12977 } else { 12978 if (mdi_pi_find(pdip, plun->lun_guid, uaddr) == pip) { 12979 rval = FC_SUCCESS; 12980 } 12981 } 12982 return (rval); 12983 } 12984 12985 static mdi_pathinfo_t * 12986 fcp_find_existing_pip(struct fcp_lun *plun, dev_info_t *pdip) 12987 { 12988 char buf[MAXNAMELEN]; 12989 char uaddr[MAXNAMELEN]; 12990 mdi_pathinfo_t *pip; 12991 struct fcp_tgt *ptgt = plun->lun_tgt; 12992 struct fcp_port *pptr = ptgt->tgt_port; 12993 12994 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 12995 12996 fcp_wwn_to_ascii(ptgt->tgt_port_wwn.raw_wwn, buf); 12997 (void) snprintf(uaddr, MAXNAMELEN, "w%s,%x", buf, plun->lun_num); 12998 12999 pip = mdi_pi_find(pdip, plun->lun_guid, uaddr); 13000 13001 return (pip); 13002 } 13003 13004 13005 static int 13006 fcp_online_child(struct fcp_lun *plun, child_info_t *cip, int lcount, 13007 int tcount, int flags, int *circ) 13008 { 13009 int rval; 13010 struct fcp_port *pptr = plun->lun_tgt->tgt_port; 13011 struct fcp_tgt *ptgt = plun->lun_tgt; 13012 dev_info_t *cdip = NULL; 13013 13014 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 13015 ASSERT(MUTEX_HELD(&plun->lun_mutex)); 13016 13017 if (plun->lun_cip == NULL) { 13018 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13019 fcp_trace, FCP_BUF_LEVEL_3, 0, 13020 "fcp_online_child: plun->lun_cip is NULL: " 13021 "plun: %p state: %x num: %d target state: %x", 13022 plun, plun->lun_state, plun->lun_num, 13023 plun->lun_tgt->tgt_port->port_state); 13024 return (NDI_FAILURE); 13025 } 13026 again: 13027 if (plun->lun_mpxio == 0) { 13028 cdip = DIP(cip); 13029 mutex_exit(&plun->lun_mutex); 13030 mutex_exit(&pptr->port_mutex); 13031 13032 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13033 fcp_trace, FCP_BUF_LEVEL_3, 0, 13034 "!Invoking ndi_devi_online for %s: target=%x lun=%x", 13035 ddi_get_name(cdip), ptgt->tgt_d_id, plun->lun_num); 13036 13037 /* 13038 * We could check for FCP_LUN_INIT here but chances 13039 * of getting here when it's already in FCP_LUN_INIT 13040 * is rare and a duplicate ndi_devi_online wouldn't 13041 * hurt either (as the node would already have been 13042 * in CF2) 13043 */ 13044 if (!i_ddi_devi_attached(ddi_get_parent(cdip))) { 13045 rval = ndi_devi_bind_driver(cdip, flags); 13046 } else { 13047 rval = ndi_devi_online(cdip, flags); 13048 } 13049 /* 13050 * We log the message into trace buffer if the device 13051 * is "ses" and into syslog for any other device 13052 * type. This is to prevent the ndi_devi_online failure 13053 * message that appears for V880/A5K ses devices. 13054 */ 13055 if (rval == NDI_SUCCESS) { 13056 mutex_enter(&ptgt->tgt_mutex); 13057 plun->lun_state |= FCP_LUN_INIT; 13058 mutex_exit(&ptgt->tgt_mutex); 13059 } else if (strncmp(ddi_node_name(cdip), "ses", 3) != 0) { 13060 fcp_log(CE_NOTE, pptr->port_dip, 13061 "!ndi_devi_online:" 13062 " failed for %s: target=%x lun=%x %x", 13063 ddi_get_name(cdip), ptgt->tgt_d_id, 13064 plun->lun_num, rval); 13065 } else { 13066 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13067 fcp_trace, FCP_BUF_LEVEL_3, 0, 13068 " !ndi_devi_online:" 13069 " failed for %s: target=%x lun=%x %x", 13070 ddi_get_name(cdip), ptgt->tgt_d_id, 13071 plun->lun_num, rval); 13072 } 13073 } else { 13074 cdip = mdi_pi_get_client(PIP(cip)); 13075 mutex_exit(&plun->lun_mutex); 13076 mutex_exit(&pptr->port_mutex); 13077 13078 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13079 fcp_trace, FCP_BUF_LEVEL_3, 0, 13080 "!Invoking mdi_pi_online for %s: target=%x lun=%x", 13081 ddi_get_name(cdip), ptgt->tgt_d_id, plun->lun_num); 13082 13083 /* 13084 * Hold path and exit phci to avoid deadlock with power 13085 * management code during mdi_pi_online. 13086 */ 13087 mdi_hold_path(PIP(cip)); 13088 mdi_devi_exit_phci(pptr->port_dip, *circ); 13089 13090 rval = mdi_pi_online(PIP(cip), flags); 13091 13092 mdi_devi_enter_phci(pptr->port_dip, circ); 13093 mdi_rele_path(PIP(cip)); 13094 13095 if (rval == MDI_SUCCESS) { 13096 mutex_enter(&ptgt->tgt_mutex); 13097 plun->lun_state |= FCP_LUN_INIT; 13098 mutex_exit(&ptgt->tgt_mutex); 13099 13100 /* 13101 * Clear MPxIO path permanent disable in case 13102 * fcp hotplug dropped the offline event. 13103 */ 13104 (void) mdi_pi_enable_path(PIP(cip), DRIVER_DISABLE); 13105 13106 } else if (rval == MDI_NOT_SUPPORTED) { 13107 child_info_t *old_cip = cip; 13108 13109 /* 13110 * MPxIO does not support this device yet. 13111 * Enumerate in legacy mode. 13112 */ 13113 mutex_enter(&pptr->port_mutex); 13114 mutex_enter(&plun->lun_mutex); 13115 plun->lun_mpxio = 0; 13116 plun->lun_cip = NULL; 13117 cdip = fcp_create_dip(plun, lcount, tcount); 13118 plun->lun_cip = cip = CIP(cdip); 13119 if (cip == NULL) { 13120 fcp_log(CE_WARN, pptr->port_dip, 13121 "!fcp_online_child: " 13122 "Create devinfo failed for LU=%p", plun); 13123 mutex_exit(&plun->lun_mutex); 13124 13125 mutex_enter(&ptgt->tgt_mutex); 13126 plun->lun_state |= FCP_LUN_OFFLINE; 13127 mutex_exit(&ptgt->tgt_mutex); 13128 13129 mutex_exit(&pptr->port_mutex); 13130 13131 /* 13132 * free the mdi_pathinfo node 13133 */ 13134 (void) mdi_pi_free(PIP(old_cip), 0); 13135 } else { 13136 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13137 fcp_trace, FCP_BUF_LEVEL_3, 0, 13138 "fcp_online_child: creating devinfo " 13139 "node 0x%p for plun 0x%p", 13140 cip, plun); 13141 mutex_exit(&plun->lun_mutex); 13142 mutex_exit(&pptr->port_mutex); 13143 /* 13144 * free the mdi_pathinfo node 13145 */ 13146 (void) mdi_pi_free(PIP(old_cip), 0); 13147 mutex_enter(&pptr->port_mutex); 13148 mutex_enter(&plun->lun_mutex); 13149 goto again; 13150 } 13151 } else { 13152 if (cdip) { 13153 fcp_log(CE_NOTE, pptr->port_dip, 13154 "!fcp_online_child: mdi_pi_online:" 13155 " failed for %s: target=%x lun=%x %x", 13156 ddi_get_name(cdip), ptgt->tgt_d_id, 13157 plun->lun_num, rval); 13158 } 13159 } 13160 rval = (rval == MDI_SUCCESS) ? NDI_SUCCESS : NDI_FAILURE; 13161 } 13162 13163 if (rval == NDI_SUCCESS) { 13164 if (cdip) { 13165 (void) ndi_event_retrieve_cookie( 13166 pptr->port_ndi_event_hdl, cdip, FCAL_INSERT_EVENT, 13167 &fcp_insert_eid, NDI_EVENT_NOPASS); 13168 (void) ndi_event_run_callbacks(pptr->port_ndi_event_hdl, 13169 cdip, fcp_insert_eid, NULL); 13170 } 13171 } 13172 mutex_enter(&pptr->port_mutex); 13173 mutex_enter(&plun->lun_mutex); 13174 return (rval); 13175 } 13176 13177 /* ARGSUSED */ 13178 static int 13179 fcp_offline_child(struct fcp_lun *plun, child_info_t *cip, int lcount, 13180 int tcount, int flags, int *circ) 13181 { 13182 int rval; 13183 struct fcp_port *pptr = plun->lun_tgt->tgt_port; 13184 struct fcp_tgt *ptgt = plun->lun_tgt; 13185 dev_info_t *cdip; 13186 13187 ASSERT(MUTEX_HELD(&plun->lun_mutex)); 13188 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 13189 13190 if (plun->lun_cip == NULL) { 13191 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13192 fcp_trace, FCP_BUF_LEVEL_3, 0, 13193 "fcp_offline_child: plun->lun_cip is NULL: " 13194 "plun: %p lun state: %x num: %d target state: %x", 13195 plun, plun->lun_state, plun->lun_num, 13196 plun->lun_tgt->tgt_port->port_state); 13197 return (NDI_FAILURE); 13198 } 13199 13200 if (plun->lun_mpxio == 0) { 13201 cdip = DIP(cip); 13202 mutex_exit(&plun->lun_mutex); 13203 mutex_exit(&pptr->port_mutex); 13204 rval = ndi_devi_offline(DIP(cip), flags); 13205 if (rval != NDI_SUCCESS) { 13206 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13207 fcp_trace, FCP_BUF_LEVEL_3, 0, 13208 "fcp_offline_child: ndi_devi_offline failed " 13209 "rval=%x cip=%p", rval, cip); 13210 } 13211 } else { 13212 cdip = mdi_pi_get_client(PIP(cip)); 13213 mutex_exit(&plun->lun_mutex); 13214 mutex_exit(&pptr->port_mutex); 13215 13216 /* 13217 * Exit phci to avoid deadlock with power management code 13218 * during mdi_pi_offline 13219 */ 13220 mdi_hold_path(PIP(cip)); 13221 mdi_devi_exit_phci(pptr->port_dip, *circ); 13222 13223 rval = mdi_pi_offline(PIP(cip), flags); 13224 13225 mdi_devi_enter_phci(pptr->port_dip, circ); 13226 mdi_rele_path(PIP(cip)); 13227 13228 if (rval == MDI_SUCCESS) { 13229 /* 13230 * Clear MPxIO path permanent disable as the path is 13231 * already offlined. 13232 */ 13233 (void) mdi_pi_enable_path(PIP(cip), DRIVER_DISABLE); 13234 13235 if (flags & NDI_DEVI_REMOVE) { 13236 (void) mdi_pi_free(PIP(cip), 0); 13237 } 13238 } else { 13239 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13240 fcp_trace, FCP_BUF_LEVEL_3, 0, 13241 "fcp_offline_child: mdi_pi_offline failed " 13242 "rval=%x cip=%p", rval, cip); 13243 } 13244 rval = (rval == MDI_SUCCESS) ? NDI_SUCCESS : NDI_FAILURE; 13245 } 13246 13247 mutex_enter(&ptgt->tgt_mutex); 13248 plun->lun_state &= ~FCP_LUN_INIT; 13249 mutex_exit(&ptgt->tgt_mutex); 13250 13251 mutex_enter(&pptr->port_mutex); 13252 mutex_enter(&plun->lun_mutex); 13253 13254 if (rval == NDI_SUCCESS) { 13255 cdip = NULL; 13256 if (flags & NDI_DEVI_REMOVE) { 13257 /* 13258 * If the guid of the LUN changes, lun_cip will not 13259 * equal to cip, and after offlining the LUN with the 13260 * old guid, we should keep lun_cip since it's the cip 13261 * of the LUN with the new guid. 13262 * Otherwise remove our reference to child node. 13263 */ 13264 if (plun->lun_cip == cip) { 13265 plun->lun_cip = NULL; 13266 } 13267 if (plun->lun_old_guid) { 13268 kmem_free(plun->lun_old_guid, 13269 plun->lun_old_guid_size); 13270 plun->lun_old_guid = NULL; 13271 plun->lun_old_guid_size = 0; 13272 } 13273 } 13274 } 13275 13276 if (cdip) { 13277 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13278 fcp_trace, FCP_BUF_LEVEL_3, 0, "!%s failed for %s:" 13279 " target=%x lun=%x", "ndi_offline", 13280 ddi_get_name(cdip), ptgt->tgt_d_id, plun->lun_num); 13281 } 13282 13283 return (rval); 13284 } 13285 13286 static void 13287 fcp_remove_child(struct fcp_lun *plun) 13288 { 13289 ASSERT(MUTEX_HELD(&plun->lun_mutex)); 13290 13291 if (fcp_is_child_present(plun, plun->lun_cip) == FC_SUCCESS) { 13292 if (plun->lun_mpxio == 0) { 13293 (void) ndi_prop_remove_all(DIP(plun->lun_cip)); 13294 (void) ndi_devi_free(DIP(plun->lun_cip)); 13295 } else { 13296 mutex_exit(&plun->lun_mutex); 13297 mutex_exit(&plun->lun_tgt->tgt_mutex); 13298 mutex_exit(&plun->lun_tgt->tgt_port->port_mutex); 13299 FCP_TRACE(fcp_logq, 13300 plun->lun_tgt->tgt_port->port_instbuf, 13301 fcp_trace, FCP_BUF_LEVEL_3, 0, 13302 "lun=%p pip freed %p", plun, plun->lun_cip); 13303 (void) mdi_prop_remove(PIP(plun->lun_cip), NULL); 13304 (void) mdi_pi_free(PIP(plun->lun_cip), 0); 13305 mutex_enter(&plun->lun_tgt->tgt_port->port_mutex); 13306 mutex_enter(&plun->lun_tgt->tgt_mutex); 13307 mutex_enter(&plun->lun_mutex); 13308 } 13309 } 13310 13311 plun->lun_cip = NULL; 13312 } 13313 13314 /* 13315 * called when a timeout occurs 13316 * 13317 * can be scheduled during an attach or resume (if not already running) 13318 * 13319 * one timeout is set up for all ports 13320 * 13321 * acquires and releases the global mutex 13322 */ 13323 /*ARGSUSED*/ 13324 static void 13325 fcp_watch(void *arg) 13326 { 13327 struct fcp_port *pptr; 13328 struct fcp_ipkt *icmd; 13329 struct fcp_ipkt *nicmd; 13330 struct fcp_pkt *cmd; 13331 struct fcp_pkt *ncmd; 13332 struct fcp_pkt *tail; 13333 struct fcp_pkt *pcmd; 13334 struct fcp_pkt *save_head; 13335 struct fcp_port *save_port; 13336 13337 /* increment global watchdog time */ 13338 fcp_watchdog_time += fcp_watchdog_timeout; 13339 13340 mutex_enter(&fcp_global_mutex); 13341 13342 /* scan each port in our list */ 13343 for (pptr = fcp_port_head; pptr != NULL; pptr = pptr->port_next) { 13344 save_port = fcp_port_head; 13345 pptr->port_state |= FCP_STATE_IN_WATCHDOG; 13346 mutex_exit(&fcp_global_mutex); 13347 13348 mutex_enter(&pptr->port_mutex); 13349 if (pptr->port_ipkt_list == NULL && 13350 (pptr->port_state & (FCP_STATE_SUSPENDED | 13351 FCP_STATE_DETACHING | FCP_STATE_POWER_DOWN))) { 13352 pptr->port_state &= ~FCP_STATE_IN_WATCHDOG; 13353 mutex_exit(&pptr->port_mutex); 13354 mutex_enter(&fcp_global_mutex); 13355 goto end_of_watchdog; 13356 } 13357 13358 /* 13359 * We check if a list of targets need to be offlined. 13360 */ 13361 if (pptr->port_offline_tgts) { 13362 fcp_scan_offline_tgts(pptr); 13363 } 13364 13365 /* 13366 * We check if a list of luns need to be offlined. 13367 */ 13368 if (pptr->port_offline_luns) { 13369 fcp_scan_offline_luns(pptr); 13370 } 13371 13372 /* 13373 * We check if a list of targets or luns need to be reset. 13374 */ 13375 if (pptr->port_reset_list) { 13376 fcp_check_reset_delay(pptr); 13377 } 13378 13379 mutex_exit(&pptr->port_mutex); 13380 13381 /* 13382 * This is where the pending commands (pkt) are checked for 13383 * timeout. 13384 */ 13385 mutex_enter(&pptr->port_pkt_mutex); 13386 tail = pptr->port_pkt_tail; 13387 13388 for (pcmd = NULL, cmd = pptr->port_pkt_head; 13389 cmd != NULL; cmd = ncmd) { 13390 ncmd = cmd->cmd_next; 13391 /* 13392 * If a command is in this queue the bit CFLAG_IN_QUEUE 13393 * must be set. 13394 */ 13395 ASSERT(cmd->cmd_flags & CFLAG_IN_QUEUE); 13396 /* 13397 * FCP_INVALID_TIMEOUT will be set for those 13398 * command that need to be failed. Mostly those 13399 * cmds that could not be queued down for the 13400 * "timeout" value. cmd->cmd_timeout is used 13401 * to try and requeue the command regularly. 13402 */ 13403 if (cmd->cmd_timeout >= fcp_watchdog_time) { 13404 /* 13405 * This command hasn't timed out yet. Let's 13406 * go to the next one. 13407 */ 13408 pcmd = cmd; 13409 goto end_of_loop; 13410 } 13411 13412 if (cmd == pptr->port_pkt_head) { 13413 ASSERT(pcmd == NULL); 13414 pptr->port_pkt_head = cmd->cmd_next; 13415 } else { 13416 ASSERT(pcmd != NULL); 13417 pcmd->cmd_next = cmd->cmd_next; 13418 } 13419 13420 if (cmd == pptr->port_pkt_tail) { 13421 ASSERT(cmd->cmd_next == NULL); 13422 pptr->port_pkt_tail = pcmd; 13423 if (pcmd) { 13424 pcmd->cmd_next = NULL; 13425 } 13426 } 13427 cmd->cmd_next = NULL; 13428 13429 /* 13430 * save the current head before dropping the 13431 * mutex - If the head doesn't remain the 13432 * same after re acquiring the mutex, just 13433 * bail out and revisit on next tick. 13434 * 13435 * PS: The tail pointer can change as the commands 13436 * get requeued after failure to retransport 13437 */ 13438 save_head = pptr->port_pkt_head; 13439 mutex_exit(&pptr->port_pkt_mutex); 13440 13441 if (cmd->cmd_fp_pkt->pkt_timeout == 13442 FCP_INVALID_TIMEOUT) { 13443 struct scsi_pkt *pkt = cmd->cmd_pkt; 13444 struct fcp_lun *plun; 13445 struct fcp_tgt *ptgt; 13446 13447 plun = ADDR2LUN(&pkt->pkt_address); 13448 ptgt = plun->lun_tgt; 13449 13450 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13451 fcp_trace, FCP_BUF_LEVEL_2, 0, 13452 "SCSI cmd 0x%x to D_ID=%x timed out", 13453 pkt->pkt_cdbp[0], ptgt->tgt_d_id); 13454 13455 cmd->cmd_state == FCP_PKT_ABORTING ? 13456 fcp_fail_cmd(cmd, CMD_RESET, 13457 STAT_DEV_RESET) : fcp_fail_cmd(cmd, 13458 CMD_TIMEOUT, STAT_ABORTED); 13459 } else { 13460 fcp_retransport_cmd(pptr, cmd); 13461 } 13462 mutex_enter(&pptr->port_pkt_mutex); 13463 if (save_head && save_head != pptr->port_pkt_head) { 13464 /* 13465 * Looks like linked list got changed (mostly 13466 * happens when an an OFFLINE LUN code starts 13467 * returning overflow queue commands in 13468 * parallel. So bail out and revisit during 13469 * next tick 13470 */ 13471 break; 13472 } 13473 end_of_loop: 13474 /* 13475 * Scan only upto the previously known tail pointer 13476 * to avoid excessive processing - lots of new packets 13477 * could have been added to the tail or the old ones 13478 * re-queued. 13479 */ 13480 if (cmd == tail) { 13481 break; 13482 } 13483 } 13484 mutex_exit(&pptr->port_pkt_mutex); 13485 13486 mutex_enter(&pptr->port_mutex); 13487 for (icmd = pptr->port_ipkt_list; icmd != NULL; icmd = nicmd) { 13488 struct fcp_tgt *ptgt = icmd->ipkt_tgt; 13489 13490 nicmd = icmd->ipkt_next; 13491 if ((icmd->ipkt_restart != 0) && 13492 (icmd->ipkt_restart >= fcp_watchdog_time)) { 13493 /* packet has not timed out */ 13494 continue; 13495 } 13496 13497 /* time for packet re-transport */ 13498 if (icmd == pptr->port_ipkt_list) { 13499 pptr->port_ipkt_list = icmd->ipkt_next; 13500 if (pptr->port_ipkt_list) { 13501 pptr->port_ipkt_list->ipkt_prev = 13502 NULL; 13503 } 13504 } else { 13505 icmd->ipkt_prev->ipkt_next = icmd->ipkt_next; 13506 if (icmd->ipkt_next) { 13507 icmd->ipkt_next->ipkt_prev = 13508 icmd->ipkt_prev; 13509 } 13510 } 13511 icmd->ipkt_next = NULL; 13512 icmd->ipkt_prev = NULL; 13513 mutex_exit(&pptr->port_mutex); 13514 13515 if (fcp_is_retryable(icmd)) { 13516 fc_ulp_rscn_info_t *rscnp = 13517 (fc_ulp_rscn_info_t *)icmd->ipkt_fpkt-> 13518 pkt_ulp_rscn_infop; 13519 13520 FCP_TRACE(fcp_logq, pptr->port_instbuf, 13521 fcp_trace, FCP_BUF_LEVEL_2, 0, 13522 "%x to D_ID=%x Retrying..", 13523 icmd->ipkt_opcode, 13524 icmd->ipkt_fpkt->pkt_cmd_fhdr.d_id); 13525 13526 /* 13527 * Update the RSCN count in the packet 13528 * before resending. 13529 */ 13530 13531 if (rscnp != NULL) { 13532 rscnp->ulp_rscn_count = 13533 fc_ulp_get_rscn_count(pptr-> 13534 port_fp_handle); 13535 } 13536 13537 mutex_enter(&pptr->port_mutex); 13538 mutex_enter(&ptgt->tgt_mutex); 13539 if (!FCP_STATE_CHANGED(pptr, ptgt, icmd)) { 13540 mutex_exit(&ptgt->tgt_mutex); 13541 mutex_exit(&pptr->port_mutex); 13542 switch (icmd->ipkt_opcode) { 13543 int rval; 13544 case LA_ELS_PLOGI: 13545 if ((rval = fc_ulp_login( 13546 pptr->port_fp_handle, 13547 &icmd->ipkt_fpkt, 1)) == 13548 FC_SUCCESS) { 13549 mutex_enter( 13550 &pptr->port_mutex); 13551 continue; 13552 } 13553 if (fcp_handle_ipkt_errors( 13554 pptr, ptgt, icmd, rval, 13555 "PLOGI") == DDI_SUCCESS) { 13556 mutex_enter( 13557 &pptr->port_mutex); 13558 continue; 13559 } 13560 break; 13561 13562 case LA_ELS_PRLI: 13563 if ((rval = fc_ulp_issue_els( 13564 pptr->port_fp_handle, 13565 icmd->ipkt_fpkt)) == 13566 FC_SUCCESS) { 13567 mutex_enter( 13568 &pptr->port_mutex); 13569 continue; 13570 } 13571 if (fcp_handle_ipkt_errors( 13572 pptr, ptgt, icmd, rval, 13573 "PRLI") == DDI_SUCCESS) { 13574 mutex_enter( 13575 &pptr->port_mutex); 13576 continue; 13577 } 13578 break; 13579 13580 default: 13581 if ((rval = fcp_transport( 13582 pptr->port_fp_handle, 13583 icmd->ipkt_fpkt, 1)) == 13584 FC_SUCCESS) { 13585 mutex_enter( 13586 &pptr->port_mutex); 13587 continue; 13588 } 13589 if (fcp_handle_ipkt_errors( 13590 pptr, ptgt, icmd, rval, 13591 "PRLI") == DDI_SUCCESS) { 13592 mutex_enter( 13593 &pptr->port_mutex); 13594 continue; 13595 } 13596 break; 13597 } 13598 } else { 13599 mutex_exit(&ptgt->tgt_mutex); 13600 mutex_exit(&pptr->port_mutex); 13601 } 13602 } else { 13603 fcp_print_error(icmd->ipkt_fpkt); 13604 } 13605 13606 (void) fcp_call_finish_init(pptr, ptgt, 13607 icmd->ipkt_link_cnt, icmd->ipkt_change_cnt, 13608 icmd->ipkt_cause); 13609 fcp_icmd_free(pptr, icmd); 13610 mutex_enter(&pptr->port_mutex); 13611 } 13612 13613 pptr->port_state &= ~FCP_STATE_IN_WATCHDOG; 13614 mutex_exit(&pptr->port_mutex); 13615 mutex_enter(&fcp_global_mutex); 13616 13617 end_of_watchdog: 13618 /* 13619 * Bail out early before getting into trouble 13620 */ 13621 if (save_port != fcp_port_head) { 13622 break; 13623 } 13624 } 13625 13626 if (fcp_watchdog_init > 0) { 13627 /* reschedule timeout to go again */ 13628 fcp_watchdog_id = 13629 timeout(fcp_watch, NULL, fcp_watchdog_tick); 13630 } 13631 mutex_exit(&fcp_global_mutex); 13632 } 13633 13634 13635 static void 13636 fcp_check_reset_delay(struct fcp_port *pptr) 13637 { 13638 uint32_t tgt_cnt; 13639 int level; 13640 struct fcp_tgt *ptgt; 13641 struct fcp_lun *plun; 13642 struct fcp_reset_elem *cur = NULL; 13643 struct fcp_reset_elem *next = NULL; 13644 struct fcp_reset_elem *prev = NULL; 13645 13646 ASSERT(mutex_owned(&pptr->port_mutex)); 13647 13648 next = pptr->port_reset_list; 13649 while ((cur = next) != NULL) { 13650 next = cur->next; 13651 13652 if (cur->timeout < fcp_watchdog_time) { 13653 prev = cur; 13654 continue; 13655 } 13656 13657 ptgt = cur->tgt; 13658 plun = cur->lun; 13659 tgt_cnt = cur->tgt_cnt; 13660 13661 if (ptgt) { 13662 level = RESET_TARGET; 13663 } else { 13664 ASSERT(plun != NULL); 13665 level = RESET_LUN; 13666 ptgt = plun->lun_tgt; 13667 } 13668 if (prev) { 13669 prev->next = next; 13670 } else { 13671 /* 13672 * Because we drop port mutex while doing aborts for 13673 * packets, we can't rely on reset_list pointing to 13674 * our head 13675 */ 13676 if (cur == pptr->port_reset_list) { 13677 pptr->port_reset_list = next; 13678 } else { 13679 struct fcp_reset_elem *which; 13680 13681 which = pptr->port_reset_list; 13682 while (which && which->next != cur) { 13683 which = which->next; 13684 } 13685 ASSERT(which != NULL); 13686 13687 which->next = next; 13688 prev = which; 13689 } 13690 } 13691 13692 kmem_free(cur, sizeof (*cur)); 13693 13694 if (tgt_cnt == ptgt->tgt_change_cnt) { 13695 mutex_enter(&ptgt->tgt_mutex); 13696 if (level == RESET_TARGET) { 13697 fcp_update_tgt_state(ptgt, 13698 FCP_RESET, FCP_LUN_BUSY); 13699 } else { 13700 fcp_update_lun_state(plun, 13701 FCP_RESET, FCP_LUN_BUSY); 13702 } 13703 mutex_exit(&ptgt->tgt_mutex); 13704 13705 mutex_exit(&pptr->port_mutex); 13706 fcp_abort_all(pptr, ptgt, plun, tgt_cnt); 13707 mutex_enter(&pptr->port_mutex); 13708 } 13709 } 13710 } 13711 13712 13713 static void 13714 fcp_abort_all(struct fcp_port *pptr, struct fcp_tgt *ttgt, 13715 struct fcp_lun *rlun, int tgt_cnt) 13716 { 13717 int rval; 13718 struct fcp_lun *tlun, *nlun; 13719 struct fcp_pkt *pcmd = NULL, *ncmd = NULL, 13720 *cmd = NULL, *head = NULL, 13721 *tail = NULL; 13722 13723 mutex_enter(&pptr->port_pkt_mutex); 13724 for (cmd = pptr->port_pkt_head; cmd != NULL; cmd = ncmd) { 13725 struct fcp_lun *plun = ADDR2LUN(&cmd->cmd_pkt->pkt_address); 13726 struct fcp_tgt *ptgt = plun->lun_tgt; 13727 13728 ncmd = cmd->cmd_next; 13729 13730 if (ptgt != ttgt && plun != rlun) { 13731 pcmd = cmd; 13732 continue; 13733 } 13734 13735 if (pcmd != NULL) { 13736 ASSERT(pptr->port_pkt_head != cmd); 13737 pcmd->cmd_next = ncmd; 13738 } else { 13739 ASSERT(cmd == pptr->port_pkt_head); 13740 pptr->port_pkt_head = ncmd; 13741 } 13742 if (pptr->port_pkt_tail == cmd) { 13743 ASSERT(cmd->cmd_next == NULL); 13744 pptr->port_pkt_tail = pcmd; 13745 if (pcmd != NULL) { 13746 pcmd->cmd_next = NULL; 13747 } 13748 } 13749 13750 if (head == NULL) { 13751 head = tail = cmd; 13752 } else { 13753 ASSERT(tail != NULL); 13754 tail->cmd_next = cmd; 13755 tail = cmd; 13756 } 13757 cmd->cmd_next = NULL; 13758 } 13759 mutex_exit(&pptr->port_pkt_mutex); 13760 13761 for (cmd = head; cmd != NULL; cmd = ncmd) { 13762 struct scsi_pkt *pkt = cmd->cmd_pkt; 13763 13764 ncmd = cmd->cmd_next; 13765 ASSERT(pkt != NULL); 13766 13767 mutex_enter(&pptr->port_mutex); 13768 if (ttgt->tgt_change_cnt == tgt_cnt) { 13769 mutex_exit(&pptr->port_mutex); 13770 cmd->cmd_flags &= ~CFLAG_IN_QUEUE; 13771 pkt->pkt_reason = CMD_RESET; 13772 pkt->pkt_statistics |= STAT_DEV_RESET; 13773 cmd->cmd_state = FCP_PKT_IDLE; 13774 fcp_post_callback(cmd); 13775 } else { 13776 mutex_exit(&pptr->port_mutex); 13777 } 13778 } 13779 13780 /* 13781 * If the FCA will return all the commands in its queue then our 13782 * work is easy, just return. 13783 */ 13784 13785 if (pptr->port_reset_action == FC_RESET_RETURN_ALL) { 13786 return; 13787 } 13788 13789 /* 13790 * For RESET_LUN get hold of target pointer 13791 */ 13792 if (ttgt == NULL) { 13793 ASSERT(rlun != NULL); 13794 13795 ttgt = rlun->lun_tgt; 13796 13797 ASSERT(ttgt != NULL); 13798 } 13799 13800 /* 13801 * There are some severe race conditions here. 13802 * While we are trying to abort the pkt, it might be completing 13803 * so mark it aborted and if the abort does not succeed then 13804 * handle it in the watch thread. 13805 */ 13806 mutex_enter(&ttgt->tgt_mutex); 13807 nlun = ttgt->tgt_lun; 13808 mutex_exit(&ttgt->tgt_mutex); 13809 while ((tlun = nlun) != NULL) { 13810 int restart = 0; 13811 if (rlun && rlun != tlun) { 13812 mutex_enter(&ttgt->tgt_mutex); 13813 nlun = tlun->lun_next; 13814 mutex_exit(&ttgt->tgt_mutex); 13815 continue; 13816 } 13817 mutex_enter(&tlun->lun_mutex); 13818 cmd = tlun->lun_pkt_head; 13819 while (cmd != NULL) { 13820 if (cmd->cmd_state == FCP_PKT_ISSUED) { 13821 struct scsi_pkt *pkt; 13822 13823 restart = 1; 13824 cmd->cmd_state = FCP_PKT_ABORTING; 13825 mutex_exit(&tlun->lun_mutex); 13826 rval = fc_ulp_abort(pptr->port_fp_handle, 13827 cmd->cmd_fp_pkt, KM_SLEEP); 13828 if (rval == FC_SUCCESS) { 13829 pkt = cmd->cmd_pkt; 13830 pkt->pkt_reason = CMD_RESET; 13831 pkt->pkt_statistics |= STAT_DEV_RESET; 13832 cmd->cmd_state = FCP_PKT_IDLE; 13833 fcp_post_callback(cmd); 13834 } else { 13835 caddr_t msg; 13836 13837 (void) fc_ulp_error(rval, &msg); 13838 13839 /* 13840 * This part is tricky. The abort 13841 * failed and now the command could 13842 * be completing. The cmd_state == 13843 * FCP_PKT_ABORTING should save 13844 * us in fcp_cmd_callback. If we 13845 * are already aborting ignore the 13846 * command in fcp_cmd_callback. 13847 * Here we leave this packet for 20 13848 * sec to be aborted in the 13849 * fcp_watch thread. 13850 */ 13851 fcp_log(CE_WARN, pptr->port_dip, 13852 "!Abort failed after reset %s", 13853 msg); 13854 13855 cmd->cmd_timeout = 13856 fcp_watchdog_time + 13857 cmd->cmd_pkt->pkt_time + 13858 FCP_FAILED_DELAY; 13859 13860 cmd->cmd_fp_pkt->pkt_timeout = 13861 FCP_INVALID_TIMEOUT; 13862 /* 13863 * This is a hack, cmd is put in the 13864 * overflow queue so that it can be 13865 * timed out finally 13866 */ 13867 cmd->cmd_flags |= CFLAG_IN_QUEUE; 13868 13869 mutex_enter(&pptr->port_pkt_mutex); 13870 if (pptr->port_pkt_head) { 13871 ASSERT(pptr->port_pkt_tail 13872 != NULL); 13873 pptr->port_pkt_tail->cmd_next 13874 = cmd; 13875 pptr->port_pkt_tail = cmd; 13876 } else { 13877 ASSERT(pptr->port_pkt_tail 13878 == NULL); 13879 pptr->port_pkt_head = 13880 pptr->port_pkt_tail 13881 = cmd; 13882 } 13883 cmd->cmd_next = NULL; 13884 mutex_exit(&pptr->port_pkt_mutex); 13885 } 13886 mutex_enter(&tlun->lun_mutex); 13887 cmd = tlun->lun_pkt_head; 13888 } else { 13889 cmd = cmd->cmd_forw; 13890 } 13891 } 13892 mutex_exit(&tlun->lun_mutex); 13893 13894 mutex_enter(&ttgt->tgt_mutex); 13895 restart == 1 ? (nlun = ttgt->tgt_lun) : (nlun = tlun->lun_next); 13896 mutex_exit(&ttgt->tgt_mutex); 13897 13898 mutex_enter(&pptr->port_mutex); 13899 if (tgt_cnt != ttgt->tgt_change_cnt) { 13900 mutex_exit(&pptr->port_mutex); 13901 return; 13902 } else { 13903 mutex_exit(&pptr->port_mutex); 13904 } 13905 } 13906 } 13907 13908 13909 /* 13910 * unlink the soft state, returning the soft state found (if any) 13911 * 13912 * acquires and releases the global mutex 13913 */ 13914 struct fcp_port * 13915 fcp_soft_state_unlink(struct fcp_port *pptr) 13916 { 13917 struct fcp_port *hptr; /* ptr index */ 13918 struct fcp_port *tptr; /* prev hptr */ 13919 13920 mutex_enter(&fcp_global_mutex); 13921 for (hptr = fcp_port_head, tptr = NULL; 13922 hptr != NULL; 13923 tptr = hptr, hptr = hptr->port_next) { 13924 if (hptr == pptr) { 13925 /* we found a match -- remove this item */ 13926 if (tptr == NULL) { 13927 /* we're at the head of the list */ 13928 fcp_port_head = hptr->port_next; 13929 } else { 13930 tptr->port_next = hptr->port_next; 13931 } 13932 break; /* success */ 13933 } 13934 } 13935 if (fcp_port_head == NULL) { 13936 fcp_cleanup_blacklist(&fcp_lun_blacklist); 13937 } 13938 mutex_exit(&fcp_global_mutex); 13939 return (hptr); 13940 } 13941 13942 13943 /* 13944 * called by fcp_scsi_hba_tgt_init to find a LUN given a 13945 * WWN and a LUN number 13946 */ 13947 /* ARGSUSED */ 13948 static struct fcp_lun * 13949 fcp_lookup_lun(struct fcp_port *pptr, uchar_t *wwn, uint16_t lun) 13950 { 13951 int hash; 13952 struct fcp_tgt *ptgt; 13953 struct fcp_lun *plun; 13954 13955 ASSERT(mutex_owned(&pptr->port_mutex)); 13956 13957 hash = FCP_HASH(wwn); 13958 for (ptgt = pptr->port_tgt_hash_table[hash]; ptgt != NULL; 13959 ptgt = ptgt->tgt_next) { 13960 if (bcmp((caddr_t)wwn, (caddr_t)&ptgt->tgt_port_wwn.raw_wwn[0], 13961 sizeof (ptgt->tgt_port_wwn)) == 0) { 13962 mutex_enter(&ptgt->tgt_mutex); 13963 for (plun = ptgt->tgt_lun; 13964 plun != NULL; 13965 plun = plun->lun_next) { 13966 if (plun->lun_num == lun) { 13967 mutex_exit(&ptgt->tgt_mutex); 13968 return (plun); 13969 } 13970 } 13971 mutex_exit(&ptgt->tgt_mutex); 13972 return (NULL); 13973 } 13974 } 13975 return (NULL); 13976 } 13977 13978 /* 13979 * Function: fcp_prepare_pkt 13980 * 13981 * Description: This function prepares the SCSI cmd pkt, passed by the caller, 13982 * for fcp_start(). It binds the data or partially maps it. 13983 * Builds the FCP header and starts the initialization of the 13984 * Fibre Channel header. 13985 * 13986 * Argument: *pptr FCP port. 13987 * *cmd FCP packet. 13988 * *plun LUN the command will be sent to. 13989 * 13990 * Context: User, Kernel and Interrupt context. 13991 */ 13992 static void 13993 fcp_prepare_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd, 13994 struct fcp_lun *plun) 13995 { 13996 fc_packet_t *fpkt = cmd->cmd_fp_pkt; 13997 struct fcp_tgt *ptgt = plun->lun_tgt; 13998 struct fcp_cmd *fcmd = &cmd->cmd_fcp_cmd; 13999 14000 ASSERT(cmd->cmd_pkt->pkt_comp || 14001 (cmd->cmd_pkt->pkt_flags & FLAG_NOINTR)); 14002 14003 if (cmd->cmd_pkt->pkt_numcookies) { 14004 if (cmd->cmd_pkt->pkt_dma_flags & DDI_DMA_READ) { 14005 fcmd->fcp_cntl.cntl_read_data = 1; 14006 fcmd->fcp_cntl.cntl_write_data = 0; 14007 fpkt->pkt_tran_type = FC_PKT_FCP_READ; 14008 } else { 14009 fcmd->fcp_cntl.cntl_read_data = 0; 14010 fcmd->fcp_cntl.cntl_write_data = 1; 14011 fpkt->pkt_tran_type = FC_PKT_FCP_WRITE; 14012 } 14013 14014 fpkt->pkt_data_cookie = cmd->cmd_pkt->pkt_cookies; 14015 14016 fpkt->pkt_data_cookie_cnt = cmd->cmd_pkt->pkt_numcookies; 14017 ASSERT(fpkt->pkt_data_cookie_cnt <= 14018 pptr->port_data_dma_attr.dma_attr_sgllen); 14019 14020 cmd->cmd_dmacount = cmd->cmd_pkt->pkt_dma_len; 14021 14022 /* FCA needs pkt_datalen to be set */ 14023 fpkt->pkt_datalen = cmd->cmd_dmacount; 14024 fcmd->fcp_data_len = cmd->cmd_dmacount; 14025 } else { 14026 fcmd->fcp_cntl.cntl_read_data = 0; 14027 fcmd->fcp_cntl.cntl_write_data = 0; 14028 fpkt->pkt_tran_type = FC_PKT_EXCHANGE; 14029 fpkt->pkt_datalen = 0; 14030 fcmd->fcp_data_len = 0; 14031 } 14032 14033 /* set up the Tagged Queuing type */ 14034 if (cmd->cmd_pkt->pkt_flags & FLAG_HTAG) { 14035 fcmd->fcp_cntl.cntl_qtype = FCP_QTYPE_HEAD_OF_Q; 14036 } else if (cmd->cmd_pkt->pkt_flags & FLAG_OTAG) { 14037 fcmd->fcp_cntl.cntl_qtype = FCP_QTYPE_ORDERED; 14038 } else if (cmd->cmd_pkt->pkt_flags & FLAG_STAG) { 14039 fcmd->fcp_cntl.cntl_qtype = FCP_QTYPE_SIMPLE; 14040 } else { 14041 fcmd->fcp_cntl.cntl_qtype = FCP_QTYPE_UNTAGGED; 14042 } 14043 14044 fcmd->fcp_ent_addr = plun->lun_addr; 14045 14046 if (pptr->port_fcp_dma != FC_NO_DVMA_SPACE) { 14047 FCP_CP_OUT((uint8_t *)fcmd, fpkt->pkt_cmd, 14048 fpkt->pkt_cmd_acc, sizeof (struct fcp_cmd)); 14049 } else { 14050 ASSERT(fpkt->pkt_cmd_dma == NULL && fpkt->pkt_resp_dma == NULL); 14051 } 14052 14053 cmd->cmd_pkt->pkt_reason = CMD_CMPLT; 14054 cmd->cmd_pkt->pkt_state = 0; 14055 cmd->cmd_pkt->pkt_statistics = 0; 14056 cmd->cmd_pkt->pkt_resid = 0; 14057 14058 cmd->cmd_fp_pkt->pkt_data_dma = cmd->cmd_pkt->pkt_handle; 14059 14060 if (cmd->cmd_pkt->pkt_flags & FLAG_NOINTR) { 14061 fpkt->pkt_tran_flags = (FC_TRAN_CLASS3 | FC_TRAN_NO_INTR); 14062 fpkt->pkt_comp = NULL; 14063 } else { 14064 fpkt->pkt_tran_flags = (FC_TRAN_CLASS3 | FC_TRAN_INTR); 14065 if (cmd->cmd_pkt->pkt_flags & FLAG_IMMEDIATE_CB) { 14066 fpkt->pkt_tran_flags |= FC_TRAN_IMMEDIATE_CB; 14067 } 14068 fpkt->pkt_comp = fcp_cmd_callback; 14069 } 14070 14071 mutex_enter(&pptr->port_mutex); 14072 if (pptr->port_state & FCP_STATE_SUSPENDED) { 14073 fpkt->pkt_tran_flags |= FC_TRAN_DUMPING; 14074 } 14075 mutex_exit(&pptr->port_mutex); 14076 14077 fpkt->pkt_cmd_fhdr.d_id = ptgt->tgt_d_id; 14078 fpkt->pkt_cmd_fhdr.s_id = pptr->port_id; 14079 14080 /* 14081 * Save a few kernel cycles here 14082 */ 14083 #ifndef __lock_lint 14084 fpkt->pkt_fca_device = ptgt->tgt_fca_dev; 14085 #endif /* __lock_lint */ 14086 } 14087 14088 static void 14089 fcp_post_callback(struct fcp_pkt *cmd) 14090 { 14091 scsi_hba_pkt_comp(cmd->cmd_pkt); 14092 } 14093 14094 14095 /* 14096 * called to do polled I/O by fcp_start() 14097 * 14098 * return a transport status value, i.e. TRAN_ACCECPT for success 14099 */ 14100 static int 14101 fcp_dopoll(struct fcp_port *pptr, struct fcp_pkt *cmd) 14102 { 14103 int rval; 14104 14105 #ifdef DEBUG 14106 mutex_enter(&pptr->port_pkt_mutex); 14107 pptr->port_npkts++; 14108 mutex_exit(&pptr->port_pkt_mutex); 14109 #endif /* DEBUG */ 14110 14111 if (cmd->cmd_fp_pkt->pkt_timeout) { 14112 cmd->cmd_fp_pkt->pkt_timeout = cmd->cmd_pkt->pkt_time; 14113 } else { 14114 cmd->cmd_fp_pkt->pkt_timeout = FCP_POLL_TIMEOUT; 14115 } 14116 14117 ASSERT(cmd->cmd_fp_pkt->pkt_comp == NULL); 14118 14119 cmd->cmd_state = FCP_PKT_ISSUED; 14120 14121 rval = fc_ulp_transport(pptr->port_fp_handle, cmd->cmd_fp_pkt); 14122 14123 #ifdef DEBUG 14124 mutex_enter(&pptr->port_pkt_mutex); 14125 pptr->port_npkts--; 14126 mutex_exit(&pptr->port_pkt_mutex); 14127 #endif /* DEBUG */ 14128 14129 cmd->cmd_state = FCP_PKT_IDLE; 14130 14131 switch (rval) { 14132 case FC_SUCCESS: 14133 if (cmd->cmd_fp_pkt->pkt_state == FC_PKT_SUCCESS) { 14134 fcp_complete_pkt(cmd->cmd_fp_pkt); 14135 rval = TRAN_ACCEPT; 14136 } else { 14137 rval = TRAN_FATAL_ERROR; 14138 } 14139 break; 14140 14141 case FC_TRAN_BUSY: 14142 rval = TRAN_BUSY; 14143 cmd->cmd_pkt->pkt_resid = 0; 14144 break; 14145 14146 case FC_BADPACKET: 14147 rval = TRAN_BADPKT; 14148 break; 14149 14150 default: 14151 rval = TRAN_FATAL_ERROR; 14152 break; 14153 } 14154 14155 return (rval); 14156 } 14157 14158 14159 /* 14160 * called by some of the following transport-called routines to convert 14161 * a supplied dip ptr to a port struct ptr (i.e. to the soft state) 14162 */ 14163 static struct fcp_port * 14164 fcp_dip2port(dev_info_t *dip) 14165 { 14166 int instance; 14167 14168 instance = ddi_get_instance(dip); 14169 return (ddi_get_soft_state(fcp_softstate, instance)); 14170 } 14171 14172 14173 /* 14174 * called internally to return a LUN given a dip 14175 */ 14176 struct fcp_lun * 14177 fcp_get_lun_from_cip(struct fcp_port *pptr, child_info_t *cip) 14178 { 14179 struct fcp_tgt *ptgt; 14180 struct fcp_lun *plun; 14181 int i; 14182 14183 14184 ASSERT(mutex_owned(&pptr->port_mutex)); 14185 14186 for (i = 0; i < FCP_NUM_HASH; i++) { 14187 for (ptgt = pptr->port_tgt_hash_table[i]; 14188 ptgt != NULL; 14189 ptgt = ptgt->tgt_next) { 14190 mutex_enter(&ptgt->tgt_mutex); 14191 for (plun = ptgt->tgt_lun; plun != NULL; 14192 plun = plun->lun_next) { 14193 mutex_enter(&plun->lun_mutex); 14194 if (plun->lun_cip == cip) { 14195 mutex_exit(&plun->lun_mutex); 14196 mutex_exit(&ptgt->tgt_mutex); 14197 return (plun); /* match found */ 14198 } 14199 mutex_exit(&plun->lun_mutex); 14200 } 14201 mutex_exit(&ptgt->tgt_mutex); 14202 } 14203 } 14204 return (NULL); /* no LUN found */ 14205 } 14206 14207 /* 14208 * pass an element to the hotplug list, kick the hotplug thread 14209 * and wait for the element to get processed by the hotplug thread. 14210 * on return the element is freed. 14211 * 14212 * return zero success and non-zero on failure 14213 * 14214 * acquires/releases the target mutex 14215 * 14216 */ 14217 static int 14218 fcp_pass_to_hp_and_wait(struct fcp_port *pptr, struct fcp_lun *plun, 14219 child_info_t *cip, int what, int link_cnt, int tgt_cnt, int flags) 14220 { 14221 struct fcp_hp_elem *elem; 14222 int rval; 14223 14224 mutex_enter(&plun->lun_tgt->tgt_mutex); 14225 if ((elem = fcp_pass_to_hp(pptr, plun, cip, 14226 what, link_cnt, tgt_cnt, flags, 1)) == NULL) { 14227 mutex_exit(&plun->lun_tgt->tgt_mutex); 14228 fcp_log(CE_CONT, pptr->port_dip, 14229 "Can not pass_to_hp: what: %d; D_ID=%x, LUN=%x\n", 14230 what, plun->lun_tgt->tgt_d_id, plun->lun_num); 14231 return (NDI_FAILURE); 14232 } 14233 mutex_exit(&plun->lun_tgt->tgt_mutex); 14234 mutex_enter(&elem->mutex); 14235 if (elem->wait) { 14236 while (elem->wait) { 14237 cv_wait(&elem->cv, &elem->mutex); 14238 } 14239 } 14240 rval = (elem->result); 14241 mutex_exit(&elem->mutex); 14242 mutex_destroy(&elem->mutex); 14243 cv_destroy(&elem->cv); 14244 kmem_free(elem, sizeof (struct fcp_hp_elem)); 14245 return (rval); 14246 } 14247 14248 /* 14249 * pass an element to the hotplug list, and then 14250 * kick the hotplug thread 14251 * 14252 * return Boolean success, i.e. non-zero if all goes well, else zero on error 14253 * 14254 * acquires/releases the hotplug mutex 14255 * 14256 * called with the target mutex owned 14257 * 14258 * memory acquired in NOSLEEP mode 14259 * NOTE: if wait is set to 1 then the caller is responsible for waiting on 14260 * for the hp daemon to process the request and is responsible for 14261 * freeing the element 14262 */ 14263 static struct fcp_hp_elem * 14264 fcp_pass_to_hp(struct fcp_port *pptr, struct fcp_lun *plun, 14265 child_info_t *cip, int what, int link_cnt, int tgt_cnt, int flags, int wait) 14266 { 14267 struct fcp_hp_elem *elem; 14268 dev_info_t *pdip; 14269 14270 ASSERT(pptr != NULL); 14271 ASSERT(plun != NULL); 14272 ASSERT(plun->lun_tgt != NULL); 14273 ASSERT(mutex_owned(&plun->lun_tgt->tgt_mutex)); 14274 14275 /* create space for a hotplug element */ 14276 if ((elem = kmem_zalloc(sizeof (struct fcp_hp_elem), KM_NOSLEEP)) 14277 == NULL) { 14278 fcp_log(CE_WARN, NULL, 14279 "!can't allocate memory for hotplug element"); 14280 return (NULL); 14281 } 14282 14283 /* fill in hotplug element */ 14284 elem->port = pptr; 14285 elem->lun = plun; 14286 elem->cip = cip; 14287 elem->old_lun_mpxio = plun->lun_mpxio; 14288 elem->what = what; 14289 elem->flags = flags; 14290 elem->link_cnt = link_cnt; 14291 elem->tgt_cnt = tgt_cnt; 14292 elem->wait = wait; 14293 mutex_init(&elem->mutex, NULL, MUTEX_DRIVER, NULL); 14294 cv_init(&elem->cv, NULL, CV_DRIVER, NULL); 14295 14296 /* schedule the hotplug task */ 14297 pdip = pptr->port_dip; 14298 mutex_enter(&plun->lun_mutex); 14299 if (elem->what == FCP_ONLINE || elem->what == FCP_OFFLINE) { 14300 plun->lun_event_count++; 14301 elem->event_cnt = plun->lun_event_count; 14302 } 14303 mutex_exit(&plun->lun_mutex); 14304 if (taskq_dispatch(DEVI(pdip)->devi_taskq, fcp_hp_task, 14305 (void *)elem, KM_NOSLEEP) == NULL) { 14306 mutex_enter(&plun->lun_mutex); 14307 if (elem->what == FCP_ONLINE || elem->what == FCP_OFFLINE) { 14308 plun->lun_event_count--; 14309 } 14310 mutex_exit(&plun->lun_mutex); 14311 kmem_free(elem, sizeof (*elem)); 14312 return (0); 14313 } 14314 14315 return (elem); 14316 } 14317 14318 14319 static void 14320 fcp_retransport_cmd(struct fcp_port *pptr, struct fcp_pkt *cmd) 14321 { 14322 int rval; 14323 struct scsi_address *ap; 14324 struct fcp_lun *plun; 14325 struct fcp_tgt *ptgt; 14326 fc_packet_t *fpkt; 14327 14328 ap = &cmd->cmd_pkt->pkt_address; 14329 plun = ADDR2LUN(ap); 14330 ptgt = plun->lun_tgt; 14331 14332 ASSERT(cmd->cmd_flags & CFLAG_IN_QUEUE); 14333 14334 cmd->cmd_state = FCP_PKT_IDLE; 14335 14336 mutex_enter(&pptr->port_mutex); 14337 mutex_enter(&ptgt->tgt_mutex); 14338 if (((plun->lun_state & (FCP_LUN_BUSY | FCP_LUN_OFFLINE)) == 0) && 14339 (!(pptr->port_state & FCP_STATE_ONLINING))) { 14340 fc_ulp_rscn_info_t *rscnp; 14341 14342 cmd->cmd_state = FCP_PKT_ISSUED; 14343 14344 /* 14345 * It is possible for pkt_pd to be NULL if tgt_pd_handle was 14346 * originally NULL, hence we try to set it to the pd pointed 14347 * to by the SCSI device we're trying to get to. 14348 */ 14349 14350 fpkt = cmd->cmd_fp_pkt; 14351 if ((fpkt->pkt_pd == NULL) && (ptgt->tgt_pd_handle != NULL)) { 14352 fpkt->pkt_pd = ptgt->tgt_pd_handle; 14353 /* 14354 * We need to notify the transport that we now have a 14355 * reference to the remote port handle. 14356 */ 14357 fc_ulp_hold_remote_port(ptgt->tgt_pd_handle); 14358 } 14359 14360 mutex_exit(&ptgt->tgt_mutex); 14361 mutex_exit(&pptr->port_mutex); 14362 14363 ASSERT((cmd->cmd_pkt->pkt_flags & FLAG_NOINTR) == 0); 14364 14365 /* prepare the packet */ 14366 14367 fcp_prepare_pkt(pptr, cmd, plun); 14368 14369 rscnp = (fc_ulp_rscn_info_t *)cmd->cmd_fp_pkt-> 14370 pkt_ulp_rscn_infop; 14371 14372 cmd->cmd_timeout = cmd->cmd_pkt->pkt_time ? 14373 fcp_watchdog_time + cmd->cmd_pkt->pkt_time : 0; 14374 14375 if (rscnp != NULL) { 14376 rscnp->ulp_rscn_count = 14377 fc_ulp_get_rscn_count(pptr-> 14378 port_fp_handle); 14379 } 14380 14381 rval = fcp_transport(pptr->port_fp_handle, 14382 cmd->cmd_fp_pkt, 0); 14383 14384 if (rval == FC_SUCCESS) { 14385 return; 14386 } 14387 cmd->cmd_state &= ~FCP_PKT_ISSUED; 14388 } else { 14389 mutex_exit(&ptgt->tgt_mutex); 14390 mutex_exit(&pptr->port_mutex); 14391 } 14392 14393 fcp_queue_pkt(pptr, cmd); 14394 } 14395 14396 14397 static void 14398 fcp_fail_cmd(struct fcp_pkt *cmd, uchar_t reason, uint_t statistics) 14399 { 14400 ASSERT(cmd->cmd_flags & CFLAG_IN_QUEUE); 14401 14402 cmd->cmd_flags &= ~CFLAG_IN_QUEUE; 14403 cmd->cmd_state = FCP_PKT_IDLE; 14404 14405 cmd->cmd_pkt->pkt_reason = reason; 14406 cmd->cmd_pkt->pkt_state = 0; 14407 cmd->cmd_pkt->pkt_statistics = statistics; 14408 14409 fcp_post_callback(cmd); 14410 } 14411 14412 /* 14413 * Function: fcp_queue_pkt 14414 * 14415 * Description: This function queues the packet passed by the caller into 14416 * the list of packets of the FCP port. 14417 * 14418 * Argument: *pptr FCP port. 14419 * *cmd FCP packet to queue. 14420 * 14421 * Return Value: None 14422 * 14423 * Context: User, Kernel and Interrupt context. 14424 */ 14425 static void 14426 fcp_queue_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd) 14427 { 14428 ASSERT((cmd->cmd_pkt->pkt_flags & FLAG_NOQUEUE) == NULL); 14429 14430 mutex_enter(&pptr->port_pkt_mutex); 14431 cmd->cmd_flags |= CFLAG_IN_QUEUE; 14432 ASSERT(cmd->cmd_state != FCP_PKT_ISSUED); 14433 cmd->cmd_timeout = fcp_watchdog_time + FCP_QUEUE_DELAY; 14434 14435 /* 14436 * zero pkt_time means hang around for ever 14437 */ 14438 if (cmd->cmd_pkt->pkt_time) { 14439 if (cmd->cmd_fp_pkt->pkt_timeout > FCP_QUEUE_DELAY) { 14440 cmd->cmd_fp_pkt->pkt_timeout -= FCP_QUEUE_DELAY; 14441 } else { 14442 /* 14443 * Indicate the watch thread to fail the 14444 * command by setting it to highest value 14445 */ 14446 cmd->cmd_timeout = fcp_watchdog_time; 14447 cmd->cmd_fp_pkt->pkt_timeout = FCP_INVALID_TIMEOUT; 14448 } 14449 } 14450 14451 if (pptr->port_pkt_head) { 14452 ASSERT(pptr->port_pkt_tail != NULL); 14453 14454 pptr->port_pkt_tail->cmd_next = cmd; 14455 pptr->port_pkt_tail = cmd; 14456 } else { 14457 ASSERT(pptr->port_pkt_tail == NULL); 14458 14459 pptr->port_pkt_head = pptr->port_pkt_tail = cmd; 14460 } 14461 cmd->cmd_next = NULL; 14462 mutex_exit(&pptr->port_pkt_mutex); 14463 } 14464 14465 /* 14466 * Function: fcp_update_targets 14467 * 14468 * Description: This function applies the specified change of state to all 14469 * the targets listed. The operation applied is 'set'. 14470 * 14471 * Argument: *pptr FCP port. 14472 * *dev_list Array of fc_portmap_t structures. 14473 * count Length of dev_list. 14474 * state State bits to update. 14475 * cause Reason for the update. 14476 * 14477 * Return Value: None 14478 * 14479 * Context: User, Kernel and Interrupt context. 14480 * The mutex pptr->port_mutex must be held. 14481 */ 14482 static void 14483 fcp_update_targets(struct fcp_port *pptr, fc_portmap_t *dev_list, 14484 uint32_t count, uint32_t state, int cause) 14485 { 14486 fc_portmap_t *map_entry; 14487 struct fcp_tgt *ptgt; 14488 14489 ASSERT(MUTEX_HELD(&pptr->port_mutex)); 14490 14491 while (count--) { 14492 map_entry = &(dev_list[count]); 14493 ptgt = fcp_lookup_target(pptr, 14494 (uchar_t *)&(map_entry->map_pwwn)); 14495 if (ptgt == NULL) { 14496 continue; 14497 } 14498 14499 mutex_enter(&ptgt->tgt_mutex); 14500 ptgt->tgt_trace = 0; 14501 ptgt->tgt_change_cnt++; 14502 ptgt->tgt_statec_cause = cause; 14503 ptgt->tgt_tmp_cnt = 1; 14504 fcp_update_tgt_state(ptgt, FCP_SET, state); 14505 mutex_exit(&ptgt->tgt_mutex); 14506 } 14507 } 14508 14509 static int 14510 fcp_call_finish_init(struct fcp_port *pptr, struct fcp_tgt *ptgt, 14511 int lcount, int tcount, int cause) 14512 { 14513 int rval; 14514 14515 mutex_enter(&pptr->port_mutex); 14516 rval = fcp_call_finish_init_held(pptr, ptgt, lcount, tcount, cause); 14517 mutex_exit(&pptr->port_mutex); 14518 14519 return (rval); 14520 } 14521 14522 14523 static int 14524 fcp_call_finish_init_held(struct fcp_port *pptr, struct fcp_tgt *ptgt, 14525 int lcount, int tcount, int cause) 14526 { 14527 int finish_init = 0; 14528 int finish_tgt = 0; 14529 int do_finish_init = 0; 14530 int rval = FCP_NO_CHANGE; 14531 14532 if (cause == FCP_CAUSE_LINK_CHANGE || 14533 cause == FCP_CAUSE_LINK_DOWN) { 14534 do_finish_init = 1; 14535 } 14536 14537 if (ptgt != NULL) { 14538 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 14539 FCP_BUF_LEVEL_2, 0, 14540 "link_cnt: %d,%d; tgt_cnt: %d,%d; tmp_cnt: %d,%d;" 14541 " cause = %d, d_id = 0x%x, tgt_done = %d", 14542 pptr->port_link_cnt, lcount, ptgt->tgt_change_cnt, tcount, 14543 pptr->port_tmp_cnt, ptgt->tgt_tmp_cnt, cause, 14544 ptgt->tgt_d_id, ptgt->tgt_done); 14545 14546 mutex_enter(&ptgt->tgt_mutex); 14547 14548 if (tcount && (ptgt->tgt_change_cnt != tcount)) { 14549 rval = FCP_DEV_CHANGE; 14550 if (do_finish_init && ptgt->tgt_done == 0) { 14551 ptgt->tgt_done++; 14552 finish_init = 1; 14553 } 14554 } else { 14555 if (--ptgt->tgt_tmp_cnt <= 0) { 14556 ptgt->tgt_tmp_cnt = 0; 14557 finish_tgt = 1; 14558 14559 if (do_finish_init) { 14560 finish_init = 1; 14561 } 14562 } 14563 } 14564 mutex_exit(&ptgt->tgt_mutex); 14565 } else { 14566 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 14567 FCP_BUF_LEVEL_2, 0, 14568 "Call Finish Init for NO target"); 14569 14570 if (do_finish_init) { 14571 finish_init = 1; 14572 } 14573 } 14574 14575 if (finish_tgt) { 14576 ASSERT(ptgt != NULL); 14577 14578 mutex_enter(&ptgt->tgt_mutex); 14579 #ifdef DEBUG 14580 bzero(ptgt->tgt_tmp_cnt_stack, 14581 sizeof (ptgt->tgt_tmp_cnt_stack)); 14582 14583 ptgt->tgt_tmp_cnt_depth = getpcstack(ptgt->tgt_tmp_cnt_stack, 14584 FCP_STACK_DEPTH); 14585 #endif /* DEBUG */ 14586 mutex_exit(&ptgt->tgt_mutex); 14587 14588 (void) fcp_finish_tgt(pptr, ptgt, lcount, tcount, cause); 14589 } 14590 14591 if (finish_init && lcount == pptr->port_link_cnt) { 14592 ASSERT(pptr->port_tmp_cnt > 0); 14593 if (--pptr->port_tmp_cnt == 0) { 14594 fcp_finish_init(pptr); 14595 } 14596 } else if (lcount != pptr->port_link_cnt) { 14597 FCP_TRACE(fcp_logq, pptr->port_instbuf, 14598 fcp_trace, FCP_BUF_LEVEL_2, 0, 14599 "fcp_call_finish_init_held,1: state change occured" 14600 " for D_ID=0x%x", (ptgt) ? ptgt->tgt_d_id : 0); 14601 } 14602 14603 return (rval); 14604 } 14605 14606 static void 14607 fcp_reconfigure_luns(void * tgt_handle) 14608 { 14609 uint32_t dev_cnt; 14610 fc_portmap_t *devlist; 14611 struct fcp_tgt *ptgt = (struct fcp_tgt *)tgt_handle; 14612 struct fcp_port *pptr = ptgt->tgt_port; 14613 14614 /* 14615 * If the timer that fires this off got canceled too late, the 14616 * target could have been destroyed. 14617 */ 14618 14619 if (ptgt->tgt_tid == NULL) { 14620 return; 14621 } 14622 14623 devlist = kmem_zalloc(sizeof (*devlist), KM_NOSLEEP); 14624 if (devlist == NULL) { 14625 fcp_log(CE_WARN, pptr->port_dip, 14626 "!fcp%d: failed to allocate for portmap", 14627 pptr->port_instance); 14628 return; 14629 } 14630 14631 dev_cnt = 1; 14632 devlist->map_pd = ptgt->tgt_pd_handle; 14633 devlist->map_hard_addr.hard_addr = ptgt->tgt_hard_addr; 14634 devlist->map_did.port_id = ptgt->tgt_d_id; 14635 14636 bcopy(&ptgt->tgt_node_wwn.raw_wwn[0], &devlist->map_nwwn, FC_WWN_SIZE); 14637 bcopy(&ptgt->tgt_port_wwn.raw_wwn[0], &devlist->map_pwwn, FC_WWN_SIZE); 14638 14639 devlist->map_state = PORT_DEVICE_LOGGED_IN; 14640 devlist->map_type = PORT_DEVICE_REPORTLUN_CHANGED; 14641 devlist->map_flags = 0; 14642 14643 fcp_statec_callback(NULL, pptr->port_fp_handle, FC_STATE_DEVICE_CHANGE, 14644 pptr->port_topology, devlist, dev_cnt, pptr->port_id); 14645 14646 /* 14647 * Clear the tgt_tid after no more references to 14648 * the fcp_tgt 14649 */ 14650 mutex_enter(&ptgt->tgt_mutex); 14651 ptgt->tgt_tid = NULL; 14652 mutex_exit(&ptgt->tgt_mutex); 14653 14654 kmem_free(devlist, sizeof (*devlist)); 14655 } 14656 14657 14658 static void 14659 fcp_free_targets(struct fcp_port *pptr) 14660 { 14661 int i; 14662 struct fcp_tgt *ptgt; 14663 14664 mutex_enter(&pptr->port_mutex); 14665 for (i = 0; i < FCP_NUM_HASH; i++) { 14666 ptgt = pptr->port_tgt_hash_table[i]; 14667 while (ptgt != NULL) { 14668 struct fcp_tgt *next_tgt = ptgt->tgt_next; 14669 14670 fcp_free_target(ptgt); 14671 ptgt = next_tgt; 14672 } 14673 } 14674 mutex_exit(&pptr->port_mutex); 14675 } 14676 14677 14678 static void 14679 fcp_free_target(struct fcp_tgt *ptgt) 14680 { 14681 struct fcp_lun *plun; 14682 timeout_id_t tid; 14683 14684 mutex_enter(&ptgt->tgt_mutex); 14685 tid = ptgt->tgt_tid; 14686 14687 /* 14688 * Cancel any pending timeouts for this target. 14689 */ 14690 14691 if (tid != NULL) { 14692 /* 14693 * Set tgt_tid to NULL first to avoid a race in the callback. 14694 * If tgt_tid is NULL, the callback will simply return. 14695 */ 14696 ptgt->tgt_tid = NULL; 14697 mutex_exit(&ptgt->tgt_mutex); 14698 (void) untimeout(tid); 14699 mutex_enter(&ptgt->tgt_mutex); 14700 } 14701 14702 plun = ptgt->tgt_lun; 14703 while (plun != NULL) { 14704 struct fcp_lun *next_lun = plun->lun_next; 14705 14706 fcp_dealloc_lun(plun); 14707 plun = next_lun; 14708 } 14709 14710 mutex_exit(&ptgt->tgt_mutex); 14711 fcp_dealloc_tgt(ptgt); 14712 } 14713 14714 /* 14715 * Function: fcp_is_retryable 14716 * 14717 * Description: Indicates if the internal packet is retryable. 14718 * 14719 * Argument: *icmd FCP internal packet. 14720 * 14721 * Return Value: 0 Not retryable 14722 * 1 Retryable 14723 * 14724 * Context: User, Kernel and Interrupt context 14725 */ 14726 static int 14727 fcp_is_retryable(struct fcp_ipkt *icmd) 14728 { 14729 if (icmd->ipkt_port->port_state & (FCP_STATE_SUSPENDED | 14730 FCP_STATE_DETACHING | FCP_STATE_POWER_DOWN)) { 14731 return (0); 14732 } 14733 14734 return (((fcp_watchdog_time + icmd->ipkt_fpkt->pkt_timeout) < 14735 icmd->ipkt_port->port_deadline) ? 1 : 0); 14736 } 14737 14738 /* 14739 * Function: fcp_create_on_demand 14740 * 14741 * Argument: *pptr FCP port. 14742 * *pwwn Port WWN. 14743 * 14744 * Return Value: 0 Success 14745 * EIO 14746 * ENOMEM 14747 * EBUSY 14748 * EINVAL 14749 * 14750 * Context: User and Kernel context 14751 */ 14752 static int 14753 fcp_create_on_demand(struct fcp_port *pptr, uchar_t *pwwn) 14754 { 14755 int wait_ms; 14756 int tcount; 14757 int lcount; 14758 int ret; 14759 int error; 14760 int rval = EIO; 14761 int ntries; 14762 fc_portmap_t *devlist; 14763 opaque_t pd; 14764 struct fcp_lun *plun; 14765 struct fcp_tgt *ptgt; 14766 int old_manual = 0; 14767 14768 /* Allocates the fc_portmap_t structure. */ 14769 devlist = kmem_zalloc(sizeof (*devlist), KM_SLEEP); 14770 14771 /* 14772 * If FC_INVALID_RSCN_COUNT is non-zero, we will have to init as shown 14773 * in the commented statement below: 14774 * 14775 * devlist->map_rscn_info.ulp_rscn_count = FC_INVALID_RSCN_COUNT; 14776 * 14777 * Below, the deadline for the discovery process is set. 14778 */ 14779 mutex_enter(&pptr->port_mutex); 14780 pptr->port_deadline = fcp_watchdog_time + FCP_ICMD_DEADLINE; 14781 mutex_exit(&pptr->port_mutex); 14782 14783 /* 14784 * We try to find the remote port based on the WWN provided by the 14785 * caller. We actually ask fp/fctl if it has it. 14786 */ 14787 pd = fc_ulp_get_remote_port(pptr->port_fp_handle, 14788 (la_wwn_t *)pwwn, &error, 1); 14789 14790 if (pd == NULL) { 14791 kmem_free(devlist, sizeof (*devlist)); 14792 return (rval); 14793 } 14794 14795 /* 14796 * The remote port was found. We ask fp/fctl to update our 14797 * fc_portmap_t structure. 14798 */ 14799 ret = fc_ulp_pwwn_to_portmap(pptr->port_fp_handle, 14800 (la_wwn_t *)pwwn, devlist); 14801 if (ret != FC_SUCCESS) { 14802 kmem_free(devlist, sizeof (*devlist)); 14803 return (rval); 14804 } 14805 14806 /* 14807 * The map flag field is set to indicates that the creation is being 14808 * done at the user request (Ioclt probably luxadm or cfgadm). 14809 */ 14810 devlist->map_type = PORT_DEVICE_USER_CREATE; 14811 14812 mutex_enter(&pptr->port_mutex); 14813 14814 /* 14815 * We check to see if fcp already has a target that describes the 14816 * device being created. If not it is created. 14817 */ 14818 ptgt = fcp_lookup_target(pptr, pwwn); 14819 if (ptgt == NULL) { 14820 lcount = pptr->port_link_cnt; 14821 mutex_exit(&pptr->port_mutex); 14822 14823 ptgt = fcp_alloc_tgt(pptr, devlist, lcount); 14824 if (ptgt == NULL) { 14825 fcp_log(CE_WARN, pptr->port_dip, 14826 "!FC target allocation failed"); 14827 return (ENOMEM); 14828 } 14829 14830 mutex_enter(&pptr->port_mutex); 14831 } 14832 14833 mutex_enter(&ptgt->tgt_mutex); 14834 ptgt->tgt_statec_cause = FCP_CAUSE_USER_CREATE; 14835 ptgt->tgt_tmp_cnt = 1; 14836 ptgt->tgt_device_created = 0; 14837 /* 14838 * If fabric and auto config is set but the target was 14839 * manually unconfigured then reset to the manual_config_only to 14840 * 0 so the device will get configured. 14841 */ 14842 if (FC_TOP_EXTERNAL(pptr->port_topology) && 14843 fcp_enable_auto_configuration && 14844 ptgt->tgt_manual_config_only == 1) { 14845 old_manual = 1; 14846 ptgt->tgt_manual_config_only = 0; 14847 } 14848 mutex_exit(&ptgt->tgt_mutex); 14849 14850 fcp_update_targets(pptr, devlist, 1, 14851 FCP_LUN_BUSY | FCP_LUN_MARK, FCP_CAUSE_USER_CREATE); 14852 14853 lcount = pptr->port_link_cnt; 14854 tcount = ptgt->tgt_change_cnt; 14855 14856 if (fcp_handle_mapflags(pptr, ptgt, devlist, lcount, 14857 tcount, FCP_CAUSE_USER_CREATE) == TRUE) { 14858 if (FC_TOP_EXTERNAL(pptr->port_topology) && 14859 fcp_enable_auto_configuration && old_manual) { 14860 mutex_enter(&ptgt->tgt_mutex); 14861 ptgt->tgt_manual_config_only = 1; 14862 mutex_exit(&ptgt->tgt_mutex); 14863 } 14864 14865 if (pptr->port_link_cnt != lcount || 14866 ptgt->tgt_change_cnt != tcount) { 14867 rval = EBUSY; 14868 } 14869 mutex_exit(&pptr->port_mutex); 14870 14871 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 14872 FCP_BUF_LEVEL_3, 0, 14873 "fcp_create_on_demand: mapflags ptgt=%x, " 14874 "lcount=%x::port_link_cnt=%x, " 14875 "tcount=%x: tgt_change_cnt=%x, rval=%x", 14876 ptgt, lcount, pptr->port_link_cnt, 14877 tcount, ptgt->tgt_change_cnt, rval); 14878 return (rval); 14879 } 14880 14881 /* 14882 * Due to lack of synchronization mechanisms, we perform 14883 * periodic monitoring of our request; Because requests 14884 * get dropped when another one supercedes (either because 14885 * of a link change or a target change), it is difficult to 14886 * provide a clean synchronization mechanism (such as a 14887 * semaphore or a conditional variable) without exhaustively 14888 * rewriting the mainline discovery code of this driver. 14889 */ 14890 wait_ms = 500; 14891 14892 ntries = fcp_max_target_retries; 14893 14894 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 14895 FCP_BUF_LEVEL_3, 0, 14896 "fcp_create_on_demand(1): ntries=%x, ptgt=%x, " 14897 "lcount=%x::port_link_cnt=%x, " 14898 "tcount=%x::tgt_change_cnt=%x, rval=%x, tgt_device_created=%x " 14899 "tgt_tmp_cnt =%x", 14900 ntries, ptgt, lcount, pptr->port_link_cnt, 14901 tcount, ptgt->tgt_change_cnt, rval, ptgt->tgt_device_created, 14902 ptgt->tgt_tmp_cnt); 14903 14904 mutex_enter(&ptgt->tgt_mutex); 14905 while (ntries-- != 0 && pptr->port_link_cnt == lcount && 14906 ptgt->tgt_change_cnt == tcount && ptgt->tgt_device_created == 0) { 14907 mutex_exit(&ptgt->tgt_mutex); 14908 mutex_exit(&pptr->port_mutex); 14909 14910 delay(drv_usectohz(wait_ms * 1000)); 14911 14912 mutex_enter(&pptr->port_mutex); 14913 mutex_enter(&ptgt->tgt_mutex); 14914 } 14915 14916 14917 if (pptr->port_link_cnt != lcount || ptgt->tgt_change_cnt != tcount) { 14918 rval = EBUSY; 14919 } else { 14920 if (ptgt->tgt_tmp_cnt == 0 && ptgt->tgt_node_state == 14921 FCP_TGT_NODE_PRESENT) { 14922 rval = 0; 14923 } 14924 } 14925 14926 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 14927 FCP_BUF_LEVEL_3, 0, 14928 "fcp_create_on_demand(2): ntries=%x, ptgt=%x, " 14929 "lcount=%x::port_link_cnt=%x, " 14930 "tcount=%x::tgt_change_cnt=%x, rval=%x, tgt_device_created=%x " 14931 "tgt_tmp_cnt =%x", 14932 ntries, ptgt, lcount, pptr->port_link_cnt, 14933 tcount, ptgt->tgt_change_cnt, rval, ptgt->tgt_device_created, 14934 ptgt->tgt_tmp_cnt); 14935 14936 if (rval) { 14937 if (FC_TOP_EXTERNAL(pptr->port_topology) && 14938 fcp_enable_auto_configuration && old_manual) { 14939 ptgt->tgt_manual_config_only = 1; 14940 } 14941 mutex_exit(&ptgt->tgt_mutex); 14942 mutex_exit(&pptr->port_mutex); 14943 kmem_free(devlist, sizeof (*devlist)); 14944 14945 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 14946 FCP_BUF_LEVEL_3, 0, 14947 "fcp_create_on_demand(3): ntries=%x, ptgt=%x, " 14948 "lcount=%x::port_link_cnt=%x, " 14949 "tcount=%x::tgt_change_cnt=%x, rval=%x, " 14950 "tgt_device_created=%x, tgt D_ID=%x", 14951 ntries, ptgt, lcount, pptr->port_link_cnt, 14952 tcount, ptgt->tgt_change_cnt, rval, 14953 ptgt->tgt_device_created, ptgt->tgt_d_id); 14954 return (rval); 14955 } 14956 14957 if ((plun = ptgt->tgt_lun) != NULL) { 14958 tcount = plun->lun_tgt->tgt_change_cnt; 14959 } else { 14960 rval = EINVAL; 14961 } 14962 lcount = pptr->port_link_cnt; 14963 14964 /* 14965 * Configuring the target with no LUNs will fail. We 14966 * should reset the node state so that it is not 14967 * automatically configured when the LUNs are added 14968 * to this target. 14969 */ 14970 if (ptgt->tgt_lun_cnt == 0) { 14971 ptgt->tgt_node_state = FCP_TGT_NODE_NONE; 14972 } 14973 mutex_exit(&ptgt->tgt_mutex); 14974 mutex_exit(&pptr->port_mutex); 14975 14976 while (plun) { 14977 child_info_t *cip; 14978 14979 mutex_enter(&plun->lun_mutex); 14980 cip = plun->lun_cip; 14981 mutex_exit(&plun->lun_mutex); 14982 14983 mutex_enter(&ptgt->tgt_mutex); 14984 if (!(plun->lun_state & FCP_LUN_OFFLINE)) { 14985 mutex_exit(&ptgt->tgt_mutex); 14986 14987 rval = fcp_pass_to_hp_and_wait(pptr, plun, cip, 14988 FCP_ONLINE, lcount, tcount, 14989 NDI_ONLINE_ATTACH); 14990 if (rval != NDI_SUCCESS) { 14991 FCP_TRACE(fcp_logq, 14992 pptr->port_instbuf, fcp_trace, 14993 FCP_BUF_LEVEL_3, 0, 14994 "fcp_create_on_demand: " 14995 "pass_to_hp_and_wait failed " 14996 "rval=%x", rval); 14997 rval = EIO; 14998 } else { 14999 mutex_enter(&LUN_TGT->tgt_mutex); 15000 plun->lun_state &= ~(FCP_LUN_OFFLINE | 15001 FCP_LUN_BUSY); 15002 mutex_exit(&LUN_TGT->tgt_mutex); 15003 } 15004 mutex_enter(&ptgt->tgt_mutex); 15005 } 15006 15007 plun = plun->lun_next; 15008 mutex_exit(&ptgt->tgt_mutex); 15009 } 15010 15011 kmem_free(devlist, sizeof (*devlist)); 15012 15013 if (FC_TOP_EXTERNAL(pptr->port_topology) && 15014 fcp_enable_auto_configuration && old_manual) { 15015 mutex_enter(&ptgt->tgt_mutex); 15016 /* if successful then set manual to 0 */ 15017 if (rval == 0) { 15018 ptgt->tgt_manual_config_only = 0; 15019 } else { 15020 /* reset to 1 so the user has to do the config */ 15021 ptgt->tgt_manual_config_only = 1; 15022 } 15023 mutex_exit(&ptgt->tgt_mutex); 15024 } 15025 15026 return (rval); 15027 } 15028 15029 15030 static void 15031 fcp_ascii_to_wwn(caddr_t string, uchar_t bytes[], unsigned int byte_len) 15032 { 15033 int count; 15034 uchar_t byte; 15035 15036 count = 0; 15037 while (*string) { 15038 byte = FCP_ATOB(*string); string++; 15039 byte = byte << 4 | FCP_ATOB(*string); string++; 15040 bytes[count++] = byte; 15041 15042 if (count >= byte_len) { 15043 break; 15044 } 15045 } 15046 } 15047 15048 static void 15049 fcp_wwn_to_ascii(uchar_t wwn[], char *string) 15050 { 15051 int i; 15052 15053 for (i = 0; i < FC_WWN_SIZE; i++) { 15054 (void) sprintf(string + (i * 2), 15055 "%02x", wwn[i]); 15056 } 15057 15058 } 15059 15060 static void 15061 fcp_print_error(fc_packet_t *fpkt) 15062 { 15063 struct fcp_ipkt *icmd = (struct fcp_ipkt *) 15064 fpkt->pkt_ulp_private; 15065 struct fcp_port *pptr; 15066 struct fcp_tgt *ptgt; 15067 struct fcp_lun *plun; 15068 caddr_t buf; 15069 int scsi_cmd = 0; 15070 15071 ptgt = icmd->ipkt_tgt; 15072 plun = icmd->ipkt_lun; 15073 pptr = ptgt->tgt_port; 15074 15075 buf = kmem_zalloc(256, KM_NOSLEEP); 15076 if (buf == NULL) { 15077 return; 15078 } 15079 15080 switch (icmd->ipkt_opcode) { 15081 case SCMD_REPORT_LUN: 15082 (void) sprintf(buf, "!REPORT LUN to D_ID=0x%%x" 15083 " lun=0x%%x failed"); 15084 scsi_cmd++; 15085 break; 15086 15087 case SCMD_INQUIRY_PAGE83: 15088 (void) sprintf(buf, "!INQUIRY-83 to D_ID=0x%%x" 15089 " lun=0x%%x failed"); 15090 scsi_cmd++; 15091 break; 15092 15093 case SCMD_INQUIRY: 15094 (void) sprintf(buf, "!INQUIRY to D_ID=0x%%x" 15095 " lun=0x%%x failed"); 15096 scsi_cmd++; 15097 break; 15098 15099 case LA_ELS_PLOGI: 15100 (void) sprintf(buf, "!PLOGI to D_ID=0x%%x failed"); 15101 break; 15102 15103 case LA_ELS_PRLI: 15104 (void) sprintf(buf, "!PRLI to D_ID=0x%%x failed"); 15105 break; 15106 } 15107 15108 if (scsi_cmd && fpkt->pkt_state == FC_PKT_SUCCESS) { 15109 struct fcp_rsp response, *rsp; 15110 uchar_t asc, ascq; 15111 caddr_t sense_key = NULL; 15112 struct fcp_rsp_info fcp_rsp_err, *bep; 15113 15114 if (icmd->ipkt_nodma) { 15115 rsp = (struct fcp_rsp *)fpkt->pkt_resp; 15116 bep = (struct fcp_rsp_info *)((caddr_t)rsp + 15117 sizeof (struct fcp_rsp)); 15118 } else { 15119 rsp = &response; 15120 bep = &fcp_rsp_err; 15121 15122 FCP_CP_IN(fpkt->pkt_resp, rsp, fpkt->pkt_resp_acc, 15123 sizeof (struct fcp_rsp)); 15124 15125 FCP_CP_IN(fpkt->pkt_resp + sizeof (struct fcp_rsp), 15126 bep, fpkt->pkt_resp_acc, 15127 sizeof (struct fcp_rsp_info)); 15128 } 15129 15130 15131 if (fcp_validate_fcp_response(rsp, pptr) != FC_SUCCESS) { 15132 (void) sprintf(buf + strlen(buf), 15133 " : Bad FCP response values rsvd1=%%x, rsvd2=%%x," 15134 " sts-rsvd1=%%x, sts-rsvd2=%%x, rsplen=%%x," 15135 " senselen=%%x. Giving up"); 15136 15137 fcp_log(CE_WARN, pptr->port_dip, buf, 15138 ptgt->tgt_d_id, plun->lun_num, rsp->reserved_0, 15139 rsp->reserved_1, rsp->fcp_u.fcp_status.reserved_0, 15140 rsp->fcp_u.fcp_status.reserved_1, 15141 rsp->fcp_response_len, rsp->fcp_sense_len); 15142 15143 kmem_free(buf, 256); 15144 return; 15145 } 15146 15147 if (rsp->fcp_u.fcp_status.rsp_len_set && 15148 bep->rsp_code != FCP_NO_FAILURE) { 15149 (void) sprintf(buf + strlen(buf), 15150 " FCP Response code = 0x%x", bep->rsp_code); 15151 } 15152 15153 if (rsp->fcp_u.fcp_status.scsi_status & STATUS_CHECK) { 15154 struct scsi_extended_sense sense_info, *sense_ptr; 15155 15156 if (icmd->ipkt_nodma) { 15157 sense_ptr = (struct scsi_extended_sense *) 15158 ((caddr_t)fpkt->pkt_resp + 15159 sizeof (struct fcp_rsp) + 15160 rsp->fcp_response_len); 15161 } else { 15162 sense_ptr = &sense_info; 15163 15164 FCP_CP_IN(fpkt->pkt_resp + 15165 sizeof (struct fcp_rsp) + 15166 rsp->fcp_response_len, &sense_info, 15167 fpkt->pkt_resp_acc, 15168 sizeof (struct scsi_extended_sense)); 15169 } 15170 15171 if (sense_ptr->es_key < NUM_SENSE_KEYS + 15172 NUM_IMPL_SENSE_KEYS) { 15173 sense_key = sense_keys[sense_ptr->es_key]; 15174 } else { 15175 sense_key = "Undefined"; 15176 } 15177 15178 asc = sense_ptr->es_add_code; 15179 ascq = sense_ptr->es_qual_code; 15180 15181 (void) sprintf(buf + strlen(buf), 15182 ": sense key=%%s, ASC=%%x," " ASCQ=%%x." 15183 " Giving up"); 15184 15185 fcp_log(CE_WARN, pptr->port_dip, buf, 15186 ptgt->tgt_d_id, plun->lun_num, sense_key, 15187 asc, ascq); 15188 } else { 15189 (void) sprintf(buf + strlen(buf), 15190 " : SCSI status=%%x. Giving up"); 15191 15192 fcp_log(CE_WARN, pptr->port_dip, buf, 15193 ptgt->tgt_d_id, plun->lun_num, 15194 rsp->fcp_u.fcp_status.scsi_status); 15195 } 15196 } else { 15197 caddr_t state, reason, action, expln; 15198 15199 (void) fc_ulp_pkt_error(fpkt, &state, &reason, 15200 &action, &expln); 15201 15202 (void) sprintf(buf + strlen(buf), ": State:%%s," 15203 " Reason:%%s. Giving up"); 15204 15205 if (scsi_cmd) { 15206 fcp_log(CE_WARN, pptr->port_dip, buf, 15207 ptgt->tgt_d_id, plun->lun_num, state, reason); 15208 } else { 15209 fcp_log(CE_WARN, pptr->port_dip, buf, 15210 ptgt->tgt_d_id, state, reason); 15211 } 15212 } 15213 15214 kmem_free(buf, 256); 15215 } 15216 15217 15218 static int 15219 fcp_handle_ipkt_errors(struct fcp_port *pptr, struct fcp_tgt *ptgt, 15220 struct fcp_ipkt *icmd, int rval, caddr_t op) 15221 { 15222 int ret = DDI_FAILURE; 15223 char *error; 15224 15225 switch (rval) { 15226 case FC_DEVICE_BUSY_NEW_RSCN: 15227 /* 15228 * This means that there was a new RSCN that the transport 15229 * knows about (which the ULP *may* know about too) but the 15230 * pkt that was sent down was related to an older RSCN. So, we 15231 * are just going to reset the retry count and deadline and 15232 * continue to retry. The idea is that transport is currently 15233 * working on the new RSCN and will soon let the ULPs know 15234 * about it and when it does the existing logic will kick in 15235 * where it will change the tcount to indicate that something 15236 * changed on the target. So, rediscovery will start and there 15237 * will not be an infinite retry. 15238 * 15239 * For a full flow of how the RSCN info is transferred back and 15240 * forth, see fp.c 15241 */ 15242 icmd->ipkt_retries = 0; 15243 icmd->ipkt_port->port_deadline = fcp_watchdog_time + 15244 FCP_ICMD_DEADLINE; 15245 15246 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 15247 FCP_BUF_LEVEL_3, 0, 15248 "fcp_handle_ipkt_errors: rval=%x for D_ID=%x", 15249 rval, ptgt->tgt_d_id); 15250 /* FALLTHROUGH */ 15251 15252 case FC_STATEC_BUSY: 15253 case FC_DEVICE_BUSY: 15254 case FC_PBUSY: 15255 case FC_FBUSY: 15256 case FC_TRAN_BUSY: 15257 case FC_OFFLINE: 15258 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 15259 FCP_BUF_LEVEL_3, 0, 15260 "fcp_handle_ipkt_errors: rval=%x for D_ID=%x", 15261 rval, ptgt->tgt_d_id); 15262 if (icmd->ipkt_retries < FCP_MAX_RETRIES && 15263 fcp_is_retryable(icmd)) { 15264 fcp_queue_ipkt(pptr, icmd->ipkt_fpkt); 15265 ret = DDI_SUCCESS; 15266 } 15267 break; 15268 15269 case FC_LOGINREQ: 15270 /* 15271 * FC_LOGINREQ used to be handled just like all the cases 15272 * above. It has been changed to handled a PRLI that fails 15273 * with FC_LOGINREQ different than other ipkts that fail 15274 * with FC_LOGINREQ. If a PRLI fails with FC_LOGINREQ it is 15275 * a simple matter to turn it into a PLOGI instead, so that's 15276 * exactly what we do here. 15277 */ 15278 if (icmd->ipkt_opcode == LA_ELS_PRLI) { 15279 ret = fcp_send_els(icmd->ipkt_port, icmd->ipkt_tgt, 15280 icmd, LA_ELS_PLOGI, icmd->ipkt_link_cnt, 15281 icmd->ipkt_change_cnt, icmd->ipkt_cause); 15282 } else { 15283 FCP_TRACE(fcp_logq, pptr->port_instbuf, fcp_trace, 15284 FCP_BUF_LEVEL_3, 0, 15285 "fcp_handle_ipkt_errors: rval=%x for D_ID=%x", 15286 rval, ptgt->tgt_d_id); 15287 if (icmd->ipkt_retries < FCP_MAX_RETRIES && 15288 fcp_is_retryable(icmd)) { 15289 fcp_queue_ipkt(pptr, icmd->ipkt_fpkt); 15290 ret = DDI_SUCCESS; 15291 } 15292 } 15293 break; 15294 15295 default: 15296 mutex_enter(&pptr->port_mutex); 15297 mutex_enter(&ptgt->tgt_mutex); 15298 if (!FCP_STATE_CHANGED(pptr, ptgt, icmd)) { 15299 mutex_exit(&ptgt->tgt_mutex); 15300 mutex_exit(&pptr->port_mutex); 15301 15302 (void) fc_ulp_error(rval, &error); 15303 fcp_log(CE_WARN, pptr->port_dip, 15304 "!Failed to send %s to D_ID=%x error=%s", 15305 op, ptgt->tgt_d_id, error); 15306 } else { 15307 FCP_TRACE(fcp_logq, pptr->port_instbuf, 15308 fcp_trace, FCP_BUF_LEVEL_2, 0, 15309 "fcp_handle_ipkt_errors,1: state change occured" 15310 " for D_ID=0x%x", ptgt->tgt_d_id); 15311 mutex_exit(&ptgt->tgt_mutex); 15312 mutex_exit(&pptr->port_mutex); 15313 } 15314 break; 15315 } 15316 15317 return (ret); 15318 } 15319 15320 15321 /* 15322 * Check of outstanding commands on any LUN for this target 15323 */ 15324 static int 15325 fcp_outstanding_lun_cmds(struct fcp_tgt *ptgt) 15326 { 15327 struct fcp_lun *plun; 15328 struct fcp_pkt *cmd; 15329 15330 for (plun = ptgt->tgt_lun; plun != NULL; plun = plun->lun_next) { 15331 mutex_enter(&plun->lun_mutex); 15332 for (cmd = plun->lun_pkt_head; cmd != NULL; 15333 cmd = cmd->cmd_forw) { 15334 if (cmd->cmd_state == FCP_PKT_ISSUED) { 15335 mutex_exit(&plun->lun_mutex); 15336 return (FC_SUCCESS); 15337 } 15338 } 15339 mutex_exit(&plun->lun_mutex); 15340 } 15341 15342 return (FC_FAILURE); 15343 } 15344 15345 static fc_portmap_t * 15346 fcp_construct_map(struct fcp_port *pptr, uint32_t *dev_cnt) 15347 { 15348 int i; 15349 fc_portmap_t *devlist; 15350 fc_portmap_t *devptr = NULL; 15351 struct fcp_tgt *ptgt; 15352 15353 mutex_enter(&pptr->port_mutex); 15354 for (i = 0, *dev_cnt = 0; i < FCP_NUM_HASH; i++) { 15355 for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL; 15356 ptgt = ptgt->tgt_next) { 15357 if (!(ptgt->tgt_state & FCP_TGT_ORPHAN)) { 15358 ++*dev_cnt; 15359 } 15360 } 15361 } 15362 15363 devptr = devlist = kmem_zalloc(sizeof (*devlist) * *dev_cnt, 15364 KM_NOSLEEP); 15365 if (devlist == NULL) { 15366 mutex_exit(&pptr->port_mutex); 15367 fcp_log(CE_WARN, pptr->port_dip, 15368 "!fcp%d: failed to allocate for portmap for construct map", 15369 pptr->port_instance); 15370 return (devptr); 15371 } 15372 15373 for (i = 0; i < FCP_NUM_HASH; i++) { 15374 for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL; 15375 ptgt = ptgt->tgt_next) { 15376 if (!(ptgt->tgt_state & FCP_TGT_ORPHAN)) { 15377 int ret; 15378 15379 ret = fc_ulp_pwwn_to_portmap( 15380 pptr->port_fp_handle, 15381 (la_wwn_t *)&ptgt->tgt_port_wwn.raw_wwn[0], 15382 devlist); 15383 15384 if (ret == FC_SUCCESS) { 15385 devlist++; 15386 continue; 15387 } 15388 15389 devlist->map_pd = NULL; 15390 devlist->map_did.port_id = ptgt->tgt_d_id; 15391 devlist->map_hard_addr.hard_addr = 15392 ptgt->tgt_hard_addr; 15393 15394 devlist->map_state = PORT_DEVICE_INVALID; 15395 devlist->map_type = PORT_DEVICE_OLD; 15396 15397 bcopy(&ptgt->tgt_node_wwn.raw_wwn[0], 15398 &devlist->map_nwwn, FC_WWN_SIZE); 15399 15400 bcopy(&ptgt->tgt_port_wwn.raw_wwn[0], 15401 &devlist->map_pwwn, FC_WWN_SIZE); 15402 15403 devlist++; 15404 } 15405 } 15406 } 15407 15408 mutex_exit(&pptr->port_mutex); 15409 15410 return (devptr); 15411 } 15412 /* 15413 * Inimate MPxIO that the lun is busy and cannot accept regular IO 15414 */ 15415 static void 15416 fcp_update_mpxio_path_verifybusy(struct fcp_port *pptr) 15417 { 15418 int i; 15419 struct fcp_tgt *ptgt; 15420 struct fcp_lun *plun; 15421 15422 for (i = 0; i < FCP_NUM_HASH; i++) { 15423 for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL; 15424 ptgt = ptgt->tgt_next) { 15425 mutex_enter(&ptgt->tgt_mutex); 15426 for (plun = ptgt->tgt_lun; plun != NULL; 15427 plun = plun->lun_next) { 15428 if (plun->lun_mpxio && 15429 plun->lun_state & FCP_LUN_BUSY) { 15430 if (!fcp_pass_to_hp(pptr, plun, 15431 plun->lun_cip, 15432 FCP_MPXIO_PATH_SET_BUSY, 15433 pptr->port_link_cnt, 15434 ptgt->tgt_change_cnt, 0, 0)) { 15435 FCP_TRACE(fcp_logq, 15436 pptr->port_instbuf, 15437 fcp_trace, 15438 FCP_BUF_LEVEL_2, 0, 15439 "path_verifybusy: " 15440 "disable lun %p failed!", 15441 plun); 15442 } 15443 } 15444 } 15445 mutex_exit(&ptgt->tgt_mutex); 15446 } 15447 } 15448 } 15449 15450 static int 15451 fcp_update_mpxio_path(struct fcp_lun *plun, child_info_t *cip, int what) 15452 { 15453 dev_info_t *cdip = NULL; 15454 dev_info_t *pdip = NULL; 15455 15456 ASSERT(plun); 15457 15458 mutex_enter(&plun->lun_mutex); 15459 if (fcp_is_child_present(plun, cip) == FC_FAILURE) { 15460 mutex_exit(&plun->lun_mutex); 15461 return (NDI_FAILURE); 15462 } 15463 mutex_exit(&plun->lun_mutex); 15464 cdip = mdi_pi_get_client(PIP(cip)); 15465 pdip = mdi_pi_get_phci(PIP(cip)); 15466 15467 ASSERT(cdip != NULL); 15468 ASSERT(pdip != NULL); 15469 15470 if (what == FCP_MPXIO_PATH_CLEAR_BUSY) { 15471 /* LUN ready for IO */ 15472 (void) mdi_pi_enable_path(PIP(cip), DRIVER_DISABLE_TRANSIENT); 15473 } else { 15474 /* LUN busy to accept IO */ 15475 (void) mdi_pi_disable_path(PIP(cip), DRIVER_DISABLE_TRANSIENT); 15476 } 15477 return (NDI_SUCCESS); 15478 } 15479 15480 /* 15481 * Caller must free the returned string of MAXPATHLEN len 15482 * If the device is offline (-1 instance number) NULL 15483 * will be returned. 15484 */ 15485 static char * 15486 fcp_get_lun_path(struct fcp_lun *plun) { 15487 dev_info_t *dip = NULL; 15488 char *path = NULL; 15489 if (plun == NULL) { 15490 return (NULL); 15491 } 15492 if (plun->lun_mpxio == 0) { 15493 dip = DIP(plun->lun_cip); 15494 } else { 15495 dip = mdi_pi_get_client(PIP(plun->lun_cip)); 15496 } 15497 if (dip == NULL) { 15498 return (NULL); 15499 } 15500 if (ddi_get_instance(dip) < 0) { 15501 return (NULL); 15502 } 15503 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 15504 if (path == NULL) { 15505 return (NULL); 15506 } 15507 15508 (void) ddi_pathname(dip, path); 15509 /* 15510 * In reality, the user wants a fully valid path (one they can open) 15511 * but this string is lacking the mount point, and the minor node. 15512 * It would be nice if we could "figure these out" somehow 15513 * and fill them in. Otherwise, the userland code has to understand 15514 * driver specific details of which minor node is the "best" or 15515 * "right" one to expose. (Ex: which slice is the whole disk, or 15516 * which tape doesn't rewind) 15517 */ 15518 return (path); 15519 } 15520 15521 static int 15522 fcp_scsi_bus_config(dev_info_t *parent, uint_t flag, 15523 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 15524 { 15525 int64_t reset_delay; 15526 int rval, retry = 0; 15527 struct fcp_port *pptr = fcp_dip2port(parent); 15528 15529 reset_delay = (int64_t)(USEC_TO_TICK(FCP_INIT_WAIT_TIMEOUT)) - 15530 (lbolt64 - pptr->port_attach_time); 15531 if (reset_delay < 0) { 15532 reset_delay = 0; 15533 } 15534 15535 if (fcp_bus_config_debug) { 15536 flag |= NDI_DEVI_DEBUG; 15537 } 15538 15539 switch (op) { 15540 case BUS_CONFIG_ONE: 15541 /* 15542 * Retry the command since we need to ensure 15543 * the fabric devices are available for root 15544 */ 15545 while (retry++ < fcp_max_bus_config_retries) { 15546 rval = (ndi_busop_bus_config(parent, 15547 flag | NDI_MDI_FALLBACK, op, 15548 arg, childp, (clock_t)reset_delay)); 15549 if (rval == 0) { 15550 return (rval); 15551 } 15552 } 15553 15554 /* 15555 * drain taskq to make sure nodes are created and then 15556 * try again. 15557 */ 15558 taskq_wait(DEVI(parent)->devi_taskq); 15559 return (ndi_busop_bus_config(parent, flag | NDI_MDI_FALLBACK, 15560 op, arg, childp, 0)); 15561 15562 case BUS_CONFIG_DRIVER: 15563 case BUS_CONFIG_ALL: { 15564 /* 15565 * delay till all devices report in (port_tmp_cnt == 0) 15566 * or FCP_INIT_WAIT_TIMEOUT 15567 */ 15568 mutex_enter(&pptr->port_mutex); 15569 while ((reset_delay > 0) && pptr->port_tmp_cnt) { 15570 (void) cv_timedwait(&pptr->port_config_cv, 15571 &pptr->port_mutex, 15572 ddi_get_lbolt() + (clock_t)reset_delay); 15573 reset_delay = 15574 (int64_t)(USEC_TO_TICK(FCP_INIT_WAIT_TIMEOUT)) - 15575 (lbolt64 - pptr->port_attach_time); 15576 } 15577 mutex_exit(&pptr->port_mutex); 15578 /* drain taskq to make sure nodes are created */ 15579 taskq_wait(DEVI(parent)->devi_taskq); 15580 return (ndi_busop_bus_config(parent, flag, op, 15581 arg, childp, 0)); 15582 } 15583 15584 default: 15585 return (NDI_FAILURE); 15586 } 15587 /*NOTREACHED*/ 15588 } 15589 15590 static int 15591 fcp_scsi_bus_unconfig(dev_info_t *parent, uint_t flag, 15592 ddi_bus_config_op_t op, void *arg) 15593 { 15594 if (fcp_bus_config_debug) { 15595 flag |= NDI_DEVI_DEBUG; 15596 } 15597 15598 return (ndi_busop_bus_unconfig(parent, flag, op, arg)); 15599 } 15600 15601 15602 /* 15603 * Routine to copy GUID into the lun structure. 15604 * returns 0 if copy was successful and 1 if encountered a 15605 * failure and did not copy the guid. 15606 */ 15607 static int 15608 fcp_copy_guid_2_lun_block(struct fcp_lun *plun, char *guidp) 15609 { 15610 15611 int retval = 0; 15612 15613 /* add one for the null terminator */ 15614 const unsigned int len = strlen(guidp) + 1; 15615 15616 if ((guidp == NULL) || (plun == NULL)) { 15617 return (1); 15618 } 15619 15620 /* 15621 * if the plun->lun_guid already has been allocated, 15622 * then check the size. if the size is exact, reuse 15623 * it....if not free it an allocate the required size. 15624 * The reallocation should NOT typically happen 15625 * unless the GUIDs reported changes between passes. 15626 * We free up and alloc again even if the 15627 * size was more than required. This is due to the 15628 * fact that the field lun_guid_size - serves 15629 * dual role of indicating the size of the wwn 15630 * size and ALSO the allocation size. 15631 */ 15632 if (plun->lun_guid) { 15633 if (plun->lun_guid_size != len) { 15634 /* 15635 * free the allocated memory and 15636 * initialize the field 15637 * lun_guid_size to 0. 15638 */ 15639 kmem_free(plun->lun_guid, plun->lun_guid_size); 15640 plun->lun_guid = NULL; 15641 plun->lun_guid_size = 0; 15642 } 15643 } 15644 /* 15645 * alloc only if not already done. 15646 */ 15647 if (plun->lun_guid == NULL) { 15648 plun->lun_guid = kmem_zalloc(len, KM_NOSLEEP); 15649 if (plun->lun_guid == NULL) { 15650 cmn_err(CE_WARN, "fcp_copy_guid_2_lun_block:" 15651 "Unable to allocate" 15652 "Memory for GUID!!! size %d", len); 15653 retval = 1; 15654 } else { 15655 plun->lun_guid_size = len; 15656 } 15657 } 15658 if (plun->lun_guid) { 15659 /* 15660 * now copy the GUID 15661 */ 15662 bcopy(guidp, plun->lun_guid, plun->lun_guid_size); 15663 } 15664 return (retval); 15665 } 15666 15667 /* 15668 * fcp_reconfig_wait 15669 * 15670 * Wait for a rediscovery/reconfiguration to complete before continuing. 15671 */ 15672 15673 static void 15674 fcp_reconfig_wait(struct fcp_port *pptr) 15675 { 15676 clock_t reconfig_start, wait_timeout; 15677 15678 /* 15679 * Quick check. If pptr->port_tmp_cnt is 0, there is no 15680 * reconfiguration in progress. 15681 */ 15682 15683 mutex_enter(&pptr->port_mutex); 15684 if (pptr->port_tmp_cnt == 0) { 15685 mutex_exit(&pptr->port_mutex); 15686 return; 15687 } 15688 mutex_exit(&pptr->port_mutex); 15689 15690 /* 15691 * If we cause a reconfig by raising power, delay until all devices 15692 * report in (port_tmp_cnt returns to 0) 15693 */ 15694 15695 reconfig_start = ddi_get_lbolt(); 15696 wait_timeout = drv_usectohz(FCP_INIT_WAIT_TIMEOUT); 15697 15698 mutex_enter(&pptr->port_mutex); 15699 15700 while (((ddi_get_lbolt() - reconfig_start) < wait_timeout) && 15701 pptr->port_tmp_cnt) { 15702 15703 (void) cv_timedwait(&pptr->port_config_cv, &pptr->port_mutex, 15704 reconfig_start + wait_timeout); 15705 } 15706 15707 mutex_exit(&pptr->port_mutex); 15708 15709 /* 15710 * Even if fcp_tmp_count isn't 0, continue without error. The port 15711 * we want may still be ok. If not, it will error out later 15712 */ 15713 } 15714 15715 /* 15716 * Read masking info from fp.conf and construct the global fcp_lun_blacklist. 15717 * We rely on the fcp_global_mutex to provide protection against changes to 15718 * the fcp_lun_blacklist. 15719 * 15720 * You can describe a list of target port WWNs and LUN numbers which will 15721 * not be configured. LUN numbers will be interpreted as decimal. White 15722 * spaces and ',' can be used in the list of LUN numbers. 15723 * 15724 * To prevent LUNs 1 and 2 from being configured for target 15725 * port 510000f010fd92a1 and target port 510000e012079df1, set: 15726 * 15727 * pwwn-lun-blacklist= 15728 * "510000f010fd92a1,1,2", 15729 * "510000e012079df1,1,2"; 15730 */ 15731 static void 15732 fcp_read_blacklist(dev_info_t *dip, 15733 struct fcp_black_list_entry **pplun_blacklist) { 15734 char **prop_array = NULL; 15735 char *curr_pwwn = NULL; 15736 char *curr_lun = NULL; 15737 uint32_t prop_item = 0; 15738 int idx = 0; 15739 int len = 0; 15740 15741 ASSERT(mutex_owned(&fcp_global_mutex)); 15742 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, 15743 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 15744 LUN_BLACKLIST_PROP, &prop_array, &prop_item) != DDI_PROP_SUCCESS) { 15745 return; 15746 } 15747 15748 for (idx = 0; idx < prop_item; idx++) { 15749 15750 curr_pwwn = prop_array[idx]; 15751 while (*curr_pwwn == ' ') { 15752 curr_pwwn++; 15753 } 15754 if (strlen(curr_pwwn) <= (sizeof (la_wwn_t) * 2 + 1)) { 15755 fcp_log(CE_WARN, NULL, "Invalid WWN %s in the blacklist" 15756 ", please check.", curr_pwwn); 15757 continue; 15758 } 15759 if ((*(curr_pwwn + sizeof (la_wwn_t) * 2) != ' ') && 15760 (*(curr_pwwn + sizeof (la_wwn_t) * 2) != ',')) { 15761 fcp_log(CE_WARN, NULL, "Invalid WWN %s in the blacklist" 15762 ", please check.", curr_pwwn); 15763 continue; 15764 } 15765 for (len = 0; len < sizeof (la_wwn_t) * 2; len++) { 15766 if (isxdigit(curr_pwwn[len]) != TRUE) { 15767 fcp_log(CE_WARN, NULL, "Invalid WWN %s in the " 15768 "blacklist, please check.", curr_pwwn); 15769 break; 15770 } 15771 } 15772 if (len != sizeof (la_wwn_t) * 2) { 15773 continue; 15774 } 15775 15776 curr_lun = curr_pwwn + sizeof (la_wwn_t) * 2 + 1; 15777 *(curr_lun - 1) = '\0'; 15778 fcp_mask_pwwn_lun(curr_pwwn, curr_lun, pplun_blacklist); 15779 } 15780 15781 ddi_prop_free(prop_array); 15782 } 15783 15784 /* 15785 * Get the masking info about one remote target port designated by wwn. 15786 * Lun ids could be separated by ',' or white spaces. 15787 */ 15788 static void 15789 fcp_mask_pwwn_lun(char *curr_pwwn, char *curr_lun, 15790 struct fcp_black_list_entry **pplun_blacklist) { 15791 int idx = 0; 15792 uint32_t offset = 0; 15793 unsigned long lun_id = 0; 15794 char lunid_buf[16]; 15795 char *pend = NULL; 15796 int illegal_digit = 0; 15797 15798 while (offset < strlen(curr_lun)) { 15799 while ((curr_lun[offset + idx] != ',') && 15800 (curr_lun[offset + idx] != '\0') && 15801 (curr_lun[offset + idx] != ' ')) { 15802 if (isdigit(curr_lun[offset + idx]) == 0) { 15803 illegal_digit++; 15804 } 15805 idx++; 15806 } 15807 if (illegal_digit > 0) { 15808 offset += (idx+1); /* To the start of next lun */ 15809 idx = 0; 15810 illegal_digit = 0; 15811 fcp_log(CE_WARN, NULL, "Invalid LUN %s for WWN %s in " 15812 "the blacklist, please check digits.", 15813 curr_lun, curr_pwwn); 15814 continue; 15815 } 15816 if (idx >= (sizeof (lunid_buf) / sizeof (lunid_buf[0]))) { 15817 fcp_log(CE_WARN, NULL, "Invalid LUN %s for WWN %s in " 15818 "the blacklist, please check the length of LUN#.", 15819 curr_lun, curr_pwwn); 15820 break; 15821 } 15822 if (idx == 0) { /* ignore ' ' or ',' or '\0' */ 15823 offset++; 15824 continue; 15825 } 15826 15827 bcopy(curr_lun + offset, lunid_buf, idx); 15828 lunid_buf[idx] = '\0'; 15829 if (ddi_strtoul(lunid_buf, &pend, 10, &lun_id) == 0) { 15830 fcp_add_one_mask(curr_pwwn, lun_id, pplun_blacklist); 15831 } else { 15832 fcp_log(CE_WARN, NULL, "Invalid LUN %s for WWN %s in " 15833 "the blacklist, please check %s.", 15834 curr_lun, curr_pwwn, lunid_buf); 15835 } 15836 offset += (idx+1); /* To the start of next lun */ 15837 idx = 0; 15838 } 15839 } 15840 15841 /* 15842 * Add one masking record 15843 */ 15844 static void 15845 fcp_add_one_mask(char *curr_pwwn, uint32_t lun_id, 15846 struct fcp_black_list_entry **pplun_blacklist) { 15847 struct fcp_black_list_entry *tmp_entry = *pplun_blacklist; 15848 struct fcp_black_list_entry *new_entry = NULL; 15849 la_wwn_t wwn; 15850 15851 fcp_ascii_to_wwn(curr_pwwn, wwn.raw_wwn, sizeof (la_wwn_t)); 15852 while (tmp_entry) { 15853 if ((bcmp(&tmp_entry->wwn, &wwn, 15854 sizeof (la_wwn_t)) == 0) && (tmp_entry->lun == lun_id)) { 15855 return; 15856 } 15857 15858 tmp_entry = tmp_entry->next; 15859 } 15860 15861 /* add to black list */ 15862 new_entry = (struct fcp_black_list_entry *)kmem_zalloc 15863 (sizeof (struct fcp_black_list_entry), KM_SLEEP); 15864 bcopy(&wwn, &new_entry->wwn, sizeof (la_wwn_t)); 15865 new_entry->lun = lun_id; 15866 new_entry->masked = 0; 15867 new_entry->next = *pplun_blacklist; 15868 *pplun_blacklist = new_entry; 15869 } 15870 15871 /* 15872 * Check if we should mask the specified lun of this fcp_tgt 15873 */ 15874 static int 15875 fcp_should_mask(la_wwn_t *wwn, uint32_t lun_id) { 15876 struct fcp_black_list_entry *remote_port; 15877 15878 remote_port = fcp_lun_blacklist; 15879 while (remote_port != NULL) { 15880 if (bcmp(wwn, &remote_port->wwn, sizeof (la_wwn_t)) == 0) { 15881 if (remote_port->lun == lun_id) { 15882 remote_port->masked++; 15883 if (remote_port->masked == 1) { 15884 fcp_log(CE_NOTE, NULL, "LUN %d of port " 15885 "%02x%02x%02x%02x%02x%02x%02x%02x " 15886 "is masked due to black listing.\n", 15887 lun_id, wwn->raw_wwn[0], 15888 wwn->raw_wwn[1], wwn->raw_wwn[2], 15889 wwn->raw_wwn[3], wwn->raw_wwn[4], 15890 wwn->raw_wwn[5], wwn->raw_wwn[6], 15891 wwn->raw_wwn[7]); 15892 } 15893 return (TRUE); 15894 } 15895 } 15896 remote_port = remote_port->next; 15897 } 15898 return (FALSE); 15899 } 15900 15901 /* 15902 * Release all allocated resources 15903 */ 15904 static void 15905 fcp_cleanup_blacklist(struct fcp_black_list_entry **pplun_blacklist) { 15906 struct fcp_black_list_entry *tmp_entry = *pplun_blacklist; 15907 struct fcp_black_list_entry *current_entry = NULL; 15908 15909 ASSERT(mutex_owned(&fcp_global_mutex)); 15910 /* 15911 * Traverse all luns 15912 */ 15913 while (tmp_entry) { 15914 current_entry = tmp_entry; 15915 tmp_entry = tmp_entry->next; 15916 kmem_free(current_entry, sizeof (struct fcp_black_list_entry)); 15917 } 15918 *pplun_blacklist = NULL; 15919 } 15920