xref: /dragonfly/sys/dev/raid/mpr/mpr_sas_lsi.c (revision cec957e929d4fbddf545b1918d45b9eadc8268ce)
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
mprsas_evt_handler(struct mpr_softc * sc,uintptr_t data,MPI2_EVENT_NOTIFICATION_REPLY * event)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
mprsas_fw_event_free(struct mpr_softc * sc,struct mpr_fw_event_work * fw_event)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
mprsas_fw_work(struct mpr_softc * sc,struct mpr_fw_event_work * fw_event)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
mprsas_firmware_event_work(void * arg,int pending)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
mprsas_add_device(struct mpr_softc * sc,u16 handle,u8 linkrate)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
mprsas_get_sas_address_for_sata_disk(struct mpr_softc * sc,u64 * sas_address,u16 handle,u32 device_info,u8 * is_SATA_SSD)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
mprsas_get_sata_identify(struct mpr_softc * sc,u16 handle,Mpi2SataPassthroughReply_t * mpi_reply,char * id_buffer,int sz,u32 devinfo)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
mprsas_ata_id_timeout(void * data)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
mprsas_add_pcie_device(struct mpr_softc * sc,u16 handle,u8 linkrate)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
mprsas_volume_add(struct mpr_softc * sc,u16 handle)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
mprsas_SSU_to_SATA_devices(struct mpr_softc * sc)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
mprsas_stop_unit_done(struct cam_periph * periph,union ccb * done_ccb)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
mprsas_ir_shutdown(struct mpr_softc * sc)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 }
1703