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 (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 23 * 24 * Fibre Channel SCSI ULP Mapping driver 25 */ 26 27 #include <sys/scsi/scsi.h> 28 #include <sys/types.h> 29 #include <sys/varargs.h> 30 #include <sys/devctl.h> 31 #include <sys/thread.h> 32 #include <sys/thread.h> 33 #include <sys/open.h> 34 #include <sys/file.h> 35 #include <sys/sunndi.h> 36 #include <sys/console.h> 37 #include <sys/proc.h> 38 #include <sys/time.h> 39 #include <sys/utsname.h> 40 #include <sys/scsi/impl/scsi_reset_notify.h> 41 #include <sys/ndi_impldefs.h> 42 #include <sys/byteorder.h> 43 #include <sys/fs/dv_node.h> 44 #include <sys/ctype.h> 45 #include <sys/sunmdi.h> 46 47 #include <sys/fibre-channel/fc.h> 48 #include <sys/fibre-channel/impl/fc_ulpif.h> 49 #include <sys/fibre-channel/ulp/fcpvar.h> 50 51 /* 52 * Discovery Process 53 * ================= 54 * 55 * The discovery process is a major function of FCP. In order to help 56 * understand that function a flow diagram is given here. This diagram 57 * doesn't claim to cover all the cases and the events that can occur during 58 * the discovery process nor the subtleties of the code. The code paths shown 59 * are simplified. Its purpose is to help the reader (and potentially bug 60 * fixer) have an overall view of the logic of the code. For that reason the 61 * diagram covers the simple case of the line coming up cleanly or of a new 62 * port attaching to FCP the link being up. The reader must keep in mind 63 * that: 64 * 65 * - There are special cases where bringing devices online and offline 66 * is driven by Ioctl. 67 * 68 * - The behavior of the discovery process can be modified through the 69 * .conf file. 70 * 71 * - The line can go down and come back up at any time during the 72 * discovery process which explains some of the complexity of the code. 73 * 74 * ............................................................................ 75 * 76 * STEP 1: The line comes up or a new Fibre Channel port attaches to FCP. 77 * 78 * 79 * +-------------------------+ 80 * fp/fctl module --->| fcp_port_attach | 81 * +-------------------------+ 82 * | | 83 * | | 84 * | v 85 * | +-------------------------+ 86 * | | fcp_handle_port_attach | 87 * | +-------------------------+ 88 * | | 89 * | | 90 * +--------------------+ | 91 * | | 92 * v v 93 * +-------------------------+ 94 * | fcp_statec_callback | 95 * +-------------------------+ 96 * | 97 * | 98 * v 99 * +-------------------------+ 100 * | fcp_handle_devices | 101 * +-------------------------+ 102 * | 103 * | 104 * v 105 * +-------------------------+ 106 * | fcp_handle_mapflags | 107 * +-------------------------+ 108 * | 109 * | 110 * v 111 * +-------------------------+ 112 * | fcp_send_els | 113 * | | 114 * | PLOGI or PRLI To all the| 115 * | reachable devices. | 116 * +-------------------------+ 117 * 118 * 119 * ............................................................................ 120 * 121 * STEP 2: The callback functions of the PLOGI and/or PRLI requests sent during 122 * STEP 1 are called (it is actually the same function). 123 * 124 * 125 * +-------------------------+ 126 * | fcp_icmd_callback | 127 * fp/fctl module --->| | 128 * | callback for PLOGI and | 129 * | PRLI. | 130 * +-------------------------+ 131 * | 132 * | 133 * Received PLOGI Accept /-\ Received PRLI Accept 134 * _ _ _ _ _ _ / \_ _ _ _ _ _ 135 * | \ / | 136 * | \-/ | 137 * | | 138 * v v 139 * +-------------------------+ +-------------------------+ 140 * | fcp_send_els | | fcp_send_scsi | 141 * | | | | 142 * | PRLI | | REPORT_LUN | 143 * +-------------------------+ +-------------------------+ 144 * 145 * ............................................................................ 146 * 147 * STEP 3: The callback functions of the SCSI commands issued by FCP are called 148 * (It is actually the same function). 149 * 150 * 151 * +-------------------------+ 152 * fp/fctl module ------->| fcp_scsi_callback | 153 * +-------------------------+ 154 * | 155 * | 156 * | 157 * Receive REPORT_LUN reply /-\ Receive INQUIRY PAGE83 reply 158 * _ _ _ _ _ _ _ _ _ _ / \_ _ _ _ _ _ _ _ _ _ _ _ 159 * | \ / | 160 * | \-/ | 161 * | | | 162 * | Receive INQUIRY reply| | 163 * | | | 164 * v v v 165 * +------------------------+ +----------------------+ +----------------------+ 166 * | fcp_handle_reportlun | | fcp_handle_inquiry | | fcp_handle_page83 | 167 * |(Called for each Target)| | (Called for each LUN)| |(Called for each LUN) | 168 * +------------------------+ +----------------------+ +----------------------+ 169 * | | | 170 * | | | 171 * | | | 172 * v v | 173 * +-----------------+ +-----------------+ | 174 * | fcp_send_scsi | | fcp_send_scsi | | 175 * | | | | | 176 * | INQUIRY | | INQUIRY PAGE83 | | 177 * | (To each LUN) | +-----------------+ | 178 * +-----------------+ | 179 * | 180 * v 181 * +------------------------+ 182 * | fcp_call_finish_init | 183 * +------------------------+ 184 * | 185 * v 186 * +-----------------------------+ 187 * | fcp_call_finish_init_held | 188 * +-----------------------------+ 189 * | 190 * | 191 * All LUNs scanned /-\ 192 * _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ / \ 193 * | \ / 194 * | \-/ 195 * v | 196 * +------------------+ | 197 * | fcp_finish_tgt | | 198 * +------------------+ | 199 * | Target Not Offline and | 200 * Target Not Offline and | not marked and tgt_node_state | 201 * marked /-\ not FCP_TGT_NODE_ON_DEMAND | 202 * _ _ _ _ _ _ / \_ _ _ _ _ _ _ _ | 203 * | \ / | | 204 * | \-/ | | 205 * v v | 206 * +----------------------------+ +-------------------+ | 207 * | fcp_offline_target | | fcp_create_luns | | 208 * | | +-------------------+ | 209 * | A structure fcp_tgt_elem | | | 210 * | is created and queued in | v | 211 * | the FCP port list | +-------------------+ | 212 * | port_offline_tgts. It | | fcp_pass_to_hp | | 213 * | will be unqueued by the | | | | 214 * | watchdog timer. | | Called for each | | 215 * +----------------------------+ | LUN. Dispatches | | 216 * | | fcp_hp_task | | 217 * | +-------------------+ | 218 * | | | 219 * | | | 220 * | | | 221 * | +---------------->| 222 * | | 223 * +---------------------------------------------->| 224 * | 225 * | 226 * All the targets (devices) have been scanned /-\ 227 * _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ / \ 228 * | \ / 229 * | \-/ 230 * +-------------------------------------+ | 231 * | fcp_finish_init | | 232 * | | | 233 * | Signal broadcasts the condition | | 234 * | variable port_config_cv of the FCP | | 235 * | port. One potential code sequence | | 236 * | waiting on the condition variable | | 237 * | the code sequence handling | | 238 * | BUS_CONFIG_ALL and BUS_CONFIG_DRIVER| | 239 * | The other is in the function | | 240 * | fcp_reconfig_wait which is called | | 241 * | in the transmit path preventing IOs | | 242 * | from going through till the disco- | | 243 * | very process is over. | | 244 * +-------------------------------------+ | 245 * | | 246 * | | 247 * +--------------------------------->| 248 * | 249 * v 250 * Return 251 * 252 * ............................................................................ 253 * 254 * STEP 4: The hot plug task is called (for each fcp_hp_elem). 255 * 256 * 257 * +-------------------------+ 258 * | fcp_hp_task | 259 * +-------------------------+ 260 * | 261 * | 262 * v 263 * +-------------------------+ 264 * | fcp_trigger_lun | 265 * +-------------------------+ 266 * | 267 * | 268 * v 269 * Bring offline /-\ Bring online 270 * _ _ _ _ _ _ _ _ _/ \_ _ _ _ _ _ _ _ _ _ 271 * | \ / | 272 * | \-/ | 273 * v v 274 * +---------------------+ +-----------------------+ 275 * | fcp_offline_child | | fcp_get_cip | 276 * +---------------------+ | | 277 * | Creates a dev_info_t | 278 * | or a mdi_pathinfo_t | 279 * | depending on whether | 280 * | mpxio is on or off. | 281 * +-----------------------+ 282 * | 283 * | 284 * v 285 * +-----------------------+ 286 * | fcp_online_child | 287 * | | 288 * | Set device online | 289 * | using NDI or MDI. | 290 * +-----------------------+ 291 * 292 * ............................................................................ 293 * 294 * STEP 5: The watchdog timer expires. The watch dog timer does much more that 295 * what is described here. We only show the target offline path. 296 * 297 * 298 * +--------------------------+ 299 * | fcp_watch | 300 * +--------------------------+ 301 * | 302 * | 303 * v 304 * +--------------------------+ 305 * | fcp_scan_offline_tgts | 306 * +--------------------------+ 307 * | 308 * | 309 * v 310 * +--------------------------+ 311 * | fcp_offline_target_now | 312 * +--------------------------+ 313 * | 314 * | 315 * v 316 * +--------------------------+ 317 * | fcp_offline_tgt_luns | 318 * +--------------------------+ 319 * | 320 * | 321 * v 322 * +--------------------------+ 323 * | fcp_offline_lun | 324 * +--------------------------+ 325 * | 326 * | 327 * v 328 * +----------------------------------+ 329 * | fcp_offline_lun_now | 330 * | | 331 * | A request (or two if mpxio) is | 332 * | sent to the hot plug task using | 333 * | a fcp_hp_elem structure. | 334 * +----------------------------------+ 335 */ 336 337 /* 338 * Functions registered with DDI framework 339 */ 340 static int fcp_attach(dev_info_t *devi, ddi_attach_cmd_t cmd); 341 static int fcp_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 342 static int fcp_open(dev_t *devp, int flag, int otype, cred_t *credp); 343 static int fcp_close(dev_t dev, int flag, int otype, cred_t *credp); 344 static int fcp_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 345 cred_t *credp, int *rval); 346 347 /* 348 * Functions registered with FC Transport framework 349 */ 350 static int fcp_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo, 351 fc_attach_cmd_t cmd, uint32_t s_id); 352 static int fcp_port_detach(opaque_t ulph, fc_ulp_port_info_t *info, 353 fc_detach_cmd_t cmd); 354 static int fcp_port_ioctl(opaque_t ulph, opaque_t port_handle, dev_t dev, 355 int cmd, intptr_t data, int mode, cred_t *credp, int *rval, 356 uint32_t claimed); 357 static int fcp_els_callback(opaque_t ulph, opaque_t port_handle, 358 fc_unsol_buf_t *buf, uint32_t claimed); 359 static int fcp_data_callback(opaque_t ulph, opaque_t port_handle, 360 fc_unsol_buf_t *buf, uint32_t claimed); 361 static void fcp_statec_callback(opaque_t ulph, opaque_t port_handle, 362 uint32_t port_state, uint32_t port_top, fc_portmap_t *devlist, 363 uint32_t dev_cnt, uint32_t port_sid); 364 365 /* 366 * Functions registered with SCSA framework 367 */ 368 static int fcp_phys_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 369 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 370 static int fcp_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 371 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 372 static void fcp_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 373 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 374 static int fcp_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); 375 static int fcp_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 376 static int fcp_scsi_reset(struct scsi_address *ap, int level); 377 static int fcp_scsi_getcap(struct scsi_address *ap, char *cap, int whom); 378 static int fcp_scsi_setcap(struct scsi_address *ap, char *cap, int value, 379 int whom); 380 static void fcp_pkt_teardown(struct scsi_pkt *pkt); 381 static int fcp_scsi_reset_notify(struct scsi_address *ap, int flag, 382 void (*callback)(caddr_t), caddr_t arg); 383 static int fcp_scsi_bus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip, 384 char *name, ddi_eventcookie_t *event_cookiep); 385 static int fcp_scsi_bus_add_eventcall(dev_info_t *dip, dev_info_t *rdip, 386 ddi_eventcookie_t eventid, void (*callback)(), void *arg, 387 ddi_callback_id_t *cb_id); 388 static int fcp_scsi_bus_remove_eventcall(dev_info_t *devi, 389 ddi_callback_id_t cb_id); 390 static int fcp_scsi_bus_post_event(dev_info_t *dip, dev_info_t *rdip, 391 ddi_eventcookie_t eventid, void *impldata); 392 static int fcp_scsi_bus_config(dev_info_t *parent, uint_t flag, 393 ddi_bus_config_op_t op, void *arg, dev_info_t **childp); 394 static int fcp_scsi_bus_unconfig(dev_info_t *parent, uint_t flag, 395 ddi_bus_config_op_t op, void *arg); 396 397 /* 398 * Internal functions 399 */ 400 static int fcp_setup_device_data_ioctl(int cmd, struct fcp_ioctl *data, 401 int mode, int *rval); 402 403 static int fcp_setup_scsi_ioctl(struct fcp_scsi_cmd *u_fscsi, 404 int mode, int *rval); 405 static int fcp_copyin_scsi_cmd(caddr_t base_addr, 406 struct fcp_scsi_cmd *fscsi, int mode); 407 static int fcp_copyout_scsi_cmd(struct fcp_scsi_cmd *fscsi, 408 caddr_t base_addr, int mode); 409 static int fcp_send_scsi_ioctl(struct fcp_scsi_cmd *fscsi); 410 411 static struct fcp_tgt *fcp_port_create_tgt(struct fcp_port *pptr, 412 la_wwn_t *pwwn, int *ret_val, int *fc_status, int *fc_pkt_state, 413 int *fc_pkt_reason, int *fc_pkt_action); 414 static int fcp_tgt_send_plogi(struct fcp_tgt *ptgt, int *fc_status, 415 int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action); 416 static int fcp_tgt_send_prli(struct fcp_tgt *ptgt, int *fc_status, 417 int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action); 418 static void fcp_ipkt_sema_init(struct fcp_ipkt *icmd); 419 static int fcp_ipkt_sema_wait(struct fcp_ipkt *icmd); 420 static void fcp_ipkt_sema_callback(struct fc_packet *fpkt); 421 static void fcp_ipkt_sema_cleanup(struct fcp_ipkt *icmd); 422 423 static void fcp_handle_devices(struct fcp_port *pptr, 424 fc_portmap_t devlist[], uint32_t dev_cnt, int link_cnt, 425 fcp_map_tag_t *map_tag, int cause); 426 static int fcp_handle_mapflags(struct fcp_port *pptr, 427 struct fcp_tgt *ptgt, fc_portmap_t *map_entry, int link_cnt, 428 int tgt_cnt, int cause); 429 static int fcp_handle_reportlun_changed(struct fcp_tgt *ptgt, int cause); 430 static int fcp_send_els(struct fcp_port *pptr, struct fcp_tgt *ptgt, 431 struct fcp_ipkt *icmd, uchar_t opcode, int lcount, int tcount, int cause); 432 static void fcp_update_state(struct fcp_port *pptr, uint32_t state, 433 int cause); 434 static void fcp_update_tgt_state(struct fcp_tgt *ptgt, int flag, 435 uint32_t state); 436 static struct fcp_port *fcp_get_port(opaque_t port_handle); 437 static void fcp_unsol_callback(fc_packet_t *fpkt); 438 static void fcp_unsol_resp_init(fc_packet_t *pkt, fc_unsol_buf_t *buf, 439 uchar_t r_ctl, uchar_t type); 440 static int fcp_unsol_prli(struct fcp_port *pptr, fc_unsol_buf_t *buf); 441 static struct fcp_ipkt *fcp_icmd_alloc(struct fcp_port *pptr, 442 struct fcp_tgt *ptgt, int cmd_len, int resp_len, int data_len, 443 int nodma, int lcount, int tcount, int cause, uint32_t rscn_count); 444 static void fcp_icmd_free(struct fcp_port *pptr, struct fcp_ipkt *icmd); 445 static int fcp_alloc_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd, 446 int nodma, int flags); 447 static void fcp_free_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd); 448 static struct fcp_tgt *fcp_lookup_target(struct fcp_port *pptr, 449 uchar_t *wwn); 450 static struct fcp_tgt *fcp_get_target_by_did(struct fcp_port *pptr, 451 uint32_t d_id); 452 static void fcp_icmd_callback(fc_packet_t *fpkt); 453 static int fcp_send_scsi(struct fcp_lun *plun, uchar_t opcode, 454 int len, int lcount, int tcount, int cause, uint32_t rscn_count); 455 static int fcp_check_reportlun(struct fcp_rsp *rsp, fc_packet_t *fpkt); 456 static void fcp_scsi_callback(fc_packet_t *fpkt); 457 static void fcp_retry_scsi_cmd(fc_packet_t *fpkt); 458 static void fcp_handle_inquiry(fc_packet_t *fpkt, struct fcp_ipkt *icmd); 459 static void fcp_handle_reportlun(fc_packet_t *fpkt, struct fcp_ipkt *icmd); 460 static struct fcp_lun *fcp_get_lun(struct fcp_tgt *ptgt, 461 uint16_t lun_num); 462 static int fcp_finish_tgt(struct fcp_port *pptr, struct fcp_tgt *ptgt, 463 int link_cnt, int tgt_cnt, int cause); 464 static void fcp_finish_init(struct fcp_port *pptr); 465 static void fcp_create_luns(struct fcp_tgt *ptgt, int link_cnt, 466 int tgt_cnt, int cause); 467 static int fcp_trigger_lun(struct fcp_lun *plun, child_info_t *cip, 468 int old_mpxio, int online, int link_cnt, int tgt_cnt, int flags); 469 static int fcp_offline_target(struct fcp_port *pptr, struct fcp_tgt *ptgt, 470 int link_cnt, int tgt_cnt, int nowait, int flags); 471 static void fcp_offline_target_now(struct fcp_port *pptr, 472 struct fcp_tgt *ptgt, int link_cnt, int tgt_cnt, int flags); 473 static void fcp_offline_tgt_luns(struct fcp_tgt *ptgt, int link_cnt, 474 int tgt_cnt, int flags); 475 static void fcp_offline_lun(struct fcp_lun *plun, int link_cnt, int tgt_cnt, 476 int nowait, int flags); 477 static void fcp_prepare_offline_lun(struct fcp_lun *plun, int link_cnt, 478 int tgt_cnt); 479 static void fcp_offline_lun_now(struct fcp_lun *plun, int link_cnt, 480 int tgt_cnt, int flags); 481 static void fcp_scan_offline_luns(struct fcp_port *pptr); 482 static void fcp_scan_offline_tgts(struct fcp_port *pptr); 483 static void fcp_update_offline_flags(struct fcp_lun *plun); 484 static struct fcp_pkt *fcp_scan_commands(struct fcp_lun *plun); 485 static void fcp_abort_commands(struct fcp_pkt *head, struct 486 fcp_port *pptr); 487 static void fcp_cmd_callback(fc_packet_t *fpkt); 488 static void fcp_complete_pkt(fc_packet_t *fpkt); 489 static int fcp_validate_fcp_response(struct fcp_rsp *rsp, 490 struct fcp_port *pptr); 491 static int fcp_device_changed(struct fcp_port *pptr, struct fcp_tgt *ptgt, 492 fc_portmap_t *map_entry, int link_cnt, int tgt_cnt, int cause); 493 static struct fcp_lun *fcp_alloc_lun(struct fcp_tgt *ptgt); 494 static void fcp_dealloc_lun(struct fcp_lun *plun); 495 static struct fcp_tgt *fcp_alloc_tgt(struct fcp_port *pptr, 496 fc_portmap_t *map_entry, int link_cnt); 497 static void fcp_dealloc_tgt(struct fcp_tgt *ptgt); 498 static void fcp_queue_ipkt(struct fcp_port *pptr, fc_packet_t *fpkt); 499 static int fcp_transport(opaque_t port_handle, fc_packet_t *fpkt, 500 int internal); 501 static void fcp_log(int level, dev_info_t *dip, const char *fmt, ...); 502 static int fcp_handle_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo, 503 uint32_t s_id, int instance); 504 static int fcp_handle_port_detach(struct fcp_port *pptr, int flag, 505 int instance); 506 static void fcp_cleanup_port(struct fcp_port *pptr, int instance); 507 static int fcp_kmem_cache_constructor(struct scsi_pkt *, scsi_hba_tran_t *, 508 int); 509 static void fcp_kmem_cache_destructor(struct scsi_pkt *, scsi_hba_tran_t *); 510 static int fcp_pkt_setup(struct scsi_pkt *, int (*)(), caddr_t); 511 static int fcp_alloc_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt, 512 int flags); 513 static void fcp_free_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt); 514 static int fcp_reset_target(struct scsi_address *ap, int level); 515 static int fcp_commoncap(struct scsi_address *ap, char *cap, 516 int val, int tgtonly, int doset); 517 static int fcp_scsi_get_name(struct scsi_device *sd, char *name, int len); 518 static int fcp_scsi_get_bus_addr(struct scsi_device *sd, char *name, int len); 519 static int fcp_linkreset(struct fcp_port *pptr, struct scsi_address *ap, 520 int sleep); 521 static int fcp_handle_port_resume(opaque_t ulph, fc_ulp_port_info_t *pinfo, 522 uint32_t s_id, fc_attach_cmd_t cmd, int instance); 523 static void fcp_cp_pinfo(struct fcp_port *pptr, fc_ulp_port_info_t *pinfo); 524 static void fcp_process_elem(struct fcp_hp_elem *elem, int result); 525 static child_info_t *fcp_get_cip(struct fcp_lun *plun, child_info_t *cip, 526 int lcount, int tcount); 527 static int fcp_is_dip_present(struct fcp_lun *plun, dev_info_t *cdip); 528 static int fcp_is_child_present(struct fcp_lun *plun, child_info_t *cip); 529 static dev_info_t *fcp_create_dip(struct fcp_lun *plun, int link_cnt, 530 int tgt_cnt); 531 static dev_info_t *fcp_find_existing_dip(struct fcp_lun *plun, 532 dev_info_t *pdip, caddr_t name); 533 static int fcp_online_child(struct fcp_lun *plun, child_info_t *cip, 534 int lcount, int tcount, int flags, int *circ); 535 static int fcp_offline_child(struct fcp_lun *plun, child_info_t *cip, 536 int lcount, int tcount, int flags, int *circ); 537 static void fcp_remove_child(struct fcp_lun *plun); 538 static void fcp_watch(void *arg); 539 static void fcp_check_reset_delay(struct fcp_port *pptr); 540 static void fcp_abort_all(struct fcp_port *pptr, struct fcp_tgt *ttgt, 541 struct fcp_lun *rlun, int tgt_cnt); 542 struct fcp_port *fcp_soft_state_unlink(struct fcp_port *pptr); 543 static struct fcp_lun *fcp_lookup_lun(struct fcp_port *pptr, 544 uchar_t *wwn, uint16_t lun); 545 static void fcp_prepare_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd, 546 struct fcp_lun *plun); 547 static void fcp_post_callback(struct fcp_pkt *cmd); 548 static int fcp_dopoll(struct fcp_port *pptr, struct fcp_pkt *cmd); 549 static struct fcp_port *fcp_dip2port(dev_info_t *dip); 550 struct fcp_lun *fcp_get_lun_from_cip(struct fcp_port *pptr, 551 child_info_t *cip); 552 static int fcp_pass_to_hp_and_wait(struct fcp_port *pptr, 553 struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt, 554 int tgt_cnt, int flags); 555 static struct fcp_hp_elem *fcp_pass_to_hp(struct fcp_port *pptr, 556 struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt, 557 int tgt_cnt, int flags, int wait); 558 static void fcp_retransport_cmd(struct fcp_port *pptr, 559 struct fcp_pkt *cmd); 560 static void fcp_fail_cmd(struct fcp_pkt *cmd, uchar_t reason, 561 uint_t statistics); 562 static void fcp_queue_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd); 563 static void fcp_update_targets(struct fcp_port *pptr, 564 fc_portmap_t *dev_list, uint32_t count, uint32_t state, int cause); 565 static int fcp_call_finish_init(struct fcp_port *pptr, 566 struct fcp_tgt *ptgt, int lcount, int tcount, int cause); 567 static int fcp_call_finish_init_held(struct fcp_port *pptr, 568 struct fcp_tgt *ptgt, int lcount, int tcount, int cause); 569 static void fcp_reconfigure_luns(void * tgt_handle); 570 static void fcp_free_targets(struct fcp_port *pptr); 571 static void fcp_free_target(struct fcp_tgt *ptgt); 572 static int fcp_is_retryable(struct fcp_ipkt *icmd); 573 static int fcp_create_on_demand(struct fcp_port *pptr, uchar_t *pwwn); 574 static void fcp_ascii_to_wwn(caddr_t string, uchar_t bytes[], unsigned int); 575 static void fcp_wwn_to_ascii(uchar_t bytes[], char *string); 576 static void fcp_print_error(fc_packet_t *fpkt); 577 static int fcp_handle_ipkt_errors(struct fcp_port *pptr, 578 struct fcp_tgt *ptgt, struct fcp_ipkt *icmd, int rval, caddr_t op); 579 static int fcp_outstanding_lun_cmds(struct fcp_tgt *ptgt); 580 static fc_portmap_t *fcp_construct_map(struct fcp_port *pptr, 581 uint32_t *dev_cnt); 582 static void fcp_offline_all(struct fcp_port *pptr, int lcount, int cause); 583 static int fcp_get_statec_count(struct fcp_ioctl *data, int mode, int *rval); 584 static int fcp_copyin_fcp_ioctl_data(struct fcp_ioctl *, int, int *, 585 struct fcp_ioctl *, struct fcp_port **); 586 static char *fcp_get_lun_path(struct fcp_lun *plun); 587 static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode, 588 int *rval); 589 static int fcp_do_ns_registry(struct fcp_port *pptr, uint32_t s_id); 590 static void fcp_retry_ns_registry(struct fcp_port *pptr, uint32_t s_id); 591 static char *fcp_get_lun_path(struct fcp_lun *plun); 592 static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode, 593 int *rval); 594 static void fcp_reconfig_wait(struct fcp_port *pptr); 595 596 /* 597 * New functions added for mpxio support 598 */ 599 static int fcp_virt_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 600 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 601 static mdi_pathinfo_t *fcp_create_pip(struct fcp_lun *plun, int lcount, 602 int tcount); 603 static mdi_pathinfo_t *fcp_find_existing_pip(struct fcp_lun *plun, 604 dev_info_t *pdip); 605 static int fcp_is_pip_present(struct fcp_lun *plun, mdi_pathinfo_t *pip); 606 static void fcp_handle_page83(fc_packet_t *, struct fcp_ipkt *, int); 607 static void fcp_update_mpxio_path_verifybusy(struct fcp_port *pptr); 608 static int fcp_copy_guid_2_lun_block(struct fcp_lun *plun, char *guidp); 609 static int fcp_update_mpxio_path(struct fcp_lun *plun, child_info_t *cip, 610 int what); 611 static int fcp_is_reconfig_needed(struct fcp_tgt *ptgt, 612 fc_packet_t *fpkt); 613 static int fcp_symmetric_device_probe(struct fcp_lun *plun); 614 615 /* 616 * New functions added for lun masking support 617 */ 618 static void fcp_read_blacklist(dev_info_t *dip, 619 struct fcp_black_list_entry **pplun_blacklist); 620 static void fcp_mask_pwwn_lun(char *curr_pwwn, char *curr_lun, 621 struct fcp_black_list_entry **pplun_blacklist); 622 static void fcp_add_one_mask(char *curr_pwwn, uint32_t lun_id, 623 struct fcp_black_list_entry **pplun_blacklist); 624 static int fcp_should_mask(la_wwn_t *wwn, uint32_t lun_id); 625 static void fcp_cleanup_blacklist(struct fcp_black_list_entry **lun_blacklist); 626 627 /* 628 * New functions to support software FCA (like fcoei) 629 */ 630 static struct scsi_pkt *fcp_pseudo_init_pkt( 631 struct scsi_address *ap, struct scsi_pkt *pkt, 632 struct buf *bp, int cmdlen, int statuslen, 633 int tgtlen, int flags, int (*callback)(), caddr_t arg); 634 static void fcp_pseudo_destroy_pkt( 635 struct scsi_address *ap, struct scsi_pkt *pkt); 636 static void fcp_pseudo_sync_pkt( 637 struct scsi_address *ap, struct scsi_pkt *pkt); 638 static int fcp_pseudo_start(struct scsi_address *ap, struct scsi_pkt *pkt); 639 static void fcp_pseudo_dmafree( 640 struct scsi_address *ap, struct scsi_pkt *pkt); 641 642 extern struct mod_ops mod_driverops; 643 /* 644 * This variable is defined in modctl.c and set to '1' after the root driver 645 * and fs are loaded. It serves as an indication that the root filesystem can 646 * be used. 647 */ 648 extern int modrootloaded; 649 /* 650 * This table contains strings associated with the SCSI sense key codes. It 651 * is used by FCP to print a clear explanation of the code returned in the 652 * sense information by a device. 653 */ 654 extern char *sense_keys[]; 655 /* 656 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is 657 * under this device that the paths to a physical device are created when 658 * MPxIO is used. 659 */ 660 extern dev_info_t *scsi_vhci_dip; 661 662 /* 663 * Report lun processing 664 */ 665 #define FCP_LUN_ADDRESSING 0x80 666 #define FCP_PD_ADDRESSING 0x00 667 #define FCP_VOLUME_ADDRESSING 0x40 668 669 #define FCP_SVE_THROTTLE 0x28 /* Vicom */ 670 #define MAX_INT_DMA 0x7fffffff 671 /* 672 * Property definitions 673 */ 674 #define NODE_WWN_PROP (char *)fcp_node_wwn_prop 675 #define PORT_WWN_PROP (char *)fcp_port_wwn_prop 676 #define TARGET_PROP (char *)fcp_target_prop 677 #define LUN_PROP (char *)fcp_lun_prop 678 #define SAM_LUN_PROP (char *)fcp_sam_lun_prop 679 #define CONF_WWN_PROP (char *)fcp_conf_wwn_prop 680 #define OBP_BOOT_WWN (char *)fcp_obp_boot_wwn 681 #define MANUAL_CFG_ONLY (char *)fcp_manual_config_only 682 #define INIT_PORT_PROP (char *)fcp_init_port_prop 683 #define TGT_PORT_PROP (char *)fcp_tgt_port_prop 684 #define LUN_BLACKLIST_PROP (char *)fcp_lun_blacklist_prop 685 /* 686 * Short hand macros. 687 */ 688 #define LUN_PORT (plun->lun_tgt->tgt_port) 689 #define LUN_TGT (plun->lun_tgt) 690 691 /* 692 * Driver private macros 693 */ 694 #define FCP_ATOB(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : \ 695 ((x) >= 'a' && (x) <= 'f') ? \ 696 ((x) - 'a' + 10) : ((x) - 'A' + 10)) 697 698 #define FCP_MAX(a, b) ((a) > (b) ? (a) : (b)) 699 700 #define FCP_N_NDI_EVENTS \ 701 (sizeof (fcp_ndi_event_defs) / sizeof (ndi_event_definition_t)) 702 703 #define FCP_LINK_STATE_CHANGED(p, c) \ 704 ((p)->port_link_cnt != (c)->ipkt_link_cnt) 705 706 #define FCP_TGT_STATE_CHANGED(t, c) \ 707 ((t)->tgt_change_cnt != (c)->ipkt_change_cnt) 708 709 #define FCP_STATE_CHANGED(p, t, c) \ 710 (FCP_TGT_STATE_CHANGED(t, c)) 711 712 #define FCP_MUST_RETRY(fpkt) \ 713 ((fpkt)->pkt_state == FC_PKT_LOCAL_BSY || \ 714 (fpkt)->pkt_state == FC_PKT_LOCAL_RJT || \ 715 (fpkt)->pkt_state == FC_PKT_TRAN_BSY || \ 716 (fpkt)->pkt_state == FC_PKT_ELS_IN_PROGRESS || \ 717 (fpkt)->pkt_state == FC_PKT_NPORT_BSY || \ 718 (fpkt)->pkt_state == FC_PKT_FABRIC_BSY || \ 719 (fpkt)->pkt_state == FC_PKT_PORT_OFFLINE || \ 720 (fpkt)->pkt_reason == FC_REASON_OFFLINE) 721 722 #define FCP_SENSE_REPORTLUN_CHANGED(es) \ 723 ((es)->es_key == KEY_UNIT_ATTENTION && \ 724 (es)->es_add_code == 0x3f && \ 725 (es)->es_qual_code == 0x0e) 726 727 #define FCP_SENSE_NO_LUN(es) \ 728 ((es)->es_key == KEY_ILLEGAL_REQUEST && \ 729 (es)->es_add_code == 0x25 && \ 730 (es)->es_qual_code == 0x0) 731 732 #define FCP_VERSION "20091208-1.192" 733 #define FCP_NAME_VERSION "SunFC FCP v" FCP_VERSION 734 735 #define FCP_NUM_ELEMENTS(array) \ 736 (sizeof (array) / sizeof ((array)[0])) 737 738 /* 739 * Debugging, Error reporting, and tracing 740 */ 741 #define FCP_LOG_SIZE 1024 * 1024 742 743 #define FCP_LEVEL_1 0x00001 /* attach/detach PM CPR */ 744 #define FCP_LEVEL_2 0x00002 /* failures/Invalid data */ 745 #define FCP_LEVEL_3 0x00004 /* state change, discovery */ 746 #define FCP_LEVEL_4 0x00008 /* ULP messages */ 747 #define FCP_LEVEL_5 0x00010 /* ELS/SCSI cmds */ 748 #define FCP_LEVEL_6 0x00020 /* Transport failures */ 749 #define FCP_LEVEL_7 0x00040 750 #define FCP_LEVEL_8 0x00080 /* I/O tracing */ 751 #define FCP_LEVEL_9 0x00100 /* I/O tracing */ 752 753 754 755 /* 756 * Log contents to system messages file 757 */ 758 #define FCP_MSG_LEVEL_1 (FCP_LEVEL_1 | FC_TRACE_LOG_MSG) 759 #define FCP_MSG_LEVEL_2 (FCP_LEVEL_2 | FC_TRACE_LOG_MSG) 760 #define FCP_MSG_LEVEL_3 (FCP_LEVEL_3 | FC_TRACE_LOG_MSG) 761 #define FCP_MSG_LEVEL_4 (FCP_LEVEL_4 | FC_TRACE_LOG_MSG) 762 #define FCP_MSG_LEVEL_5 (FCP_LEVEL_5 | FC_TRACE_LOG_MSG) 763 #define FCP_MSG_LEVEL_6 (FCP_LEVEL_6 | FC_TRACE_LOG_MSG) 764 #define FCP_MSG_LEVEL_7 (FCP_LEVEL_7 | FC_TRACE_LOG_MSG) 765 #define FCP_MSG_LEVEL_8 (FCP_LEVEL_8 | FC_TRACE_LOG_MSG) 766 #define FCP_MSG_LEVEL_9 (FCP_LEVEL_9 | FC_TRACE_LOG_MSG) 767 768 769 /* 770 * Log contents to trace buffer 771 */ 772 #define FCP_BUF_LEVEL_1 (FCP_LEVEL_1 | FC_TRACE_LOG_BUF) 773 #define FCP_BUF_LEVEL_2 (FCP_LEVEL_2 | FC_TRACE_LOG_BUF) 774 #define FCP_BUF_LEVEL_3 (FCP_LEVEL_3 | FC_TRACE_LOG_BUF) 775 #define FCP_BUF_LEVEL_4 (FCP_LEVEL_4 | FC_TRACE_LOG_BUF) 776 #define FCP_BUF_LEVEL_5 (FCP_LEVEL_5 | FC_TRACE_LOG_BUF) 777 #define FCP_BUF_LEVEL_6 (FCP_LEVEL_6 | FC_TRACE_LOG_BUF) 778 #define FCP_BUF_LEVEL_7 (FCP_LEVEL_7 | FC_TRACE_LOG_BUF) 779 #define FCP_BUF_LEVEL_8 (FCP_LEVEL_8 | FC_TRACE_LOG_BUF) 780 #define FCP_BUF_LEVEL_9 (FCP_LEVEL_9 | FC_TRACE_LOG_BUF) 781 782 783 /* 784 * Log contents to both system messages file and trace buffer 785 */ 786 #define FCP_MSG_BUF_LEVEL_1 (FCP_LEVEL_1 | FC_TRACE_LOG_BUF | \ 787 FC_TRACE_LOG_MSG) 788 #define FCP_MSG_BUF_LEVEL_2 (FCP_LEVEL_2 | FC_TRACE_LOG_BUF | \ 789 FC_TRACE_LOG_MSG) 790 #define FCP_MSG_BUF_LEVEL_3 (FCP_LEVEL_3 | FC_TRACE_LOG_BUF | \ 791 FC_TRACE_LOG_MSG) 792 #define FCP_MSG_BUF_LEVEL_4 (FCP_LEVEL_4 | FC_TRACE_LOG_BUF | \ 793 FC_TRACE_LOG_MSG) 794 #define FCP_MSG_BUF_LEVEL_5 (FCP_LEVEL_5 | FC_TRACE_LOG_BUF | \ 795 FC_TRACE_LOG_MSG) 796 #define FCP_MSG_BUF_LEVEL_6 (FCP_LEVEL_6 | FC_TRACE_LOG_BUF | \ 797 FC_TRACE_LOG_MSG) 798 #define FCP_MSG_BUF_LEVEL_7 (FCP_LEVEL_7 | FC_TRACE_LOG_BUF | \ 799 FC_TRACE_LOG_MSG) 800 #define FCP_MSG_BUF_LEVEL_8 (FCP_LEVEL_8 | FC_TRACE_LOG_BUF | \ 801 FC_TRACE_LOG_MSG) 802 #define FCP_MSG_BUF_LEVEL_9 (FCP_LEVEL_9 | FC_TRACE_LOG_BUF | \ 803 FC_TRACE_LOG_MSG) 804 #ifdef DEBUG 805 #define FCP_DTRACE fc_trace_debug 806 #else 807 #define FCP_DTRACE 808 #endif 809 810 #define FCP_TRACE fc_trace_debug 811 812 static struct cb_ops fcp_cb_ops = { 813 fcp_open, /* open */ 814 fcp_close, /* close */ 815 nodev, /* strategy */ 816 nodev, /* print */ 817 nodev, /* dump */ 818 nodev, /* read */ 819 nodev, /* write */ 820 fcp_ioctl, /* ioctl */ 821 nodev, /* devmap */ 822 nodev, /* mmap */ 823 nodev, /* segmap */ 824 nochpoll, /* chpoll */ 825 ddi_prop_op, /* cb_prop_op */ 826 0, /* streamtab */ 827 D_NEW | D_MP | D_HOTPLUG, /* cb_flag */ 828 CB_REV, /* rev */ 829 nodev, /* aread */ 830 nodev /* awrite */ 831 }; 832 833 834 static struct dev_ops fcp_ops = { 835 DEVO_REV, 836 0, 837 ddi_getinfo_1to1, 838 nulldev, /* identify */ 839 nulldev, /* probe */ 840 fcp_attach, /* attach and detach are mandatory */ 841 fcp_detach, 842 nodev, /* reset */ 843 &fcp_cb_ops, /* cb_ops */ 844 NULL, /* bus_ops */ 845 NULL, /* power */ 846 }; 847 848 849 char *fcp_version = FCP_NAME_VERSION; 850 851 static struct modldrv modldrv = { 852 &mod_driverops, 853 FCP_NAME_VERSION, 854 &fcp_ops 855 }; 856 857 858 static struct modlinkage modlinkage = { 859 MODREV_1, 860 &modldrv, 861 NULL 862 }; 863 864 865 static fc_ulp_modinfo_t fcp_modinfo = { 866 &fcp_modinfo, /* ulp_handle */ 867 FCTL_ULP_MODREV_4, /* ulp_rev */ 868 FC4_SCSI_FCP, /* ulp_type */ 869 "fcp", /* ulp_name */ 870 FCP_STATEC_MASK, /* ulp_statec_mask */ 871 fcp_port_attach, /* ulp_port_attach */ 872 fcp_port_detach, /* ulp_port_detach */ 873 fcp_port_ioctl, /* ulp_port_ioctl */ 874 fcp_els_callback, /* ulp_els_callback */ 875 fcp_data_callback, /* ulp_data_callback */ 876 fcp_statec_callback /* ulp_statec_callback */ 877 }; 878 879 #ifdef DEBUG 880 #define FCP_TRACE_DEFAULT (FC_TRACE_LOG_MASK | FCP_LEVEL_1 | \ 881 FCP_LEVEL_2 | FCP_LEVEL_3 | \ 882 FCP_LEVEL_4 | FCP_LEVEL_5 | \ 883 FCP_LEVEL_6 | FCP_LEVEL_7) 884 #else 885 #define FCP_TRACE_DEFAULT (FC_TRACE_LOG_MASK | FCP_LEVEL_1 | \ 886 FCP_LEVEL_2 | FCP_LEVEL_3 | \ 887 FCP_LEVEL_4 | FCP_LEVEL_5 | \ 888 FCP_LEVEL_6 | FCP_LEVEL_7) 889 #endif 890 891 /* FCP global variables */ 892 int fcp_bus_config_debug = 0; 893 static int fcp_log_size = FCP_LOG_SIZE; 894 static int fcp_trace = FCP_TRACE_DEFAULT; 895 static fc_trace_logq_t *fcp_logq = NULL; 896 static struct fcp_black_list_entry *fcp_lun_blacklist = NULL; 897 /* 898 * The auto-configuration is set by default. The only way of disabling it is 899 * through the property MANUAL_CFG_ONLY in the fcp.conf file. 900 */ 901 static int fcp_enable_auto_configuration = 1; 902 static int fcp_max_bus_config_retries = 4; 903 static int fcp_lun_ready_retry = 300; 904 /* 905 * The value assigned to the following variable has changed several times due 906 * to a problem with the data underruns reporting of some firmware(s). The 907 * current value of 50 gives a timeout value of 25 seconds for a max number 908 * of 256 LUNs. 909 */ 910 static int fcp_max_target_retries = 50; 911 /* 912 * Watchdog variables 913 * ------------------ 914 * 915 * fcp_watchdog_init 916 * 917 * Indicates if the watchdog timer is running or not. This is actually 918 * a counter of the number of Fibre Channel ports that attached. When 919 * the first port attaches the watchdog is started. When the last port 920 * detaches the watchdog timer is stopped. 921 * 922 * fcp_watchdog_time 923 * 924 * This is the watchdog clock counter. It is incremented by 925 * fcp_watchdog_time each time the watchdog timer expires. 926 * 927 * fcp_watchdog_timeout 928 * 929 * Increment value of the variable fcp_watchdog_time as well as the 930 * the timeout value of the watchdog timer. The unit is 1 second. It 931 * is strange that this is not a #define but a variable since the code 932 * never changes this value. The reason why it can be said that the 933 * unit is 1 second is because the number of ticks for the watchdog 934 * timer is determined like this: 935 * 936 * fcp_watchdog_tick = fcp_watchdog_timeout * 937 * drv_usectohz(1000000); 938 * 939 * The value 1000000 is hard coded in the code. 940 * 941 * fcp_watchdog_tick 942 * 943 * Watchdog timer value in ticks. 944 */ 945 static int fcp_watchdog_init = 0; 946 static int fcp_watchdog_time = 0; 947 static int fcp_watchdog_timeout = 1; 948 static int fcp_watchdog_tick; 949 950 /* 951 * fcp_offline_delay is a global variable to enable customisation of 952 * the timeout on link offlines or RSCNs. The default value is set 953 * to match FCP_OFFLINE_DELAY (20sec), which is 2*RA_TOV_els as 954 * specified in FCP4 Chapter 11 (see www.t10.org). 955 * 956 * The variable fcp_offline_delay is specified in SECONDS. 957 * 958 * If we made this a static var then the user would not be able to 959 * change it. This variable is set in fcp_attach(). 960 */ 961 unsigned int fcp_offline_delay = FCP_OFFLINE_DELAY; 962 963 static void *fcp_softstate = NULL; /* for soft state */ 964 static uchar_t fcp_oflag = FCP_IDLE; /* open flag */ 965 static kmutex_t fcp_global_mutex; 966 static kmutex_t fcp_ioctl_mutex; 967 static dev_info_t *fcp_global_dip = NULL; 968 static timeout_id_t fcp_watchdog_id; 969 const char *fcp_lun_prop = "lun"; 970 const char *fcp_sam_lun_prop = "sam-lun"; 971 const char *fcp_target_prop = "target"; 972 /* 973 * NOTE: consumers of "node-wwn" property include stmsboot in ON 974 * consolidation. 975 */ 976 const char *fcp_node_wwn_prop = "node-wwn"; 977 const char *fcp_port_wwn_prop = "port-wwn"; 978 const char *fcp_conf_wwn_prop = "fc-port-wwn"; 979 const char *fcp_obp_boot_wwn = "fc-boot-dev-portwwn"; 980 const char *fcp_manual_config_only = "manual_configuration_only"; 981 const char *fcp_init_port_prop = "initiator-port"; 982 const char *fcp_tgt_port_prop = "target-port"; 983 const char *fcp_lun_blacklist_prop = "pwwn-lun-blacklist"; 984 985 static struct fcp_port *fcp_port_head = NULL; 986 static ddi_eventcookie_t fcp_insert_eid; 987 static ddi_eventcookie_t fcp_remove_eid; 988 989 static ndi_event_definition_t fcp_ndi_event_defs[] = { 990 { FCP_EVENT_TAG_INSERT, FCAL_INSERT_EVENT, EPL_KERNEL }, 991 { FCP_EVENT_TAG_REMOVE, FCAL_REMOVE_EVENT, EPL_INTERRUPT } 992 }; 993 994 /* 995 * List of valid commands for the scsi_ioctl call 996 */ 997 static uint8_t scsi_ioctl_list[] = { 998 SCMD_INQUIRY, 999 SCMD_REPORT_LUN, 1000 SCMD_READ_CAPACITY 1001 }; 1002 1003 /* 1004 * this is used to dummy up a report lun response for cases 1005 * where the target doesn't support it 1006 */ 1007 static uchar_t fcp_dummy_lun[] = { 1008 0x00, /* MSB length (length = no of luns * 8) */ 1009 0x00, 1010 0x00, 1011 0x08, /* LSB length */ 1012 0x00, /* MSB reserved */ 1013 0x00, 1014 0x00, 1015 0x00, /* LSB reserved */ 1016 FCP_PD_ADDRESSING, 1017 0x00, /* LUN is ZERO at the first level */ 1018 0x00, 1019 0x00, /* second level is zero */ 1020 0x00, 1021 0x00, /* third level is zero */ 1022 0x00, 1023 0x00 /* fourth level is zero */ 1024 }; 1025 1026 static uchar_t fcp_alpa_to_switch[] = { 1027 0x00, 0x7d, 0x7c, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x7a, 0x00, 1028 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x78, 0x00, 0x00, 0x00, 1029 0x00, 0x00, 0x00, 0x77, 0x76, 0x00, 0x00, 0x75, 0x00, 0x74, 1030 0x73, 0x72, 0x00, 0x00, 0x00, 0x71, 0x00, 0x70, 0x6f, 0x6e, 1031 0x00, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x00, 0x00, 0x67, 1032 0x66, 0x65, 0x64, 0x63, 0x62, 0x00, 0x00, 0x61, 0x60, 0x00, 1033 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x5d, 1034 0x5c, 0x5b, 0x00, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x00, 1035 0x00, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x00, 0x00, 0x4e, 1036 0x4d, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 1037 0x00, 0x4a, 0x49, 0x48, 0x00, 0x47, 0x46, 0x45, 0x44, 0x43, 1038 0x42, 0x00, 0x00, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x00, 1039 0x00, 0x3b, 0x3a, 0x00, 0x39, 0x00, 0x00, 0x00, 0x38, 0x37, 1040 0x36, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 1041 0x00, 0x00, 0x00, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 1042 0x00, 0x31, 0x30, 0x00, 0x00, 0x2f, 0x00, 0x2e, 0x2d, 0x2c, 1043 0x00, 0x00, 0x00, 0x2b, 0x00, 0x2a, 0x29, 0x28, 0x00, 0x27, 1044 0x26, 0x25, 0x24, 0x23, 0x22, 0x00, 0x00, 0x21, 0x20, 0x1f, 1045 0x1e, 0x1d, 0x1c, 0x00, 0x00, 0x1b, 0x1a, 0x00, 0x19, 0x00, 1046 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x17, 0x16, 0x15, 1047 0x00, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x00, 0x00, 0x0e, 1048 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x00, 0x00, 0x08, 0x07, 0x00, 1049 0x06, 0x00, 0x00, 0x00, 0x05, 0x04, 0x03, 0x00, 0x02, 0x00, 1050 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1051 }; 1052 1053 static caddr_t pid = "SESS01 "; 1054 1055 #if !defined(lint) 1056 1057 _NOTE(MUTEX_PROTECTS_DATA(fcp_global_mutex, 1058 fcp_port::fcp_next fcp_watchdog_id)) 1059 1060 _NOTE(DATA_READABLE_WITHOUT_LOCK(fcp_watchdog_time)) 1061 1062 _NOTE(SCHEME_PROTECTS_DATA("Unshared", 1063 fcp_insert_eid 1064 fcp_remove_eid 1065 fcp_watchdog_time)) 1066 1067 _NOTE(SCHEME_PROTECTS_DATA("Unshared", 1068 fcp_cb_ops 1069 fcp_ops 1070 callb_cpr)) 1071 1072 #endif /* lint */ 1073 1074 /* 1075 * This table is used to determine whether or not it's safe to copy in 1076 * the target node name for a lun. Since all luns behind the same target 1077 * have the same wwnn, only tagets that do not support multiple luns are 1078 * eligible to be enumerated under mpxio if they aren't page83 compliant. 1079 */ 1080 1081 char *fcp_symmetric_disk_table[] = { 1082 "SEAGATE ST", 1083 "IBM DDYFT", 1084 "SUNW SUNWGS", /* Daktari enclosure */ 1085 "SUN SENA", /* SES device */ 1086 "SUN SESS01" /* VICOM SVE box */ 1087 }; 1088 1089 int fcp_symmetric_disk_table_size = 1090 sizeof (fcp_symmetric_disk_table)/sizeof (char *); 1091 1092 /* 1093 * This structure is bogus. scsi_hba_attach_setup() requires, as in the kernel 1094 * will panic if you don't pass this in to the routine, this information. 1095 * Need to determine what the actual impact to the system is by providing 1096 * this information if any. Since dma allocation is done in pkt_init it may 1097 * not have any impact. These values are straight from the Writing Device 1098 * Driver manual. 1099 */ 1100 static ddi_dma_attr_t pseudo_fca_dma_attr = { 1101 DMA_ATTR_V0, /* ddi_dma_attr version */ 1102 0, /* low address */ 1103 0xffffffff, /* high address */ 1104 0x00ffffff, /* counter upper bound */ 1105 1, /* alignment requirements */ 1106 0x3f, /* burst sizes */ 1107 1, /* minimum DMA access */ 1108 0xffffffff, /* maximum DMA access */ 1109 (1 << 24) - 1, /* segment boundary restrictions */ 1110 1, /* scater/gather list length */ 1111 512, /* device granularity */ 1112 0 /* DMA flags */ 1113 }; 1114 1115 /* 1116 * The _init(9e) return value should be that of mod_install(9f). Under 1117 * some circumstances, a failure may not be related mod_install(9f) and 1118 * one would then require a return value to indicate the failure. Looking 1119 * at mod_install(9f), it is expected to return 0 for success and non-zero 1120 * for failure. mod_install(9f) for device drivers, further goes down the 1121 * calling chain and ends up in ddi_installdrv(), whose return values are 1122 * DDI_SUCCESS and DDI_FAILURE - There are also other functions in the 1123 * calling chain of mod_install(9f) which return values like EINVAL and 1124 * in some even return -1. 1125 * 1126 * To work around the vagaries of the mod_install() calling chain, return 1127 * either 0 or ENODEV depending on the success or failure of mod_install() 1128 */ 1129 int 1130 _init(void) 1131 { 1132 int rval; 1133 1134 /* 1135 * Allocate soft state and prepare to do ddi_soft_state_zalloc() 1136 * before registering with the transport first. 1137 */ 1138 if (ddi_soft_state_init(&fcp_softstate, 1139 sizeof (struct fcp_port), FCP_INIT_ITEMS) != 0) { 1140 return (EINVAL); 1141 } 1142 1143 mutex_init(&fcp_global_mutex, NULL, MUTEX_DRIVER, NULL); 1144 mutex_init(&fcp_ioctl_mutex, NULL, MUTEX_DRIVER, NULL); 1145 1146 if ((rval = fc_ulp_add(&fcp_modinfo)) != FC_SUCCESS) { 1147 cmn_err(CE_WARN, "fcp: fc_ulp_add failed"); 1148 mutex_destroy(&fcp_global_mutex); 1149 mutex_destroy(&fcp_ioctl_mutex); 1150 ddi_soft_state_fini(&fcp_softstate); 1151 return (ENODEV); 1152 } 1153 1154 fcp_logq = fc_trace_alloc_logq(fcp_log_size); 1155 1156 if ((rval = mod_install(&modlinkage)) != 0) { 1157 fc_trace_free_logq(fcp_logq); 1158 (void) fc_ulp_remove(&fcp_modinfo); 1159 mutex_destroy(&fcp_global_mutex); 1160 mutex_destroy(&fcp_ioctl_mutex); 1161 ddi_soft_state_fini(&fcp_softstate); 1162 rval = ENODEV; 1163 } 1164 1165 return (rval); 1166 } 1167 1168 1169 /* 1170 * the system is done with us as a driver, so clean up 1171 */ 1172 int 1173 _fini(void) 1174 { 1175 int rval; 1176 1177 /* 1178 * don't start cleaning up until we know that the module remove 1179 * has worked -- if this works, then we know that each instance 1180 * has successfully been DDI_DETACHed 1181 */ 1182 if ((rval = mod_remove(&modlinkage)) != 0) { 1183 return (rval); 1184 } 1185 1186 (void) fc_ulp_remove(&fcp_modinfo); 1187 1188 ddi_soft_state_fini(&fcp_softstate); 1189 mutex_destroy(&fcp_global_mutex); 1190 mutex_destroy(&fcp_ioctl_mutex); 1191 fc_trace_free_logq(fcp_logq); 1192 1193 return (rval); 1194 } 1195 1196 1197 int 1198 _info(struct modinfo *modinfop) 1199 { 1200 return (mod_info(&modlinkage, modinfop)); 1201 } 1202 1203 1204 /* 1205 * attach the module 1206 */ 1207 static int 1208 fcp_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 1209 { 1210 int rval = DDI_SUCCESS; 1211 1212 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 1213 FCP_BUF_LEVEL_8, 0, "fcp module attach: cmd=0x%x", cmd); 1214 1215 if (cmd == DDI_ATTACH) { 1216 /* The FCP pseudo device is created here. */ 1217 mutex_enter(&fcp_global_mutex); 1218 fcp_global_dip = devi; 1219 mutex_exit(&fcp_global_mutex); 1220 1221 if (ddi_create_minor_node(fcp_global_dip, "fcp", S_IFCHR, 1222 0, DDI_PSEUDO, 0) == DDI_SUCCESS) { 1223 ddi_report_dev(fcp_global_dip); 1224 } else { 1225 cmn_err(CE_WARN, "FCP: Cannot create minor node"); 1226 mutex_enter(&fcp_global_mutex); 1227 fcp_global_dip = NULL; 1228 mutex_exit(&fcp_global_mutex); 1229 1230 rval = DDI_FAILURE; 1231 } 1232 /* 1233 * We check the fcp_offline_delay property at this 1234 * point. This variable is global for the driver, 1235 * not specific to an instance. 1236 * 1237 * We do not recommend setting the value to less 1238 * than 10 seconds (RA_TOV_els), or greater than 1239 * 60 seconds. 1240 */ 1241 fcp_offline_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 1242 devi, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 1243 "fcp_offline_delay", FCP_OFFLINE_DELAY); 1244 if ((fcp_offline_delay < 10) || 1245 (fcp_offline_delay > 60)) { 1246 cmn_err(CE_WARN, "Setting fcp_offline_delay " 1247 "to %d second(s). This is outside the " 1248 "recommended range of 10..60 seconds.", 1249 fcp_offline_delay); 1250 } 1251 } 1252 1253 return (rval); 1254 } 1255 1256 1257 /*ARGSUSED*/ 1258 static int 1259 fcp_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1260 { 1261 int res = DDI_SUCCESS; 1262 1263 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 1264 FCP_BUF_LEVEL_8, 0, "module detach: cmd=0x%x", cmd); 1265 1266 if (cmd == DDI_DETACH) { 1267 /* 1268 * Check if there are active ports/threads. If there 1269 * are any, we will fail, else we will succeed (there 1270 * should not be much to clean up) 1271 */ 1272 mutex_enter(&fcp_global_mutex); 1273 FCP_DTRACE(fcp_logq, "fcp", 1274 fcp_trace, FCP_BUF_LEVEL_8, 0, "port_head=%p", 1275 (void *) fcp_port_head); 1276 1277 if (fcp_port_head == NULL) { 1278 ddi_remove_minor_node(fcp_global_dip, NULL); 1279 fcp_global_dip = NULL; 1280 mutex_exit(&fcp_global_mutex); 1281 } else { 1282 mutex_exit(&fcp_global_mutex); 1283 res = DDI_FAILURE; 1284 } 1285 } 1286 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 1287 FCP_BUF_LEVEL_8, 0, "module detach returning %d", res); 1288 1289 return (res); 1290 } 1291 1292 1293 /* ARGSUSED */ 1294 static int 1295 fcp_open(dev_t *devp, int flag, int otype, cred_t *credp) 1296 { 1297 if (otype != OTYP_CHR) { 1298 return (EINVAL); 1299 } 1300 1301 /* 1302 * Allow only root to talk; 1303 */ 1304 if (drv_priv(credp)) { 1305 return (EPERM); 1306 } 1307 1308 mutex_enter(&fcp_global_mutex); 1309 if (fcp_oflag & FCP_EXCL) { 1310 mutex_exit(&fcp_global_mutex); 1311 return (EBUSY); 1312 } 1313 1314 if (flag & FEXCL) { 1315 if (fcp_oflag & FCP_OPEN) { 1316 mutex_exit(&fcp_global_mutex); 1317 return (EBUSY); 1318 } 1319 fcp_oflag |= FCP_EXCL; 1320 } 1321 fcp_oflag |= FCP_OPEN; 1322 mutex_exit(&fcp_global_mutex); 1323 1324 return (0); 1325 } 1326 1327 1328 /* ARGSUSED */ 1329 static int 1330 fcp_close(dev_t dev, int flag, int otype, cred_t *credp) 1331 { 1332 if (otype != OTYP_CHR) { 1333 return (EINVAL); 1334 } 1335 1336 mutex_enter(&fcp_global_mutex); 1337 if (!(fcp_oflag & FCP_OPEN)) { 1338 mutex_exit(&fcp_global_mutex); 1339 return (ENODEV); 1340 } 1341 fcp_oflag = FCP_IDLE; 1342 mutex_exit(&fcp_global_mutex); 1343 1344 return (0); 1345 } 1346 1347 1348 /* 1349 * fcp_ioctl 1350 * Entry point for the FCP ioctls 1351 * 1352 * Input: 1353 * See ioctl(9E) 1354 * 1355 * Output: 1356 * See ioctl(9E) 1357 * 1358 * Returns: 1359 * See ioctl(9E) 1360 * 1361 * Context: 1362 * Kernel context. 1363 */ 1364 /* ARGSUSED */ 1365 static int 1366 fcp_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 1367 int *rval) 1368 { 1369 int ret = 0; 1370 1371 mutex_enter(&fcp_global_mutex); 1372 if (!(fcp_oflag & FCP_OPEN)) { 1373 mutex_exit(&fcp_global_mutex); 1374 return (ENXIO); 1375 } 1376 mutex_exit(&fcp_global_mutex); 1377 1378 switch (cmd) { 1379 case FCP_TGT_INQUIRY: 1380 case FCP_TGT_CREATE: 1381 case FCP_TGT_DELETE: 1382 ret = fcp_setup_device_data_ioctl(cmd, 1383 (struct fcp_ioctl *)data, mode, rval); 1384 break; 1385 1386 case FCP_TGT_SEND_SCSI: 1387 mutex_enter(&fcp_ioctl_mutex); 1388 ret = fcp_setup_scsi_ioctl( 1389 (struct fcp_scsi_cmd *)data, mode, rval); 1390 mutex_exit(&fcp_ioctl_mutex); 1391 break; 1392 1393 case FCP_STATE_COUNT: 1394 ret = fcp_get_statec_count((struct fcp_ioctl *)data, 1395 mode, rval); 1396 break; 1397 case FCP_GET_TARGET_MAPPINGS: 1398 ret = fcp_get_target_mappings((struct fcp_ioctl *)data, 1399 mode, rval); 1400 break; 1401 default: 1402 fcp_log(CE_WARN, NULL, 1403 "!Invalid ioctl opcode = 0x%x", cmd); 1404 ret = EINVAL; 1405 } 1406 1407 return (ret); 1408 } 1409 1410 1411 /* 1412 * fcp_setup_device_data_ioctl 1413 * Setup handler for the "device data" style of 1414 * ioctl for FCP. See "fcp_util.h" for data structure 1415 * definition. 1416 * 1417 * Input: 1418 * cmd = FCP ioctl command 1419 * data = ioctl data 1420 * mode = See ioctl(9E) 1421 * 1422 * Output: 1423 * data = ioctl data 1424 * rval = return value - see ioctl(9E) 1425 * 1426 * Returns: 1427 * See ioctl(9E) 1428 * 1429 * Context: 1430 * Kernel context. 1431 */ 1432 /* ARGSUSED */ 1433 static int 1434 fcp_setup_device_data_ioctl(int cmd, struct fcp_ioctl *data, int mode, 1435 int *rval) 1436 { 1437 struct fcp_port *pptr; 1438 struct device_data *dev_data; 1439 uint32_t link_cnt; 1440 la_wwn_t *wwn_ptr = NULL; 1441 struct fcp_tgt *ptgt = NULL; 1442 struct fcp_lun *plun = NULL; 1443 int i, error; 1444 struct fcp_ioctl fioctl; 1445 1446 #ifdef _MULTI_DATAMODEL 1447 switch (ddi_model_convert_from(mode & FMODELS)) { 1448 case DDI_MODEL_ILP32: { 1449 struct fcp32_ioctl f32_ioctl; 1450 1451 if (ddi_copyin((void *)data, (void *)&f32_ioctl, 1452 sizeof (struct fcp32_ioctl), mode)) { 1453 return (EFAULT); 1454 } 1455 fioctl.fp_minor = f32_ioctl.fp_minor; 1456 fioctl.listlen = f32_ioctl.listlen; 1457 fioctl.list = (caddr_t)(long)f32_ioctl.list; 1458 break; 1459 } 1460 case DDI_MODEL_NONE: 1461 if (ddi_copyin((void *)data, (void *)&fioctl, 1462 sizeof (struct fcp_ioctl), mode)) { 1463 return (EFAULT); 1464 } 1465 break; 1466 } 1467 1468 #else /* _MULTI_DATAMODEL */ 1469 if (ddi_copyin((void *)data, (void *)&fioctl, 1470 sizeof (struct fcp_ioctl), mode)) { 1471 return (EFAULT); 1472 } 1473 #endif /* _MULTI_DATAMODEL */ 1474 1475 /* 1476 * Right now we can assume that the minor number matches with 1477 * this instance of fp. If this changes we will need to 1478 * revisit this logic. 1479 */ 1480 mutex_enter(&fcp_global_mutex); 1481 pptr = fcp_port_head; 1482 while (pptr) { 1483 if (pptr->port_instance == (uint32_t)fioctl.fp_minor) { 1484 break; 1485 } else { 1486 pptr = pptr->port_next; 1487 } 1488 } 1489 mutex_exit(&fcp_global_mutex); 1490 if (pptr == NULL) { 1491 return (ENXIO); 1492 } 1493 mutex_enter(&pptr->port_mutex); 1494 1495 1496 if ((dev_data = kmem_zalloc((sizeof (struct device_data)) * 1497 fioctl.listlen, KM_NOSLEEP)) == NULL) { 1498 mutex_exit(&pptr->port_mutex); 1499 return (ENOMEM); 1500 } 1501 1502 if (ddi_copyin(fioctl.list, dev_data, 1503 (sizeof (struct device_data)) * fioctl.listlen, mode)) { 1504 kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen); 1505 mutex_exit(&pptr->port_mutex); 1506 return (EFAULT); 1507 } 1508 link_cnt = pptr->port_link_cnt; 1509 1510 if (cmd == FCP_TGT_INQUIRY) { 1511 wwn_ptr = (la_wwn_t *)&(dev_data[0].dev_pwwn); 1512 if (bcmp(wwn_ptr->raw_wwn, pptr->port_pwwn.raw_wwn, 1513 sizeof (wwn_ptr->raw_wwn)) == 0) { 1514 /* This ioctl is requesting INQ info of local HBA */ 1515 mutex_exit(&pptr->port_mutex); 1516 dev_data[0].dev0_type = DTYPE_UNKNOWN; 1517 dev_data[0].dev_status = 0; 1518 if (ddi_copyout(dev_data, fioctl.list, 1519 (sizeof (struct device_data)) * fioctl.listlen, 1520 mode)) { 1521 kmem_free(dev_data, 1522 sizeof (*dev_data) * fioctl.listlen); 1523 return (EFAULT); 1524 } 1525 kmem_free(dev_data, 1526 sizeof (*dev_data) * fioctl.listlen); 1527 #ifdef _MULTI_DATAMODEL 1528 switch (ddi_model_convert_from(mode & FMODELS)) { 1529 case DDI_MODEL_ILP32: { 1530 struct fcp32_ioctl f32_ioctl; 1531 f32_ioctl.fp_minor = fioctl.fp_minor; 1532 f32_ioctl.listlen = fioctl.listlen; 1533 f32_ioctl.list = (caddr32_t)(long)fioctl.list; 1534 if (ddi_copyout((void *)&f32_ioctl, 1535 (void *)data, 1536 sizeof (struct fcp32_ioctl), mode)) { 1537 return (EFAULT); 1538 } 1539 break; 1540 } 1541 case DDI_MODEL_NONE: 1542 if (ddi_copyout((void *)&fioctl, (void *)data, 1543 sizeof (struct fcp_ioctl), mode)) { 1544 return (EFAULT); 1545 } 1546 break; 1547 } 1548 #else /* _MULTI_DATAMODEL */ 1549 if (ddi_copyout((void *)&fioctl, (void *)data, 1550 sizeof (struct fcp_ioctl), mode)) { 1551 return (EFAULT); 1552 } 1553 #endif /* _MULTI_DATAMODEL */ 1554 return (0); 1555 } 1556 } 1557 1558 if (pptr->port_state & (FCP_STATE_INIT | FCP_STATE_OFFLINE)) { 1559 kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen); 1560 mutex_exit(&pptr->port_mutex); 1561 return (ENXIO); 1562 } 1563 1564 for (i = 0; (i < fioctl.listlen) && (link_cnt == pptr->port_link_cnt); 1565 i++) { 1566 wwn_ptr = (la_wwn_t *)&(dev_data[i].dev_pwwn); 1567 1568 dev_data[i].dev0_type = DTYPE_UNKNOWN; 1569 1570 1571 dev_data[i].dev_status = ENXIO; 1572 1573 if ((ptgt = fcp_lookup_target(pptr, 1574 (uchar_t *)wwn_ptr)) == NULL) { 1575 mutex_exit(&pptr->port_mutex); 1576 if (fc_ulp_get_remote_port(pptr->port_fp_handle, 1577 wwn_ptr, &error, 0) == NULL) { 1578 dev_data[i].dev_status = ENODEV; 1579 mutex_enter(&pptr->port_mutex); 1580 continue; 1581 } else { 1582 1583 dev_data[i].dev_status = EAGAIN; 1584 1585 mutex_enter(&pptr->port_mutex); 1586 continue; 1587 } 1588 } else { 1589 mutex_enter(&ptgt->tgt_mutex); 1590 if (ptgt->tgt_state & (FCP_TGT_MARK | 1591 FCP_TGT_BUSY)) { 1592 dev_data[i].dev_status = EAGAIN; 1593 mutex_exit(&ptgt->tgt_mutex); 1594 continue; 1595 } 1596 1597 if (ptgt->tgt_state & FCP_TGT_OFFLINE) { 1598 if (ptgt->tgt_icap && !ptgt->tgt_tcap) { 1599 dev_data[i].dev_status = ENOTSUP; 1600 } else { 1601 dev_data[i].dev_status = ENXIO; 1602 } 1603 mutex_exit(&ptgt->tgt_mutex); 1604 continue; 1605 } 1606 1607 switch (cmd) { 1608 case FCP_TGT_INQUIRY: 1609 /* 1610 * The reason we give device type of 1611 * lun 0 only even though in some 1612 * cases(like maxstrat) lun 0 device 1613 * type may be 0x3f(invalid) is that 1614 * for bridge boxes target will appear 1615 * as luns and the first lun could be 1616 * a device that utility may not care 1617 * about (like a tape device). 1618 */ 1619 dev_data[i].dev_lun_cnt = ptgt->tgt_lun_cnt; 1620 dev_data[i].dev_status = 0; 1621 mutex_exit(&ptgt->tgt_mutex); 1622 1623 if ((plun = fcp_get_lun(ptgt, 0)) == NULL) { 1624 dev_data[i].dev0_type = DTYPE_UNKNOWN; 1625 } else { 1626 dev_data[i].dev0_type = plun->lun_type; 1627 } 1628 mutex_enter(&ptgt->tgt_mutex); 1629 break; 1630 1631 case FCP_TGT_CREATE: 1632 mutex_exit(&ptgt->tgt_mutex); 1633 mutex_exit(&pptr->port_mutex); 1634 1635 /* 1636 * serialize state change call backs. 1637 * only one call back will be handled 1638 * at a time. 1639 */ 1640 mutex_enter(&fcp_global_mutex); 1641 if (fcp_oflag & FCP_BUSY) { 1642 mutex_exit(&fcp_global_mutex); 1643 if (dev_data) { 1644 kmem_free(dev_data, 1645 sizeof (*dev_data) * 1646 fioctl.listlen); 1647 } 1648 return (EBUSY); 1649 } 1650 fcp_oflag |= FCP_BUSY; 1651 mutex_exit(&fcp_global_mutex); 1652 1653 dev_data[i].dev_status = 1654 fcp_create_on_demand(pptr, 1655 wwn_ptr->raw_wwn); 1656 1657 if (dev_data[i].dev_status != 0) { 1658 char buf[25]; 1659 1660 for (i = 0; i < FC_WWN_SIZE; i++) { 1661 (void) sprintf(&buf[i << 1], 1662 "%02x", 1663 wwn_ptr->raw_wwn[i]); 1664 } 1665 1666 fcp_log(CE_WARN, pptr->port_dip, 1667 "!Failed to create nodes for" 1668 " pwwn=%s; error=%x", buf, 1669 dev_data[i].dev_status); 1670 } 1671 1672 /* allow state change call backs again */ 1673 mutex_enter(&fcp_global_mutex); 1674 fcp_oflag &= ~FCP_BUSY; 1675 mutex_exit(&fcp_global_mutex); 1676 1677 mutex_enter(&pptr->port_mutex); 1678 mutex_enter(&ptgt->tgt_mutex); 1679 1680 break; 1681 1682 case FCP_TGT_DELETE: 1683 break; 1684 1685 default: 1686 fcp_log(CE_WARN, pptr->port_dip, 1687 "!Invalid device data ioctl " 1688 "opcode = 0x%x", cmd); 1689 } 1690 mutex_exit(&ptgt->tgt_mutex); 1691 } 1692 } 1693 mutex_exit(&pptr->port_mutex); 1694 1695 if (ddi_copyout(dev_data, fioctl.list, 1696 (sizeof (struct device_data)) * fioctl.listlen, mode)) { 1697 kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen); 1698 return (EFAULT); 1699 } 1700 kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen); 1701 1702 #ifdef _MULTI_DATAMODEL 1703 switch (ddi_model_convert_from(mode & FMODELS)) { 1704 case DDI_MODEL_ILP32: { 1705 struct fcp32_ioctl f32_ioctl; 1706 1707 f32_ioctl.fp_minor = fioctl.fp_minor; 1708 f32_ioctl.listlen = fioctl.listlen; 1709 f32_ioctl.list = (caddr32_t)(long)fioctl.list; 1710 if (ddi_copyout((void *)&f32_ioctl, (void *)data, 1711 sizeof (struct fcp32_ioctl), mode)) { 1712 return (EFAULT); 1713 } 1714 break; 1715 } 1716 case DDI_MODEL_NONE: 1717 if (ddi_copyout((void *)&fioctl, (void *)data, 1718 sizeof (struct fcp_ioctl), mode)) { 1719 return (EFAULT); 1720 } 1721 break; 1722 } 1723 #else /* _MULTI_DATAMODEL */ 1724 1725 if (ddi_copyout((void *)&fioctl, (void *)data, 1726 sizeof (struct fcp_ioctl), mode)) { 1727 return (EFAULT); 1728 } 1729 #endif /* _MULTI_DATAMODEL */ 1730 1731 return (0); 1732 } 1733 1734 /* 1735 * Fetch the target mappings (path, etc.) for all LUNs 1736 * on this port. 1737 */ 1738 /* ARGSUSED */ 1739 static int 1740 fcp_get_target_mappings(struct fcp_ioctl *data, 1741 int mode, int *rval) 1742 { 1743 struct fcp_port *pptr; 1744 fc_hba_target_mappings_t *mappings; 1745 fc_hba_mapping_entry_t *map; 1746 struct fcp_tgt *ptgt = NULL; 1747 struct fcp_lun *plun = NULL; 1748 int i, mapIndex, mappingSize; 1749 int listlen; 1750 struct fcp_ioctl fioctl; 1751 char *path; 1752 fcp_ent_addr_t sam_lun_addr; 1753 1754 #ifdef _MULTI_DATAMODEL 1755 switch (ddi_model_convert_from(mode & FMODELS)) { 1756 case DDI_MODEL_ILP32: { 1757 struct fcp32_ioctl f32_ioctl; 1758 1759 if (ddi_copyin((void *)data, (void *)&f32_ioctl, 1760 sizeof (struct fcp32_ioctl), mode)) { 1761 return (EFAULT); 1762 } 1763 fioctl.fp_minor = f32_ioctl.fp_minor; 1764 fioctl.listlen = f32_ioctl.listlen; 1765 fioctl.list = (caddr_t)(long)f32_ioctl.list; 1766 break; 1767 } 1768 case DDI_MODEL_NONE: 1769 if (ddi_copyin((void *)data, (void *)&fioctl, 1770 sizeof (struct fcp_ioctl), mode)) { 1771 return (EFAULT); 1772 } 1773 break; 1774 } 1775 1776 #else /* _MULTI_DATAMODEL */ 1777 if (ddi_copyin((void *)data, (void *)&fioctl, 1778 sizeof (struct fcp_ioctl), mode)) { 1779 return (EFAULT); 1780 } 1781 #endif /* _MULTI_DATAMODEL */ 1782 1783 /* 1784 * Right now we can assume that the minor number matches with 1785 * this instance of fp. If this changes we will need to 1786 * revisit this logic. 1787 */ 1788 mutex_enter(&fcp_global_mutex); 1789 pptr = fcp_port_head; 1790 while (pptr) { 1791 if (pptr->port_instance == (uint32_t)fioctl.fp_minor) { 1792 break; 1793 } else { 1794 pptr = pptr->port_next; 1795 } 1796 } 1797 mutex_exit(&fcp_global_mutex); 1798 if (pptr == NULL) { 1799 cmn_err(CE_NOTE, "target mappings: unknown instance number: %d", 1800 fioctl.fp_minor); 1801 return (ENXIO); 1802 } 1803 1804 1805 /* We use listlen to show the total buffer size */ 1806 mappingSize = fioctl.listlen; 1807 1808 /* Now calculate how many mapping entries will fit */ 1809 listlen = fioctl.listlen + sizeof (fc_hba_mapping_entry_t) 1810 - sizeof (fc_hba_target_mappings_t); 1811 if (listlen <= 0) { 1812 cmn_err(CE_NOTE, "target mappings: Insufficient buffer"); 1813 return (ENXIO); 1814 } 1815 listlen = listlen / sizeof (fc_hba_mapping_entry_t); 1816 1817 if ((mappings = kmem_zalloc(mappingSize, KM_SLEEP)) == NULL) { 1818 return (ENOMEM); 1819 } 1820 mappings->version = FC_HBA_TARGET_MAPPINGS_VERSION; 1821 1822 /* Now get to work */ 1823 mapIndex = 0; 1824 1825 mutex_enter(&pptr->port_mutex); 1826 /* Loop through all targets on this port */ 1827 for (i = 0; i < FCP_NUM_HASH; i++) { 1828 for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL; 1829 ptgt = ptgt->tgt_next) { 1830 1831 mutex_enter(&ptgt->tgt_mutex); 1832 1833 /* Loop through all LUNs on this target */ 1834 for (plun = ptgt->tgt_lun; plun != NULL; 1835 plun = plun->lun_next) { 1836 if (plun->lun_state & FCP_LUN_OFFLINE) { 1837 continue; 1838 } 1839 1840 path = fcp_get_lun_path(plun); 1841 if (path == NULL) { 1842 continue; 1843 } 1844 1845 if (mapIndex >= listlen) { 1846 mapIndex ++; 1847 kmem_free(path, MAXPATHLEN); 1848 continue; 1849 } 1850 map = &mappings->entries[mapIndex++]; 1851 bcopy(path, map->targetDriver, 1852 sizeof (map->targetDriver)); 1853 map->d_id = ptgt->tgt_d_id; 1854 map->busNumber = 0; 1855 map->targetNumber = ptgt->tgt_d_id; 1856 map->osLUN = plun->lun_num; 1857 1858 /* 1859 * We had swapped lun when we stored it in 1860 * lun_addr. We need to swap it back before 1861 * returning it to user land 1862 */ 1863 1864 sam_lun_addr.ent_addr_0 = 1865 BE_16(plun->lun_addr.ent_addr_0); 1866 sam_lun_addr.ent_addr_1 = 1867 BE_16(plun->lun_addr.ent_addr_1); 1868 sam_lun_addr.ent_addr_2 = 1869 BE_16(plun->lun_addr.ent_addr_2); 1870 sam_lun_addr.ent_addr_3 = 1871 BE_16(plun->lun_addr.ent_addr_3); 1872 1873 bcopy(&sam_lun_addr, &map->samLUN, 1874 FCP_LUN_SIZE); 1875 bcopy(ptgt->tgt_node_wwn.raw_wwn, 1876 map->NodeWWN.raw_wwn, sizeof (la_wwn_t)); 1877 bcopy(ptgt->tgt_port_wwn.raw_wwn, 1878 map->PortWWN.raw_wwn, sizeof (la_wwn_t)); 1879 1880 if (plun->lun_guid) { 1881 1882 /* convert ascii wwn to bytes */ 1883 fcp_ascii_to_wwn(plun->lun_guid, 1884 map->guid, sizeof (map->guid)); 1885 1886 if ((sizeof (map->guid)) < 1887 plun->lun_guid_size / 2) { 1888 cmn_err(CE_WARN, 1889 "fcp_get_target_mappings:" 1890 "guid copy space " 1891 "insufficient." 1892 "Copy Truncation - " 1893 "available %d; need %d", 1894 (int)sizeof (map->guid), 1895 (int) 1896 plun->lun_guid_size / 2); 1897 } 1898 } 1899 kmem_free(path, MAXPATHLEN); 1900 } 1901 mutex_exit(&ptgt->tgt_mutex); 1902 } 1903 } 1904 mutex_exit(&pptr->port_mutex); 1905 mappings->numLuns = mapIndex; 1906 1907 if (ddi_copyout(mappings, fioctl.list, mappingSize, mode)) { 1908 kmem_free(mappings, mappingSize); 1909 return (EFAULT); 1910 } 1911 kmem_free(mappings, mappingSize); 1912 1913 #ifdef _MULTI_DATAMODEL 1914 switch (ddi_model_convert_from(mode & FMODELS)) { 1915 case DDI_MODEL_ILP32: { 1916 struct fcp32_ioctl f32_ioctl; 1917 1918 f32_ioctl.fp_minor = fioctl.fp_minor; 1919 f32_ioctl.listlen = fioctl.listlen; 1920 f32_ioctl.list = (caddr32_t)(long)fioctl.list; 1921 if (ddi_copyout((void *)&f32_ioctl, (void *)data, 1922 sizeof (struct fcp32_ioctl), mode)) { 1923 return (EFAULT); 1924 } 1925 break; 1926 } 1927 case DDI_MODEL_NONE: 1928 if (ddi_copyout((void *)&fioctl, (void *)data, 1929 sizeof (struct fcp_ioctl), mode)) { 1930 return (EFAULT); 1931 } 1932 break; 1933 } 1934 #else /* _MULTI_DATAMODEL */ 1935 1936 if (ddi_copyout((void *)&fioctl, (void *)data, 1937 sizeof (struct fcp_ioctl), mode)) { 1938 return (EFAULT); 1939 } 1940 #endif /* _MULTI_DATAMODEL */ 1941 1942 return (0); 1943 } 1944 1945 /* 1946 * fcp_setup_scsi_ioctl 1947 * Setup handler for the "scsi passthru" style of 1948 * ioctl for FCP. See "fcp_util.h" for data structure 1949 * definition. 1950 * 1951 * Input: 1952 * u_fscsi = ioctl data (user address space) 1953 * mode = See ioctl(9E) 1954 * 1955 * Output: 1956 * u_fscsi = ioctl data (user address space) 1957 * rval = return value - see ioctl(9E) 1958 * 1959 * Returns: 1960 * 0 = OK 1961 * EAGAIN = See errno.h 1962 * EBUSY = See errno.h 1963 * EFAULT = See errno.h 1964 * EINTR = See errno.h 1965 * EINVAL = See errno.h 1966 * EIO = See errno.h 1967 * ENOMEM = See errno.h 1968 * ENXIO = See errno.h 1969 * 1970 * Context: 1971 * Kernel context. 1972 */ 1973 /* ARGSUSED */ 1974 static int 1975 fcp_setup_scsi_ioctl(struct fcp_scsi_cmd *u_fscsi, 1976 int mode, int *rval) 1977 { 1978 int ret = 0; 1979 int temp_ret; 1980 caddr_t k_cdbbufaddr = NULL; 1981 caddr_t k_bufaddr = NULL; 1982 caddr_t k_rqbufaddr = NULL; 1983 caddr_t u_cdbbufaddr; 1984 caddr_t u_bufaddr; 1985 caddr_t u_rqbufaddr; 1986 struct fcp_scsi_cmd k_fscsi; 1987 1988 /* 1989 * Get fcp_scsi_cmd array element from user address space 1990 */ 1991 if ((ret = fcp_copyin_scsi_cmd((caddr_t)u_fscsi, &k_fscsi, mode)) 1992 != 0) { 1993 return (ret); 1994 } 1995 1996 1997 /* 1998 * Even though kmem_alloc() checks the validity of the 1999 * buffer length, this check is needed when the 2000 * kmem_flags set and the zero buffer length is passed. 2001 */ 2002 if ((k_fscsi.scsi_cdblen <= 0) || 2003 (k_fscsi.scsi_buflen <= 0) || 2004 (k_fscsi.scsi_rqlen <= 0)) { 2005 return (EINVAL); 2006 } 2007 2008 /* 2009 * Allocate data for fcp_scsi_cmd pointer fields 2010 */ 2011 if (ret == 0) { 2012 k_cdbbufaddr = kmem_alloc(k_fscsi.scsi_cdblen, KM_NOSLEEP); 2013 k_bufaddr = kmem_alloc(k_fscsi.scsi_buflen, KM_NOSLEEP); 2014 k_rqbufaddr = kmem_alloc(k_fscsi.scsi_rqlen, KM_NOSLEEP); 2015 2016 if (k_cdbbufaddr == NULL || 2017 k_bufaddr == NULL || 2018 k_rqbufaddr == NULL) { 2019 ret = ENOMEM; 2020 } 2021 } 2022 2023 /* 2024 * Get fcp_scsi_cmd pointer fields from user 2025 * address space 2026 */ 2027 if (ret == 0) { 2028 u_cdbbufaddr = k_fscsi.scsi_cdbbufaddr; 2029 u_bufaddr = k_fscsi.scsi_bufaddr; 2030 u_rqbufaddr = k_fscsi.scsi_rqbufaddr; 2031 2032 if (ddi_copyin(u_cdbbufaddr, 2033 k_cdbbufaddr, 2034 k_fscsi.scsi_cdblen, 2035 mode)) { 2036 ret = EFAULT; 2037 } else if (ddi_copyin(u_bufaddr, 2038 k_bufaddr, 2039 k_fscsi.scsi_buflen, 2040 mode)) { 2041 ret = EFAULT; 2042 } else if (ddi_copyin(u_rqbufaddr, 2043 k_rqbufaddr, 2044 k_fscsi.scsi_rqlen, 2045 mode)) { 2046 ret = EFAULT; 2047 } 2048 } 2049 2050 /* 2051 * Send scsi command (blocking) 2052 */ 2053 if (ret == 0) { 2054 /* 2055 * Prior to sending the scsi command, the 2056 * fcp_scsi_cmd data structure must contain kernel, 2057 * not user, addresses. 2058 */ 2059 k_fscsi.scsi_cdbbufaddr = k_cdbbufaddr; 2060 k_fscsi.scsi_bufaddr = k_bufaddr; 2061 k_fscsi.scsi_rqbufaddr = k_rqbufaddr; 2062 2063 ret = fcp_send_scsi_ioctl(&k_fscsi); 2064 2065 /* 2066 * After sending the scsi command, the 2067 * fcp_scsi_cmd data structure must contain user, 2068 * not kernel, addresses. 2069 */ 2070 k_fscsi.scsi_cdbbufaddr = u_cdbbufaddr; 2071 k_fscsi.scsi_bufaddr = u_bufaddr; 2072 k_fscsi.scsi_rqbufaddr = u_rqbufaddr; 2073 } 2074 2075 /* 2076 * Put fcp_scsi_cmd pointer fields to user address space 2077 */ 2078 if (ret == 0) { 2079 if (ddi_copyout(k_cdbbufaddr, 2080 u_cdbbufaddr, 2081 k_fscsi.scsi_cdblen, 2082 mode)) { 2083 ret = EFAULT; 2084 } else if (ddi_copyout(k_bufaddr, 2085 u_bufaddr, 2086 k_fscsi.scsi_buflen, 2087 mode)) { 2088 ret = EFAULT; 2089 } else if (ddi_copyout(k_rqbufaddr, 2090 u_rqbufaddr, 2091 k_fscsi.scsi_rqlen, 2092 mode)) { 2093 ret = EFAULT; 2094 } 2095 } 2096 2097 /* 2098 * Free data for fcp_scsi_cmd pointer fields 2099 */ 2100 if (k_cdbbufaddr != NULL) { 2101 kmem_free(k_cdbbufaddr, k_fscsi.scsi_cdblen); 2102 } 2103 if (k_bufaddr != NULL) { 2104 kmem_free(k_bufaddr, k_fscsi.scsi_buflen); 2105 } 2106 if (k_rqbufaddr != NULL) { 2107 kmem_free(k_rqbufaddr, k_fscsi.scsi_rqlen); 2108 } 2109 2110 /* 2111 * Put fcp_scsi_cmd array element to user address space 2112 */ 2113 temp_ret = fcp_copyout_scsi_cmd(&k_fscsi, (caddr_t)u_fscsi, mode); 2114 if (temp_ret != 0) { 2115 ret = temp_ret; 2116 } 2117 2118 /* 2119 * Return status 2120 */ 2121 return (ret); 2122 } 2123 2124 2125 /* 2126 * fcp_copyin_scsi_cmd 2127 * Copy in fcp_scsi_cmd data structure from user address space. 2128 * The data may be in 32 bit or 64 bit modes. 2129 * 2130 * Input: 2131 * base_addr = from address (user address space) 2132 * mode = See ioctl(9E) and ddi_copyin(9F) 2133 * 2134 * Output: 2135 * fscsi = to address (kernel address space) 2136 * 2137 * Returns: 2138 * 0 = OK 2139 * EFAULT = Error 2140 * 2141 * Context: 2142 * Kernel context. 2143 */ 2144 static int 2145 fcp_copyin_scsi_cmd(caddr_t base_addr, struct fcp_scsi_cmd *fscsi, int mode) 2146 { 2147 #ifdef _MULTI_DATAMODEL 2148 struct fcp32_scsi_cmd f32scsi; 2149 2150 switch (ddi_model_convert_from(mode & FMODELS)) { 2151 case DDI_MODEL_ILP32: 2152 /* 2153 * Copy data from user address space 2154 */ 2155 if (ddi_copyin((void *)base_addr, 2156 &f32scsi, 2157 sizeof (struct fcp32_scsi_cmd), 2158 mode)) { 2159 return (EFAULT); 2160 } 2161 /* 2162 * Convert from 32 bit to 64 bit 2163 */ 2164 FCP32_SCSI_CMD_TO_FCP_SCSI_CMD(&f32scsi, fscsi); 2165 break; 2166 case DDI_MODEL_NONE: 2167 /* 2168 * Copy data from user address space 2169 */ 2170 if (ddi_copyin((void *)base_addr, 2171 fscsi, 2172 sizeof (struct fcp_scsi_cmd), 2173 mode)) { 2174 return (EFAULT); 2175 } 2176 break; 2177 } 2178 #else /* _MULTI_DATAMODEL */ 2179 /* 2180 * Copy data from user address space 2181 */ 2182 if (ddi_copyin((void *)base_addr, 2183 fscsi, 2184 sizeof (struct fcp_scsi_cmd), 2185 mode)) { 2186 return (EFAULT); 2187 } 2188 #endif /* _MULTI_DATAMODEL */ 2189 2190 return (0); 2191 } 2192 2193 2194 /* 2195 * fcp_copyout_scsi_cmd 2196 * Copy out fcp_scsi_cmd data structure to user address space. 2197 * The data may be in 32 bit or 64 bit modes. 2198 * 2199 * Input: 2200 * fscsi = to address (kernel address space) 2201 * mode = See ioctl(9E) and ddi_copyin(9F) 2202 * 2203 * Output: 2204 * base_addr = from address (user address space) 2205 * 2206 * Returns: 2207 * 0 = OK 2208 * EFAULT = Error 2209 * 2210 * Context: 2211 * Kernel context. 2212 */ 2213 static int 2214 fcp_copyout_scsi_cmd(struct fcp_scsi_cmd *fscsi, caddr_t base_addr, int mode) 2215 { 2216 #ifdef _MULTI_DATAMODEL 2217 struct fcp32_scsi_cmd f32scsi; 2218 2219 switch (ddi_model_convert_from(mode & FMODELS)) { 2220 case DDI_MODEL_ILP32: 2221 /* 2222 * Convert from 64 bit to 32 bit 2223 */ 2224 FCP_SCSI_CMD_TO_FCP32_SCSI_CMD(fscsi, &f32scsi); 2225 /* 2226 * Copy data to user address space 2227 */ 2228 if (ddi_copyout(&f32scsi, 2229 (void *)base_addr, 2230 sizeof (struct fcp32_scsi_cmd), 2231 mode)) { 2232 return (EFAULT); 2233 } 2234 break; 2235 case DDI_MODEL_NONE: 2236 /* 2237 * Copy data to user address space 2238 */ 2239 if (ddi_copyout(fscsi, 2240 (void *)base_addr, 2241 sizeof (struct fcp_scsi_cmd), 2242 mode)) { 2243 return (EFAULT); 2244 } 2245 break; 2246 } 2247 #else /* _MULTI_DATAMODEL */ 2248 /* 2249 * Copy data to user address space 2250 */ 2251 if (ddi_copyout(fscsi, 2252 (void *)base_addr, 2253 sizeof (struct fcp_scsi_cmd), 2254 mode)) { 2255 return (EFAULT); 2256 } 2257 #endif /* _MULTI_DATAMODEL */ 2258 2259 return (0); 2260 } 2261 2262 2263 /* 2264 * fcp_send_scsi_ioctl 2265 * Sends the SCSI command in blocking mode. 2266 * 2267 * Input: 2268 * fscsi = SCSI command data structure 2269 * 2270 * Output: 2271 * fscsi = SCSI command data structure 2272 * 2273 * Returns: 2274 * 0 = OK 2275 * EAGAIN = See errno.h 2276 * EBUSY = See errno.h 2277 * EINTR = See errno.h 2278 * EINVAL = See errno.h 2279 * EIO = See errno.h 2280 * ENOMEM = See errno.h 2281 * ENXIO = See errno.h 2282 * 2283 * Context: 2284 * Kernel context. 2285 */ 2286 static int 2287 fcp_send_scsi_ioctl(struct fcp_scsi_cmd *fscsi) 2288 { 2289 struct fcp_lun *plun = NULL; 2290 struct fcp_port *pptr = NULL; 2291 struct fcp_tgt *ptgt = NULL; 2292 fc_packet_t *fpkt = NULL; 2293 struct fcp_ipkt *icmd = NULL; 2294 int target_created = FALSE; 2295 fc_frame_hdr_t *hp; 2296 struct fcp_cmd fcp_cmd; 2297 struct fcp_cmd *fcmd; 2298 union scsi_cdb *scsi_cdb; 2299 la_wwn_t *wwn_ptr; 2300 int nodma; 2301 struct fcp_rsp *rsp; 2302 struct fcp_rsp_info *rsp_info; 2303 caddr_t rsp_sense; 2304 int buf_len; 2305 int info_len; 2306 int sense_len; 2307 struct scsi_extended_sense *sense_to = NULL; 2308 timeout_id_t tid; 2309 uint8_t reconfig_lun = FALSE; 2310 uint8_t reconfig_pending = FALSE; 2311 uint8_t scsi_cmd; 2312 int rsp_len; 2313 int cmd_index; 2314 int fc_status; 2315 int pkt_state; 2316 int pkt_action; 2317 int pkt_reason; 2318 int ret, xport_retval = ~FC_SUCCESS; 2319 int lcount; 2320 int tcount; 2321 int reconfig_status; 2322 int port_busy = FALSE; 2323 uchar_t *lun_string; 2324 2325 /* 2326 * Check valid SCSI command 2327 */ 2328 scsi_cmd = ((uint8_t *)fscsi->scsi_cdbbufaddr)[0]; 2329 ret = EINVAL; 2330 for (cmd_index = 0; 2331 cmd_index < FCP_NUM_ELEMENTS(scsi_ioctl_list) && 2332 ret != 0; 2333 cmd_index++) { 2334 /* 2335 * First byte of CDB is the SCSI command 2336 */ 2337 if (scsi_ioctl_list[cmd_index] == scsi_cmd) { 2338 ret = 0; 2339 } 2340 } 2341 2342 /* 2343 * Check inputs 2344 */ 2345 if (fscsi->scsi_flags != FCP_SCSI_READ) { 2346 ret = EINVAL; 2347 } else if (fscsi->scsi_cdblen > FCP_CDB_SIZE) { 2348 /* no larger than */ 2349 ret = EINVAL; 2350 } 2351 2352 2353 /* 2354 * Find FC port 2355 */ 2356 if (ret == 0) { 2357 /* 2358 * Acquire global mutex 2359 */ 2360 mutex_enter(&fcp_global_mutex); 2361 2362 pptr = fcp_port_head; 2363 while (pptr) { 2364 if (pptr->port_instance == 2365 (uint32_t)fscsi->scsi_fc_port_num) { 2366 break; 2367 } else { 2368 pptr = pptr->port_next; 2369 } 2370 } 2371 2372 if (pptr == NULL) { 2373 ret = ENXIO; 2374 } else { 2375 /* 2376 * fc_ulp_busy_port can raise power 2377 * so, we must not hold any mutexes involved in PM 2378 */ 2379 mutex_exit(&fcp_global_mutex); 2380 ret = fc_ulp_busy_port(pptr->port_fp_handle); 2381 } 2382 2383 if (ret == 0) { 2384 2385 /* remember port is busy, so we will release later */ 2386 port_busy = TRUE; 2387 2388 /* 2389 * If there is a reconfiguration in progress, wait 2390 * for it to complete. 2391 */ 2392 2393 fcp_reconfig_wait(pptr); 2394 2395 /* reacquire mutexes in order */ 2396 mutex_enter(&fcp_global_mutex); 2397 mutex_enter(&pptr->port_mutex); 2398 2399 /* 2400 * Will port accept DMA? 2401 */ 2402 nodma = (pptr->port_fcp_dma == FC_NO_DVMA_SPACE) 2403 ? 1 : 0; 2404 2405 /* 2406 * If init or offline, device not known 2407 * 2408 * If we are discovering (onlining), we can 2409 * NOT obviously provide reliable data about 2410 * devices until it is complete 2411 */ 2412 if (pptr->port_state & (FCP_STATE_INIT | 2413 FCP_STATE_OFFLINE)) { 2414 ret = ENXIO; 2415 } else if (pptr->port_state & FCP_STATE_ONLINING) { 2416 ret = EBUSY; 2417 } else { 2418 /* 2419 * Find target from pwwn 2420 * 2421 * The wwn must be put into a local 2422 * variable to ensure alignment. 2423 */ 2424 wwn_ptr = (la_wwn_t *)&(fscsi->scsi_fc_pwwn); 2425 ptgt = fcp_lookup_target(pptr, 2426 (uchar_t *)wwn_ptr); 2427 2428 /* 2429 * If target not found, 2430 */ 2431 if (ptgt == NULL) { 2432 /* 2433 * Note: Still have global & 2434 * port mutexes 2435 */ 2436 mutex_exit(&pptr->port_mutex); 2437 ptgt = fcp_port_create_tgt(pptr, 2438 wwn_ptr, &ret, &fc_status, 2439 &pkt_state, &pkt_action, 2440 &pkt_reason); 2441 mutex_enter(&pptr->port_mutex); 2442 2443 fscsi->scsi_fc_status = fc_status; 2444 fscsi->scsi_pkt_state = 2445 (uchar_t)pkt_state; 2446 fscsi->scsi_pkt_reason = pkt_reason; 2447 fscsi->scsi_pkt_action = 2448 (uchar_t)pkt_action; 2449 2450 if (ptgt != NULL) { 2451 target_created = TRUE; 2452 } else if (ret == 0) { 2453 ret = ENOMEM; 2454 } 2455 } 2456 2457 if (ret == 0) { 2458 /* 2459 * Acquire target 2460 */ 2461 mutex_enter(&ptgt->tgt_mutex); 2462 2463 /* 2464 * If target is mark or busy, 2465 * then target can not be used 2466 */ 2467 if (ptgt->tgt_state & 2468 (FCP_TGT_MARK | 2469 FCP_TGT_BUSY)) { 2470 ret = EBUSY; 2471 } else { 2472 /* 2473 * Mark target as busy 2474 */ 2475 ptgt->tgt_state |= 2476 FCP_TGT_BUSY; 2477 } 2478 2479 /* 2480 * Release target 2481 */ 2482 lcount = pptr->port_link_cnt; 2483 tcount = ptgt->tgt_change_cnt; 2484 mutex_exit(&ptgt->tgt_mutex); 2485 } 2486 } 2487 2488 /* 2489 * Release port 2490 */ 2491 mutex_exit(&pptr->port_mutex); 2492 } 2493 2494 /* 2495 * Release global mutex 2496 */ 2497 mutex_exit(&fcp_global_mutex); 2498 } 2499 2500 if (ret == 0) { 2501 uint64_t belun = BE_64(fscsi->scsi_lun); 2502 2503 /* 2504 * If it's a target device, find lun from pwwn 2505 * The wwn must be put into a local 2506 * variable to ensure alignment. 2507 */ 2508 mutex_enter(&pptr->port_mutex); 2509 wwn_ptr = (la_wwn_t *)&(fscsi->scsi_fc_pwwn); 2510 if (!ptgt->tgt_tcap && ptgt->tgt_icap) { 2511 /* this is not a target */ 2512 fscsi->scsi_fc_status = FC_DEVICE_NOT_TGT; 2513 ret = ENXIO; 2514 } else if ((belun << 16) != 0) { 2515 /* 2516 * Since fcp only support PD and LU addressing method 2517 * so far, the last 6 bytes of a valid LUN are expected 2518 * to be filled with 00h. 2519 */ 2520 fscsi->scsi_fc_status = FC_INVALID_LUN; 2521 cmn_err(CE_WARN, "fcp: Unsupported LUN addressing" 2522 " method 0x%02x with LUN number 0x%016" PRIx64, 2523 (uint8_t)(belun >> 62), belun); 2524 ret = ENXIO; 2525 } else if ((plun = fcp_lookup_lun(pptr, (uchar_t *)wwn_ptr, 2526 (uint16_t)((belun >> 48) & 0x3fff))) == NULL) { 2527 /* 2528 * This is a SCSI target, but no LUN at this 2529 * address. 2530 * 2531 * In the future, we may want to send this to 2532 * the target, and let it respond 2533 * appropriately 2534 */ 2535 ret = ENXIO; 2536 } 2537 mutex_exit(&pptr->port_mutex); 2538 } 2539 2540 /* 2541 * Finished grabbing external resources 2542 * Allocate internal packet (icmd) 2543 */ 2544 if (ret == 0) { 2545 /* 2546 * Calc rsp len assuming rsp info included 2547 */ 2548 rsp_len = sizeof (struct fcp_rsp) + 2549 sizeof (struct fcp_rsp_info) + fscsi->scsi_rqlen; 2550 2551 icmd = fcp_icmd_alloc(pptr, ptgt, 2552 sizeof (struct fcp_cmd), 2553 rsp_len, 2554 fscsi->scsi_buflen, 2555 nodma, 2556 lcount, /* ipkt_link_cnt */ 2557 tcount, /* ipkt_change_cnt */ 2558 0, /* cause */ 2559 FC_INVALID_RSCN_COUNT); /* invalidate the count */ 2560 2561 if (icmd == NULL) { 2562 ret = ENOMEM; 2563 } else { 2564 /* 2565 * Setup internal packet as sema sync 2566 */ 2567 fcp_ipkt_sema_init(icmd); 2568 } 2569 } 2570 2571 if (ret == 0) { 2572 /* 2573 * Init fpkt pointer for use. 2574 */ 2575 2576 fpkt = icmd->ipkt_fpkt; 2577 2578 fpkt->pkt_tran_flags = FC_TRAN_CLASS3 | FC_TRAN_INTR; 2579 fpkt->pkt_tran_type = FC_PKT_FCP_READ; /* only rd for now */ 2580 fpkt->pkt_timeout = fscsi->scsi_timeout; 2581 2582 /* 2583 * Init fcmd pointer for use by SCSI command 2584 */ 2585 2586 if (nodma) { 2587 fcmd = (struct fcp_cmd *)fpkt->pkt_cmd; 2588 } else { 2589 fcmd = &fcp_cmd; 2590 } 2591 bzero(fcmd, sizeof (struct fcp_cmd)); 2592 ptgt = plun->lun_tgt; 2593 2594 lun_string = (uchar_t *)&fscsi->scsi_lun; 2595 2596 fcmd->fcp_ent_addr.ent_addr_0 = 2597 BE_16(*(uint16_t *)&(lun_string[0])); 2598 fcmd->fcp_ent_addr.ent_addr_1 = 2599 BE_16(*(uint16_t *)&(lun_string[2])); 2600 fcmd->fcp_ent_addr.ent_addr_2 = 2601 BE_16(*(uint16_t *)&(lun_string[4])); 2602 fcmd->fcp_ent_addr.ent_addr_3 = 2603 BE_16(*(uint16_t *)&(lun_string[6])); 2604 2605 /* 2606 * Setup internal packet(icmd) 2607 */ 2608 icmd->ipkt_lun = plun; 2609 icmd->ipkt_restart = 0; 2610 icmd->ipkt_retries = 0; 2611 icmd->ipkt_opcode = 0; 2612 2613 /* 2614 * Init the frame HEADER Pointer for use 2615 */ 2616 hp = &fpkt->pkt_cmd_fhdr; 2617 2618 hp->s_id = pptr->port_id; 2619 hp->d_id = ptgt->tgt_d_id; 2620 hp->r_ctl = R_CTL_COMMAND; 2621 hp->type = FC_TYPE_SCSI_FCP; 2622 hp->f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ; 2623 hp->rsvd = 0; 2624 hp->seq_id = 0; 2625 hp->seq_cnt = 0; 2626 hp->ox_id = 0xffff; 2627 hp->rx_id = 0xffff; 2628 hp->ro = 0; 2629 2630 fcmd->fcp_cntl.cntl_qtype = FCP_QTYPE_SIMPLE; 2631 fcmd->fcp_cntl.cntl_read_data = 1; /* only rd for now */ 2632 fcmd->fcp_cntl.cntl_write_data = 0; 2633 fcmd->fcp_data_len = fscsi->scsi_buflen; 2634 2635 scsi_cdb = (union scsi_cdb *)fcmd->fcp_cdb; 2636 bcopy((char *)fscsi->scsi_cdbbufaddr, (char *)scsi_cdb, 2637 fscsi->scsi_cdblen); 2638 2639 if (!nodma) { 2640 FCP_CP_OUT((uint8_t *)fcmd, fpkt->pkt_cmd, 2641 fpkt->pkt_cmd_acc, sizeof (struct fcp_cmd)); 2642 } 2643 2644 /* 2645 * Send SCSI command to FC transport 2646 */ 2647 2648 if (ret == 0) { 2649 mutex_enter(&ptgt->tgt_mutex); 2650 2651 if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) { 2652 mutex_exit(&ptgt->tgt_mutex); 2653 fscsi->scsi_fc_status = xport_retval = 2654 fc_ulp_transport(pptr->port_fp_handle, 2655 fpkt); 2656 if (fscsi->scsi_fc_status != FC_SUCCESS) { 2657 ret = EIO; 2658 } 2659 } else { 2660 mutex_exit(&ptgt->tgt_mutex); 2661 ret = EBUSY; 2662 } 2663 } 2664 } 2665 2666 /* 2667 * Wait for completion only if fc_ulp_transport was called and it 2668 * returned a success. This is the only time callback will happen. 2669 * Otherwise, there is no point in waiting 2670 */ 2671 if ((ret == 0) && (xport_retval == FC_SUCCESS)) { 2672 ret = fcp_ipkt_sema_wait(icmd); 2673 } 2674 2675 /* 2676 * Copy data to IOCTL data structures 2677 */ 2678 rsp = NULL; 2679 if ((ret == 0) && (xport_retval == FC_SUCCESS)) { 2680 rsp = (struct fcp_rsp *)fpkt->pkt_resp; 2681 2682 if (fcp_validate_fcp_response(rsp, pptr) != FC_SUCCESS) { 2683 fcp_log(CE_WARN, pptr->port_dip, 2684 "!SCSI command to d_id=0x%x lun=0x%x" 2685 " failed, Bad FCP response values:" 2686 " rsvd1=%x, rsvd2=%x, sts-rsvd1=%x," 2687 " sts-rsvd2=%x, rsplen=%x, senselen=%x", 2688 ptgt->tgt_d_id, plun->lun_num, 2689 rsp->reserved_0, rsp->reserved_1, 2690 rsp->fcp_u.fcp_status.reserved_0, 2691 rsp->fcp_u.fcp_status.reserved_1, 2692 rsp->fcp_response_len, rsp->fcp_sense_len); 2693 2694 ret = EIO; 2695 } 2696 } 2697 2698 if ((ret == 0) && (rsp != NULL)) { 2699 /* 2700 * Calc response lengths 2701 */ 2702 sense_len = 0; 2703 info_len = 0; 2704 2705 if (rsp->fcp_u.fcp_status.rsp_len_set) { 2706 info_len = rsp->fcp_response_len; 2707 } 2708 2709 rsp_info = (struct fcp_rsp_info *) 2710 ((uint8_t *)rsp + sizeof (struct fcp_rsp)); 2711 2712 /* 2713 * Get SCSI status 2714 */ 2715 fscsi->scsi_bufstatus = rsp->fcp_u.fcp_status.scsi_status; 2716 /* 2717 * If a lun was just added or removed and the next command 2718 * comes through this interface, we need to capture the check 2719 * condition so we can discover the new topology. 2720 */ 2721 if (fscsi->scsi_bufstatus != STATUS_GOOD && 2722 rsp->fcp_u.fcp_status.sense_len_set) { 2723 sense_len = rsp->fcp_sense_len; 2724 rsp_sense = (caddr_t)((uint8_t *)rsp_info + info_len); 2725 sense_to = (struct scsi_extended_sense *)rsp_sense; 2726 if ((FCP_SENSE_REPORTLUN_CHANGED(sense_to)) || 2727 (FCP_SENSE_NO_LUN(sense_to))) { 2728 reconfig_lun = TRUE; 2729 } 2730 } 2731 2732 if (fscsi->scsi_bufstatus == STATUS_GOOD && (ptgt != NULL) && 2733 (reconfig_lun || (scsi_cdb->scc_cmd == SCMD_REPORT_LUN))) { 2734 if (reconfig_lun == FALSE) { 2735 reconfig_status = 2736 fcp_is_reconfig_needed(ptgt, fpkt); 2737 } 2738 2739 if ((reconfig_lun == TRUE) || 2740 (reconfig_status == TRUE)) { 2741 mutex_enter(&ptgt->tgt_mutex); 2742 if (ptgt->tgt_tid == NULL) { 2743 /* 2744 * Either we've been notified the 2745 * REPORT_LUN data has changed, or 2746 * we've determined on our own that 2747 * we're out of date. Kick off 2748 * rediscovery. 2749 */ 2750 tid = timeout(fcp_reconfigure_luns, 2751 (caddr_t)ptgt, drv_usectohz(1)); 2752 2753 ptgt->tgt_tid = tid; 2754 ptgt->tgt_state |= FCP_TGT_BUSY; 2755 ret = EBUSY; 2756 reconfig_pending = TRUE; 2757 } 2758 mutex_exit(&ptgt->tgt_mutex); 2759 } 2760 } 2761 2762 /* 2763 * Calc residuals and buffer lengths 2764 */ 2765 2766 if (ret == 0) { 2767 buf_len = fscsi->scsi_buflen; 2768 fscsi->scsi_bufresid = 0; 2769 if (rsp->fcp_u.fcp_status.resid_under) { 2770 if (rsp->fcp_resid <= fscsi->scsi_buflen) { 2771 fscsi->scsi_bufresid = rsp->fcp_resid; 2772 } else { 2773 cmn_err(CE_WARN, "fcp: bad residue %x " 2774 "for txfer len %x", rsp->fcp_resid, 2775 fscsi->scsi_buflen); 2776 fscsi->scsi_bufresid = 2777 fscsi->scsi_buflen; 2778 } 2779 buf_len -= fscsi->scsi_bufresid; 2780 } 2781 if (rsp->fcp_u.fcp_status.resid_over) { 2782 fscsi->scsi_bufresid = -rsp->fcp_resid; 2783 } 2784 2785 fscsi->scsi_rqresid = fscsi->scsi_rqlen - sense_len; 2786 if (fscsi->scsi_rqlen < sense_len) { 2787 sense_len = fscsi->scsi_rqlen; 2788 } 2789 2790 fscsi->scsi_fc_rspcode = 0; 2791 if (rsp->fcp_u.fcp_status.rsp_len_set) { 2792 fscsi->scsi_fc_rspcode = rsp_info->rsp_code; 2793 } 2794 fscsi->scsi_pkt_state = fpkt->pkt_state; 2795 fscsi->scsi_pkt_action = fpkt->pkt_action; 2796 fscsi->scsi_pkt_reason = fpkt->pkt_reason; 2797 2798 /* 2799 * Copy data and request sense 2800 * 2801 * Data must be copied by using the FCP_CP_IN macro. 2802 * This will ensure the proper byte order since the data 2803 * is being copied directly from the memory mapped 2804 * device register. 2805 * 2806 * The response (and request sense) will be in the 2807 * correct byte order. No special copy is necessary. 2808 */ 2809 2810 if (buf_len) { 2811 FCP_CP_IN(fpkt->pkt_data, 2812 fscsi->scsi_bufaddr, 2813 fpkt->pkt_data_acc, 2814 buf_len); 2815 } 2816 bcopy((void *)rsp_sense, 2817 (void *)fscsi->scsi_rqbufaddr, 2818 sense_len); 2819 } 2820 } 2821 2822 /* 2823 * Cleanup transport data structures if icmd was alloc-ed 2824 * So, cleanup happens in the same thread that icmd was alloc-ed 2825 */ 2826 if (icmd != NULL) { 2827 fcp_ipkt_sema_cleanup(icmd); 2828 } 2829 2830 /* restore pm busy/idle status */ 2831 if (port_busy) { 2832 fc_ulp_idle_port(pptr->port_fp_handle); 2833 } 2834 2835 /* 2836 * Cleanup target. if a reconfig is pending, don't clear the BUSY 2837 * flag, it'll be cleared when the reconfig is complete. 2838 */ 2839 if ((ptgt != NULL) && !reconfig_pending) { 2840 /* 2841 * If target was created, 2842 */ 2843 if (target_created) { 2844 mutex_enter(&ptgt->tgt_mutex); 2845 ptgt->tgt_state &= ~FCP_TGT_BUSY; 2846 mutex_exit(&ptgt->tgt_mutex); 2847 } else { 2848 /* 2849 * De-mark target as busy 2850 */ 2851 mutex_enter(&ptgt->tgt_mutex); 2852 ptgt->tgt_state &= ~FCP_TGT_BUSY; 2853 mutex_exit(&ptgt->tgt_mutex); 2854 } 2855 } 2856 return (ret); 2857 } 2858 2859 2860 static int 2861 fcp_is_reconfig_needed(struct fcp_tgt *ptgt, 2862 fc_packet_t *fpkt) 2863 { 2864 uchar_t *lun_string; 2865 uint16_t lun_num, i; 2866 int num_luns; 2867 int actual_luns; 2868 int num_masked_luns; 2869 int lun_buflen; 2870 struct fcp_lun *plun = NULL; 2871 struct fcp_reportlun_resp *report_lun; 2872 uint8_t reconfig_needed = FALSE; 2873 uint8_t lun_exists = FALSE; 2874 fcp_port_t *pptr = ptgt->tgt_port; 2875 2876 report_lun = kmem_zalloc(fpkt->pkt_datalen, KM_SLEEP); 2877 2878 FCP_CP_IN(fpkt->pkt_data, report_lun, fpkt->pkt_data_acc, 2879 fpkt->pkt_datalen); 2880 2881 /* get number of luns (which is supplied as LUNS * 8) */ 2882 num_luns = BE_32(report_lun->num_lun) >> 3; 2883 2884 /* 2885 * Figure out exactly how many lun strings our response buffer 2886 * can hold. 2887 */ 2888 lun_buflen = (fpkt->pkt_datalen - 2889 2 * sizeof (uint32_t)) / sizeof (longlong_t); 2890 2891 /* 2892 * Is our response buffer full or not? We don't want to 2893 * potentially walk beyond the number of luns we have. 2894 */ 2895 if (num_luns <= lun_buflen) { 2896 actual_luns = num_luns; 2897 } else { 2898 actual_luns = lun_buflen; 2899 } 2900 2901 mutex_enter(&ptgt->tgt_mutex); 2902 2903 /* Scan each lun to see if we have masked it. */ 2904 num_masked_luns = 0; 2905 if (fcp_lun_blacklist != NULL) { 2906 for (i = 0; i < actual_luns; i++) { 2907 lun_string = (uchar_t *)&(report_lun->lun_string[i]); 2908 switch (lun_string[0] & 0xC0) { 2909 case FCP_LUN_ADDRESSING: 2910 case FCP_PD_ADDRESSING: 2911 case FCP_VOLUME_ADDRESSING: 2912 lun_num = ((lun_string[0] & 0x3F) << 8) 2913 | lun_string[1]; 2914 if (fcp_should_mask(&ptgt->tgt_port_wwn, 2915 lun_num) == TRUE) { 2916 num_masked_luns++; 2917 } 2918 break; 2919 default: 2920 break; 2921 } 2922 } 2923 } 2924 2925 /* 2926 * The quick and easy check. If the number of LUNs reported 2927 * doesn't match the number we currently know about, we need 2928 * to reconfigure. 2929 */ 2930 if (num_luns && num_luns != (ptgt->tgt_lun_cnt + num_masked_luns)) { 2931 mutex_exit(&ptgt->tgt_mutex); 2932 kmem_free(report_lun, fpkt->pkt_datalen); 2933 return (TRUE); 2934 } 2935 2936 /* 2937 * If the quick and easy check doesn't turn up anything, we walk 2938 * the list of luns from the REPORT_LUN response and look for 2939 * any luns we don't know about. If we find one, we know we need 2940 * to reconfigure. We will skip LUNs that are masked because of the 2941 * blacklist. 2942 */ 2943 for (i = 0; i < actual_luns; i++) { 2944 lun_string = (uchar_t *)&(report_lun->lun_string[i]); 2945 lun_exists = FALSE; 2946 switch (lun_string[0] & 0xC0) { 2947 case FCP_LUN_ADDRESSING: 2948 case FCP_PD_ADDRESSING: 2949 case FCP_VOLUME_ADDRESSING: 2950 lun_num = ((lun_string[0] & 0x3F) << 8) | lun_string[1]; 2951 2952 if ((fcp_lun_blacklist != NULL) && (fcp_should_mask( 2953 &ptgt->tgt_port_wwn, lun_num) == TRUE)) { 2954 lun_exists = TRUE; 2955 break; 2956 } 2957 2958 for (plun = ptgt->tgt_lun; plun; 2959 plun = plun->lun_next) { 2960 if (plun->lun_num == lun_num) { 2961 lun_exists = TRUE; 2962 break; 2963 } 2964 } 2965 break; 2966 default: 2967 break; 2968 } 2969 2970 if (lun_exists == FALSE) { 2971 reconfig_needed = TRUE; 2972 break; 2973 } 2974 } 2975 2976 mutex_exit(&ptgt->tgt_mutex); 2977 kmem_free(report_lun, fpkt->pkt_datalen); 2978 2979 return (reconfig_needed); 2980 } 2981 2982 /* 2983 * This function is called by fcp_handle_page83 and uses inquiry response data 2984 * stored in plun->lun_inq to determine whether or not a device is a member of 2985 * the table fcp_symmetric_disk_table_size. We return 0 if it is in the table, 2986 * otherwise 1. 2987 */ 2988 static int 2989 fcp_symmetric_device_probe(struct fcp_lun *plun) 2990 { 2991 struct scsi_inquiry *stdinq = &plun->lun_inq; 2992 char *devidptr; 2993 int i, len; 2994 2995 for (i = 0; i < fcp_symmetric_disk_table_size; i++) { 2996 devidptr = fcp_symmetric_disk_table[i]; 2997 len = (int)strlen(devidptr); 2998 2999 if (bcmp(stdinq->inq_vid, devidptr, len) == 0) { 3000 return (0); 3001 } 3002 } 3003 return (1); 3004 } 3005 3006 3007 /* 3008 * This function is called by fcp_ioctl for the FCP_STATE_COUNT ioctl 3009 * It basically returns the current count of # of state change callbacks 3010 * i.e the value of tgt_change_cnt. 3011 * 3012 * INPUT: 3013 * fcp_ioctl.fp_minor -> The minor # of the fp port 3014 * fcp_ioctl.listlen -> 1 3015 * fcp_ioctl.list -> Pointer to a 32 bit integer 3016 */ 3017 /*ARGSUSED2*/ 3018 static int 3019 fcp_get_statec_count(struct fcp_ioctl *data, int mode, int *rval) 3020 { 3021 int ret; 3022 uint32_t link_cnt; 3023 struct fcp_ioctl fioctl; 3024 struct fcp_port *pptr = NULL; 3025 3026 if ((ret = fcp_copyin_fcp_ioctl_data(data, mode, rval, &fioctl, 3027 &pptr)) != 0) { 3028 return (ret); 3029 } 3030 3031 ASSERT(pptr != NULL); 3032 3033 if (fioctl.listlen != 1) { 3034 return (EINVAL); 3035 } 3036 3037 mutex_enter(&pptr->port_mutex); 3038 if (pptr->port_state & FCP_STATE_OFFLINE) { 3039 mutex_exit(&pptr->port_mutex); 3040 return (ENXIO); 3041 } 3042 3043 /* 3044 * FCP_STATE_INIT is set in 2 cases (not sure why it is overloaded): 3045 * When the fcp initially attaches to the port and there are nothing 3046 * hanging out of the port or if there was a repeat offline state change 3047 * callback (refer fcp_statec_callback() FC_STATE_OFFLINE case). 3048 * In the latter case, port_tmp_cnt will be non-zero and that is how we 3049 * will differentiate the 2 cases. 3050 */ 3051 if ((pptr->port_state & FCP_STATE_INIT) && pptr->port_tmp_cnt) { 3052 mutex_exit(&pptr->port_mutex); 3053 return (ENXIO); 3054 } 3055 3056 link_cnt = pptr->port_link_cnt; 3057 mutex_exit(&pptr->port_mutex); 3058 3059 if (ddi_copyout(&link_cnt, fioctl.list, (sizeof (uint32_t)), mode)) { 3060 return (EFAULT); 3061 } 3062 3063 #ifdef _MULTI_DATAMODEL 3064 switch (ddi_model_convert_from(mode & FMODELS)) { 3065 case DDI_MODEL_ILP32: { 3066 struct fcp32_ioctl f32_ioctl; 3067 3068 f32_ioctl.fp_minor = fioctl.fp_minor; 3069 f32_ioctl.listlen = fioctl.listlen; 3070 f32_ioctl.list = (caddr32_t)(long)fioctl.list; 3071 if (ddi_copyout((void *)&f32_ioctl, (void *)data, 3072 sizeof (struct fcp32_ioctl), mode)) { 3073 return (EFAULT); 3074 } 3075 break; 3076 } 3077 case DDI_MODEL_NONE: 3078 if (ddi_copyout((void *)&fioctl, (void *)data, 3079 sizeof (struct fcp_ioctl), mode)) { 3080 return (EFAULT); 3081 } 3082 break; 3083 } 3084 #else /* _MULTI_DATAMODEL */ 3085 3086 if (ddi_copyout((void *)&fioctl, (void *)data, 3087 sizeof (struct fcp_ioctl), mode)) { 3088 return (EFAULT); 3089 } 3090 #endif /* _MULTI_DATAMODEL */ 3091 3092 return (0); 3093 } 3094 3095 /* 3096 * This function copies the fcp_ioctl structure passed in from user land 3097 * into kernel land. Handles 32 bit applications. 3098 */ 3099 /*ARGSUSED*/ 3100 static int 3101 fcp_copyin_fcp_ioctl_data(struct fcp_ioctl *data, int mode, int *rval, 3102 struct fcp_ioctl *fioctl, struct fcp_port **pptr) 3103 { 3104 struct fcp_port *t_pptr; 3105 3106 #ifdef _MULTI_DATAMODEL 3107 switch (ddi_model_convert_from(mode & FMODELS)) { 3108 case DDI_MODEL_ILP32: { 3109 struct fcp32_ioctl f32_ioctl; 3110 3111 if (ddi_copyin((void *)data, (void *)&f32_ioctl, 3112 sizeof (struct fcp32_ioctl), mode)) { 3113 return (EFAULT); 3114 } 3115 fioctl->fp_minor = f32_ioctl.fp_minor; 3116 fioctl->listlen = f32_ioctl.listlen; 3117 fioctl->list = (caddr_t)(long)f32_ioctl.list; 3118 break; 3119 } 3120 case DDI_MODEL_NONE: 3121 if (ddi_copyin((void *)data, (void *)fioctl, 3122 sizeof (struct fcp_ioctl), mode)) { 3123 return (EFAULT); 3124 } 3125 break; 3126 } 3127 3128 #else /* _MULTI_DATAMODEL */ 3129 if (ddi_copyin((void *)data, (void *)fioctl, 3130 sizeof (struct fcp_ioctl), mode)) { 3131 return (EFAULT); 3132 } 3133 #endif /* _MULTI_DATAMODEL */ 3134 3135 /* 3136 * Right now we can assume that the minor number matches with 3137 * this instance of fp. If this changes we will need to 3138 * revisit this logic. 3139 */ 3140 mutex_enter(&fcp_global_mutex); 3141 t_pptr = fcp_port_head; 3142 while (t_pptr) { 3143 if (t_pptr->port_instance == (uint32_t)fioctl->fp_minor) { 3144 break; 3145 } else { 3146 t_pptr = t_pptr->port_next; 3147 } 3148 } 3149 *pptr = t_pptr; 3150 mutex_exit(&fcp_global_mutex); 3151 if (t_pptr == NULL) { 3152 return (ENXIO); 3153 } 3154 3155 return (0); 3156 } 3157 3158 /* 3159 * Function: fcp_port_create_tgt 3160 * 3161 * Description: As the name suggest this function creates the target context 3162 * specified by the the WWN provided by the caller. If the 3163 * creation goes well and the target is known by fp/fctl a PLOGI 3164 * followed by a PRLI are issued. 3165 * 3166 * Argument: pptr fcp port structure 3167 * pwwn WWN of the target 3168 * ret_val Address of the return code. It could be: 3169 * EIO, ENOMEM or 0. 3170 * fc_status PLOGI or PRLI status completion 3171 * fc_pkt_state PLOGI or PRLI state completion 3172 * fc_pkt_reason PLOGI or PRLI reason completion 3173 * fc_pkt_action PLOGI or PRLI action completion 3174 * 3175 * Return Value: NULL if it failed 3176 * Target structure address if it succeeds 3177 */ 3178 static struct fcp_tgt * 3179 fcp_port_create_tgt(struct fcp_port *pptr, la_wwn_t *pwwn, int *ret_val, 3180 int *fc_status, int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action) 3181 { 3182 struct fcp_tgt *ptgt = NULL; 3183 fc_portmap_t devlist; 3184 int lcount; 3185 int error; 3186 3187 *ret_val = 0; 3188 3189 /* 3190 * Check FC port device & get port map 3191 */ 3192 if (fc_ulp_get_remote_port(pptr->port_fp_handle, pwwn, 3193 &error, 1) == NULL) { 3194 *ret_val = EIO; 3195 } else { 3196 if (fc_ulp_pwwn_to_portmap(pptr->port_fp_handle, pwwn, 3197 &devlist) != FC_SUCCESS) { 3198 *ret_val = EIO; 3199 } 3200 } 3201 3202 /* Set port map flags */ 3203 devlist.map_type = PORT_DEVICE_USER_CREATE; 3204 3205 /* Allocate target */ 3206 if (*ret_val == 0) { 3207 lcount = pptr->port_link_cnt; 3208 ptgt = fcp_alloc_tgt(pptr, &devlist, lcount); 3209 if (ptgt == NULL) { 3210 fcp_log(CE_WARN, pptr->port_dip, 3211 "!FC target allocation failed"); 3212 *ret_val = ENOMEM; 3213 } else { 3214 /* Setup target */ 3215 mutex_enter(&ptgt->tgt_mutex); 3216 3217 ptgt->tgt_statec_cause = FCP_CAUSE_TGT_CHANGE; 3218 ptgt->tgt_tmp_cnt = 1; 3219 ptgt->tgt_d_id = devlist.map_did.port_id; 3220 ptgt->tgt_hard_addr = 3221 devlist.map_hard_addr.hard_addr; 3222 ptgt->tgt_pd_handle = devlist.map_pd; 3223 ptgt->tgt_fca_dev = NULL; 3224 3225 bcopy(&devlist.map_nwwn, &ptgt->tgt_node_wwn.raw_wwn[0], 3226 FC_WWN_SIZE); 3227 bcopy(&devlist.map_pwwn, &ptgt->tgt_port_wwn.raw_wwn[0], 3228 FC_WWN_SIZE); 3229 3230 mutex_exit(&ptgt->tgt_mutex); 3231 } 3232 } 3233 3234 /* Release global mutex for PLOGI and PRLI */ 3235 mutex_exit(&fcp_global_mutex); 3236 3237 /* Send PLOGI (If necessary) */ 3238 if (*ret_val == 0) { 3239 *ret_val = fcp_tgt_send_plogi(ptgt, fc_status, 3240 fc_pkt_state, fc_pkt_reason, fc_pkt_action); 3241 } 3242 3243 /* Send PRLI (If necessary) */ 3244 if (*ret_val == 0) { 3245 *ret_val = fcp_tgt_send_prli(ptgt, fc_status, 3246 fc_pkt_state, fc_pkt_reason, fc_pkt_action); 3247 } 3248 3249 mutex_enter(&fcp_global_mutex); 3250 3251 return (ptgt); 3252 } 3253 3254 /* 3255 * Function: fcp_tgt_send_plogi 3256 * 3257 * Description: This function sends a PLOGI to the target specified by the 3258 * caller and waits till it completes. 3259 * 3260 * Argument: ptgt Target to send the plogi to. 3261 * fc_status Status returned by fp/fctl in the PLOGI request. 3262 * fc_pkt_state State returned by fp/fctl in the PLOGI request. 3263 * fc_pkt_reason Reason returned by fp/fctl in the PLOGI request. 3264 * fc_pkt_action Action returned by fp/fctl in the PLOGI request. 3265 * 3266 * Return Value: 0 3267 * ENOMEM 3268 * EIO 3269 * 3270 * Context: User context. 3271 */ 3272 static int 3273 fcp_tgt_send_plogi(struct fcp_tgt *ptgt, int *fc_status, int *fc_pkt_state, 3274 int *fc_pkt_reason, int *fc_pkt_action) 3275 { 3276 struct fcp_port *pptr; 3277 struct fcp_ipkt *icmd; 3278 struct fc_packet *fpkt; 3279 fc_frame_hdr_t *hp; 3280 struct la_els_logi logi; 3281 int tcount; 3282 int lcount; 3283 int ret, login_retval = ~FC_SUCCESS; 3284 3285 ret = 0; 3286 3287 pptr = ptgt->tgt_port; 3288 3289 lcount = pptr->port_link_cnt; 3290 tcount = ptgt->tgt_change_cnt; 3291 3292 /* Alloc internal packet */ 3293 icmd = fcp_icmd_alloc(pptr, ptgt, sizeof (la_els_logi_t), 3294 sizeof (la_els_logi_t), 0, 3295 pptr->port_state & FCP_STATE_FCA_IS_NODMA, 3296 lcount, tcount, 0, FC_INVALID_RSCN_COUNT); 3297 3298 if (icmd == NULL) { 3299 ret = ENOMEM; 3300 } else { 3301 /* 3302 * Setup internal packet as sema sync 3303 */ 3304 fcp_ipkt_sema_init(icmd); 3305 3306 /* 3307 * Setup internal packet (icmd) 3308 */ 3309 icmd->ipkt_lun = NULL; 3310 icmd->ipkt_restart = 0; 3311 icmd->ipkt_retries = 0; 3312 icmd->ipkt_opcode = LA_ELS_PLOGI; 3313 3314 /* 3315 * Setup fc_packet 3316 */ 3317 fpkt = icmd->ipkt_fpkt; 3318 3319 fpkt->pkt_tran_flags = FC_TRAN_CLASS3 | FC_TRAN_INTR; 3320 fpkt->pkt_tran_type = FC_PKT_EXCHANGE; 3321 fpkt->pkt_timeout = FCP_ELS_TIMEOUT; 3322 3323 /* 3324 * Setup FC frame header 3325 */ 3326 hp = &fpkt->pkt_cmd_fhdr; 3327 3328 hp->s_id = pptr->port_id; /* source ID */ 3329 hp->d_id = ptgt->tgt_d_id; /* dest ID */ 3330 hp->r_ctl = R_CTL_ELS_REQ; 3331 hp->type = FC_TYPE_EXTENDED_LS; 3332 hp->f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ; 3333 hp->seq_id = 0; 3334 hp->rsvd = 0; 3335 hp->df_ctl = 0; 3336 hp->seq_cnt = 0; 3337 hp->ox_id = 0xffff; /* i.e. none */ 3338 hp->rx_id = 0xffff; /* i.e. none */ 3339 hp->ro = 0; 3340 3341 /* 3342 * Setup PLOGI 3343 */ 3344 bzero(&logi, sizeof (struct la_els_logi)); 3345 logi.ls_code.ls_code = LA_ELS_PLOGI; 3346 3347 FCP_CP_OUT((uint8_t *)&logi, fpkt->pkt_cmd, 3348 fpkt->pkt_cmd_acc, sizeof (struct la_els_logi)); 3349 3350 /* 3351 * Send PLOGI 3352 */ 3353 *fc_status = login_retval = 3354 fc_ulp_login(pptr->port_fp_handle, &fpkt, 1); 3355 if (*fc_status != FC_SUCCESS) { 3356 ret = EIO; 3357 } 3358 } 3359 3360 /* 3361 * Wait for completion 3362 */ 3363 if ((ret == 0) && (login_retval == FC_SUCCESS)) { 3364 ret = fcp_ipkt_sema_wait(icmd); 3365 3366 *fc_pkt_state = fpkt->pkt_state; 3367 *fc_pkt_reason = fpkt->pkt_reason; 3368 *fc_pkt_action = fpkt->pkt_action; 3369 } 3370 3371 /* 3372 * Cleanup transport data structures if icmd was alloc-ed AND if there 3373 * is going to be no callback (i.e if fc_ulp_login() failed). 3374 * Otherwise, cleanup happens in callback routine. 3375 */ 3376 if (icmd != NULL) { 3377 fcp_ipkt_sema_cleanup(icmd); 3378 } 3379 3380 return (ret); 3381 } 3382 3383 /* 3384 * Function: fcp_tgt_send_prli 3385 * 3386 * Description: Does nothing as of today. 3387 * 3388 * Argument: ptgt Target to send the prli to. 3389 * fc_status Status returned by fp/fctl in the PRLI request. 3390 * fc_pkt_state State returned by fp/fctl in the PRLI request. 3391 * fc_pkt_reason Reason returned by fp/fctl in the PRLI request. 3392 * fc_pkt_action Action returned by fp/fctl in the PRLI request. 3393 * 3394 * Return Value: 0 3395 */ 3396 /*ARGSUSED*/ 3397 static int 3398 fcp_tgt_send_prli(struct fcp_tgt *ptgt, int *fc_status, int *fc_pkt_state, 3399 int *fc_pkt_reason, int *fc_pkt_action) 3400 { 3401 return (0); 3402 } 3403 3404 /* 3405 * Function: fcp_ipkt_sema_init 3406 * 3407 * Description: Initializes the semaphore contained in the internal packet. 3408 * 3409 * Argument: icmd Internal packet the semaphore of which must be 3410 * initialized. 3411 * 3412 * Return Value: None 3413 * 3414 * Context: User context only. 3415 */ 3416 static void 3417 fcp_ipkt_sema_init(struct fcp_ipkt *icmd) 3418 { 3419 struct fc_packet *fpkt; 3420 3421 fpkt = icmd->ipkt_fpkt; 3422 3423 /* Create semaphore for sync */ 3424 sema_init(&(icmd->ipkt_sema), 0, NULL, SEMA_DRIVER, NULL); 3425 3426 /* Setup the completion callback */ 3427 fpkt->pkt_comp = fcp_ipkt_sema_callback; 3428 } 3429 3430 /* 3431 * Function: fcp_ipkt_sema_wait 3432 * 3433 * Description: Wait on the semaphore embedded in the internal packet. The 3434 * semaphore is released in the callback. 3435 * 3436 * Argument: icmd Internal packet to wait on for completion. 3437 * 3438 * Return Value: 0 3439 * EIO 3440 * EBUSY 3441 * EAGAIN 3442 * 3443 * Context: User context only. 3444 * 3445 * This function does a conversion between the field pkt_state of the fc_packet 3446 * embedded in the internal packet (icmd) and the code it returns. 3447 */ 3448 static int 3449 fcp_ipkt_sema_wait(struct fcp_ipkt *icmd) 3450 { 3451 struct fc_packet *fpkt; 3452 int ret; 3453 3454 ret = EIO; 3455 fpkt = icmd->ipkt_fpkt; 3456 3457 /* 3458 * Wait on semaphore 3459 */ 3460 sema_p(&(icmd->ipkt_sema)); 3461 3462 /* 3463 * Check the status of the FC packet 3464 */ 3465 switch (fpkt->pkt_state) { 3466 case FC_PKT_SUCCESS: 3467 ret = 0; 3468 break; 3469 case FC_PKT_LOCAL_RJT: 3470 switch (fpkt->pkt_reason) { 3471 case FC_REASON_SEQ_TIMEOUT: 3472 case FC_REASON_RX_BUF_TIMEOUT: 3473 ret = EAGAIN; 3474 break; 3475 case FC_REASON_PKT_BUSY: 3476 ret = EBUSY; 3477 break; 3478 } 3479 break; 3480 case FC_PKT_TIMEOUT: 3481 ret = EAGAIN; 3482 break; 3483 case FC_PKT_LOCAL_BSY: 3484 case FC_PKT_TRAN_BSY: 3485 case FC_PKT_NPORT_BSY: 3486 case FC_PKT_FABRIC_BSY: 3487 ret = EBUSY; 3488 break; 3489 case FC_PKT_LS_RJT: 3490 case FC_PKT_BA_RJT: 3491 switch (fpkt->pkt_reason) { 3492 case FC_REASON_LOGICAL_BSY: 3493 ret = EBUSY; 3494 break; 3495 } 3496 break; 3497 case FC_PKT_FS_RJT: 3498 switch (fpkt->pkt_reason) { 3499 case FC_REASON_FS_LOGICAL_BUSY: 3500 ret = EBUSY; 3501 break; 3502 } 3503 break; 3504 } 3505 3506 return (ret); 3507 } 3508 3509 /* 3510 * Function: fcp_ipkt_sema_callback 3511 * 3512 * Description: Registered as the completion callback function for the FC 3513 * transport when the ipkt semaphore is used for sync. This will 3514 * cleanup the used data structures, if necessary and wake up 3515 * the user thread to complete the transaction. 3516 * 3517 * Argument: fpkt FC packet (points to the icmd) 3518 * 3519 * Return Value: None 3520 * 3521 * Context: User context only 3522 */ 3523 static void 3524 fcp_ipkt_sema_callback(struct fc_packet *fpkt) 3525 { 3526 struct fcp_ipkt *icmd; 3527 3528 icmd = (struct fcp_ipkt *)fpkt->pkt_ulp_private; 3529 3530 /* 3531 * Wake up user thread 3532 */ 3533 sema_v(&(icmd->ipkt_sema)); 3534 } 3535 3536 /* 3537 * Function: fcp_ipkt_sema_cleanup 3538 * 3539 * Description: Called to cleanup (if necessary) the data structures used 3540 * when ipkt sema is used for sync. This function will detect 3541 * whether the caller is the last thread (via counter) and 3542 * cleanup only if necessary. 3543 * 3544 * Argument: icmd Internal command packet 3545 * 3546 * Return Value: None 3547 * 3548 * Context: User context only 3549 */ 3550 static void 3551 fcp_ipkt_sema_cleanup(struct fcp_ipkt *icmd) 3552 { 3553 struct fcp_tgt *ptgt; 3554 struct fcp_port *pptr; 3555 3556 ptgt = icmd->ipkt_tgt; 3557 pptr = icmd->ipkt_port; 3558 3559 /* 3560 * Acquire data structure 3561 */ 3562 mutex_enter(&ptgt->tgt_mutex); 3563 3564 /* 3565 * Destroy semaphore 3566 */ 3567 sema_destroy(&(icmd->ipkt_sema)); 3568 3569 /* 3570 * Cleanup internal packet 3571 */ 3572 mutex_exit(&ptgt->tgt_mutex); 3573 fcp_icmd_free(pptr, icmd); 3574 } 3575 3576 /* 3577 * Function: fcp_port_attach 3578 * 3579 * Description: Called by the transport framework to resume, suspend or 3580 * attach a new port. 3581 * 3582 * Argument: ulph Port handle 3583 * *pinfo Port information 3584 * cmd Command 3585 * s_id Port ID 3586 * 3587 * Return Value: FC_FAILURE or FC_SUCCESS 3588 */ 3589 /*ARGSUSED*/ 3590 static int 3591 fcp_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo, 3592 fc_attach_cmd_t cmd, uint32_t s_id) 3593 { 3594 int instance; 3595 int res = FC_FAILURE; /* default result */ 3596 3597 ASSERT(pinfo != NULL); 3598 3599 instance = ddi_get_instance(pinfo->port_dip); 3600 3601 switch (cmd) { 3602 case FC_CMD_ATTACH: 3603 /* 3604 * this port instance attaching for the first time (or after 3605 * being detached before) 3606 */ 3607 if (fcp_handle_port_attach(ulph, pinfo, s_id, 3608 instance) == DDI_SUCCESS) { 3609 res = FC_SUCCESS; 3610 } else { 3611 ASSERT(ddi_get_soft_state(fcp_softstate, 3612 instance) == NULL); 3613 } 3614 break; 3615 3616 case FC_CMD_RESUME: 3617 case FC_CMD_POWER_UP: 3618 /* 3619 * this port instance was attached and the suspended and 3620 * will now be resumed 3621 */ 3622 if (fcp_handle_port_resume(ulph, pinfo, s_id, cmd, 3623 instance) == DDI_SUCCESS) { 3624 res = FC_SUCCESS; 3625 } 3626 break; 3627 3628 default: 3629 /* shouldn't happen */ 3630 FCP_TRACE(fcp_logq, "fcp", 3631 fcp_trace, FCP_BUF_LEVEL_2, 0, 3632 "port_attach: unknown cmdcommand: %d", cmd); 3633 break; 3634 } 3635 3636 /* return result */ 3637 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 3638 FCP_BUF_LEVEL_1, 0, "fcp_port_attach returning %d", res); 3639 3640 return (res); 3641 } 3642 3643 3644 /* 3645 * detach or suspend this port instance 3646 * 3647 * acquires and releases the global mutex 3648 * 3649 * acquires and releases the mutex for this port 3650 * 3651 * acquires and releases the hotplug mutex for this port 3652 */ 3653 /*ARGSUSED*/ 3654 static int 3655 fcp_port_detach(opaque_t ulph, fc_ulp_port_info_t *info, 3656 fc_detach_cmd_t cmd) 3657 { 3658 int flag; 3659 int instance; 3660 struct fcp_port *pptr; 3661 3662 instance = ddi_get_instance(info->port_dip); 3663 pptr = ddi_get_soft_state(fcp_softstate, instance); 3664 3665 switch (cmd) { 3666 case FC_CMD_SUSPEND: 3667 FCP_DTRACE(fcp_logq, "fcp", 3668 fcp_trace, FCP_BUF_LEVEL_8, 0, 3669 "port suspend called for port %d", instance); 3670 flag = FCP_STATE_SUSPENDED; 3671 break; 3672 3673 case FC_CMD_POWER_DOWN: 3674 FCP_DTRACE(fcp_logq, "fcp", 3675 fcp_trace, FCP_BUF_LEVEL_8, 0, 3676 "port power down called for port %d", instance); 3677 flag = FCP_STATE_POWER_DOWN; 3678 break; 3679 3680 case FC_CMD_DETACH: 3681 FCP_DTRACE(fcp_logq, "fcp", 3682 fcp_trace, FCP_BUF_LEVEL_8, 0, 3683 "port detach called for port %d", instance); 3684 flag = FCP_STATE_DETACHING; 3685 break; 3686 3687 default: 3688 /* shouldn't happen */ 3689 return (FC_FAILURE); 3690 } 3691 FCP_DTRACE(fcp_logq, "fcp", fcp_trace, 3692 FCP_BUF_LEVEL_1, 0, "fcp_port_detach returning"); 3693 3694 return (fcp_handle_port_detach(pptr, flag, instance)); 3695 } 3696 3697 3698 /* 3699 * called for ioctls on the transport's devctl interface, and the transport 3700 * has passed it to us 3701 * 3702 * this will only be called for device control ioctls (i.e. hotplugging stuff) 3703 * 3704 * return FC_SUCCESS if we decide to claim the ioctl, 3705 * else return FC_UNCLAIMED 3706 * 3707 * *rval is set iff we decide to claim the ioctl 3708 */ 3709 /*ARGSUSED*/ 3710 static int 3711 fcp_port_ioctl(opaque_t ulph, opaque_t port_handle, dev_t dev, int cmd, 3712 intptr_t data, int mode, cred_t *credp, int *rval, uint32_t claimed) 3713 { 3714 int retval = FC_UNCLAIMED; /* return value */ 3715 struct fcp_port *pptr = NULL; /* our soft state */ 3716 struct devctl_iocdata *dcp = NULL; /* for devctl */ 3717 dev_info_t *cdip; 3718 mdi_pathinfo_t *pip = NULL; 3719 char *ndi_nm; /* NDI name */ 3720 char *ndi_addr; /* NDI addr */ 3721 int is_mpxio, circ; 3722 int devi_entered = 0; 3723 clock_t end_time; 3724 3725 ASSERT(rval != NULL); 3726 3727 FCP_DTRACE(fcp_logq, "fcp", 3728 fcp_trace, FCP_BUF_LEVEL_8, 0, 3729 "fcp_port_ioctl(cmd=0x%x, claimed=%d)", cmd, claimed); 3730 3731 /* if already claimed then forget it */ 3732 if (claimed) { 3733 /* 3734 * for now, if this ioctl has already been claimed, then 3735 * we just ignore it 3736 */ 3737 return (retval); 3738 } 3739 3740 /* get our port info */ 3741 if ((pptr = fcp_get_port(port_handle)) == NULL) { 3742 fcp_log(CE_WARN, NULL, 3743 "!fcp:Invalid port handle handle in ioctl"); 3744 *rval = ENXIO; 3745 return (retval); 3746 } 3747 is_mpxio = pptr->port_mpxio; 3748 3749 switch (cmd) { 3750 case DEVCTL_BUS_GETSTATE: 3751 case DEVCTL_BUS_QUIESCE: 3752 case DEVCTL_BUS_UNQUIESCE: 3753 case DEVCTL_BUS_RESET: 3754 case DEVCTL_BUS_RESETALL: 3755 3756 case DEVCTL_BUS_DEV_CREATE: 3757 if (ndi_dc_allochdl((void *)data, &dcp) != NDI_SUCCESS) { 3758 return (retval); 3759