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