Merge branch 'vendor/OPENRESOLV' with the following changes:
[dragonfly.git] / sys / dev / raid / mpr / mpr_sas_lsi.c
1 /*-
2  * Copyright (c) 2011-2015 LSI Corp.
3  * Copyright (c) 2013-2016 Avago Technologies
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
28  *
29  * $FreeBSD: head/sys/dev/mpr/mpr_sas_lsi.c 331228 2018-03-19 23:21:45Z mav $
30  */
31
32 /* Communications core for Avago Technologies (LSI) MPT3 */
33
34 /* TODO Move headers to mprvar */
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <sys/bus.h>
41 #include <sys/conf.h>
42 #include <sys/bio.h>
43 #include <sys/malloc.h>
44 #include <sys/uio.h>
45 #include <sys/sysctl.h>
46 #include <sys/endian.h>
47 #include <sys/queue.h>
48 #include <sys/kthread.h>
49 #include <sys/taskqueue.h>
50 #include <sys/sbuf.h>
51 #include <sys/eventhandler.h>
52
53 #include <sys/rman.h>
54
55 #include <machine/stdarg.h>
56
57 #include <bus/cam/cam.h>
58 #include <bus/cam/cam_ccb.h>
59 #include <bus/cam/cam_debug.h>
60 #include <bus/cam/cam_sim.h>
61 #include <bus/cam/cam_xpt_sim.h>
62 #include <bus/cam/cam_xpt_periph.h>
63 #include <bus/cam/cam_periph.h>
64 #include <bus/cam/scsi/scsi_all.h>
65 #include <bus/cam/scsi/scsi_message.h>
66
67 #include <dev/raid/mpr/mpi/mpi2_type.h>
68 #include <dev/raid/mpr/mpi/mpi2.h>
69 #include <dev/raid/mpr/mpi/mpi2_ioc.h>
70 #include <dev/raid/mpr/mpi/mpi2_sas.h>
71 #include <dev/raid/mpr/mpi/mpi2_pci.h>
72 #include <dev/raid/mpr/mpi/mpi2_cnfg.h>
73 #include <dev/raid/mpr/mpi/mpi2_init.h>
74 #include <dev/raid/mpr/mpi/mpi2_raid.h>
75 #include <dev/raid/mpr/mpi/mpi2_tool.h>
76 #include <dev/raid/mpr/mpr_ioctl.h>
77 #include <dev/raid/mpr/mprvar.h>
78 #include <dev/raid/mpr/mpr_table.h>
79 #include <dev/raid/mpr/mpr_sas.h>
80
81 /* For Hashed SAS Address creation for SATA Drives */
82 #define MPT2SAS_SN_LEN 20
83 #define MPT2SAS_MN_LEN 40
84
85 struct mpr_fw_event_work {
86         u16                     event;
87         void                    *event_data;
88         TAILQ_ENTRY(mpr_fw_event_work)  ev_link;
89 };
90
91 union _sata_sas_address {
92         u8 wwid[8];
93         struct {
94                 u32 high;
95                 u32 low;
96         } word;
97 };
98
99 /*
100  * define the IDENTIFY DEVICE structure
101  */
102 struct _ata_identify_device_data {
103         u16 reserved1[10];      /* 0-9 */
104         u16 serial_number[10];  /* 10-19 */
105         u16 reserved2[7];       /* 20-26 */
106         u16 model_number[20];   /* 27-46*/
107         u16 reserved3[170];     /* 47-216 */
108         u16 rotational_speed;   /* 217 */
109         u16 reserved4[38];      /* 218-255 */
110 };
111 static u32 event_count;
112 static void mprsas_fw_work(struct mpr_softc *sc,
113     struct mpr_fw_event_work *fw_event);
114 static void mprsas_fw_event_free(struct mpr_softc *,
115     struct mpr_fw_event_work *);
116 static int mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate);
117 static int mprsas_add_pcie_device(struct mpr_softc *sc, u16 handle,
118     u8 linkrate);
119 static int mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle,
120     Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz,
121     u32 devinfo);
122 static void mprsas_ata_id_timeout(void *data);
123 int mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc,
124     u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD);
125 static int mprsas_volume_add(struct mpr_softc *sc,
126     u16 handle);
127 static void mprsas_SSU_to_SATA_devices(struct mpr_softc *sc);
128 static void mprsas_stop_unit_done(struct cam_periph *periph,
129     union ccb *done_ccb);
130
131 void
132 mprsas_evt_handler(struct mpr_softc *sc, uintptr_t data,
133     MPI2_EVENT_NOTIFICATION_REPLY *event)
134 {
135         struct mpr_fw_event_work *fw_event;
136         u16 sz;
137
138         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
139         MPR_DPRINT_EVENT(sc, sas, event);
140         mprsas_record_event(sc, event);
141
142         fw_event = kmalloc(sizeof(struct mpr_fw_event_work), M_MPR,
143              M_ZERO|M_NOWAIT);
144         if (!fw_event) {
145                 kprintf("%s: allocate failed for fw_event\n", __func__);
146                 return;
147         }
148         sz = le16toh(event->EventDataLength) * 4;
149         fw_event->event_data = kmalloc(sz, M_MPR, M_ZERO|M_NOWAIT);
150         if (!fw_event->event_data) {
151                 kprintf("%s: allocate failed for event_data\n", __func__);
152                 kfree(fw_event, M_MPR);
153                 return;
154         }
155
156         bcopy(event->EventData, fw_event->event_data, sz);
157         fw_event->event = event->Event;
158         if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
159             event->Event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
160             event->Event == MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE ||
161             event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) &&
162             sc->track_mapping_events)
163                 sc->pending_map_events++;
164
165         /*
166          * When wait_for_port_enable flag is set, make sure that all the events
167          * are processed. Increment the startup_refcount and decrement it after
168          * events are processed.
169          */
170         if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
171             event->Event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
172             event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) &&
173             sc->wait_for_port_enable)
174                 mprsas_startup_increment(sc->sassc);
175
176         TAILQ_INSERT_TAIL(&sc->sassc->ev_queue, fw_event, ev_link);
177         taskqueue_enqueue(sc->sassc->ev_tq, &sc->sassc->ev_task);
178 }
179
180 static void
181 mprsas_fw_event_free(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
182 {
183
184         kfree(fw_event->event_data, M_MPR);
185         kfree(fw_event, M_MPR);
186 }
187
188 /**
189  * _mpr_fw_work - delayed task for processing firmware events
190  * @sc: per adapter object
191  * @fw_event: The fw_event_work object
192  * Context: user.
193  *
194  * Return nothing.
195  */
196 static void
197 mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
198 {
199         struct mprsas_softc *sassc;
200         sassc = sc->sassc;
201
202         mpr_dprint(sc, MPR_EVENT, "(%d)->(%s) Working on  Event: [%x]\n",
203             event_count++, __func__, fw_event->event);
204         switch (fw_event->event) {
205         case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 
206         {
207                 MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data;
208                 MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy;
209                 uint8_t i;
210
211                 data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
212                     fw_event->event_data;
213
214                 mpr_mapping_topology_change_event(sc, fw_event->event_data);
215
216                 for (i = 0; i < data->NumEntries; i++) {
217                         phy = &data->PHY[i];
218                         switch (phy->PhyStatus & MPI2_EVENT_SAS_TOPO_RC_MASK) {
219                         case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
220                                 if (mprsas_add_device(sc,
221                                     le16toh(phy->AttachedDevHandle),
222                                     phy->LinkRate)) {
223                                         mpr_dprint(sc, MPR_ERROR, "%s: "
224                                             "failed to add device with handle "
225                                             "0x%x\n", __func__,
226                                             le16toh(phy->AttachedDevHandle));
227                                         mprsas_prepare_remove(sassc, le16toh(
228                                             phy->AttachedDevHandle));
229                                 }
230                                 break;
231                         case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
232                                 mprsas_prepare_remove(sassc, le16toh(
233                                     phy->AttachedDevHandle));
234                                 break;
235                         case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
236                         case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
237                         case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
238                         default:
239                                 break;
240                         }
241                 }
242                 /*
243                  * refcount was incremented for this event in
244                  * mprsas_evt_handler.  Decrement it here because the event has
245                  * been processed.
246                  */
247                 mprsas_startup_decrement(sassc);
248                 break;
249         }
250         case MPI2_EVENT_SAS_DISCOVERY:
251         {
252                 MPI2_EVENT_DATA_SAS_DISCOVERY *data;
253
254                 data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)fw_event->event_data;
255
256                 if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_STARTED)
257                         mpr_dprint(sc, MPR_TRACE,"SAS discovery start event\n");
258                 if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_COMPLETED) {
259                         mpr_dprint(sc, MPR_TRACE,"SAS discovery stop event\n");
260                         sassc->flags &= ~MPRSAS_IN_DISCOVERY;
261                         mprsas_discovery_end(sassc);
262                 }
263                 break;
264         }
265         case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
266         {
267                 Mpi2EventDataSasEnclDevStatusChange_t *data;
268                 data = (Mpi2EventDataSasEnclDevStatusChange_t *)
269                     fw_event->event_data;
270                 mpr_mapping_enclosure_dev_status_change_event(sc,
271                     fw_event->event_data);
272                 break;
273         }
274         case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
275         {
276                 Mpi2EventIrConfigElement_t *element;
277                 int i;
278                 u8 foreign_config, reason;
279                 u16 elementType;
280                 Mpi2EventDataIrConfigChangeList_t *event_data;
281                 struct mprsas_target *targ;
282                 unsigned int id;
283
284                 event_data = fw_event->event_data;
285                 foreign_config = (le32toh(event_data->Flags) &
286                     MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
287
288                 element =
289                     (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
290                 id = mpr_mapping_get_raid_tid_from_handle(sc,
291                     element->VolDevHandle);
292
293                 mpr_mapping_ir_config_change_event(sc, event_data);
294                 for (i = 0; i < event_data->NumElements; i++, element++) {
295                         reason = element->ReasonCode;
296                         elementType = le16toh(element->ElementFlags) &
297                             MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK;
298                         /*
299                          * check for element type of Phys Disk or Hot Spare
300                          */
301                         if ((elementType != 
302                             MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT)
303                             && (elementType !=
304                             MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT))
305                                 // do next element
306                                 goto skip_fp_send;
307
308                         /*
309                          * check for reason of Hide, Unhide, PD Created, or PD
310                          * Deleted
311                          */
312                         if ((reason != MPI2_EVENT_IR_CHANGE_RC_HIDE) &&
313                             (reason != MPI2_EVENT_IR_CHANGE_RC_UNHIDE) &&
314                             (reason != MPI2_EVENT_IR_CHANGE_RC_PD_CREATED) &&
315                             (reason != MPI2_EVENT_IR_CHANGE_RC_PD_DELETED))
316                                 goto skip_fp_send;
317
318                         // check for a reason of Hide or PD Created
319                         if ((reason == MPI2_EVENT_IR_CHANGE_RC_HIDE) ||
320                             (reason == MPI2_EVENT_IR_CHANGE_RC_PD_CREATED))
321                         {
322                                 // build RAID Action message
323                                 Mpi2RaidActionRequest_t *action;
324                                 Mpi2RaidActionReply_t *reply = NULL;
325                                 struct mpr_command *cm;
326                                 int error = 0;
327                                 if ((cm = mpr_alloc_command(sc)) == NULL) {
328                                         kprintf("%s: command alloc failed\n",
329                                             __func__);
330                                         return;
331                                 }
332
333                                 mpr_dprint(sc, MPR_EVENT, "Sending FP action "
334                                     "from "
335                                     "MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST "
336                                     ":\n");
337                                 action = (MPI2_RAID_ACTION_REQUEST *)cm->cm_req;
338                                 action->Function = MPI2_FUNCTION_RAID_ACTION;
339                                 action->Action =
340                                     MPI2_RAID_ACTION_PHYSDISK_HIDDEN;
341                                 action->PhysDiskNum = element->PhysDiskNum;
342                                 cm->cm_desc.Default.RequestFlags =
343                                     MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
344                                 error = mpr_request_polled(sc, &cm);
345                                 if (cm != NULL)
346                                         reply = (Mpi2RaidActionReply_t *)
347                                             cm->cm_reply;
348                                 if (error || (reply == NULL)) {
349                                         /* FIXME */
350                                         /*
351                                          * If the poll returns error then we
352                                          * need to do diag reset
353                                          */
354                                         kprintf("%s: poll for page completed "
355                                             "with error %d", __func__, error);
356                                 }
357                                 if (reply && (le16toh(reply->IOCStatus) &
358                                     MPI2_IOCSTATUS_MASK) !=
359                                     MPI2_IOCSTATUS_SUCCESS) {
360                                         mpr_dprint(sc, MPR_ERROR, "%s: error "
361                                             "sending RaidActionPage; "
362                                             "iocstatus = 0x%x\n", __func__,
363                                             le16toh(reply->IOCStatus));
364                                 }
365
366                                 if (cm)
367                                         mpr_free_command(sc, cm);
368                         }
369 skip_fp_send:
370                         mpr_dprint(sc, MPR_EVENT, "Received "
371                             "MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST Reason "
372                             "code %x:\n", element->ReasonCode);
373                         switch (element->ReasonCode) {
374                         case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
375                         case MPI2_EVENT_IR_CHANGE_RC_ADDED:
376                                 if (!foreign_config) {
377                                         if (mprsas_volume_add(sc,
378                                             le16toh(element->VolDevHandle))) {
379                                                 kprintf("%s: failed to add RAID "
380                                                     "volume with handle 0x%x\n",
381                                                     __func__, le16toh(element->
382                                                     VolDevHandle));
383                                         }
384                                 }
385                                 break;
386                         case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
387                         case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
388                                 /*
389                                  * Rescan after volume is deleted or removed.
390                                  */
391                                 if (!foreign_config) {
392                                         if (id == MPR_MAP_BAD_ID) {
393                                                 kprintf("%s: could not get ID "
394                                                     "for volume with handle "
395                                                     "0x%04x\n", __func__,
396                                                     le16toh(element->
397                                                     VolDevHandle));
398                                                 break;
399                                         }
400                                         
401                                         targ = &sassc->targets[id];
402                                         targ->handle = 0x0;
403                                         targ->encl_slot = 0x0;
404                                         targ->encl_handle = 0x0;
405                                         targ->encl_level_valid = 0x0;
406                                         targ->encl_level = 0x0;
407                                         targ->connector_name[0] = ' ';
408                                         targ->connector_name[1] = ' ';
409                                         targ->connector_name[2] = ' ';
410                                         targ->connector_name[3] = ' ';
411                                         targ->exp_dev_handle = 0x0;
412                                         targ->phy_num = 0x0;
413                                         targ->linkrate = 0x0;
414                                         mprsas_rescan_target(sc, targ);
415                                         kprintf("RAID target id 0x%x removed\n",
416                                             targ->tid);
417                                 }
418                                 break;
419                         case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
420                         case MPI2_EVENT_IR_CHANGE_RC_HIDE:
421                                 /*
422                                  * Phys Disk of a volume has been created.  Hide
423                                  * it from the OS.
424                                  */
425                                 targ = mprsas_find_target_by_handle(sassc, 0,
426                                     element->PhysDiskDevHandle);
427                                 if (targ == NULL) 
428                                         break;
429                                 targ->flags |= MPR_TARGET_FLAGS_RAID_COMPONENT;
430                                 mprsas_rescan_target(sc, targ);
431                                 break;
432                         case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
433                                 /*
434                                  * Phys Disk of a volume has been deleted.
435                                  * Expose it to the OS.
436                                  */
437                                 if (mprsas_add_device(sc,
438                                     le16toh(element->PhysDiskDevHandle), 0)) {
439                                         kprintf("%s: failed to add device with "
440                                             "handle 0x%x\n", __func__,
441                                             le16toh(element->
442                                             PhysDiskDevHandle));
443                                         mprsas_prepare_remove(sassc,
444                                             le16toh(element->
445                                             PhysDiskDevHandle));
446                                 }
447                                 break;
448                         }
449                 }
450                 /*
451                  * refcount was incremented for this event in
452                  * mprsas_evt_handler.  Decrement it here because the event has
453                  * been processed.
454                  */
455                 mprsas_startup_decrement(sassc);
456                 break;
457         }
458         case MPI2_EVENT_IR_VOLUME:
459         {
460                 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
461
462                 /*
463                  * Informational only.
464                  */
465                 mpr_dprint(sc, MPR_EVENT, "Received IR Volume event:\n");
466                 switch (event_data->ReasonCode) {
467                 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
468                         mpr_dprint(sc, MPR_EVENT, "   Volume Settings "
469                             "changed from 0x%x to 0x%x for Volome with "
470                             "handle 0x%x", le32toh(event_data->PreviousValue),
471                             le32toh(event_data->NewValue),
472                             le16toh(event_data->VolDevHandle));
473                         break;
474                 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
475                         mpr_dprint(sc, MPR_EVENT, "   Volume Status "
476                             "changed from 0x%x to 0x%x for Volome with "
477                             "handle 0x%x", le32toh(event_data->PreviousValue),
478                             le32toh(event_data->NewValue),
479                             le16toh(event_data->VolDevHandle));
480                         break;
481                 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
482                         mpr_dprint(sc, MPR_EVENT, "   Volume State "
483                             "changed from 0x%x to 0x%x for Volome with "
484                             "handle 0x%x", le32toh(event_data->PreviousValue),
485                             le32toh(event_data->NewValue),
486                             le16toh(event_data->VolDevHandle));
487                                 u32 state;
488                                 struct mprsas_target *targ;
489                                 state = le32toh(event_data->NewValue);
490                                 switch (state) {
491                                 case MPI2_RAID_VOL_STATE_MISSING:
492                                 case MPI2_RAID_VOL_STATE_FAILED:
493                                         mprsas_prepare_volume_remove(sassc,
494                                             event_data->VolDevHandle);
495                                         break;
496                  
497                                 case MPI2_RAID_VOL_STATE_ONLINE:
498                                 case MPI2_RAID_VOL_STATE_DEGRADED:
499                                 case MPI2_RAID_VOL_STATE_OPTIMAL:
500                                         targ =
501                                             mprsas_find_target_by_handle(sassc,
502                                             0, event_data->VolDevHandle);
503                                         if (targ) {
504                                                 kprintf("%s %d: Volume handle "
505                                                     "0x%x is already added \n",
506                                                     __func__, __LINE__,
507                                                     event_data->VolDevHandle);
508                                                 break;
509                                         }
510                                         if (mprsas_volume_add(sc,
511                                             le16toh(event_data->
512                                             VolDevHandle))) {
513                                                 kprintf("%s: failed to add RAID "
514                                                     "volume with handle 0x%x\n",
515                                                     __func__, le16toh(
516                                                     event_data->VolDevHandle));
517                                         }
518                                         break;
519                                 default:
520                                         break;
521                                 }
522                         break;
523                 default:
524                         break;
525                 }
526                 break;
527         }
528         case MPI2_EVENT_IR_PHYSICAL_DISK:
529         {
530                 Mpi2EventDataIrPhysicalDisk_t *event_data =
531                     fw_event->event_data;
532                 struct mprsas_target *targ;
533
534                 /*
535                  * Informational only.
536                  */
537                 mpr_dprint(sc, MPR_EVENT, "Received IR Phys Disk event:\n");
538                 switch (event_data->ReasonCode) {
539                 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED:
540                         mpr_dprint(sc, MPR_EVENT, "   Phys Disk Settings "
541                             "changed from 0x%x to 0x%x for Phys Disk Number "
542                             "%d and handle 0x%x at Enclosure handle 0x%x, Slot "
543                             "%d", le32toh(event_data->PreviousValue),
544                             le32toh(event_data->NewValue),
545                             event_data->PhysDiskNum,
546                             le16toh(event_data->PhysDiskDevHandle),
547                             le16toh(event_data->EnclosureHandle),
548                             le16toh(event_data->Slot));
549                         break;
550                 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
551                         mpr_dprint(sc, MPR_EVENT, "   Phys Disk Status changed "
552                             "from 0x%x to 0x%x for Phys Disk Number %d and "
553                             "handle 0x%x at Enclosure handle 0x%x, Slot %d",
554                             le32toh(event_data->PreviousValue),
555                             le32toh(event_data->NewValue),
556                             event_data->PhysDiskNum,
557                             le16toh(event_data->PhysDiskDevHandle),
558                             le16toh(event_data->EnclosureHandle),
559                             le16toh(event_data->Slot));
560                         break;
561                 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
562                         mpr_dprint(sc, MPR_EVENT, "   Phys Disk State changed "
563                             "from 0x%x to 0x%x for Phys Disk Number %d and "
564                             "handle 0x%x at Enclosure handle 0x%x, Slot %d",
565                             le32toh(event_data->PreviousValue),
566                             le32toh(event_data->NewValue),
567                             event_data->PhysDiskNum,
568                             le16toh(event_data->PhysDiskDevHandle),
569                             le16toh(event_data->EnclosureHandle),
570                             le16toh(event_data->Slot));
571                         switch (event_data->NewValue) {
572                                 case MPI2_RAID_PD_STATE_ONLINE:
573                                 case MPI2_RAID_PD_STATE_DEGRADED:
574                                 case MPI2_RAID_PD_STATE_REBUILDING:
575                                 case MPI2_RAID_PD_STATE_OPTIMAL:
576                                 case MPI2_RAID_PD_STATE_HOT_SPARE:
577                                         targ = mprsas_find_target_by_handle(
578                                             sassc, 0,
579                                             event_data->PhysDiskDevHandle);
580                                         if (targ) {
581                                                 targ->flags |=
582                                                     MPR_TARGET_FLAGS_RAID_COMPONENT;
583                                                 kprintf("%s %d: Found Target "
584                                                     "for handle 0x%x.\n", 
585                                                     __func__, __LINE__ ,
586                                                     event_data->
587                                                     PhysDiskDevHandle);
588                                         }
589                                 break;
590                                 case MPI2_RAID_PD_STATE_OFFLINE:
591                                 case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
592                                 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
593                                 default:
594                                         targ = mprsas_find_target_by_handle(
595                                             sassc, 0,
596                                             event_data->PhysDiskDevHandle);
597                                         if (targ) {
598                                                 targ->flags |=
599                                             ~MPR_TARGET_FLAGS_RAID_COMPONENT;
600                                                 kprintf("%s %d: Found Target "
601                                                     "for handle 0x%x.  \n",
602                                                     __func__, __LINE__ ,
603                                                     event_data->
604                                                     PhysDiskDevHandle);
605                                         }
606                                 break;
607                         }
608                 default:
609                         break;
610                 }
611                 break;
612         }
613         case MPI2_EVENT_IR_OPERATION_STATUS:
614         {
615                 Mpi2EventDataIrOperationStatus_t *event_data =
616                     fw_event->event_data;
617
618                 /*
619                  * Informational only.
620                  */
621                 mpr_dprint(sc, MPR_EVENT, "Received IR Op Status event:\n");
622                 mpr_dprint(sc, MPR_EVENT, "   RAID Operation of %d is %d "
623                     "percent complete for Volume with handle 0x%x",
624                     event_data->RAIDOperation, event_data->PercentComplete,
625                     le16toh(event_data->VolDevHandle));
626                 break;
627         }
628         case MPI2_EVENT_TEMP_THRESHOLD:
629         {
630                 pMpi2EventDataTemperature_t     temp_event;
631
632                 temp_event = (pMpi2EventDataTemperature_t)fw_event->event_data;
633
634                 /*
635                  * The Temp Sensor Count must be greater than the event's Sensor
636                  * Num to be valid.  If valid, print the temp thresholds that
637                  * have been exceeded.
638                  */
639                 if (sc->iounit_pg8.NumSensors > temp_event->SensorNum) {
640                         mpr_dprint(sc, MPR_FAULT, "Temperature Threshold flags "
641                             "%s %s %s %s exceeded for Sensor: %d !!!\n",
642                             ((temp_event->Status & 0x01) == 1) ? "0 " : " ",
643                             ((temp_event->Status & 0x02) == 2) ? "1 " : " ",
644                             ((temp_event->Status & 0x04) == 4) ? "2 " : " ",
645                             ((temp_event->Status & 0x08) == 8) ? "3 " : " ",
646                             temp_event->SensorNum);
647                         mpr_dprint(sc, MPR_FAULT, "Current Temp in Celsius: "
648                             "%d\n", temp_event->CurrentTemperature);
649                 }
650                 break;
651         }
652         case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
653         {
654                 pMpi26EventDataActiveCableExcept_t      ace_event_data;
655                 ace_event_data =
656                     (pMpi26EventDataActiveCableExcept_t)fw_event->event_data;
657
658                 switch(ace_event_data->ReasonCode) {
659                 case MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER:
660                 {
661                         mpr_printf(sc, "Currently a cable with "
662                             "ReceptacleID %d cannot be powered and device "
663                             "connected to this active cable will not be seen. "
664                             "This active cable requires %d mW of power.\n",
665                             ace_event_data->ReceptacleID,
666                             ace_event_data->ActiveCablePowerRequirement);
667                         break;
668                 }
669                 case MPI26_EVENT_ACTIVE_CABLE_DEGRADED:
670                 {
671                         mpr_printf(sc, "Currently a cable with "
672                             "ReceptacleID %d is not running at optimal speed "
673                             "(12 Gb/s rate)\n", ace_event_data->ReceptacleID);
674                         break;
675                 }
676                 default:
677                         break;
678                 }
679                 break;
680         }
681         case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
682         {
683                 pMpi25EventDataSasDeviceDiscoveryError_t discovery_error_data;
684                 uint64_t sas_address;
685
686                 discovery_error_data =
687                     (pMpi25EventDataSasDeviceDiscoveryError_t)
688                     fw_event->event_data;
689                 
690                 sas_address = discovery_error_data->SASAddress.High;
691                 sas_address = (sas_address << 32) |
692                     discovery_error_data->SASAddress.Low;
693
694                 switch(discovery_error_data->ReasonCode) {
695                 case MPI25_EVENT_SAS_DISC_ERR_SMP_FAILED:
696                 {
697                         mpr_printf(sc, "SMP command failed during discovery "
698                             "for expander with SAS Address %jx and "
699                             "handle 0x%x.\n", sas_address,
700                             discovery_error_data->DevHandle);
701                         break;
702                 }
703                 case MPI25_EVENT_SAS_DISC_ERR_SMP_TIMEOUT:
704                 {
705                         mpr_printf(sc, "SMP command timed out during "
706                             "discovery for expander with SAS Address %jx and "
707                             "handle 0x%x.\n", sas_address,
708                             discovery_error_data->DevHandle);
709                         break;
710                 }
711                 default:
712                         break;
713                 }
714                 break;
715         }
716         case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST: 
717         {
718                 MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST *data;
719                 MPI26_EVENT_PCIE_TOPO_PORT_ENTRY *port_entry;
720                 uint8_t i, link_rate;
721                 uint16_t handle;
722
723                 data = (MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST *)
724                     fw_event->event_data;
725
726                 mpr_mapping_pcie_topology_change_event(sc,
727                     fw_event->event_data);
728
729                 for (i = 0; i < data->NumEntries; i++) {
730                         port_entry = &data->PortEntry[i];
731                         handle = le16toh(port_entry->AttachedDevHandle);
732                         link_rate = port_entry->CurrentPortInfo &
733                             MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK;
734                         switch (port_entry->PortStatus) {
735                         case MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED:
736                                 if (link_rate <
737                                     MPI26_EVENT_PCIE_TOPO_PI_RATE_2_5) {
738                                         mpr_dprint(sc, MPR_ERROR, "%s: Cannot "
739                                             "add PCIe device with handle 0x%x "
740                                             "with unknown link rate.\n",
741                                             __func__, handle);
742                                         break;
743                                 }
744                                 if (mprsas_add_pcie_device(sc, handle,
745                                     link_rate)) {
746                                         mpr_dprint(sc, MPR_ERROR, "%s: failed "
747                                             "to add PCIe device with handle "
748                                             "0x%x\n", __func__, handle);
749                                         mprsas_prepare_remove(sassc, handle);
750                                 }
751                                 break;
752                         case MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING:
753                                 mprsas_prepare_remove(sassc, handle);
754                                 break;
755                         case MPI26_EVENT_PCIE_TOPO_PS_PORT_CHANGED:
756                         case MPI26_EVENT_PCIE_TOPO_PS_NO_CHANGE:
757                         case MPI26_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING:
758                         default:
759                                 break;
760                         }
761                 }
762                 /*
763                  * refcount was incremented for this event in
764                  * mprsas_evt_handler.  Decrement it here because the event has
765                  * been processed.
766                  */
767                 mprsas_startup_decrement(sassc);
768                 break;
769         }
770         case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
771         case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
772         default:
773                 mpr_dprint(sc, MPR_TRACE,"Unhandled event 0x%0X\n",
774                     fw_event->event);
775                 break;
776
777         }
778         mpr_dprint(sc, MPR_EVENT, "(%d)->(%s) Event Free: [%x]\n", event_count,
779             __func__, fw_event->event);
780         mprsas_fw_event_free(sc, fw_event);
781 }
782
783 void
784 mprsas_firmware_event_work(void *arg, int pending)
785 {
786         struct mpr_fw_event_work *fw_event;
787         struct mpr_softc *sc;
788
789         sc = (struct mpr_softc *)arg;
790         mpr_lock(sc);
791         while ((fw_event = TAILQ_FIRST(&sc->sassc->ev_queue)) != NULL) {
792                 TAILQ_REMOVE(&sc->sassc->ev_queue, fw_event, ev_link);
793                 mprsas_fw_work(sc, fw_event);
794         }
795         mpr_unlock(sc);
796 }
797
798 static int
799 mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate)
800 {
801         char devstring[80];
802         struct mprsas_softc *sassc;
803         struct mprsas_target *targ;
804         Mpi2ConfigReply_t mpi_reply;
805         Mpi2SasDevicePage0_t config_page;
806         uint64_t sas_address, parent_sas_address = 0;
807         u32 device_info, parent_devinfo = 0;
808         unsigned int id;
809         int ret = 1, error = 0, i;
810         struct mprsas_lun *lun;
811         u8 is_SATA_SSD = 0;
812         struct mpr_command *cm;
813
814         sassc = sc->sassc;
815         mprsas_startup_increment(sassc);
816         if (mpr_config_get_sas_device_pg0(sc, &mpi_reply, &config_page,
817             MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle) != 0) {
818                 mpr_dprint(sc, MPR_INFO|MPR_MAPPING|MPR_FAULT,
819                     "Error reading SAS device %#x page0, iocstatus= 0x%x\n",
820                     handle, mpi_reply.IOCStatus);
821                 error = ENXIO;
822                 goto out;
823         }
824
825         device_info = le32toh(config_page.DeviceInfo);
826
827         if (((device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET) == 0)
828             && (le16toh(config_page.ParentDevHandle) != 0)) {
829                 Mpi2ConfigReply_t tmp_mpi_reply;
830                 Mpi2SasDevicePage0_t parent_config_page;
831
832                 if (mpr_config_get_sas_device_pg0(sc, &tmp_mpi_reply,
833                     &parent_config_page, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
834                     le16toh(config_page.ParentDevHandle)) != 0) {
835                         mpr_dprint(sc, MPR_MAPPING|MPR_FAULT,
836                             "Error reading parent SAS device %#x page0, "
837                             "iocstatus= 0x%x\n",
838                             le16toh(config_page.ParentDevHandle),
839                             tmp_mpi_reply.IOCStatus);
840                 } else {
841                         parent_sas_address = parent_config_page.SASAddress.High;
842                         parent_sas_address = (parent_sas_address << 32) |
843                             parent_config_page.SASAddress.Low;
844                         parent_devinfo = le32toh(parent_config_page.DeviceInfo);
845                 }
846         }
847         /* TODO Check proper endianness */
848         sas_address = config_page.SASAddress.High;
849         sas_address = (sas_address << 32) | config_page.SASAddress.Low;
850         mpr_dprint(sc, MPR_MAPPING, "Handle 0x%04x SAS Address from SAS device "
851             "page0 = %jx\n", handle, sas_address);
852
853         /*
854          * Always get SATA Identify information because this is used to
855          * determine if Start/Stop Unit should be sent to the drive when the
856          * system is shutdown.
857          */
858         if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) {
859                 ret = mprsas_get_sas_address_for_sata_disk(sc, &sas_address,
860                     handle, device_info, &is_SATA_SSD);
861                 if (ret) {
862                         mpr_dprint(sc, MPR_MAPPING|MPR_ERROR,
863                             "%s: failed to get disk type (SSD or HDD) for SATA "
864                             "device with handle 0x%04x\n",
865                             __func__, handle);
866                 } else {
867                         mpr_dprint(sc, MPR_MAPPING, "Handle 0x%04x SAS Address "
868                             "from SATA device = %jx\n", handle, sas_address);
869                 }
870         }
871
872         /*
873          * use_phynum:
874          *  1 - use the PhyNum field as a fallback to the mapping logic
875          *  0 - never use the PhyNum field
876          * -1 - only use the PhyNum field
877          *
878          * Note that using the Phy number to map a device can cause device adds
879          * to fail if multiple enclosures/expanders are in the topology. For
880          * example, if two devices are in the same slot number in two different
881          * enclosures within the topology, only one of those devices will be
882          * added. PhyNum mapping should not be used if multiple enclosures are
883          * in the topology.
884          */
885         id = MPR_MAP_BAD_ID;
886         if (sc->use_phynum != -1) 
887                 id = mpr_mapping_get_tid(sc, sas_address, handle);
888         if (id == MPR_MAP_BAD_ID) {
889                 if ((sc->use_phynum == 0) ||
890                     ((id = config_page.PhyNum) > sassc->maxtargets)) {
891                         mpr_dprint(sc, MPR_INFO, "failure at %s:%d/%s()! "
892                             "Could not get ID for device with handle 0x%04x\n",
893                             __FILE__, __LINE__, __func__, handle);
894                         error = ENXIO;
895                         goto out;
896                 }
897         }
898         mpr_dprint(sc, MPR_MAPPING, "%s: Target ID for added device is %d.\n",
899             __func__, id);
900
901         /*
902          * Only do the ID check and reuse check if the target is not from a
903          * RAID Component. For Physical Disks of a Volume, the ID will be reused
904          * when a volume is deleted because the mapping entry for the PD will
905          * still be in the mapping table. The ID check should not be done here
906          * either since this PD is already being used.
907          */
908         targ = &sassc->targets[id];
909         if (!(targ->flags & MPR_TARGET_FLAGS_RAID_COMPONENT)) {
910                 if (mprsas_check_id(sassc, id) != 0) {
911                         mpr_dprint(sc, MPR_MAPPING|MPR_INFO,
912                             "Excluding target id %d\n", id);
913                         error = ENXIO;
914                         goto out;
915                 }
916
917                 if (targ->handle != 0x0) {
918                         mpr_dprint(sc, MPR_MAPPING, "Attempting to reuse "
919                             "target id %d handle 0x%04x\n", id, targ->handle);
920                         error = ENXIO;
921                         goto out;
922                 }
923         }
924
925         targ->devinfo = device_info;
926         targ->devname = le32toh(config_page.DeviceName.High);
927         targ->devname = (targ->devname << 32) | 
928             le32toh(config_page.DeviceName.Low);
929         targ->encl_handle = le16toh(config_page.EnclosureHandle);
930         targ->encl_slot = le16toh(config_page.Slot);
931         targ->encl_level = config_page.EnclosureLevel;
932         targ->connector_name[0] = config_page.ConnectorName[0];
933         targ->connector_name[1] = config_page.ConnectorName[1];
934         targ->connector_name[2] = config_page.ConnectorName[2];
935         targ->connector_name[3] = config_page.ConnectorName[3];
936         targ->handle = handle;
937         targ->parent_handle = le16toh(config_page.ParentDevHandle);
938         targ->sasaddr = mpr_to_u64(&config_page.SASAddress);
939         targ->parent_sasaddr = le64toh(parent_sas_address);
940         targ->parent_devinfo = parent_devinfo;
941         targ->tid = id;
942         targ->linkrate = (linkrate>>4);
943         targ->flags = 0;
944         if (is_SATA_SSD) {
945                 targ->flags = MPR_TARGET_IS_SATA_SSD;
946         }
947         if ((le16toh(config_page.Flags) &
948             MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) &&
949             (le16toh(config_page.Flags) &
950             MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE)) {
951                 targ->scsi_req_desc_type =
952                     MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
953         }
954         if (le16toh(config_page.Flags) &
955             MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
956                 targ->encl_level_valid = TRUE;
957         }
958         TAILQ_INIT(&targ->commands);
959         TAILQ_INIT(&targ->timedout_commands);
960         while (!SLIST_EMPTY(&targ->luns)) {
961                 lun = SLIST_FIRST(&targ->luns);
962                 SLIST_REMOVE_HEAD(&targ->luns, lun_link);
963                 kfree(lun, M_MPR);
964         }
965         SLIST_INIT(&targ->luns);
966
967         mpr_describe_devinfo(targ->devinfo, devstring, 80);
968         mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "Found device <%s> <%s> "
969             "handle<0x%04x> enclosureHandle<0x%04x> slot %d\n", devstring,
970             mpr_describe_table(mpr_linkrate_names, targ->linkrate),
971             targ->handle, targ->encl_handle, targ->encl_slot);
972         if (targ->encl_level_valid) {
973                 mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "At enclosure level %d "
974                     "and connector name (%4s)\n", targ->encl_level,
975                     targ->connector_name);
976         }
977 #if 1 /* ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000039)) || \
978     (__FreeBSD_version < 902502) */
979         if ((sassc->flags & MPRSAS_IN_STARTUP) == 0)
980 #endif
981                 mprsas_rescan_target(sc, targ);
982         mpr_dprint(sc, MPR_MAPPING, "Target id 0x%x added\n", targ->tid);
983
984         /*
985          * Check all commands to see if the SATA_ID_TIMEOUT flag has been set.
986          * If so, send a Target Reset TM to the target that was just created.
987          * An Abort Task TM should be used instead of a Target Reset, but that
988          * would be much more difficult because targets have not been fully
989          * discovered yet, and LUN's haven't been setup.  So, just reset the
990          * target instead of the LUN.
991          */
992         for (i = 1; i < sc->num_reqs; i++) {
993                 cm = &sc->commands[i];
994                 if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
995                         targ->timeouts++;
996                         cm->cm_state = MPR_CM_STATE_TIMEDOUT;
997
998                         if ((targ->tm = mprsas_alloc_tm(sc)) != NULL) {
999                                 mpr_dprint(sc, MPR_INFO, "%s: sending Target "
1000                                     "Reset for stuck SATA identify command "
1001                                     "(cm = %p)\n", __func__, cm);
1002                                 targ->tm->cm_targ = targ;
1003                                 mprsas_send_reset(sc, targ->tm,
1004                                     MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
1005                         } else {
1006                                 mpr_dprint(sc, MPR_ERROR, "Failed to allocate "
1007                                     "tm for Target Reset after SATA ID command "
1008                                     "timed out (cm %p)\n", cm);
1009                         }
1010                         /*
1011                          * No need to check for more since the target is
1012                          * already being reset.
1013                          */
1014                         break;
1015                 }
1016         }
1017 out:
1018         /*
1019          * Free the commands that may not have been freed from the SATA ID call
1020          */
1021         for (i = 1; i < sc->num_reqs; i++) {
1022                 cm = &sc->commands[i];
1023                 if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
1024                         mpr_free_command(sc, cm);
1025                 }
1026         }
1027         mprsas_startup_decrement(sassc);
1028         return (error);
1029 }
1030
1031 int
1032 mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc,
1033     u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD)
1034 {
1035         Mpi2SataPassthroughReply_t mpi_reply;
1036         int i, rc, try_count;
1037         u32 *bufferptr;
1038         union _sata_sas_address hash_address;
1039         struct _ata_identify_device_data ata_identify;
1040         u8 buffer[MPT2SAS_MN_LEN + MPT2SAS_SN_LEN];
1041         u32 ioc_status;
1042         u8 sas_status;
1043
1044         memset(&ata_identify, 0, sizeof(ata_identify));
1045         memset(&mpi_reply, 0, sizeof(mpi_reply));
1046         try_count = 0;
1047         do {
1048                 rc = mprsas_get_sata_identify(sc, handle, &mpi_reply,
1049                     (char *)&ata_identify, sizeof(ata_identify), device_info);
1050                 try_count++;
1051                 ioc_status = le16toh(mpi_reply.IOCStatus)
1052                     & MPI2_IOCSTATUS_MASK;
1053                 sas_status = mpi_reply.SASStatus;
1054                 switch (ioc_status) {
1055                 case MPI2_IOCSTATUS_SUCCESS:
1056                         break;
1057                 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
1058                         /* No sense sleeping.  this error won't get better */
1059                         break;
1060                 default:
1061                         if (sc->spinup_wait_time > 0) {
1062                                 mpr_dprint(sc, MPR_INFO, "Sleeping %d seconds "
1063                                     "after SATA ID error to wait for spinup\n",
1064                                     sc->spinup_wait_time);
1065                                 lksleep(&sc->msleep_fake_chan, &sc->mpr_lock, 0,
1066                                     "mprid", sc->spinup_wait_time * hz);
1067                         }
1068                 }
1069         } while (((rc && (rc != EWOULDBLOCK)) ||
1070             (ioc_status && (ioc_status != MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR))
1071             || sas_status) && (try_count < 5));
1072
1073         if (rc == 0 && !ioc_status && !sas_status) {
1074                 mpr_dprint(sc, MPR_MAPPING, "%s: got SATA identify "
1075                     "successfully for handle = 0x%x with try_count = %d\n",
1076                     __func__, handle, try_count);
1077         } else {
1078                 mpr_dprint(sc, MPR_MAPPING, "%s: handle = 0x%x failed\n",
1079                     __func__, handle);
1080                 return -1;
1081         }
1082         /* Copy & byteswap the 40 byte model number to a buffer */
1083         for (i = 0; i < MPT2SAS_MN_LEN; i += 2) {
1084                 buffer[i] = ((u8 *)ata_identify.model_number)[i + 1];
1085                 buffer[i + 1] = ((u8 *)ata_identify.model_number)[i];
1086         }
1087         /* Copy & byteswap the 20 byte serial number to a buffer */
1088         for (i = 0; i < MPT2SAS_SN_LEN; i += 2) {
1089                 buffer[MPT2SAS_MN_LEN + i] =
1090                     ((u8 *)ata_identify.serial_number)[i + 1];
1091                 buffer[MPT2SAS_MN_LEN + i + 1] =
1092                     ((u8 *)ata_identify.serial_number)[i];
1093         }
1094         bufferptr = (u32 *)buffer;
1095         /* There are 60 bytes to hash down to 8. 60 isn't divisible by 8,
1096          * so loop through the first 56 bytes (7*8),
1097          * and then add in the last dword.
1098          */
1099         hash_address.word.low  = 0;
1100         hash_address.word.high = 0;
1101         for (i = 0; (i < ((MPT2SAS_MN_LEN+MPT2SAS_SN_LEN)/8)); i++) {
1102                 hash_address.word.low += *bufferptr;
1103                 bufferptr++;
1104                 hash_address.word.high += *bufferptr;
1105                 bufferptr++;
1106         }
1107         /* Add the last dword */
1108         hash_address.word.low += *bufferptr;
1109         /* Make sure the hash doesn't start with 5, because it could clash
1110          * with a SAS address. Change 5 to a D.
1111          */
1112         if ((hash_address.word.high & 0x000000F0) == (0x00000050))
1113                 hash_address.word.high |= 0x00000080;
1114         *sas_address = (u64)hash_address.wwid[0] << 56 |
1115             (u64)hash_address.wwid[1] << 48 | (u64)hash_address.wwid[2] << 40 |
1116             (u64)hash_address.wwid[3] << 32 | (u64)hash_address.wwid[4] << 24 |
1117             (u64)hash_address.wwid[5] << 16 | (u64)hash_address.wwid[6] <<  8 |
1118             (u64)hash_address.wwid[7];
1119         if (ata_identify.rotational_speed == 1) {
1120                 *is_SATA_SSD = 1;
1121         }
1122
1123         return 0;
1124 }
1125
1126 static int
1127 mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle,
1128     Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz, u32 devinfo)
1129 {
1130         Mpi2SataPassthroughRequest_t *mpi_request;
1131         Mpi2SataPassthroughReply_t *reply = NULL; /* XXX swildner: warning fix */
1132         struct mpr_command *cm;
1133         char *buffer;
1134         int error = 0;
1135
1136         buffer = kmalloc( sz, M_MPR, M_NOWAIT | M_ZERO);
1137         if (!buffer)
1138                 return ENOMEM;
1139
1140         if ((cm = mpr_alloc_command(sc)) == NULL) {
1141                 kfree(buffer, M_MPR);
1142                 return (EBUSY);
1143         }
1144         mpi_request = (MPI2_SATA_PASSTHROUGH_REQUEST *)cm->cm_req;
1145         bzero(mpi_request,sizeof(MPI2_SATA_PASSTHROUGH_REQUEST));
1146         mpi_request->Function = MPI2_FUNCTION_SATA_PASSTHROUGH;
1147         mpi_request->VF_ID = 0;
1148         mpi_request->DevHandle = htole16(handle);
1149         mpi_request->PassthroughFlags = (MPI2_SATA_PT_REQ_PT_FLAGS_PIO |
1150             MPI2_SATA_PT_REQ_PT_FLAGS_READ);
1151         mpi_request->DataLength = htole32(sz);
1152         mpi_request->CommandFIS[0] = 0x27;
1153         mpi_request->CommandFIS[1] = 0x80;
1154         mpi_request->CommandFIS[2] =  (devinfo &
1155             MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE) ? 0xA1 : 0xEC;
1156         cm->cm_sge = &mpi_request->SGL;
1157         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1158         cm->cm_flags = MPR_CM_FLAGS_DATAIN;
1159         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1160         cm->cm_data = buffer;
1161         cm->cm_length = htole32(sz);
1162
1163         /*
1164          * Start a timeout counter specifically for the SATA ID command. This
1165          * is used to fix a problem where the FW does not send a reply sometimes
1166          * when a bad disk is in the topology. So, this is used to timeout the
1167          * command so that processing can continue normally.
1168          */
1169         mpr_dprint(sc, MPR_XINFO, "%s start timeout counter for SATA ID "
1170             "command\n", __func__);
1171         callout_reset(&cm->cm_callout, MPR_ATA_ID_TIMEOUT * hz,
1172             mprsas_ata_id_timeout, cm);
1173         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1174         mpr_dprint(sc, MPR_XINFO, "%s stop timeout counter for SATA ID "
1175             "command\n", __func__);
1176         /* XXX KDM need to fix the case where this command is destroyed */
1177         callout_stop(&cm->cm_callout);
1178
1179         if (cm != NULL)
1180                 reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply;
1181         if (error || (reply == NULL)) {
1182                 /* FIXME */
1183                 /*
1184                  * If the request returns an error then we need to do a diag
1185                  * reset
1186                  */
1187                 mpr_dprint(sc, MPR_INFO|MPR_FAULT|MPR_MAPPING,
1188                     "Request for SATA PASSTHROUGH page completed with error %d",
1189                     error);
1190                 error = ENXIO;
1191                 goto out;
1192         }
1193         bcopy(buffer, id_buffer, sz);
1194         bcopy(reply, mpi_reply, sizeof(Mpi2SataPassthroughReply_t));
1195         if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) !=
1196             MPI2_IOCSTATUS_SUCCESS) {
1197                 mpr_dprint(sc, MPR_INFO|MPR_MAPPING|MPR_FAULT,
1198                     "Error reading device %#x SATA PASSTHRU; iocstatus= 0x%x\n",
1199                     handle, reply->IOCStatus);
1200                 error = ENXIO;
1201                 goto out;
1202         }
1203 out:
1204         /*
1205          * If the SATA_ID_TIMEOUT flag has been set for this command, don't free
1206          * it.  The command will be freed after sending a target reset TM. If
1207          * the command did timeout, use EWOULDBLOCK.
1208          */
1209         if ((cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
1210                 mpr_free_command(sc, cm);
1211         else if (error == 0)
1212                 error = EWOULDBLOCK;
1213         cm->cm_data = NULL;
1214         kfree(buffer, M_MPR);
1215         return (error);
1216 }
1217
1218 static void
1219 mprsas_ata_id_timeout(void *data)
1220 {
1221         struct mpr_softc *sc;
1222         struct mpr_command *cm;
1223
1224         cm = (struct mpr_command *)data;
1225         sc = cm->cm_sc;
1226         KKASSERT(lockowned(&sc->mpr_lock));
1227
1228         mpr_dprint(sc, MPR_INFO, "%s checking ATA ID command %p sc %p\n",
1229             __func__, cm, sc);
1230         if ((callout_pending(&cm->cm_callout)) ||
1231             (!callout_active(&cm->cm_callout))) {
1232                 mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed out\n",
1233                     __func__);
1234                 return;
1235         }
1236         callout_deactivate(&cm->cm_callout);
1237
1238         /*
1239          * Run the interrupt handler to make sure it's not pending.  This
1240          * isn't perfect because the command could have already completed
1241          * and been re-used, though this is unlikely.
1242          */
1243         mpr_intr_locked(sc);
1244         if (cm->cm_state == MPR_CM_STATE_FREE) {
1245                 mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed out\n",
1246                     __func__);
1247                 return;
1248         }
1249
1250         mpr_dprint(sc, MPR_INFO, "ATA ID command timeout cm %p\n", cm);
1251
1252         /*
1253          * Send wakeup() to the sleeping thread that issued this ATA ID command.
1254          * wakeup() will cause msleep to return a 0 (not EWOULDBLOCK), and this
1255          * will keep reinit() from being called. This way, an Abort Task TM can
1256          * be issued so that the timed out command can be cleared. The Abort
1257          * Task cannot be sent from here because the driver has not completed
1258          * setting up targets.  Instead, the command is flagged so that special
1259          * handling will be used to send the abort.
1260          */
1261         cm->cm_flags |= MPR_CM_FLAGS_SATA_ID_TIMEOUT;
1262         wakeup(cm);
1263 }
1264
1265 static int
1266 mprsas_add_pcie_device(struct mpr_softc *sc, u16 handle, u8 linkrate)
1267 {
1268         char devstring[80];
1269         struct mprsas_softc *sassc;
1270         struct mprsas_target *targ;
1271         Mpi2ConfigReply_t mpi_reply;
1272         Mpi26PCIeDevicePage0_t config_page;
1273         Mpi26PCIeDevicePage2_t config_page2;
1274         uint64_t pcie_wwid, parent_wwid = 0;
1275         u32 device_info, parent_devinfo = 0;
1276         unsigned int id;
1277         int error = 0;
1278         struct mprsas_lun *lun;
1279
1280         sassc = sc->sassc;
1281         mprsas_startup_increment(sassc);
1282         if ((mpr_config_get_pcie_device_pg0(sc, &mpi_reply, &config_page,
1283              MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle))) {
1284                 kprintf("%s: error reading PCIe device page0\n", __func__);
1285                 error = ENXIO;
1286                 goto out;
1287         }
1288
1289         device_info = le32toh(config_page.DeviceInfo);
1290
1291         if (((device_info & MPI26_PCIE_DEVINFO_PCI_SWITCH) == 0)
1292             && (le16toh(config_page.ParentDevHandle) != 0)) {
1293                 Mpi2ConfigReply_t tmp_mpi_reply;
1294                 Mpi26PCIeDevicePage0_t parent_config_page;
1295
1296                 if ((mpr_config_get_pcie_device_pg0(sc, &tmp_mpi_reply,
1297                      &parent_config_page, MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE,
1298                      le16toh(config_page.ParentDevHandle)))) {
1299                         kprintf("%s: error reading PCIe device %#x page0\n",
1300                             __func__, le16toh(config_page.ParentDevHandle));
1301                 } else {
1302                         parent_wwid = parent_config_page.WWID.High;
1303                         parent_wwid = (parent_wwid << 32) |
1304                             parent_config_page.WWID.Low;
1305                         parent_devinfo = le32toh(parent_config_page.DeviceInfo);
1306                 }
1307         }
1308         /* TODO Check proper endianness */
1309         pcie_wwid = config_page.WWID.High;
1310         pcie_wwid = (pcie_wwid << 32) | config_page.WWID.Low;
1311         mpr_dprint(sc, MPR_INFO, "PCIe WWID from PCIe device page0 = %jx\n",
1312             pcie_wwid);
1313
1314         if ((mpr_config_get_pcie_device_pg2(sc, &mpi_reply, &config_page2,
1315              MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle))) {
1316                 kprintf("%s: error reading PCIe device page2\n", __func__);
1317                 error = ENXIO;
1318                 goto out;
1319         }
1320
1321         id = mpr_mapping_get_tid(sc, pcie_wwid, handle);
1322         if (id == MPR_MAP_BAD_ID) {
1323                 mpr_dprint(sc, MPR_ERROR | MPR_INFO, "failure at %s:%d/%s()! "
1324                     "Could not get ID for device with handle 0x%04x\n",
1325                     __FILE__, __LINE__, __func__, handle);
1326                 error = ENXIO;
1327                 goto out;
1328         }
1329         mpr_dprint(sc, MPR_MAPPING, "%s: Target ID for added device is %d.\n",
1330             __func__, id);
1331
1332         if (mprsas_check_id(sassc, id) != 0) {
1333                 mpr_dprint(sc, MPR_MAPPING|MPR_INFO,
1334                     "Excluding target id %d\n", id);
1335                 error = ENXIO;
1336                 goto out;
1337         }
1338
1339         mpr_dprint(sc, MPR_MAPPING, "WWID from PCIe device page0 = %jx\n",
1340             pcie_wwid);
1341         targ = &sassc->targets[id];
1342         targ->devinfo = device_info;
1343         targ->encl_handle = le16toh(config_page.EnclosureHandle);
1344         targ->encl_slot = le16toh(config_page.Slot);
1345         targ->encl_level = config_page.EnclosureLevel;
1346         targ->connector_name[0] = ((char *)&config_page.ConnectorName)[0];
1347         targ->connector_name[1] = ((char *)&config_page.ConnectorName)[1];
1348         targ->connector_name[2] = ((char *)&config_page.ConnectorName)[2];
1349         targ->connector_name[3] = ((char *)&config_page.ConnectorName)[3];
1350         targ->is_nvme = device_info & MPI26_PCIE_DEVINFO_NVME;
1351         targ->MDTS = config_page2.MaximumDataTransferSize;
1352         /*
1353          * Assume always TRUE for encl_level_valid because there is no valid
1354          * flag for PCIe.
1355          */
1356         targ->encl_level_valid = TRUE;
1357         targ->handle = handle;
1358         targ->parent_handle = le16toh(config_page.ParentDevHandle);
1359         targ->sasaddr = mpr_to_u64(&config_page.WWID);
1360         targ->parent_sasaddr = le64toh(parent_wwid);
1361         targ->parent_devinfo = parent_devinfo;
1362         targ->tid = id;
1363         targ->linkrate = linkrate;
1364         targ->flags = 0;
1365         if ((le16toh(config_page.Flags) &
1366             MPI26_PCIEDEV0_FLAGS_ENABLED_FAST_PATH) && 
1367             (le16toh(config_page.Flags) &
1368             MPI26_PCIEDEV0_FLAGS_FAST_PATH_CAPABLE)) {
1369                 targ->scsi_req_desc_type =
1370                     MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
1371         }
1372         TAILQ_INIT(&targ->commands);
1373         TAILQ_INIT(&targ->timedout_commands);
1374         while (!SLIST_EMPTY(&targ->luns)) {
1375                 lun = SLIST_FIRST(&targ->luns);
1376                 SLIST_REMOVE_HEAD(&targ->luns, lun_link);
1377                 kfree(lun, M_MPR);
1378         }
1379         SLIST_INIT(&targ->luns);
1380
1381         mpr_describe_devinfo(targ->devinfo, devstring, 80);
1382         mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "Found PCIe device <%s> <%s> "
1383             "handle<0x%04x> enclosureHandle<0x%04x> slot %d\n", devstring,
1384             mpr_describe_table(mpr_pcie_linkrate_names, targ->linkrate),
1385             targ->handle, targ->encl_handle, targ->encl_slot);
1386         if (targ->encl_level_valid) {
1387                 mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "At enclosure level %d "
1388                     "and connector name (%4s)\n", targ->encl_level,
1389                     targ->connector_name);
1390         }
1391 #if 1 /* ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000039)) || \
1392     (__FreeBSD_version < 902502) */
1393         if ((sassc->flags & MPRSAS_IN_STARTUP) == 0)
1394 #endif
1395                 mprsas_rescan_target(sc, targ);
1396         mpr_dprint(sc, MPR_MAPPING, "Target id 0x%x added\n", targ->tid);
1397
1398 out:
1399         mprsas_startup_decrement(sassc);
1400         return (error);
1401 }
1402
1403 static int
1404 mprsas_volume_add(struct mpr_softc *sc, u16 handle)
1405 {
1406         struct mprsas_softc *sassc;
1407         struct mprsas_target *targ;
1408         u64 wwid;
1409         unsigned int id;
1410         int error = 0;
1411         struct mprsas_lun *lun;
1412
1413         sassc = sc->sassc;
1414         mprsas_startup_increment(sassc);
1415         /* wwid is endian safe */
1416         mpr_config_get_volume_wwid(sc, handle, &wwid);
1417         if (!wwid) {
1418                 kprintf("%s: invalid WWID; cannot add volume to mapping table\n",
1419                     __func__);
1420                 error = ENXIO;
1421                 goto out;
1422         }
1423
1424         id = mpr_mapping_get_raid_tid(sc, wwid, handle);
1425         if (id == MPR_MAP_BAD_ID) {
1426                 kprintf("%s: could not get ID for volume with handle 0x%04x and "
1427                     "WWID 0x%016llx\n", __func__, handle,
1428                     (unsigned long long)wwid);
1429                 error = ENXIO;
1430                 goto out;
1431         }
1432
1433         targ = &sassc->targets[id];
1434         targ->tid = id;
1435         targ->handle = handle;
1436         targ->devname = wwid;
1437         TAILQ_INIT(&targ->commands);
1438         TAILQ_INIT(&targ->timedout_commands);
1439         while (!SLIST_EMPTY(&targ->luns)) {
1440                 lun = SLIST_FIRST(&targ->luns);
1441                 SLIST_REMOVE_HEAD(&targ->luns, lun_link);
1442                 kfree(lun, M_MPR);
1443         }
1444         SLIST_INIT(&targ->luns);
1445 #if 1 /* ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000039)) || \
1446     (__FreeBSD_version < 902502) */
1447         if ((sassc->flags & MPRSAS_IN_STARTUP) == 0)
1448 #endif
1449                 mprsas_rescan_target(sc, targ);
1450         mpr_dprint(sc, MPR_MAPPING, "RAID target id %d added (WWID = 0x%jx)\n",
1451             targ->tid, wwid);
1452 out:
1453         mprsas_startup_decrement(sassc);
1454         return (error);
1455 }
1456
1457 /**
1458  * mprsas_SSU_to_SATA_devices 
1459  * @sc: per adapter object
1460  *
1461  * Looks through the target list and issues a StartStopUnit SCSI command to each
1462  * SATA direct-access device.  This helps to ensure that data corruption is
1463  * avoided when the system is being shut down.  This must be called after the IR
1464  * System Shutdown RAID Action is sent if in IR mode.
1465  *
1466  * Return nothing.
1467  */
1468 static void
1469 mprsas_SSU_to_SATA_devices(struct mpr_softc *sc)
1470 {
1471         struct mprsas_softc *sassc = sc->sassc;
1472         union ccb *ccb;
1473         path_id_t pathid = cam_sim_path(sassc->sim);
1474         target_id_t targetid;
1475         struct mprsas_target *target;
1476         char path_str[64];
1477         struct timeval cur_time, start_time;
1478
1479         mpr_lock(sc);
1480
1481         /*
1482          * For each target, issue a StartStopUnit command to stop the device.
1483          */
1484         sc->SSU_started = TRUE;
1485         sc->SSU_refcount = 0;
1486         for (targetid = 0; targetid < sc->max_devices; targetid++) {
1487                 target = &sassc->targets[targetid];
1488                 if (target->handle == 0x0) {
1489                         continue;
1490                 }
1491
1492                 /*
1493                  * The stop_at_shutdown flag will be set if this device is
1494                  * a SATA direct-access end device.
1495                  */
1496                 if (target->stop_at_shutdown) {
1497                         ccb = xpt_alloc_ccb();
1498                         if (ccb == NULL) {
1499                                 mpr_dprint(sc, MPR_FAULT, "Unable to alloc CCB "
1500                                     "to stop unit.\n");
1501                                 return;
1502                         }
1503
1504                         if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
1505                             pathid, targetid, CAM_LUN_WILDCARD) !=
1506                             CAM_REQ_CMP) {
1507                                 mpr_dprint(sc, MPR_ERROR, "Unable to create "
1508                                     "path to stop unit.\n");
1509                                 xpt_free_ccb(&ccb->ccb_h);
1510                                 return;
1511                         }
1512                         xpt_path_string(ccb->ccb_h.path, path_str,
1513                             sizeof(path_str));
1514
1515                         mpr_dprint(sc, MPR_INFO, "Sending StopUnit: path %s "
1516                             "handle %d\n", path_str, target->handle);
1517
1518                         /*
1519                          * Issue a START STOP UNIT command for the target.
1520                          * Increment the SSU counter to be used to count the
1521                          * number of required replies.
1522                          */
1523                         mpr_dprint(sc, MPR_INFO, "Incrementing SSU count\n");
1524                         sc->SSU_refcount++;
1525                         ccb->ccb_h.target_id =
1526                             xpt_path_target_id(ccb->ccb_h.path);
1527                         ccb->ccb_h.ppriv_ptr1 = sassc;
1528                         scsi_start_stop(&ccb->csio,
1529                             /*retries*/0,
1530                             mprsas_stop_unit_done,
1531                             MSG_SIMPLE_Q_TAG,
1532                             /*start*/FALSE,
1533                             /*load/eject*/0,
1534                             /*immediate*/FALSE,
1535                             MPR_SENSE_LEN,
1536                             /*timeout*/10000);
1537                         xpt_action(ccb);
1538                 }
1539         }
1540
1541         mpr_unlock(sc);
1542
1543         /*
1544          * Wait until all of the SSU commands have completed or time has
1545          * expired (60 seconds).  Pause for 100ms each time through.  If any
1546          * command times out, the target will be reset in the SCSI command
1547          * timeout routine.
1548          */
1549         getmicrotime(&start_time);
1550         while (sc->SSU_refcount) {
1551                 tsleep(mprsas_SSU_to_SATA_devices, 0, "mprwait", hz/10);
1552                 
1553                 getmicrotime(&cur_time);
1554                 if ((cur_time.tv_sec - start_time.tv_sec) > 60) {
1555                         mpr_dprint(sc, MPR_ERROR, "Time has expired waiting "
1556                             "for SSU commands to complete.\n");
1557                         break;
1558                 }
1559         }
1560 }
1561
1562 static void
1563 mprsas_stop_unit_done(struct cam_periph *periph, union ccb *done_ccb)
1564 {
1565         struct mprsas_softc *sassc;
1566         char path_str[64];
1567
1568         if (done_ccb == NULL)
1569                 return;
1570
1571         sassc = (struct mprsas_softc *)done_ccb->ccb_h.ppriv_ptr1;
1572
1573         xpt_path_string(done_ccb->ccb_h.path, path_str, sizeof(path_str));
1574         mpr_dprint(sassc->sc, MPR_INFO, "Completing stop unit for %s\n",
1575             path_str);
1576
1577         /*
1578          * Nothing more to do except free the CCB and path.  If the command
1579          * timed out, an abort reset, then target reset will be issued during
1580          * the SCSI Command process.
1581          */
1582         xpt_free_path(done_ccb->ccb_h.path);
1583         xpt_free_ccb(&done_ccb->ccb_h);
1584 }
1585
1586 /**
1587  * mprsas_ir_shutdown - IR shutdown notification
1588  * @sc: per adapter object
1589  *
1590  * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that
1591  * the host system is shutting down.
1592  *
1593  * Return nothing.
1594  */
1595 void
1596 mprsas_ir_shutdown(struct mpr_softc *sc)
1597 {
1598         u16 volume_mapping_flags;
1599         u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
1600         struct dev_mapping_table *mt_entry;
1601         u32 start_idx, end_idx;
1602         unsigned int id, found_volume = 0;
1603         struct mpr_command *cm;
1604         Mpi2RaidActionRequest_t *action;
1605         target_id_t targetid;
1606         struct mprsas_target *target;
1607
1608         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1609
1610         /* is IR firmware build loaded? */
1611         if (!sc->ir_firmware)
1612                 goto out;
1613
1614         /* are there any volumes?  Look at IR target IDs. */
1615         // TODO-later, this should be looked up in the RAID config structure
1616         // when it is implemented.
1617         volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) &
1618             MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
1619         if (volume_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) {
1620                 start_idx = 0;
1621                 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0)
1622                         start_idx = 1;
1623         } else
1624                 start_idx = sc->max_devices - sc->max_volumes;
1625         end_idx = start_idx + sc->max_volumes - 1;
1626
1627         for (id = start_idx; id < end_idx; id++) {
1628                 mt_entry = &sc->mapping_table[id];
1629                 if ((mt_entry->physical_id != 0) &&
1630                     (mt_entry->missing_count == 0)) {
1631                         found_volume = 1;
1632                         break;
1633                 }
1634         }
1635
1636         if (!found_volume)
1637                 goto out;
1638
1639         if ((cm = mpr_alloc_command(sc)) == NULL) {
1640                 kprintf("%s: command alloc failed\n", __func__);
1641                 goto out;
1642         }
1643
1644         action = (MPI2_RAID_ACTION_REQUEST *)cm->cm_req;
1645         action->Function = MPI2_FUNCTION_RAID_ACTION;
1646         action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
1647         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1648         mpr_lock(sc);
1649         mpr_wait_command(sc, &cm, 5, CAN_SLEEP);
1650         mpr_unlock(sc);
1651
1652         /*
1653          * Don't check for reply, just leave.
1654          */
1655         if (cm)
1656                 mpr_free_command(sc, cm);
1657
1658 out:
1659         /*
1660          * All of the targets must have the correct value set for
1661          * 'stop_at_shutdown' for the current 'enable_ssu' sysctl variable.
1662          *
1663          * The possible values for the 'enable_ssu' variable are:
1664          * 0: disable to SSD and HDD
1665          * 1: disable only to HDD (default)
1666          * 2: disable only to SSD
1667          * 3: enable to SSD and HDD
1668          * anything else will default to 1.
1669          */
1670         for (targetid = 0; targetid < sc->max_devices; targetid++) {
1671                 target = &sc->sassc->targets[targetid];
1672                 if (target->handle == 0x0) {
1673                         continue;
1674                 }
1675
1676                 if (target->supports_SSU) {
1677                         switch (sc->enable_ssu) {
1678                         case MPR_SSU_DISABLE_SSD_DISABLE_HDD:
1679                                 target->stop_at_shutdown = FALSE;
1680                                 break;
1681                         case MPR_SSU_DISABLE_SSD_ENABLE_HDD:
1682                                 target->stop_at_shutdown = TRUE;
1683                                 if (target->flags & MPR_TARGET_IS_SATA_SSD) {
1684                                         target->stop_at_shutdown = FALSE;
1685                                 }
1686                                 break;
1687                         case MPR_SSU_ENABLE_SSD_ENABLE_HDD:
1688                                 target->stop_at_shutdown = TRUE;
1689                                 break;
1690                         case MPR_SSU_ENABLE_SSD_DISABLE_HDD:
1691                         default:
1692                                 target->stop_at_shutdown = TRUE;
1693                                 if ((target->flags &
1694                                     MPR_TARGET_IS_SATA_SSD) == 0) {
1695                                         target->stop_at_shutdown = FALSE;
1696                                 }
1697                                 break;
1698                         }
1699                 }
1700         }
1701         mprsas_SSU_to_SATA_devices(sc);
1702 }