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,