1 /*- 2 * Copyright (c) 2011, 2012 LSI Corp. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * LSI MPT-Fusion Host Adapter FreeBSD 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 /* Communications core for LSI MPT2 */ 33 34 /* TODO Move headers to mpsvar */ 35 #include <sys/types.h> 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/selinfo.h> 40 #include <sys/module.h> 41 #include <sys/bus.h> 42 #include <sys/conf.h> 43 #include <sys/bio.h> 44 #include <sys/malloc.h> 45 #include <sys/uio.h> 46 #include <sys/sysctl.h> 47 #include <sys/endian.h> 48 #include <sys/queue.h> 49 #include <sys/kthread.h> 50 #include <sys/taskqueue.h> 51 #include <sys/sbuf.h> 52 53 #include <machine/bus.h> 54 #include <machine/resource.h> 55 #include <sys/rman.h> 56 57 #include <machine/stdarg.h> 58 59 #include <cam/cam.h> 60 #include <cam/cam_ccb.h> 61 #include <cam/cam_debug.h> 62 #include <cam/cam_sim.h> 63 #include <cam/cam_xpt_sim.h> 64 #include <cam/cam_xpt_periph.h> 65 #include <cam/cam_periph.h> 66 #include <cam/scsi/scsi_all.h> 67 #include <cam/scsi/scsi_message.h> 68 69 #include <dev/mps/mpi/mpi2_type.h> 70 #include <dev/mps/mpi/mpi2.h> 71 #include <dev/mps/mpi/mpi2_ioc.h> 72 #include <dev/mps/mpi/mpi2_sas.h> 73 #include <dev/mps/mpi/mpi2_cnfg.h> 74 #include <dev/mps/mpi/mpi2_init.h> 75 #include <dev/mps/mpi/mpi2_raid.h> 76 #include <dev/mps/mpi/mpi2_tool.h> 77 #include <dev/mps/mps_ioctl.h> 78 #include <dev/mps/mpsvar.h> 79 #include <dev/mps/mps_table.h> 80 #include <dev/mps/mps_sas.h> 81 82 /* For Hashed SAS Address creation for SATA Drives */ 83 #define MPT2SAS_SN_LEN 20 84 #define MPT2SAS_MN_LEN 40 85 86 struct mps_fw_event_work { 87 u16 event; 88 void *event_data; 89 TAILQ_ENTRY(mps_fw_event_work) ev_link; 90 }; 91 92 union _sata_sas_address { 93 u8 wwid[8]; 94 struct { 95 u32 high; 96 u32 low; 97 } word; 98 }; 99 100 /* 101 * define the IDENTIFY DEVICE structure 102 */ 103 struct _ata_identify_device_data { 104 u16 reserved1[10]; /* 0-9 */ 105 u16 serial_number[10]; /* 10-19 */ 106 u16 reserved2[7]; /* 20-26 */ 107 u16 model_number[20]; /* 27-46*/ 108 u16 reserved3[209]; /* 47-255*/ 109 }; 110 static u32 event_count; 111 static void mpssas_fw_work(struct mps_softc *sc, 112 struct mps_fw_event_work *fw_event); 113 static void mpssas_fw_event_free(struct mps_softc *, 114 struct mps_fw_event_work *); 115 static int mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate); 116 static int mpssas_get_sata_identify(struct mps_softc *sc, u16 handle, 117 Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz, 118 u32 devinfo); 119 int mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc, 120 u64 *sas_address, u16 handle, u32 device_info); 121 static int mpssas_volume_add(struct mps_softc *sc, 122 u16 handle); 123 static void mpssas_SSU_to_SATA_devices(struct mps_softc *sc); 124 static void mpssas_stop_unit_done(struct cam_periph *periph, 125 union ccb *done_ccb); 126 127 void 128 mpssas_evt_handler(struct mps_softc *sc, uintptr_t data, 129 MPI2_EVENT_NOTIFICATION_REPLY *event) 130 { 131 struct mps_fw_event_work *fw_event; 132 u16 sz; 133 134 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 135 mps_print_evt_sas(sc, event); 136 mpssas_record_event(sc, event); 137 138 fw_event = malloc(sizeof(struct mps_fw_event_work), M_MPT2, 139 M_ZERO|M_NOWAIT); 140 if (!fw_event) { 141 printf("%s: allocate failed for fw_event\n", __func__); 142 return; 143 } 144 sz = le16toh(event->EventDataLength) * 4; 145 fw_event->event_data = malloc(sz, M_MPT2, M_ZERO|M_NOWAIT); 146 if (!fw_event->event_data) { 147 printf("%s: allocate failed for event_data\n", __func__); 148 free(fw_event, M_MPT2); 149 return; 150 } 151 152 bcopy(event->EventData, fw_event->event_data, sz); 153 fw_event->event = event->Event; 154 if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST || 155 event->Event == MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE || 156 event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) && 157 sc->track_mapping_events) 158 sc->pending_map_events++; 159 160 /* 161 * When wait_for_port_enable flag is set, make sure that all the events 162 * are processed. Increment the startup_refcount and decrement it after 163 * events are processed. 164 */ 165 if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST || 166 event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) && 167 sc->wait_for_port_enable) 168 mpssas_startup_increment(sc->sassc); 169 170 TAILQ_INSERT_TAIL(&sc->sassc->ev_queue, fw_event, ev_link); 171 taskqueue_enqueue(sc->sassc->ev_tq, &sc->sassc->ev_task); 172 173 } 174 175 static void 176 mpssas_fw_event_free(struct mps_softc *sc, struct mps_fw_event_work *fw_event) 177 { 178 179 free(fw_event->event_data, M_MPT2); 180 free(fw_event, M_MPT2); 181 } 182 183 /** 184 * _mps_fw_work - delayed task for processing firmware events 185 * @sc: per adapter object 186 * @fw_event: The fw_event_work object 187 * Context: user. 188 * 189 * Return nothing. 190 */ 191 static void 192 mpssas_fw_work(struct mps_softc *sc, struct mps_fw_event_work *fw_event) 193 { 194 struct mpssas_softc *sassc; 195 sassc = sc->sassc; 196 197 mps_dprint(sc, MPS_EVENT, "(%d)->(%s) Working on Event: [%x]\n", 198 event_count++,__func__,fw_event->event); 199 switch (fw_event->event) { 200 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 201 { 202 MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data; 203 MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy; 204 int i; 205 206 data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *) 207 fw_event->event_data; 208 209 mps_mapping_topology_change_event(sc, fw_event->event_data); 210 211 for (i = 0; i < data->NumEntries; i++) { 212 phy = &data->PHY[i]; 213 switch (phy->PhyStatus & MPI2_EVENT_SAS_TOPO_RC_MASK) { 214 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 215 if (mpssas_add_device(sc, 216 le16toh(phy->AttachedDevHandle), phy->LinkRate)){ 217 printf("%s: failed to add device with " 218 "handle 0x%x\n", __func__, 219 le16toh(phy->AttachedDevHandle)); 220 mpssas_prepare_remove(sassc, le16toh( 221 phy->AttachedDevHandle)); 222 } 223 break; 224 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 225 mpssas_prepare_remove(sassc,le16toh( 226 phy->AttachedDevHandle)); 227 break; 228 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 229 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 230 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 231 default: 232 break; 233 } 234 } 235 /* 236 * refcount was incremented for this event in 237 * mpssas_evt_handler. Decrement it here because the event has 238 * been processed. 239 */ 240 mpssas_startup_decrement(sassc); 241 break; 242 } 243 case MPI2_EVENT_SAS_DISCOVERY: 244 { 245 MPI2_EVENT_DATA_SAS_DISCOVERY *data; 246 247 data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)fw_event->event_data; 248 249 if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_STARTED) 250 mps_dprint(sc, MPS_TRACE,"SAS discovery start event\n"); 251 if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_COMPLETED) { 252 mps_dprint(sc, MPS_TRACE,"SAS discovery stop event\n"); 253 sassc->flags &= ~MPSSAS_IN_DISCOVERY; 254 mpssas_discovery_end(sassc); 255 } 256 break; 257 } 258 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 259 { 260 Mpi2EventDataSasEnclDevStatusChange_t *data; 261 data = (Mpi2EventDataSasEnclDevStatusChange_t *) 262 fw_event->event_data; 263 mps_mapping_enclosure_dev_status_change_event(sc, 264 fw_event->event_data); 265 break; 266 } 267 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 268 { 269 Mpi2EventIrConfigElement_t *element; 270 int i; 271 u8 foreign_config; 272 Mpi2EventDataIrConfigChangeList_t *event_data; 273 struct mpssas_target *targ; 274 unsigned int id; 275 276 event_data = fw_event->event_data; 277 foreign_config = (le32toh(event_data->Flags) & 278 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; 279 280 element = 281 (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; 282 id = mps_mapping_get_raid_id_from_handle 283 (sc, element->VolDevHandle); 284 285 mps_mapping_ir_config_change_event(sc, event_data); 286 287 for (i = 0; i < event_data->NumElements; i++, element++) { 288 switch (element->ReasonCode) { 289 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: 290 case MPI2_EVENT_IR_CHANGE_RC_ADDED: 291 if (!foreign_config) { 292 if (mpssas_volume_add(sc, le16toh(element->VolDevHandle))){ 293 printf("%s: failed to add RAID " 294 "volume with handle 0x%x\n", 295 __func__, le16toh(element-> 296 VolDevHandle)); 297 } 298 } 299 break; 300 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 301 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 302 /* 303 * Rescan after volume is deleted or removed. 304 */ 305 if (!foreign_config) { 306 if (id == MPS_MAP_BAD_ID) { 307 printf("%s: could not get ID " 308 "for volume with handle " 309 "0x%04x\n", __func__, 310 le16toh(element->VolDevHandle)); 311 break; 312 } 313 314 targ = &sassc->targets[id]; 315 targ->handle = 0x0; 316 targ->encl_slot = 0x0; 317 targ->encl_handle = 0x0; 318 targ->exp_dev_handle = 0x0; 319 targ->phy_num = 0x0; 320 targ->linkrate = 0x0; 321 mpssas_rescan_target(sc, targ); 322 printf("RAID target id 0x%x removed\n", 323 targ->tid); 324 } 325 break; 326 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 327 case MPI2_EVENT_IR_CHANGE_RC_HIDE: 328 /* 329 * Phys Disk of a volume has been created. Hide 330 * it from the OS. 331 */ 332 targ = mpssas_find_target_by_handle(sassc, 0, element->PhysDiskDevHandle); 333 if (targ == NULL) 334 break; 335 336 /* Set raid component flags only if it is not WD. 337 * OR WrapDrive with WD_HIDE_ALWAYS/WD_HIDE_IF_VOLUME is set in NVRAM 338 */ 339 if((!sc->WD_available) || 340 ((sc->WD_available && 341 (sc->WD_hide_expose == MPS_WD_HIDE_ALWAYS)) || 342 (sc->WD_valid_config && (sc->WD_hide_expose == 343 MPS_WD_HIDE_IF_VOLUME)))) { 344 targ->flags |= MPS_TARGET_FLAGS_RAID_COMPONENT; 345 } 346 mpssas_rescan_target(sc, targ); 347 348 break; 349 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: 350 /* 351 * Phys Disk of a volume has been deleted. 352 * Expose it to the OS. 353 */ 354 if (mpssas_add_device(sc, 355 le16toh(element->PhysDiskDevHandle), 0)){ 356 printf("%s: failed to add device with " 357 "handle 0x%x\n", __func__, 358 le16toh(element->PhysDiskDevHandle)); 359 mpssas_prepare_remove(sassc, le16toh(element-> 360 PhysDiskDevHandle)); 361 } 362 break; 363 } 364 } 365 /* 366 * refcount was incremented for this event in 367 * mpssas_evt_handler. Decrement it here because the event has 368 * been processed. 369 */ 370 mpssas_startup_decrement(sassc); 371 break; 372 } 373 case MPI2_EVENT_IR_VOLUME: 374 { 375 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data; 376 377 /* 378 * Informational only. 379 */ 380 mps_dprint(sc, MPS_EVENT, "Received IR Volume event:\n"); 381 switch (event_data->ReasonCode) { 382 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED: 383 mps_dprint(sc, MPS_EVENT, " Volume Settings " 384 "changed from 0x%x to 0x%x for Volome with " 385 "handle 0x%x", le32toh(event_data->PreviousValue), 386 le32toh(event_data->NewValue), 387 le16toh(event_data->VolDevHandle)); 388 break; 389 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED: 390 mps_dprint(sc, MPS_EVENT, " Volume Status " 391 "changed from 0x%x to 0x%x for Volome with " 392 "handle 0x%x", le32toh(event_data->PreviousValue), 393 le32toh(event_data->NewValue), 394 le16toh(event_data->VolDevHandle)); 395 break; 396 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED: 397 mps_dprint(sc, MPS_EVENT, " Volume State " 398 "changed from 0x%x to 0x%x for Volome with " 399 "handle 0x%x", le32toh(event_data->PreviousValue), 400 le32toh(event_data->NewValue), 401 le16toh(event_data->VolDevHandle)); 402 u32 state; 403 struct mpssas_target *targ; 404 state = le32toh(event_data->NewValue); 405 switch (state) { 406 case MPI2_RAID_VOL_STATE_MISSING: 407 case MPI2_RAID_VOL_STATE_FAILED: 408 mpssas_prepare_volume_remove(sassc, event_data-> 409 VolDevHandle); 410 break; 411 412 case MPI2_RAID_VOL_STATE_ONLINE: 413 case MPI2_RAID_VOL_STATE_DEGRADED: 414 case MPI2_RAID_VOL_STATE_OPTIMAL: 415 targ = mpssas_find_target_by_handle(sassc, 0, event_data->VolDevHandle); 416 if (targ) { 417 printf("%s %d: Volume handle 0x%x is already added \n", 418 __func__, __LINE__ , event_data->VolDevHandle); 419 break; 420 } 421 if (mpssas_volume_add(sc, le16toh(event_data->VolDevHandle))) { 422 printf("%s: failed to add RAID " 423 "volume with handle 0x%x\n", 424 __func__, le16toh(event_data-> 425 VolDevHandle)); 426 } 427 break; 428 default: 429 break; 430 } 431 break; 432 default: 433 break; 434 } 435 break; 436 } 437 case MPI2_EVENT_IR_PHYSICAL_DISK: 438 { 439 Mpi2EventDataIrPhysicalDisk_t *event_data = 440 fw_event->event_data; 441 struct mpssas_target *targ; 442 443 /* 444 * Informational only. 445 */ 446 mps_dprint(sc, MPS_EVENT, "Received IR Phys Disk event:\n"); 447 switch (event_data->ReasonCode) { 448 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED: 449 mps_dprint(sc, MPS_EVENT, " Phys Disk Settings " 450 "changed from 0x%x to 0x%x for Phys Disk Number " 451 "%d and handle 0x%x at Enclosure handle 0x%x, Slot " 452 "%d", le32toh(event_data->PreviousValue), 453 le32toh(event_data->NewValue), 454 event_data->PhysDiskNum, 455 le16toh(event_data->PhysDiskDevHandle), 456 le16toh(event_data->EnclosureHandle), le16toh(event_data->Slot)); 457 break; 458 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED: 459 mps_dprint(sc, MPS_EVENT, " Phys Disk Status changed " 460 "from 0x%x to 0x%x for Phys Disk Number %d and " 461 "handle 0x%x at Enclosure handle 0x%x, Slot %d", 462 le32toh(event_data->PreviousValue), 463 le32toh(event_data->NewValue), event_data->PhysDiskNum, 464 le16toh(event_data->PhysDiskDevHandle), 465 le16toh(event_data->EnclosureHandle), le16toh(event_data->Slot)); 466 break; 467 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED: 468 mps_dprint(sc, MPS_EVENT, " Phys Disk State changed " 469 "from 0x%x to 0x%x for Phys Disk Number %d and " 470 "handle 0x%x at Enclosure handle 0x%x, Slot %d", 471 le32toh(event_data->PreviousValue), 472 le32toh(event_data->NewValue), event_data->PhysDiskNum, 473 le16toh(event_data->PhysDiskDevHandle), 474 le16toh(event_data->EnclosureHandle), le16toh(event_data->Slot)); 475 switch (event_data->NewValue) { 476 case MPI2_RAID_PD_STATE_ONLINE: 477 case MPI2_RAID_PD_STATE_DEGRADED: 478 case MPI2_RAID_PD_STATE_REBUILDING: 479 case MPI2_RAID_PD_STATE_OPTIMAL: 480 case MPI2_RAID_PD_STATE_HOT_SPARE: 481 targ = mpssas_find_target_by_handle(sassc, 0, 482 event_data->PhysDiskDevHandle); 483 if (targ) { 484 if(!sc->WD_available) { 485 targ->flags |= MPS_TARGET_FLAGS_RAID_COMPONENT; 486 printf("%s %d: Found Target for handle 0x%x. \n", 487 __func__, __LINE__ , event_data->PhysDiskDevHandle); 488 } else if ((sc->WD_available && 489 (sc->WD_hide_expose == MPS_WD_HIDE_ALWAYS)) || 490 (sc->WD_valid_config && (sc->WD_hide_expose == 491 MPS_WD_HIDE_IF_VOLUME))) { 492 targ->flags |= MPS_TARGET_FLAGS_RAID_COMPONENT; 493 printf("%s %d: WD: Found Target for handle 0x%x. \n", 494 __func__, __LINE__ , event_data->PhysDiskDevHandle); 495 } 496 } 497 break; 498 case MPI2_RAID_PD_STATE_OFFLINE: 499 case MPI2_RAID_PD_STATE_NOT_CONFIGURED: 500 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: 501 default: 502 targ = mpssas_find_target_by_handle(sassc, 0, 503 event_data->PhysDiskDevHandle); 504 if (targ) { 505 targ->flags |= ~MPS_TARGET_FLAGS_RAID_COMPONENT; 506 printf("%s %d: Found Target for handle 0x%x. \n", 507 __func__, __LINE__ , event_data->PhysDiskDevHandle); 508 } 509 break; 510 } 511 default: 512 break; 513 } 514 break; 515 } 516 case MPI2_EVENT_IR_OPERATION_STATUS: 517 { 518 Mpi2EventDataIrOperationStatus_t *event_data = 519 fw_event->event_data; 520 521 /* 522 * Informational only. 523 */ 524 mps_dprint(sc, MPS_EVENT, "Received IR Op Status event:\n"); 525 mps_dprint(sc, MPS_EVENT, " RAID Operation of %d is %d " 526 "percent complete for Volume with handle 0x%x", 527 event_data->RAIDOperation, event_data->PercentComplete, 528 le16toh(event_data->VolDevHandle)); 529 break; 530 } 531 case MPI2_EVENT_LOG_ENTRY_ADDED: 532 { 533 pMpi2EventDataLogEntryAdded_t logEntry; 534 uint16_t logQualifier; 535 uint8_t logCode; 536 537 logEntry = (pMpi2EventDataLogEntryAdded_t)fw_event->event_data; 538 logQualifier = logEntry->LogEntryQualifier; 539 540 if (logQualifier == MPI2_WD_LOG_ENTRY) { 541 logCode = logEntry->LogData[0]; 542 543 switch (logCode) { 544 case MPI2_WD_SSD_THROTTLING: 545 printf("WarpDrive Warning: IO Throttling has " 546 "occurred in the WarpDrive subsystem. " 547 "Check WarpDrive documentation for " 548 "additional details\n"); 549 break; 550 case MPI2_WD_DRIVE_LIFE_WARN: 551 printf("WarpDrive Warning: Program/Erase " 552 "Cycles for the WarpDrive subsystem in " 553 "degraded range. Check WarpDrive " 554 "documentation for additional details\n"); 555 break; 556 case MPI2_WD_DRIVE_LIFE_DEAD: 557 printf("WarpDrive Fatal Error: There are no " 558 "Program/Erase Cycles for the WarpDrive " 559 "subsystem. The storage device will be in " 560 "read-only mode. Check WarpDrive " 561 "documentation for additional details\n"); 562 break; 563 case MPI2_WD_RAIL_MON_FAIL: 564 printf("WarpDrive Fatal Error: The Backup Rail " 565 "Monitor has failed on the WarpDrive " 566 "subsystem. Check WarpDrive documentation " 567 "for additional details\n"); 568 break; 569 default: 570 break; 571 } 572 } 573 break; 574 } 575 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 576 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 577 default: 578 mps_dprint(sc, MPS_TRACE,"Unhandled event 0x%0X\n", 579 fw_event->event); 580 break; 581 582 } 583 mps_dprint(sc, MPS_EVENT, "(%d)->(%s) Event Free: [%x]\n",event_count,__func__, fw_event->event); 584 mpssas_fw_event_free(sc, fw_event); 585 } 586 587 void 588 mpssas_firmware_event_work(void *arg, int pending) 589 { 590 struct mps_fw_event_work *fw_event; 591 struct mps_softc *sc; 592 593 sc = (struct mps_softc *)arg; 594 mps_lock(sc); 595 while ((fw_event = TAILQ_FIRST(&sc->sassc->ev_queue)) != NULL) { 596 TAILQ_REMOVE(&sc->sassc->ev_queue, fw_event, ev_link); 597 mpssas_fw_work(sc, fw_event); 598 } 599 mps_unlock(sc); 600 } 601 602 static int 603 mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){ 604 char devstring[80]; 605 struct mpssas_softc *sassc; 606 struct mpssas_target *targ; 607 Mpi2ConfigReply_t mpi_reply; 608 Mpi2SasDevicePage0_t config_page; 609 uint64_t sas_address, sata_sas_address; 610 uint64_t parent_sas_address = 0; 611 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 612 u32 device_info, parent_devinfo = 0; 613 unsigned int id; 614 int ret; 615 int error = 0; 616 struct mpssas_lun *lun; 617 618 sassc = sc->sassc; 619 mpssas_startup_increment(sassc); 620 if ((mps_config_get_sas_device_pg0(sc, &mpi_reply, &config_page, 621 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { 622 printf("%s: error reading SAS device page0\n", __func__); 623 error = ENXIO; 624 goto out; 625 } 626 627 device_info = le32toh(config_page.DeviceInfo); 628 629 if (((device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET) == 0) 630 && (le16toh(config_page.ParentDevHandle) != 0)) { 631 Mpi2ConfigReply_t tmp_mpi_reply; 632 Mpi2SasDevicePage0_t parent_config_page; 633 634 if ((mps_config_get_sas_device_pg0(sc, &tmp_mpi_reply, 635 &parent_config_page, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, 636 le16toh(config_page.ParentDevHandle)))) { 637 printf("%s: error reading SAS device %#x page0\n", 638 __func__, le16toh(config_page.ParentDevHandle)); 639 } else { 640 parent_sas_address = parent_config_page.SASAddress.High; 641 parent_sas_address = (parent_sas_address << 32) | 642 parent_config_page.SASAddress.Low; 643 parent_devinfo = le32toh(parent_config_page.DeviceInfo); 644 } 645 } 646 /* TODO Check proper endianess */ 647 sas_address = config_page.SASAddress.High; 648 sas_address = (sas_address << 32) | 649 config_page.SASAddress.Low; 650 651 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) 652 == MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 653 if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) { 654 ret = mpssas_get_sas_address_for_sata_disk(sc, 655 &sata_sas_address, handle, device_info); 656 if (!ret) 657 id = mps_mapping_get_sas_id(sc, 658 sata_sas_address, handle); 659 else 660 id = mps_mapping_get_sas_id(sc, 661 sas_address, handle); 662 } else 663 id = mps_mapping_get_sas_id(sc, sas_address, 664 handle); 665 } else 666 id = mps_mapping_get_sas_id(sc, sas_address, handle); 667 668 if (id == MPS_MAP_BAD_ID) { 669 printf("failure at %s:%d/%s()! Could not get ID for device " 670 "with handle 0x%04x\n", __FILE__, __LINE__, __func__, 671 handle); 672 error = ENXIO; 673 goto out; 674 } 675 676 if (mpssas_check_id(sassc, id) != 0) { 677 device_printf(sc->mps_dev, "Excluding target id %d\n", id); 678 error = ENXIO; 679 goto out; 680 } 681 682 mps_dprint(sc, MPS_MAPPING, "SAS Address from SAS device page0 = %jx\n", 683 sas_address); 684 targ = &sassc->targets[id]; 685 targ->devinfo = device_info; 686 targ->devname = le32toh(config_page.DeviceName.High); 687 targ->devname = (targ->devname << 32) | 688 le32toh(config_page.DeviceName.Low); 689 targ->encl_handle = le16toh(config_page.EnclosureHandle); 690 targ->encl_slot = le16toh(config_page.Slot); 691 targ->handle = handle; 692 targ->parent_handle = le16toh(config_page.ParentDevHandle); 693 targ->sasaddr = mps_to_u64(&config_page.SASAddress); 694 targ->parent_sasaddr = le64toh(parent_sas_address); 695 targ->parent_devinfo = parent_devinfo; 696 targ->tid = id; 697 targ->linkrate = (linkrate>>4); 698 targ->flags = 0; 699 TAILQ_INIT(&targ->commands); 700 TAILQ_INIT(&targ->timedout_commands); 701 while(!SLIST_EMPTY(&targ->luns)) { 702 lun = SLIST_FIRST(&targ->luns); 703 SLIST_REMOVE_HEAD(&targ->luns, lun_link); 704 free(lun, M_MPT2); 705 } 706 SLIST_INIT(&targ->luns); 707 708 mps_describe_devinfo(targ->devinfo, devstring, 80); 709 mps_dprint(sc, MPS_MAPPING, "Found device <%s> <%s> <0x%04x> <%d/%d>\n", devstring, 710 mps_describe_table(mps_linkrate_names, targ->linkrate), 711 targ->handle, targ->encl_handle, targ->encl_slot); 712 713 #if __FreeBSD_version < 1000039 714 if ((sassc->flags & MPSSAS_IN_STARTUP) == 0) 715 #endif 716 mpssas_rescan_target(sc, targ); 717 mps_dprint(sc, MPS_MAPPING, "Target id 0x%x added\n", targ->tid); 718 out: 719 mpssas_startup_decrement(sassc); 720 return (error); 721 722 } 723 724 int 725 mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc, 726 u64 *sas_address, u16 handle, u32 device_info) 727 { 728 Mpi2SataPassthroughReply_t mpi_reply; 729 int i, rc, try_count; 730 u32 *bufferptr; 731 union _sata_sas_address hash_address; 732 struct _ata_identify_device_data ata_identify; 733 u8 buffer[MPT2SAS_MN_LEN + MPT2SAS_SN_LEN]; 734 u32 ioc_status; 735 u8 sas_status; 736 737 memset(&ata_identify, 0, sizeof(ata_identify)); 738 try_count = 0; 739 do { 740 rc = mpssas_get_sata_identify(sc, handle, &mpi_reply, 741 (char *)&ata_identify, sizeof(ata_identify), device_info); 742 try_count++; 743 ioc_status = le16toh(mpi_reply.IOCStatus) 744 & MPI2_IOCSTATUS_MASK; 745 sas_status = mpi_reply.SASStatus; 746 } while ((rc == -EAGAIN || ioc_status || sas_status) && 747 (try_count < 5)); 748 749 if (rc == 0 && !ioc_status && !sas_status) { 750 mps_dprint(sc, MPS_MAPPING, "%s: got SATA identify successfully " 751 "for handle = 0x%x with try_count = %d\n", 752 __func__, handle, try_count); 753 } else { 754 mps_dprint(sc, MPS_MAPPING, "%s: handle = 0x%x failed\n", 755 __func__, handle); 756 return -1; 757 } 758 /* Copy & byteswap the 40 byte model number to a buffer */ 759 for (i = 0; i < MPT2SAS_MN_LEN; i += 2) { 760 buffer[i] = ((u8 *)ata_identify.model_number)[i + 1]; 761 buffer[i + 1] = ((u8 *)ata_identify.model_number)[i]; 762 } 763 /* Copy & byteswap the 20 byte serial number to a buffer */ 764 for (i = 0; i < MPT2SAS_SN_LEN; i += 2) { 765 buffer[MPT2SAS_MN_LEN + i] = 766 ((u8 *)ata_identify.serial_number)[i + 1]; 767 buffer[MPT2SAS_MN_LEN + i + 1] = 768 ((u8 *)ata_identify.serial_number)[i]; 769 } 770 bufferptr = (u32 *)buffer; 771 /* There are 60 bytes to hash down to 8. 60 isn't divisible by 8, 772 * so loop through the first 56 bytes (7*8), 773 * and then add in the last dword. 774 */ 775 hash_address.word.low = 0; 776 hash_address.word.high = 0; 777 for (i = 0; (i < ((MPT2SAS_MN_LEN+MPT2SAS_SN_LEN)/8)); i++) { 778 hash_address.word.low += *bufferptr; 779 bufferptr++; 780 hash_address.word.high += *bufferptr; 781 bufferptr++; 782 } 783 /* Add the last dword */ 784 hash_address.word.low += *bufferptr; 785 /* Make sure the hash doesn't start with 5, because it could clash 786 * with a SAS address. Change 5 to a D. 787 */ 788 if ((hash_address.word.high & 0x000000F0) == (0x00000050)) 789 hash_address.word.high |= 0x00000080; 790 *sas_address = (u64)hash_address.wwid[0] << 56 | 791 (u64)hash_address.wwid[1] << 48 | (u64)hash_address.wwid[2] << 40 | 792 (u64)hash_address.wwid[3] << 32 | (u64)hash_address.wwid[4] << 24 | 793 (u64)hash_address.wwid[5] << 16 | (u64)hash_address.wwid[6] << 8 | 794 (u64)hash_address.wwid[7]; 795 return 0; 796 } 797 798 static int 799 mpssas_get_sata_identify(struct mps_softc *sc, u16 handle, 800 Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz, u32 devinfo) 801 { 802 Mpi2SataPassthroughRequest_t *mpi_request; 803 Mpi2SataPassthroughReply_t *reply; 804 struct mps_command *cm; 805 char *buffer; 806 int error = 0; 807 808 buffer = malloc( sz, M_MPT2, M_NOWAIT | M_ZERO); 809 if (!buffer) 810 return ENOMEM; 811 812 if ((cm = mps_alloc_command(sc)) == NULL) { 813 free(buffer, M_MPT2); 814 return (EBUSY); 815 } 816 mpi_request = (MPI2_SATA_PASSTHROUGH_REQUEST *)cm->cm_req; 817 bzero(mpi_request,sizeof(MPI2_SATA_PASSTHROUGH_REQUEST)); 818 mpi_request->Function = MPI2_FUNCTION_SATA_PASSTHROUGH; 819 mpi_request->VF_ID = 0; 820 mpi_request->DevHandle = htole16(handle); 821 mpi_request->PassthroughFlags = (MPI2_SATA_PT_REQ_PT_FLAGS_PIO | 822 MPI2_SATA_PT_REQ_PT_FLAGS_READ); 823 mpi_request->DataLength = htole32(sz); 824 mpi_request->CommandFIS[0] = 0x27; 825 mpi_request->CommandFIS[1] = 0x80; 826 mpi_request->CommandFIS[2] = (devinfo & 827 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE) ? 0xA1 : 0xEC; 828 cm->cm_sge = &mpi_request->SGL; 829 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 830 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 831 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 832 cm->cm_data = buffer; 833 cm->cm_length = htole32(sz); 834 error = mps_wait_command(sc, cm, 60, CAN_SLEEP); 835 reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply; 836 if (error || (reply == NULL)) { 837 /* FIXME */ 838 /* 839 * If the request returns an error then we need to do a diag 840 * reset 841 */ 842 printf("%s: request for page completed with error %d", 843 __func__, error); 844 error = ENXIO; 845 goto out; 846 } 847 bcopy(buffer, id_buffer, sz); 848 bcopy(reply, mpi_reply, sizeof(Mpi2SataPassthroughReply_t)); 849 if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) != 850 MPI2_IOCSTATUS_SUCCESS) { 851 printf("%s: error reading SATA PASSTHRU; iocstatus = 0x%x\n", 852 __func__, reply->IOCStatus); 853 error = ENXIO; 854 goto out; 855 } 856 out: 857 mps_free_command(sc, cm); 858 free(buffer, M_MPT2); 859 return (error); 860 } 861 862 static int 863 mpssas_volume_add(struct mps_softc *sc, u16 handle) 864 { 865 struct mpssas_softc *sassc; 866 struct mpssas_target *targ; 867 u64 wwid; 868 unsigned int id; 869 int error = 0; 870 struct mpssas_lun *lun; 871 872 sassc = sc->sassc; 873 mpssas_startup_increment(sassc); 874 /* wwid is endian safe */ 875 mps_config_get_volume_wwid(sc, handle, &wwid); 876 if (!wwid) { 877 printf("%s: invalid WWID; cannot add volume to mapping table\n", 878 __func__); 879 error = ENXIO; 880 goto out; 881 } 882 883 id = mps_mapping_get_raid_id(sc, wwid, handle); 884 if (id == MPS_MAP_BAD_ID) { 885 printf("%s: could not get ID for volume with handle 0x%04x and " 886 "WWID 0x%016llx\n", __func__, handle, 887 (unsigned long long)wwid); 888 error = ENXIO; 889 goto out; 890 } 891 892 targ = &sassc->targets[id]; 893 targ->tid = id; 894 targ->handle = handle; 895 targ->devname = wwid; 896 TAILQ_INIT(&targ->commands); 897 TAILQ_INIT(&targ->timedout_commands); 898 while(!SLIST_EMPTY(&targ->luns)) { 899 lun = SLIST_FIRST(&targ->luns); 900 SLIST_REMOVE_HEAD(&targ->luns, lun_link); 901 free(lun, M_MPT2); 902 } 903 SLIST_INIT(&targ->luns); 904 #if __FreeBSD_version < 1000039 905 if ((sassc->flags & MPSSAS_IN_STARTUP) == 0) 906 #endif 907 mpssas_rescan_target(sc, targ); 908 mps_dprint(sc, MPS_MAPPING, "RAID target id %d added (WWID = 0x%jx)\n", 909 targ->tid, wwid); 910 out: 911 mpssas_startup_decrement(sassc); 912 return (error); 913 } 914 915 /** 916 * mpssas_SSU_to_SATA_devices 917 * @sc: per adapter object 918 * 919 * Looks through the target list and issues a StartStopUnit SCSI command to each 920 * SATA direct-access device. This helps to ensure that data corruption is 921 * avoided when the system is being shut down. This must be called after the IR 922 * System Shutdown RAID Action is sent if in IR mode. 923 * 924 * Return nothing. 925 */ 926 static void 927 mpssas_SSU_to_SATA_devices(struct mps_softc *sc) 928 { 929 struct mpssas_softc *sassc = sc->sassc; 930 union ccb *ccb; 931 path_id_t pathid = cam_sim_path(sassc->sim); 932 target_id_t targetid; 933 struct mpssas_target *target; 934 struct mpssas_lun *lun; 935 char path_str[64]; 936 struct timeval cur_time, start_time; 937 938 /* 939 * For each LUN of each target, issue a StartStopUnit command to stop 940 * the device. 941 */ 942 sc->SSU_started = TRUE; 943 sc->SSU_refcount = 0; 944 for (targetid = 0; targetid < sc->facts->MaxTargets; targetid++) { 945 target = &sassc->targets[targetid]; 946 if (target->handle == 0x0) { 947 continue; 948 } 949 950 SLIST_FOREACH(lun, &target->luns, lun_link) { 951 ccb = xpt_alloc_ccb_nowait(); 952 if (ccb == NULL) { 953 mps_dprint(sc, MPS_FAULT, "Unable to alloc CCB " 954 "to stop unit.\n"); 955 return; 956 } 957 958 /* 959 * The stop_at_shutdown flag will be set if this LUN is 960 * a SATA direct-access end device. 961 */ 962 if (lun->stop_at_shutdown) { 963 if (xpt_create_path(&ccb->ccb_h.path, 964 xpt_periph, pathid, targetid, 965 lun->lun_id) != CAM_REQ_CMP) { 966 mps_dprint(sc, MPS_FAULT, "Unable to " 967 "create LUN path to stop unit.\n"); 968 xpt_free_ccb(ccb); 969 return; 970 } 971 xpt_path_string(ccb->ccb_h.path, path_str, 972 sizeof(path_str)); 973 974 mps_dprint(sc, MPS_INFO, "Sending StopUnit: " 975 "path %s handle %d\n", path_str, 976 target->handle); 977 978 /* 979 * Issue a START STOP UNIT command for the LUN. 980 * Increment the SSU counter to be used to 981 * count the number of required replies. 982 */ 983 mps_dprint(sc, MPS_INFO, "Incrementing SSU " 984 "count\n"); 985 sc->SSU_refcount++; 986 ccb->ccb_h.target_id = 987 xpt_path_target_id(ccb->ccb_h.path); 988 ccb->ccb_h.target_lun = lun->lun_id; 989 ccb->ccb_h.ppriv_ptr1 = sassc; 990 scsi_start_stop(&ccb->csio, 991 /*retries*/0, 992 mpssas_stop_unit_done, 993 MSG_SIMPLE_Q_TAG, 994 /*start*/FALSE, 995 /*load/eject*/0, 996 /*immediate*/FALSE, 997 MPS_SENSE_LEN, 998 /*timeout*/10000); 999 xpt_action(ccb); 1000 } 1001 } 1002 } 1003 1004 /* 1005 * Wait until all of the SSU commands have completed or time has 1006 * expired (60 seconds). pause for 100ms each time through. If any 1007 * command times out, the target will be reset in the SCSI command 1008 * timeout routine. 1009 */ 1010 getmicrotime(&start_time); 1011 while (sc->SSU_refcount) { 1012 pause("mpswait", hz/10); 1013 1014 getmicrotime(&cur_time); 1015 if ((cur_time.tv_sec - start_time.tv_sec) > 60) { 1016 mps_dprint(sc, MPS_FAULT, "Time has expired waiting " 1017 "for SSU commands to complete.\n"); 1018 break; 1019 } 1020 } 1021 } 1022 1023 static void 1024 mpssas_stop_unit_done(struct cam_periph *periph, union ccb *done_ccb) 1025 { 1026 struct mpssas_softc *sassc; 1027 char path_str[64]; 1028 1029 sassc = (struct mpssas_softc *)done_ccb->ccb_h.ppriv_ptr1; 1030 1031 xpt_path_string(done_ccb->ccb_h.path, path_str, sizeof(path_str)); 1032 mps_dprint(sassc->sc, MPS_INFO, "Completing stop unit for %s\n", 1033 path_str); 1034 1035 if (done_ccb == NULL) 1036 return; 1037 1038 /* 1039 * Nothing more to do except free the CCB and path. If the command 1040 * timed out, an abort reset, then target reset will be issued during 1041 * the SCSI Command process. 1042 */ 1043 xpt_free_path(done_ccb->ccb_h.path); 1044 xpt_free_ccb(done_ccb); 1045 } 1046 1047 /** 1048 * mpssas_ir_shutdown - IR shutdown notification 1049 * @sc: per adapter object 1050 * 1051 * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that 1052 * the host system is shutting down. 1053 * 1054 * Return nothing. 1055 */ 1056 void 1057 mpssas_ir_shutdown(struct mps_softc *sc) 1058 { 1059 u16 volume_mapping_flags; 1060 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1061 struct dev_mapping_table *mt_entry; 1062 u32 start_idx, end_idx; 1063 unsigned int id, found_volume = 0; 1064 struct mps_command *cm; 1065 Mpi2RaidActionRequest_t *action; 1066 1067 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 1068 1069 /* is IR firmware build loaded? */ 1070 if (!sc->ir_firmware) 1071 goto out; 1072 1073 /* are there any volumes? Look at IR target IDs. */ 1074 // TODO-later, this should be looked up in the RAID config structure 1075 // when it is implemented. 1076 volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 1077 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 1078 if (volume_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) { 1079 start_idx = 0; 1080 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 1081 start_idx = 1; 1082 } else 1083 start_idx = sc->max_devices - sc->max_volumes; 1084 end_idx = start_idx + sc->max_volumes - 1; 1085 1086 for (id = start_idx; id < end_idx; id++) { 1087 mt_entry = &sc->mapping_table[id]; 1088 if ((mt_entry->physical_id != 0) && 1089 (mt_entry->missing_count == 0)) { 1090 found_volume = 1; 1091 break; 1092 } 1093 } 1094 1095 if (!found_volume) 1096 goto out; 1097 1098 if ((cm = mps_alloc_command(sc)) == NULL) { 1099 printf("%s: command alloc failed\n", __func__); 1100 goto out; 1101 } 1102 1103 action = (MPI2_RAID_ACTION_REQUEST *)cm->cm_req; 1104 action->Function = MPI2_FUNCTION_RAID_ACTION; 1105 action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; 1106 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1107 mps_lock(sc); 1108 mps_wait_command(sc, cm, 5, CAN_SLEEP); 1109 mps_unlock(sc); 1110 1111 /* 1112 * Don't check for reply, just leave. 1113 */ 1114 if (cm) 1115 mps_free_command(sc, cm); 1116 1117 out: 1118 mpssas_SSU_to_SATA_devices(sc); 1119 } 1120