2 * Routines for handling the integrated RAID features LSI MPT Fusion adapters.
4 * Copyright (c) 2005, WHEEL Sp. z o.o.
5 * Copyright (c) 2005 Justin T. Gibbs.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon including
16 * a substantially similar Disclaimer requirement for further binary
18 * 3. Neither the names of the above listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
32 * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 * Some Breakage and Bug Fixing added later.
36 * Copyright (c) 2006, by Matthew Jacob
39 * Support from LSI-Logic has also gone a great deal toward making this a
40 * workable subsystem and is gratefully acknowledged.
42 * $FreeBSD: src/sys/dev/mpt/mpt_raid.c,v 1.20 2009/05/21 12:36:40 jhb Exp $
45 #include <dev/disk/mpt/mpt.h>
46 #include <dev/disk/mpt/mpt_raid.h>
48 #include "dev/disk/mpt/mpilib/mpi_ioc.h" /* XXX Fix Event Handling!!! */
49 #include "dev/disk/mpt/mpilib/mpi_raid.h"
51 #include <bus/cam/cam.h>
52 #include <bus/cam/cam_ccb.h>
53 #include <bus/cam/cam_sim.h>
54 #include <bus/cam/cam_xpt_periph.h>
55 #include <bus/cam/cam_xpt_sim.h>
57 #if __FreeBSD_version < 500000
58 #include <sys/devicestat.h>
59 #define GIANT_REQUIRED
61 #include <bus/cam/cam_periph.h>
63 #include <sys/callout.h>
64 #include <sys/kthread.h>
65 #include <sys/sysctl.h>
67 #include <machine/stdarg.h>
69 struct mpt_raid_action_result
72 MPI_RAID_VOL_INDICATOR indicator_struct;
73 uint32_t new_settings;
74 uint8_t phys_disk_num;
76 uint16_t action_status;
79 #define REQ_TO_RAID_ACTION_RESULT(req) ((struct mpt_raid_action_result *) \
80 (((MSG_RAID_ACTION_REQUEST *)(req->req_vbuf)) + 1))
82 #define REQ_IOCSTATUS(req) ((req)->IOCStatus & MPI_IOCSTATUS_MASK)
85 static mpt_probe_handler_t mpt_raid_probe;
86 static mpt_attach_handler_t mpt_raid_attach;
87 static mpt_enable_handler_t mpt_raid_enable;
88 static mpt_event_handler_t mpt_raid_event;
89 static mpt_shutdown_handler_t mpt_raid_shutdown;
90 static mpt_reset_handler_t mpt_raid_ioc_reset;
91 static mpt_detach_handler_t mpt_raid_detach;
93 static struct mpt_personality mpt_raid_personality =
96 .probe = mpt_raid_probe,
97 .attach = mpt_raid_attach,
98 .enable = mpt_raid_enable,
99 .event = mpt_raid_event,
100 .reset = mpt_raid_ioc_reset,
101 .shutdown = mpt_raid_shutdown,
102 .detach = mpt_raid_detach,
105 DECLARE_MPT_PERSONALITY(mpt_raid, SI_ORDER_THIRD);
106 MPT_PERSONALITY_DEPEND(mpt_raid, mpt_cam, 1, 1, 1);
108 static mpt_reply_handler_t mpt_raid_reply_handler;
109 static int mpt_raid_reply_frame_handler(struct mpt_softc *mpt, request_t *req,
110 MSG_DEFAULT_REPLY *reply_frame);
111 static int mpt_spawn_raid_thread(struct mpt_softc *mpt);
112 static void mpt_terminate_raid_thread(struct mpt_softc *mpt);
113 static void mpt_raid_thread(void *arg);
114 static timeout_t mpt_raid_timer;
116 static void mpt_enable_vol(struct mpt_softc *mpt,
117 struct mpt_raid_volume *mpt_vol, int enable);
119 static void mpt_verify_mwce(struct mpt_softc *, struct mpt_raid_volume *);
120 static void mpt_adjust_queue_depth(struct mpt_softc *, struct mpt_raid_volume *,
122 #if __FreeBSD_version < 500000
123 #define mpt_raid_sysctl_attach(x) do { } while (0)
125 static void mpt_raid_sysctl_attach(struct mpt_softc *);
128 static uint32_t raid_handler_id = MPT_HANDLER_ID_NONE;
131 mpt_vol_type(struct mpt_raid_volume *vol)
133 switch (vol->config_page->VolumeType) {
134 case MPI_RAID_VOL_TYPE_IS:
136 case MPI_RAID_VOL_TYPE_IME:
138 case MPI_RAID_VOL_TYPE_IM:
146 mpt_vol_state(struct mpt_raid_volume *vol)
148 switch (vol->config_page->VolumeStatus.State) {
149 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
151 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
153 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
161 mpt_disk_state(struct mpt_raid_disk *disk)
163 switch (disk->config_page.PhysDiskStatus.State) {
164 case MPI_PHYSDISK0_STATUS_ONLINE:
166 case MPI_PHYSDISK0_STATUS_MISSING:
168 case MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE:
169 return ("Incompatible");
170 case MPI_PHYSDISK0_STATUS_FAILED:
172 case MPI_PHYSDISK0_STATUS_INITIALIZING:
173 return ("Initializing");
174 case MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED:
175 return ("Offline Requested");
176 case MPI_PHYSDISK0_STATUS_FAILED_REQUESTED:
177 return ("Failed per Host Request");
178 case MPI_PHYSDISK0_STATUS_OTHER_OFFLINE:
186 mpt_vol_prt(struct mpt_softc *mpt, struct mpt_raid_volume *vol,
187 const char *fmt, ...)
191 kprintf("%s:vol%d(%s:%d:%d): ", device_get_nameunit(mpt->dev),
192 (u_int)(vol - mpt->raid_volumes), device_get_nameunit(mpt->dev),
193 vol->config_page->VolumeBus, vol->config_page->VolumeID);
200 mpt_disk_prt(struct mpt_softc *mpt, struct mpt_raid_disk *disk,
201 const char *fmt, ...)
205 if (disk->volume != NULL) {
206 kprintf("(%s:vol%d:%d): ",
207 device_get_nameunit(mpt->dev),
208 disk->volume->config_page->VolumeID,
209 disk->member_number);
211 kprintf("(%s:%d:%d): ", device_get_nameunit(mpt->dev),
212 disk->config_page.PhysDiskBus,
213 disk->config_page.PhysDiskID);
221 mpt_raid_async(void *callback_arg, u_int32_t code,
222 struct cam_path *path, void *arg)
224 struct mpt_softc *mpt;
226 mpt = (struct mpt_softc*)callback_arg;
228 case AC_FOUND_DEVICE:
230 struct ccb_getdev *cgd;
231 struct mpt_raid_volume *mpt_vol;
233 cgd = (struct ccb_getdev *)arg;
238 mpt_lprt(mpt, MPT_PRT_DEBUG, "Callback for %d\n",
239 cgd->ccb_h.target_id);
241 RAID_VOL_FOREACH(mpt, mpt_vol) {
242 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
245 if (mpt_vol->config_page->VolumeID
246 == cgd->ccb_h.target_id) {
247 mpt_adjust_queue_depth(mpt, mpt_vol, path);
258 mpt_raid_probe(struct mpt_softc *mpt)
260 if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) {
267 mpt_raid_attach(struct mpt_softc *mpt)
269 struct ccb_setasync csa;
270 mpt_handler_t handler;
273 mpt_callout_init(&mpt->raid_timer);
275 error = mpt_spawn_raid_thread(mpt);
277 mpt_prt(mpt, "Unable to spawn RAID thread!\n");
282 handler.reply_handler = mpt_raid_reply_handler;
283 error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
286 mpt_prt(mpt, "Unable to register RAID haandler!\n");
290 xpt_setup_ccb(&csa.ccb_h, mpt->path, 5);
291 csa.ccb_h.func_code = XPT_SASYNC_CB;
292 csa.event_enable = AC_FOUND_DEVICE;
293 csa.callback = mpt_raid_async;
294 csa.callback_arg = mpt;
295 xpt_action((union ccb *)&csa);
296 if (csa.ccb_h.status != CAM_REQ_CMP) {
297 mpt_prt(mpt, "mpt_raid_attach: Unable to register "
298 "CAM async handler.\n");
302 mpt_raid_sysctl_attach(mpt);
306 mpt_raid_detach(mpt);
311 mpt_raid_enable(struct mpt_softc *mpt)
317 mpt_raid_detach(struct mpt_softc *mpt)
319 struct ccb_setasync csa;
320 mpt_handler_t handler;
322 callout_stop(&mpt->raid_timer);
324 mpt_terminate_raid_thread(mpt);
326 handler.reply_handler = mpt_raid_reply_handler;
327 mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
329 xpt_setup_ccb(&csa.ccb_h, mpt->path, /*priority*/5);
330 csa.ccb_h.func_code = XPT_SASYNC_CB;
331 csa.event_enable = 0;
332 csa.callback = mpt_raid_async;
333 csa.callback_arg = mpt;
334 xpt_action((union ccb *)&csa);
339 mpt_raid_ioc_reset(struct mpt_softc *mpt, int type)
341 /* Nothing to do yet. */
344 static const char *raid_event_txt[] =
348 "Volume Settings Changed",
349 "Volume Status Changed",
350 "Volume Physical Disk Membership Changed",
351 "Physical Disk Created",
352 "Physical Disk Deleted",
353 "Physical Disk Settings Changed",
354 "Physical Disk Status Changed",
355 "Domain Validation Required",
356 "SMART Data Received",
357 "Replace Action Started",
361 mpt_raid_event(struct mpt_softc *mpt, request_t *req,
362 MSG_EVENT_NOTIFY_REPLY *msg)
364 EVENT_DATA_RAID *raid_event;
365 struct mpt_raid_volume *mpt_vol;
366 struct mpt_raid_disk *mpt_disk;
367 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
371 if (msg->Event != MPI_EVENT_INTEGRATED_RAID) {
375 raid_event = (EVENT_DATA_RAID *)&msg->Data;
379 if (mpt->raid_volumes != NULL && mpt->ioc_page2 != NULL) {
380 for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
381 mpt_vol = &mpt->raid_volumes[i];
382 vol_pg = mpt_vol->config_page;
384 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
387 if (vol_pg->VolumeID == raid_event->VolumeID
388 && vol_pg->VolumeBus == raid_event->VolumeBus)
391 if (i >= mpt->ioc_page2->MaxVolumes) {
398 if (raid_event->PhysDiskNum != 0xFF && mpt->raid_disks != NULL) {
399 mpt_disk = mpt->raid_disks + raid_event->PhysDiskNum;
400 if ((mpt_disk->flags & MPT_RDF_ACTIVE) == 0) {
406 switch(raid_event->ReasonCode) {
407 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
408 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
410 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
411 if (mpt_vol != NULL) {
412 if ((mpt_vol->flags & MPT_RVF_UP2DATE) != 0) {
413 mpt_vol->flags &= ~MPT_RVF_UP2DATE;
416 * Coalesce status messages into one
417 * per background run of our RAID thread.
418 * This removes "spurious" status messages
425 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
426 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
428 if (mpt_vol != NULL) {
429 mpt_vol->flags &= ~(MPT_RVF_UP2DATE|MPT_RVF_ANNOUNCED);
432 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
433 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
436 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
437 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
439 if (mpt_disk != NULL) {
440 mpt_disk->flags &= ~MPT_RDF_UP2DATE;
443 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
446 case MPI_EVENT_RAID_RC_SMART_DATA:
447 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
452 if (mpt_disk != NULL) {
453 mpt_disk_prt(mpt, mpt_disk, "");
454 } else if (mpt_vol != NULL) {
455 mpt_vol_prt(mpt, mpt_vol, "");
457 mpt_prt(mpt, "Volume(%d:%d", raid_event->VolumeBus,
458 raid_event->VolumeID);
460 if (raid_event->PhysDiskNum != 0xFF)
461 mpt_prtc(mpt, ":%d): ",
462 raid_event->PhysDiskNum);
464 mpt_prtc(mpt, "): ");
467 if (raid_event->ReasonCode >= NUM_ELEMENTS(raid_event_txt))
468 mpt_prtc(mpt, "Unhandled RaidEvent %#x\n",
469 raid_event->ReasonCode);
471 mpt_prtc(mpt, "%s\n",
472 raid_event_txt[raid_event->ReasonCode]);
475 if (raid_event->ReasonCode == MPI_EVENT_RAID_RC_SMART_DATA) {
476 /* XXX Use CAM's print sense for this... */
477 if (mpt_disk != NULL)
478 mpt_disk_prt(mpt, mpt_disk, "");
480 mpt_prt(mpt, "Volume(%d:%d:%d: ",
481 raid_event->VolumeBus, raid_event->VolumeID,
482 raid_event->PhysDiskNum);
483 mpt_prtc(mpt, "ASC 0x%x, ASCQ 0x%x)\n",
484 raid_event->ASC, raid_event->ASCQ);
487 mpt_raid_wakeup(mpt);
492 mpt_raid_shutdown(struct mpt_softc *mpt)
494 struct mpt_raid_volume *mpt_vol;
496 if (mpt->raid_mwce_setting != MPT_RAID_MWCE_REBUILD_ONLY) {
500 mpt->raid_mwce_setting = MPT_RAID_MWCE_OFF;
501 RAID_VOL_FOREACH(mpt, mpt_vol) {
502 mpt_verify_mwce(mpt, mpt_vol);
507 mpt_raid_reply_handler(struct mpt_softc *mpt, request_t *req,
508 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
516 if (reply_frame != NULL)
517 free_req = mpt_raid_reply_frame_handler(mpt, req, reply_frame);
519 else if (req->ccb != NULL) {
520 /* Complete Quiesce CCB with error... */
524 req->state &= ~REQ_STATE_QUEUED;
525 req->state |= REQ_STATE_DONE;
526 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
528 if ((req->state & REQ_STATE_NEED_WAKEUP) != 0) {
530 } else if (free_req) {
531 mpt_free_request(mpt, req);
538 * Parse additional completion information in the reply
539 * frame for RAID I/O requests.
542 mpt_raid_reply_frame_handler(struct mpt_softc *mpt, request_t *req,
543 MSG_DEFAULT_REPLY *reply_frame)
545 MSG_RAID_ACTION_REPLY *reply;
546 struct mpt_raid_action_result *action_result;
547 MSG_RAID_ACTION_REQUEST *rap;
549 reply = (MSG_RAID_ACTION_REPLY *)reply_frame;
550 req->IOCStatus = le16toh(reply->IOCStatus);
551 rap = (MSG_RAID_ACTION_REQUEST *)req->req_vbuf;
553 switch (rap->Action) {
554 case MPI_RAID_ACTION_QUIESCE_PHYS_IO:
555 mpt_prt(mpt, "QUIESCE PHYSIO DONE\n");
557 case MPI_RAID_ACTION_ENABLE_PHYS_IO:
558 mpt_prt(mpt, "ENABLY PHYSIO DONE\n");
563 action_result = REQ_TO_RAID_ACTION_RESULT(req);
564 memcpy(&action_result->action_data, &reply->ActionData,
565 sizeof(action_result->action_data));
566 action_result->action_status = le16toh(reply->ActionStatus);
571 * Utiltity routine to perform a RAID action command;
574 mpt_issue_raid_req(struct mpt_softc *mpt, struct mpt_raid_volume *vol,
575 struct mpt_raid_disk *disk, request_t *req, u_int Action,
576 uint32_t ActionDataWord, bus_addr_t addr, bus_size_t len,
579 MSG_RAID_ACTION_REQUEST *rap;
583 memset(rap, 0, sizeof *rap);
584 rap->Action = Action;
585 rap->ActionDataWord = htole32(ActionDataWord);
586 rap->Function = MPI_FUNCTION_RAID_ACTION;
587 rap->VolumeID = vol->config_page->VolumeID;
588 rap->VolumeBus = vol->config_page->VolumeBus;
590 rap->PhysDiskNum = disk->config_page.PhysDiskNum;
592 rap->PhysDiskNum = 0xFF;
593 se = (SGE_SIMPLE32 *)&rap->ActionDataSGE;
594 se->Address = htole32(addr);
595 MPI_pSGE_SET_LENGTH(se, len);
596 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
597 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
598 MPI_SGE_FLAGS_END_OF_LIST |
599 write ? MPI_SGE_FLAGS_HOST_TO_IOC : MPI_SGE_FLAGS_IOC_TO_HOST));
600 se->FlagsLength = htole32(se->FlagsLength);
601 rap->MsgContext = htole32(req->index | raid_handler_id);
603 mpt_check_doorbell(mpt);
604 mpt_send_cmd(mpt, req);
607 return (mpt_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE,
608 /*sleep_ok*/FALSE, /*time_ms*/2000));
614 /*************************** RAID Status Monitoring ***************************/
616 mpt_spawn_raid_thread(struct mpt_softc *mpt)
621 * Freeze out any CAM transactions until our thread
622 * is able to run at least once. We need to update
623 * our RAID pages before acception I/O or we may
624 * reject I/O to an ID we later determine is for a
628 xpt_freeze_simq(mpt->phydisk_sim, 1);
630 error = mpt_kthread_create(mpt_raid_thread, mpt,
631 &mpt->raid_thread, /*flags*/0, /*altstack*/0,
632 "mpt_raid%d", mpt->unit);
635 xpt_release_simq(mpt->phydisk_sim, /*run_queue*/FALSE);
642 mpt_terminate_raid_thread(struct mpt_softc *mpt)
645 if (mpt->raid_thread == NULL) {
648 mpt->shutdwn_raid = 1;
649 wakeup(mpt->raid_volumes);
651 * Sleep on a slightly different location
652 * for this interlock just for added safety.
654 mpt_sleep(mpt, &mpt->raid_thread, PUSER, "thtrm", 0);
658 mpt_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
661 xpt_free_path(ccb->ccb_h.path);
666 mpt_raid_thread(void *arg)
668 struct mpt_softc *mpt;
671 mpt = (struct mpt_softc *)arg;
674 while (mpt->shutdwn_raid == 0) {
676 if (mpt->raid_wakeup == 0) {
677 mpt_sleep(mpt, &mpt->raid_volumes, PUSER, "idle", 0);
681 mpt->raid_wakeup = 0;
683 if (mpt_refresh_raid_data(mpt)) {
684 mpt_schedule_raid_refresh(mpt); /* XX NOT QUITE RIGHT */
689 * Now that we have our first snapshot of RAID data,
690 * allow CAM to access our physical disk bus.
694 MPTLOCK_2_CAMLOCK(mpt);
695 xpt_release_simq(mpt->phydisk_sim, TRUE);
696 CAMLOCK_2_MPTLOCK(mpt);
699 if (mpt->raid_rescan != 0) {
701 struct cam_path *path;
704 mpt->raid_rescan = 0;
707 ccb = xpt_alloc_ccb();
710 error = xpt_create_path(&path, xpt_periph,
711 cam_sim_path(mpt->phydisk_sim),
712 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
713 if (error != CAM_REQ_CMP) {
715 mpt_prt(mpt, "Unable to rescan RAID Bus!\n");
717 xpt_setup_ccb(&ccb->ccb_h, path, 5);
718 ccb->ccb_h.func_code = XPT_SCAN_BUS;
719 ccb->ccb_h.cbfcnp = mpt_cam_rescan_callback;
720 ccb->crcn.flags = CAM_FLAG_NONE;
721 MPTLOCK_2_CAMLOCK(mpt);
723 CAMLOCK_2_MPTLOCK(mpt);
727 mpt->raid_thread = NULL;
728 wakeup(&mpt->raid_thread);
735 mpt_raid_quiesce_timeout(void *arg)
737 /* Complete the CCB with error */
741 static timeout_t mpt_raid_quiesce_timeout;
743 mpt_raid_quiesce_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk,
749 if ((mpt_disk->flags & MPT_RDF_QUIESCED) != 0)
750 return (CAM_REQ_CMP);
752 if ((mpt_disk->flags & MPT_RDF_QUIESCING) == 0) {
755 mpt_disk->flags |= MPT_RDF_QUIESCING;
756 xpt_freeze_devq(ccb->ccb_h.path, 1);
758 rv = mpt_issue_raid_req(mpt, mpt_disk->volume, mpt_disk, req,
759 MPI_RAID_ACTION_QUIESCE_PHYS_IO,
760 /*ActionData*/0, /*addr*/0,
761 /*len*/0, /*write*/FALSE,
764 return (CAM_REQ_CMP_ERR);
766 mpt_req_timeout(req, mpt_raid_quiesce_timeout, ccb, 5 * hz);
768 if (rv == ETIMEDOUT) {
769 mpt_disk_prt(mpt, mpt_disk, "mpt_raid_quiesce_disk: "
770 "Quiece Timed-out\n");
771 xpt_release_devq(ccb->ccb_h.path, 1, /*run*/0);
772 return (CAM_REQ_CMP_ERR);
775 ar = REQ_TO_RAID_ACTION_RESULT(req);
777 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
778 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
779 mpt_disk_prt(mpt, mpt_disk, "Quiece Failed"
780 "%d:%x:%x\n", rv, req->IOCStatus,
782 xpt_release_devq(ccb->ccb_h.path, 1, /*run*/0);
783 return (CAM_REQ_CMP_ERR);
786 return (CAM_REQ_INPROG);
788 return (CAM_REQUEUE_REQ);
792 /* XXX Ignores that there may be multiple busses/IOCs involved. */
794 mpt_map_physdisk(struct mpt_softc *mpt, union ccb *ccb, u_int *tgt)
796 struct mpt_raid_disk *mpt_disk;
798 mpt_disk = mpt->raid_disks + ccb->ccb_h.target_id;
799 if (ccb->ccb_h.target_id < mpt->raid_max_disks
800 && (mpt_disk->flags & MPT_RDF_ACTIVE) != 0) {
801 *tgt = mpt_disk->config_page.PhysDiskID;
804 mpt_lprt(mpt, MPT_PRT_DEBUG1, "mpt_map_physdisk(%d) - Not Active\n",
805 ccb->ccb_h.target_id);
809 /* XXX Ignores that there may be multiple busses/IOCs involved. */
811 mpt_is_raid_volume(struct mpt_softc *mpt, int tgt)
813 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol;
814 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_last_vol;
816 if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) {
819 ioc_vol = mpt->ioc_page2->RaidVolume;
820 ioc_last_vol = ioc_vol + mpt->ioc_page2->NumActiveVolumes;
821 for (;ioc_vol != ioc_last_vol; ioc_vol++) {
822 if (ioc_vol->VolumeID == tgt) {
831 mpt_enable_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
835 struct mpt_raid_action_result *ar;
836 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
840 vol_pg = mpt_vol->config_page;
841 enabled = vol_pg->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED;
844 * If the setting matches the configuration,
845 * there is nothing to do.
847 if ((enabled && enable)
848 || (!enabled && !enable))
851 req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
853 mpt_vol_prt(mpt, mpt_vol,
854 "mpt_enable_vol: Get request failed!\n");
858 rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
859 enable ? MPI_RAID_ACTION_ENABLE_VOLUME
860 : MPI_RAID_ACTION_DISABLE_VOLUME,
861 /*data*/0, /*addr*/0, /*len*/0,
862 /*write*/FALSE, /*wait*/TRUE);
863 if (rv == ETIMEDOUT) {
864 mpt_vol_prt(mpt, mpt_vol, "mpt_enable_vol: "
865 "%s Volume Timed-out\n",
866 enable ? "Enable" : "Disable");
869 ar = REQ_TO_RAID_ACTION_RESULT(req);
871 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
872 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
873 mpt_vol_prt(mpt, mpt_vol, "%s Volume Failed: %d:%x:%x\n",
874 enable ? "Enable" : "Disable",
875 rv, req->IOCStatus, ar->action_status);
878 mpt_free_request(mpt, req);
883 mpt_verify_mwce(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
886 struct mpt_raid_action_result *ar;
887 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
893 vol_pg = mpt_vol->config_page;
894 resyncing = vol_pg->VolumeStatus.Flags
895 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS;
896 mwce = vol_pg->VolumeSettings.Settings
897 & MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
900 * If the setting matches the configuration,
901 * there is nothing to do.
903 switch (mpt->raid_mwce_setting) {
904 case MPT_RAID_MWCE_REBUILD_ONLY:
905 if ((resyncing && mwce) || (!resyncing && !mwce)) {
908 mpt_vol->flags ^= MPT_RVF_WCE_CHANGED;
909 if ((mpt_vol->flags & MPT_RVF_WCE_CHANGED) == 0) {
911 * Wait one more status update to see if
912 * resyncing gets enabled. It gets disabled
913 * temporarilly when WCE is changed.
918 case MPT_RAID_MWCE_ON:
922 case MPT_RAID_MWCE_OFF:
926 case MPT_RAID_MWCE_NC:
930 req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
932 mpt_vol_prt(mpt, mpt_vol,
933 "mpt_verify_mwce: Get request failed!\n");
937 vol_pg->VolumeSettings.Settings ^=
938 MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
939 memcpy(&data, &vol_pg->VolumeSettings, sizeof(data));
940 vol_pg->VolumeSettings.Settings ^=
941 MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
942 rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
943 MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS,
944 data, /*addr*/0, /*len*/0,
945 /*write*/FALSE, /*wait*/TRUE);
946 if (rv == ETIMEDOUT) {
947 mpt_vol_prt(mpt, mpt_vol, "mpt_verify_mwce: "
948 "Write Cache Enable Timed-out\n");
951 ar = REQ_TO_RAID_ACTION_RESULT(req);
953 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
954 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
955 mpt_vol_prt(mpt, mpt_vol, "Write Cache Enable Failed: "
956 "%d:%x:%x\n", rv, req->IOCStatus,
959 vol_pg->VolumeSettings.Settings ^=
960 MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
962 mpt_free_request(mpt, req);
966 mpt_verify_resync_rate(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
969 struct mpt_raid_action_result *ar;
970 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
974 vol_pg = mpt_vol->config_page;
976 if (mpt->raid_resync_rate == MPT_RAID_RESYNC_RATE_NC)
980 * If the current RAID resync rate does not
981 * match our configured rate, update it.
983 prio = vol_pg->VolumeSettings.Settings
984 & MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
985 if (vol_pg->ResyncRate != 0
986 && vol_pg->ResyncRate != mpt->raid_resync_rate) {
988 req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
990 mpt_vol_prt(mpt, mpt_vol, "mpt_verify_resync_rate: "
991 "Get request failed!\n");
995 rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
996 MPI_RAID_ACTION_SET_RESYNC_RATE,
997 mpt->raid_resync_rate, /*addr*/0,
998 /*len*/0, /*write*/FALSE, /*wait*/TRUE);
999 if (rv == ETIMEDOUT) {
1000 mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_data: "
1001 "Resync Rate Setting Timed-out\n");
1005 ar = REQ_TO_RAID_ACTION_RESULT(req);
1007 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
1008 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
1009 mpt_vol_prt(mpt, mpt_vol, "Resync Rate Setting Failed: "
1010 "%d:%x:%x\n", rv, req->IOCStatus,
1013 vol_pg->ResyncRate = mpt->raid_resync_rate;
1014 mpt_free_request(mpt, req);
1015 } else if ((prio && mpt->raid_resync_rate < 128)
1016 || (!prio && mpt->raid_resync_rate >= 128)) {
1019 req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
1021 mpt_vol_prt(mpt, mpt_vol, "mpt_verify_resync_rate: "
1022 "Get request failed!\n");
1026 vol_pg->VolumeSettings.Settings ^=
1027 MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
1028 memcpy(&data, &vol_pg->VolumeSettings, sizeof(data));
1029 vol_pg->VolumeSettings.Settings ^=
1030 MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
1031 rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
1032 MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS,
1033 data, /*addr*/0, /*len*/0,
1034 /*write*/FALSE, /*wait*/TRUE);
1035 if (rv == ETIMEDOUT) {
1036 mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_data: "
1037 "Resync Rate Setting Timed-out\n");
1040 ar = REQ_TO_RAID_ACTION_RESULT(req);
1042 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
1043 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
1044 mpt_vol_prt(mpt, mpt_vol, "Resync Rate Setting Failed: "
1045 "%d:%x:%x\n", rv, req->IOCStatus,
1048 vol_pg->VolumeSettings.Settings ^=
1049 MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
1052 mpt_free_request(mpt, req);
1057 mpt_adjust_queue_depth(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
1058 struct cam_path *path)
1060 struct ccb_relsim crs;
1062 xpt_setup_ccb(&crs.ccb_h, path, /*priority*/5);
1063 crs.ccb_h.func_code = XPT_REL_SIMQ;
1064 crs.release_flags = RELSIM_ADJUST_OPENINGS;
1065 crs.openings = mpt->raid_queue_depth;
1066 xpt_action((union ccb *)&crs);
1067 if (crs.ccb_h.status != CAM_REQ_CMP)
1068 mpt_vol_prt(mpt, mpt_vol, "mpt_adjust_queue_depth failed "
1069 "with CAM status %#x\n", crs.ccb_h.status);
1073 mpt_announce_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
1075 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
1078 vol_pg = mpt_vol->config_page;
1079 mpt_vol_prt(mpt, mpt_vol, "Settings (");
1080 for (i = 1; i <= 0x8000; i <<= 1) {
1081 switch (vol_pg->VolumeSettings.Settings & i) {
1082 case MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE:
1083 mpt_prtc(mpt, " Member-WCE");
1085 case MPI_RAIDVOL0_SETTING_OFFLINE_ON_SMART:
1086 mpt_prtc(mpt, " Offline-On-SMART-Err");
1088 case MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE:
1089 mpt_prtc(mpt, " Hot-Plug-Spares");
1091 case MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC:
1092 mpt_prtc(mpt, " High-Priority-ReSync");
1098 mpt_prtc(mpt, " )\n");
1099 if (vol_pg->VolumeSettings.HotSparePool != 0) {
1100 mpt_vol_prt(mpt, mpt_vol, "Using Spare Pool%s",
1101 powerof2(vol_pg->VolumeSettings.HotSparePool)
1103 for (i = 0; i < 8; i++) {
1107 if ((vol_pg->VolumeSettings.HotSparePool & mask) == 0)
1109 mpt_prtc(mpt, " %d", i);
1111 mpt_prtc(mpt, "\n");
1113 mpt_vol_prt(mpt, mpt_vol, "%d Members:\n", vol_pg->NumPhysDisks);
1114 for (i = 0; i < vol_pg->NumPhysDisks; i++){
1115 struct mpt_raid_disk *mpt_disk;
1116 CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
1117 int pt_bus = cam_sim_bus(mpt->phydisk_sim);
1120 mpt_disk = mpt->raid_disks + vol_pg->PhysDisk[i].PhysDiskNum;
1121 disk_pg = &mpt_disk->config_page;
1123 mpt_prtc(mpt, "(%s:%d:%d:0): ", device_get_nameunit(mpt->dev),
1124 pt_bus, disk_pg->PhysDiskID);
1125 if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM) {
1126 mpt_prtc(mpt, "%s", mpt_disk->member_number == 0?
1127 "Primary" : "Secondary");
1129 mpt_prtc(mpt, "Stripe Position %d",
1130 mpt_disk->member_number);
1132 f = disk_pg->PhysDiskStatus.Flags;
1133 s = disk_pg->PhysDiskStatus.State;
1134 if (f & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC) {
1135 mpt_prtc(mpt, " Out of Sync");
1137 if (f & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED) {
1138 mpt_prtc(mpt, " Quiesced");
1140 if (f & MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME) {
1141 mpt_prtc(mpt, " Inactive");
1143 if (f & MPI_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS) {
1144 mpt_prtc(mpt, " Was Optimal");
1146 if (f & MPI_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS) {
1147 mpt_prtc(mpt, " Was Non-Optimal");
1150 case MPI_PHYSDISK0_STATUS_ONLINE:
1151 mpt_prtc(mpt, " Online");
1153 case MPI_PHYSDISK0_STATUS_MISSING:
1154 mpt_prtc(mpt, " Missing");
1156 case MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE:
1157 mpt_prtc(mpt, " Incompatible");
1159 case MPI_PHYSDISK0_STATUS_FAILED:
1160 mpt_prtc(mpt, " Failed");
1162 case MPI_PHYSDISK0_STATUS_INITIALIZING:
1163 mpt_prtc(mpt, " Initializing");
1165 case MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED:
1166 mpt_prtc(mpt, " Requested Offline");
1168 case MPI_PHYSDISK0_STATUS_FAILED_REQUESTED:
1169 mpt_prtc(mpt, " Requested Failed");
1171 case MPI_PHYSDISK0_STATUS_OTHER_OFFLINE:
1173 mpt_prtc(mpt, " Offline Other (%x)", s);
1176 mpt_prtc(mpt, "\n");
1181 mpt_announce_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk)
1183 CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
1184 int rd_bus = cam_sim_bus(mpt->sim);
1185 int pt_bus = cam_sim_bus(mpt->phydisk_sim);
1188 disk_pg = &mpt_disk->config_page;
1189 mpt_disk_prt(mpt, mpt_disk,
1190 "Physical (%s:%d:%d:0), Pass-thru (%s:%d:%d:0)\n",
1191 device_get_nameunit(mpt->dev), rd_bus,
1192 disk_pg->PhysDiskID, device_get_nameunit(mpt->dev),
1193 pt_bus, mpt_disk - mpt->raid_disks);
1194 if (disk_pg->PhysDiskSettings.HotSparePool == 0)
1196 mpt_disk_prt(mpt, mpt_disk, "Member of Hot Spare Pool%s",
1197 powerof2(disk_pg->PhysDiskSettings.HotSparePool)
1199 for (i = 0; i < 8; i++) {
1203 if ((disk_pg->PhysDiskSettings.HotSparePool & mask) == 0)
1205 mpt_prtc(mpt, " %d", i);
1207 mpt_prtc(mpt, "\n");
1211 mpt_refresh_raid_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk,
1212 IOC_3_PHYS_DISK *ioc_disk)
1216 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK,
1217 /*PageNumber*/0, ioc_disk->PhysDiskNum,
1218 &mpt_disk->config_page.Header,
1219 /*sleep_ok*/TRUE, /*timeout_ms*/5000);
1221 mpt_prt(mpt, "mpt_refresh_raid_disk: "
1222 "Failed to read RAID Disk Hdr(%d)\n",
1223 ioc_disk->PhysDiskNum);
1226 rv = mpt_read_cur_cfg_page(mpt, ioc_disk->PhysDiskNum,
1227 &mpt_disk->config_page.Header,
1228 sizeof(mpt_disk->config_page),
1229 /*sleep_ok*/TRUE, /*timeout_ms*/5000);
1231 mpt_prt(mpt, "mpt_refresh_raid_disk: "
1232 "Failed to read RAID Disk Page(%d)\n",
1233 ioc_disk->PhysDiskNum);
1234 mpt2host_config_page_raid_phys_disk_0(&mpt_disk->config_page);
1238 mpt_refresh_raid_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
1239 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol)
1241 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
1242 struct mpt_raid_action_result *ar;
1247 vol_pg = mpt_vol->config_page;
1248 mpt_vol->flags &= ~MPT_RVF_UP2DATE;
1250 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 0,
1251 ioc_vol->VolumePageNumber, &vol_pg->Header, TRUE, 5000);
1253 mpt_vol_prt(mpt, mpt_vol,
1254 "mpt_refresh_raid_vol: Failed to read RAID Vol Hdr(%d)\n",
1255 ioc_vol->VolumePageNumber);
1259 rv = mpt_read_cur_cfg_page(mpt, ioc_vol->VolumePageNumber,
1260 &vol_pg->Header, mpt->raid_page0_len, TRUE, 5000);
1262 mpt_vol_prt(mpt, mpt_vol,
1263 "mpt_refresh_raid_vol: Failed to read RAID Vol Page(%d)\n",
1264 ioc_vol->VolumePageNumber);
1267 mpt2host_config_page_raid_vol_0(vol_pg);
1269 mpt_vol->flags |= MPT_RVF_ACTIVE;
1271 /* Update disk entry array data. */
1272 for (i = 0; i < vol_pg->NumPhysDisks; i++) {
1273 struct mpt_raid_disk *mpt_disk;
1274 mpt_disk = mpt->raid_disks + vol_pg->PhysDisk[i].PhysDiskNum;
1275 mpt_disk->volume = mpt_vol;
1276 mpt_disk->member_number = vol_pg->PhysDisk[i].PhysDiskMap;
1277 if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM) {
1278 mpt_disk->member_number--;
1282 if ((vol_pg->VolumeStatus.Flags
1283 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) == 0)
1286 req = mpt_get_request(mpt, TRUE);
1288 mpt_vol_prt(mpt, mpt_vol,
1289 "mpt_refresh_raid_vol: Get request failed!\n");
1292 rv = mpt_issue_raid_req(mpt, mpt_vol, NULL, req,
1293 MPI_RAID_ACTION_INDICATOR_STRUCT, 0, 0, 0, FALSE, TRUE);
1294 if (rv == ETIMEDOUT) {
1295 mpt_vol_prt(mpt, mpt_vol,
1296 "mpt_refresh_raid_vol: Progress Indicator fetch timeout\n");
1297 mpt_free_request(mpt, req);
1301 ar = REQ_TO_RAID_ACTION_RESULT(req);
1303 && ar->action_status == MPI_RAID_ACTION_ASTATUS_SUCCESS
1304 && REQ_IOCSTATUS(req) == MPI_IOCSTATUS_SUCCESS) {
1305 memcpy(&mpt_vol->sync_progress,
1306 &ar->action_data.indicator_struct,
1307 sizeof(mpt_vol->sync_progress));
1308 mpt2host_mpi_raid_vol_indicator(&mpt_vol->sync_progress);
1310 mpt_vol_prt(mpt, mpt_vol,
1311 "mpt_refresh_raid_vol: Progress indicator fetch failed!\n");
1313 mpt_free_request(mpt, req);
1317 * Update in-core information about RAID support. We update any entries
1318 * that didn't previously exists or have been marked as needing to
1319 * be updated by our event handler. Interesting changes are displayed
1323 mpt_refresh_raid_data(struct mpt_softc *mpt)
1325 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol;
1326 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_last_vol;
1327 IOC_3_PHYS_DISK *ioc_disk;
1328 IOC_3_PHYS_DISK *ioc_last_disk;
1329 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
1333 u_int nonopt_volumes;
1335 if (mpt->ioc_page2 == NULL || mpt->ioc_page3 == NULL) {
1340 * Mark all items as unreferenced by the configuration.
1341 * This allows us to find, report, and discard stale
1344 for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++) {
1345 mpt->raid_disks[i].flags &= ~MPT_RDF_REFERENCED;
1347 for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
1348 mpt->raid_volumes[i].flags &= ~MPT_RVF_REFERENCED;
1352 * Get Physical Disk information.
1354 len = mpt->ioc_page3->Header.PageLength * sizeof(uint32_t);
1355 rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
1356 &mpt->ioc_page3->Header, len,
1357 /*sleep_ok*/TRUE, /*timeout_ms*/5000);
1360 "mpt_refresh_raid_data: Failed to read IOC Page 3\n");
1363 mpt2host_config_page_ioc3(mpt->ioc_page3);
1365 ioc_disk = mpt->ioc_page3->PhysDisk;
1366 ioc_last_disk = ioc_disk + mpt->ioc_page3->NumPhysDisks;
1367 for (; ioc_disk != ioc_last_disk; ioc_disk++) {
1368 struct mpt_raid_disk *mpt_disk;
1370 mpt_disk = mpt->raid_disks + ioc_disk->PhysDiskNum;
1371 mpt_disk->flags |= MPT_RDF_REFERENCED;
1372 if ((mpt_disk->flags & (MPT_RDF_ACTIVE|MPT_RDF_UP2DATE))
1373 != (MPT_RDF_ACTIVE|MPT_RDF_UP2DATE)) {
1375 mpt_refresh_raid_disk(mpt, mpt_disk, ioc_disk);
1378 mpt_disk->flags |= MPT_RDF_ACTIVE;
1383 * Refresh volume data.
1385 len = mpt->ioc_page2->Header.PageLength * sizeof(uint32_t);
1386 rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
1387 &mpt->ioc_page2->Header, len,
1388 /*sleep_ok*/TRUE, /*timeout_ms*/5000);
1390 mpt_prt(mpt, "mpt_refresh_raid_data: "
1391 "Failed to read IOC Page 2\n");
1394 mpt2host_config_page_ioc2(mpt->ioc_page2);
1396 ioc_vol = mpt->ioc_page2->RaidVolume;
1397 ioc_last_vol = ioc_vol + mpt->ioc_page2->NumActiveVolumes;
1398 for (;ioc_vol != ioc_last_vol; ioc_vol++) {
1399 struct mpt_raid_volume *mpt_vol;
1401 mpt_vol = mpt->raid_volumes + ioc_vol->VolumePageNumber;
1402 mpt_vol->flags |= MPT_RVF_REFERENCED;
1403 vol_pg = mpt_vol->config_page;
1406 if (((mpt_vol->flags & (MPT_RVF_ACTIVE|MPT_RVF_UP2DATE))
1407 != (MPT_RVF_ACTIVE|MPT_RVF_UP2DATE))
1408 || (vol_pg->VolumeStatus.Flags
1409 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) != 0) {
1411 mpt_refresh_raid_vol(mpt, mpt_vol, ioc_vol);
1413 mpt_vol->flags |= MPT_RVF_ACTIVE;
1417 for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
1418 struct mpt_raid_volume *mpt_vol;
1424 mpt_vol = &mpt->raid_volumes[i];
1426 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0) {
1430 vol_pg = mpt_vol->config_page;
1431 if ((mpt_vol->flags & (MPT_RVF_REFERENCED|MPT_RVF_ANNOUNCED))
1432 == MPT_RVF_ANNOUNCED) {
1433 mpt_vol_prt(mpt, mpt_vol, "No longer configured\n");
1438 if ((mpt_vol->flags & MPT_RVF_ANNOUNCED) == 0) {
1439 mpt_announce_vol(mpt, mpt_vol);
1440 mpt_vol->flags |= MPT_RVF_ANNOUNCED;
1443 if (vol_pg->VolumeStatus.State !=
1444 MPI_RAIDVOL0_STATUS_STATE_OPTIMAL)
1447 if ((mpt_vol->flags & MPT_RVF_UP2DATE) != 0)
1450 mpt_vol->flags |= MPT_RVF_UP2DATE;
1451 mpt_vol_prt(mpt, mpt_vol, "%s - %s\n",
1452 mpt_vol_type(mpt_vol), mpt_vol_state(mpt_vol));
1453 mpt_verify_mwce(mpt, mpt_vol);
1455 if (vol_pg->VolumeStatus.Flags == 0) {
1459 mpt_vol_prt(mpt, mpt_vol, "Status (");
1460 for (m = 1; m <= 0x80; m <<= 1) {
1461 switch (vol_pg->VolumeStatus.Flags & m) {
1462 case MPI_RAIDVOL0_STATUS_FLAG_ENABLED:
1463 mpt_prtc(mpt, " Enabled");
1465 case MPI_RAIDVOL0_STATUS_FLAG_QUIESCED:
1466 mpt_prtc(mpt, " Quiesced");
1468 case MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS:
1469 mpt_prtc(mpt, " Re-Syncing");
1471 case MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE:
1472 mpt_prtc(mpt, " Inactive");
1478 mpt_prtc(mpt, " )\n");
1480 if ((vol_pg->VolumeStatus.Flags
1481 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) == 0)
1484 mpt_verify_resync_rate(mpt, mpt_vol);
1486 left = MPT_U64_2_SCALAR(mpt_vol->sync_progress.BlocksRemaining);
1487 total = MPT_U64_2_SCALAR(mpt_vol->sync_progress.TotalBlocks);
1488 if (vol_pg->ResyncRate != 0) {
1490 prio = ((u_int)vol_pg->ResyncRate * 100000) / 0xFF;
1491 mpt_vol_prt(mpt, mpt_vol, "Rate %d.%d%%\n",
1492 prio / 1000, prio % 1000);
1494 prio = vol_pg->VolumeSettings.Settings
1495 & MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
1496 mpt_vol_prt(mpt, mpt_vol, "%s Priority Re-Sync\n",
1497 prio ? "High" : "Low");
1499 #if __FreeBSD_version >= 500000
1500 mpt_vol_prt(mpt, mpt_vol, "%ju of %ju "
1501 "blocks remaining\n", (uintmax_t)left,
1504 mpt_vol_prt(mpt, mpt_vol, "%llu of %llu "
1505 "blocks remaining\n", (uint64_t)left,
1509 /* Periodically report on sync progress. */
1510 mpt_schedule_raid_refresh(mpt);
1513 for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++) {
1514 struct mpt_raid_disk *mpt_disk;
1515 CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
1518 mpt_disk = &mpt->raid_disks[i];
1519 disk_pg = &mpt_disk->config_page;
1521 if ((mpt_disk->flags & MPT_RDF_ACTIVE) == 0)
1524 if ((mpt_disk->flags & (MPT_RDF_REFERENCED|MPT_RDF_ANNOUNCED))
1525 == MPT_RDF_ANNOUNCED) {
1526 mpt_disk_prt(mpt, mpt_disk, "No longer configured\n");
1527 mpt_disk->flags = 0;
1532 if ((mpt_disk->flags & MPT_RDF_ANNOUNCED) == 0) {
1534 mpt_announce_disk(mpt, mpt_disk);
1535 mpt_disk->flags |= MPT_RVF_ANNOUNCED;
1538 if ((mpt_disk->flags & MPT_RDF_UP2DATE) != 0)
1541 mpt_disk->flags |= MPT_RDF_UP2DATE;
1542 mpt_disk_prt(mpt, mpt_disk, "%s\n", mpt_disk_state(mpt_disk));
1543 if (disk_pg->PhysDiskStatus.Flags == 0)
1546 mpt_disk_prt(mpt, mpt_disk, "Status (");
1547 for (m = 1; m <= 0x80; m <<= 1) {
1548 switch (disk_pg->PhysDiskStatus.Flags & m) {
1549 case MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC:
1550 mpt_prtc(mpt, " Out-Of-Sync");
1552 case MPI_PHYSDISK0_STATUS_FLAG_QUIESCED:
1553 mpt_prtc(mpt, " Quiesced");
1559 mpt_prtc(mpt, " )\n");
1562 mpt->raid_nonopt_volumes = nonopt_volumes;
1567 mpt_raid_timer(void *arg)
1569 struct mpt_softc *mpt;
1571 mpt = (struct mpt_softc *)arg;
1573 mpt_raid_wakeup(mpt);
1578 mpt_schedule_raid_refresh(struct mpt_softc *mpt)
1580 callout_reset(&mpt->raid_timer, MPT_RAID_SYNC_REPORT_INTERVAL,
1581 mpt_raid_timer, mpt);
1585 mpt_raid_free_mem(struct mpt_softc *mpt)
1588 if (mpt->raid_volumes) {
1589 struct mpt_raid_volume *mpt_raid;
1591 for (i = 0; i < mpt->raid_max_volumes; i++) {
1592 mpt_raid = &mpt->raid_volumes[i];
1593 if (mpt_raid->config_page) {
1594 kfree(mpt_raid->config_page, M_DEVBUF);
1595 mpt_raid->config_page = NULL;
1598 kfree(mpt->raid_volumes, M_DEVBUF);
1599 mpt->raid_volumes = NULL;
1601 if (mpt->raid_disks) {
1602 kfree(mpt->raid_disks, M_DEVBUF);
1603 mpt->raid_disks = NULL;
1605 if (mpt->ioc_page2) {
1606 kfree(mpt->ioc_page2, M_DEVBUF);
1607 mpt->ioc_page2 = NULL;
1609 if (mpt->ioc_page3) {
1610 kfree(mpt->ioc_page3, M_DEVBUF);
1611 mpt->ioc_page3 = NULL;
1613 mpt->raid_max_volumes = 0;
1614 mpt->raid_max_disks = 0;
1617 #if __FreeBSD_version >= 500000
1619 mpt_raid_set_vol_resync_rate(struct mpt_softc *mpt, u_int rate)
1621 struct mpt_raid_volume *mpt_vol;
1623 if ((rate > MPT_RAID_RESYNC_RATE_MAX
1624 || rate < MPT_RAID_RESYNC_RATE_MIN)
1625 && rate != MPT_RAID_RESYNC_RATE_NC)
1629 mpt->raid_resync_rate = rate;
1630 RAID_VOL_FOREACH(mpt, mpt_vol) {
1631 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0) {
1634 mpt_verify_resync_rate(mpt, mpt_vol);
1641 mpt_raid_set_vol_queue_depth(struct mpt_softc *mpt, u_int vol_queue_depth)
1643 struct mpt_raid_volume *mpt_vol;
1645 if (vol_queue_depth > 255 || vol_queue_depth < 1)
1649 mpt->raid_queue_depth = vol_queue_depth;
1650 RAID_VOL_FOREACH(mpt, mpt_vol) {
1651 struct cam_path *path;
1654 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
1657 mpt->raid_rescan = 0;
1659 MPTLOCK_2_CAMLOCK(mpt);
1660 error = xpt_create_path(&path, xpt_periph,
1661 cam_sim_path(mpt->sim),
1662 mpt_vol->config_page->VolumeID,
1664 if (error != CAM_REQ_CMP) {
1665 CAMLOCK_2_MPTLOCK(mpt);
1666 mpt_vol_prt(mpt, mpt_vol, "Unable to allocate path!\n");
1669 mpt_adjust_queue_depth(mpt, mpt_vol, path);
1670 xpt_free_path(path);
1671 CAMLOCK_2_MPTLOCK(mpt);
1678 mpt_raid_set_vol_mwce(struct mpt_softc *mpt, mpt_raid_mwce_t mwce)
1680 struct mpt_raid_volume *mpt_vol;
1681 int force_full_resync;
1684 if (mwce == mpt->raid_mwce_setting) {
1690 * Catch MWCE being left on due to a failed shutdown. Since
1691 * sysctls cannot be set by the loader, we treat the first
1692 * setting of this varible specially and force a full volume
1693 * resync if MWCE is enabled and a resync is in progress.
1695 force_full_resync = 0;
1696 if (mpt->raid_mwce_set == 0
1697 && mpt->raid_mwce_setting == MPT_RAID_MWCE_NC
1698 && mwce == MPT_RAID_MWCE_REBUILD_ONLY)
1699 force_full_resync = 1;
1701 mpt->raid_mwce_setting = mwce;
1702 RAID_VOL_FOREACH(mpt, mpt_vol) {
1703 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
1707 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
1710 vol_pg = mpt_vol->config_page;
1711 resyncing = vol_pg->VolumeStatus.Flags
1712 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS;
1713 mwce = vol_pg->VolumeSettings.Settings
1714 & MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
1715 if (force_full_resync && resyncing && mwce) {
1718 * XXX disable/enable volume should force a resync,
1719 * but we'll need to queice, drain, and restart
1722 mpt_vol_prt(mpt, mpt_vol, "WARNING - Unsafe shutdown "
1723 "detected. Suggest full resync.\n");
1725 mpt_verify_mwce(mpt, mpt_vol);
1727 mpt->raid_mwce_set = 1;
1731 const char *mpt_vol_mwce_strs[] =
1735 "On-During-Rebuild",
1740 mpt_raid_sysctl_vol_member_wce(SYSCTL_HANDLER_ARGS)
1743 struct mpt_softc *mpt;
1751 mpt = (struct mpt_softc *)arg1;
1752 str = mpt_vol_mwce_strs[mpt->raid_mwce_setting];
1753 error = SYSCTL_OUT(req, str, strlen(str) + 1);
1754 if (error || !req->newptr) {
1758 size = req->newlen - req->newidx;
1759 if (size >= sizeof(inbuf)) {
1763 error = SYSCTL_IN(req, inbuf, size);
1768 for (i = 0; i < NUM_ELEMENTS(mpt_vol_mwce_strs); i++) {
1769 if (strcmp(mpt_vol_mwce_strs[i], inbuf) == 0) {
1770 return (mpt_raid_set_vol_mwce(mpt, i));
1777 mpt_raid_sysctl_vol_resync_rate(SYSCTL_HANDLER_ARGS)
1779 struct mpt_softc *mpt;
1780 u_int raid_resync_rate;
1785 mpt = (struct mpt_softc *)arg1;
1786 raid_resync_rate = mpt->raid_resync_rate;
1788 error = sysctl_handle_int(oidp, &raid_resync_rate, 0, req);
1789 if (error || !req->newptr) {
1793 return (mpt_raid_set_vol_resync_rate(mpt, raid_resync_rate));
1797 mpt_raid_sysctl_vol_queue_depth(SYSCTL_HANDLER_ARGS)
1799 struct mpt_softc *mpt;
1800 u_int raid_queue_depth;
1805 mpt = (struct mpt_softc *)arg1;
1806 raid_queue_depth = mpt->raid_queue_depth;
1808 error = sysctl_handle_int(oidp, &raid_queue_depth, 0, req);
1809 if (error || !req->newptr) {
1813 return (mpt_raid_set_vol_queue_depth(mpt, raid_queue_depth));
1817 mpt_raid_sysctl_attach(struct mpt_softc *mpt)
1819 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev);
1820 struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev);
1822 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1823 "vol_member_wce", CTLTYPE_STRING | CTLFLAG_RW, mpt, 0,
1824 mpt_raid_sysctl_vol_member_wce, "A",
1825 "volume member WCE(On,Off,On-During-Rebuild,NC)");
1827 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1828 "vol_queue_depth", CTLTYPE_INT | CTLFLAG_RW, mpt, 0,
1829 mpt_raid_sysctl_vol_queue_depth, "I",
1830 "default volume queue depth");
1832 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1833 "vol_resync_rate", CTLTYPE_INT | CTLFLAG_RW, mpt, 0,
1834 mpt_raid_sysctl_vol_resync_rate, "I",
1835 "volume resync priority (0 == NC, 1 - 255)");
1836 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1837 "nonoptimal_volumes", CTLFLAG_RD,
1838 &mpt->raid_nonopt_volumes, 0,
1839 "number of nonoptimal volumes");