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.30 2011/07/29 18:38:31 marius 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_sim.h>
56 #include <sys/devicestat.h>
57 #include <bus/cam/cam_periph.h>
59 #include <sys/callout.h>
60 #include <sys/kthread.h>
61 #include <sys/sysctl.h>
63 #include <machine/stdarg.h>
65 struct mpt_raid_action_result
68 MPI_RAID_VOL_INDICATOR indicator_struct;
69 uint32_t new_settings;
70 uint8_t phys_disk_num;
72 uint16_t action_status;
75 #define REQ_TO_RAID_ACTION_RESULT(req) ((struct mpt_raid_action_result *) \
76 (((MSG_RAID_ACTION_REQUEST *)(req->req_vbuf)) + 1))
78 #define REQ_IOCSTATUS(req) ((req)->IOCStatus & MPI_IOCSTATUS_MASK)
80 static mpt_probe_handler_t mpt_raid_probe;
81 static mpt_attach_handler_t mpt_raid_attach;
82 static mpt_enable_handler_t mpt_raid_enable;
83 static mpt_event_handler_t mpt_raid_event;
84 static mpt_shutdown_handler_t mpt_raid_shutdown;
85 static mpt_reset_handler_t mpt_raid_ioc_reset;
86 static mpt_detach_handler_t mpt_raid_detach;
88 static struct mpt_personality mpt_raid_personality =
91 .probe = mpt_raid_probe,
92 .attach = mpt_raid_attach,
93 .enable = mpt_raid_enable,
94 .event = mpt_raid_event,
95 .reset = mpt_raid_ioc_reset,
96 .shutdown = mpt_raid_shutdown,
97 .detach = mpt_raid_detach,
100 DECLARE_MPT_PERSONALITY(mpt_raid, SI_ORDER_THIRD);
101 MPT_PERSONALITY_DEPEND(mpt_raid, mpt_cam, 1, 1, 1);
103 static mpt_reply_handler_t mpt_raid_reply_handler;
104 static int mpt_raid_reply_frame_handler(struct mpt_softc *mpt, request_t *req,
105 MSG_DEFAULT_REPLY *reply_frame);
106 static int mpt_spawn_raid_thread(struct mpt_softc *mpt);
107 static void mpt_terminate_raid_thread(struct mpt_softc *mpt);
108 static void mpt_raid_thread(void *arg);
109 static timeout_t mpt_raid_timer;
111 static void mpt_enable_vol(struct mpt_softc *mpt,
112 struct mpt_raid_volume *mpt_vol, int enable);
114 static void mpt_verify_mwce(struct mpt_softc *, struct mpt_raid_volume *);
115 static void mpt_adjust_queue_depth(struct mpt_softc *, struct mpt_raid_volume *,
117 static void mpt_raid_sysctl_attach(struct mpt_softc *);
119 static const char *mpt_vol_type(struct mpt_raid_volume *vol);
120 static const char *mpt_vol_state(struct mpt_raid_volume *vol);
121 static const char *mpt_disk_state(struct mpt_raid_disk *disk);
122 static void mpt_vol_prt(struct mpt_softc *mpt, struct mpt_raid_volume *vol,
123 const char *fmt, ...);
124 static void mpt_disk_prt(struct mpt_softc *mpt, struct mpt_raid_disk *disk,
125 const char *fmt, ...);
127 static int mpt_issue_raid_req(struct mpt_softc *mpt,
128 struct mpt_raid_volume *vol, struct mpt_raid_disk *disk, request_t *req,
129 u_int Action, uint32_t ActionDataWord, bus_addr_t addr, bus_size_t len,
130 int write, int wait);
132 static int mpt_refresh_raid_data(struct mpt_softc *mpt);
133 static void mpt_schedule_raid_refresh(struct mpt_softc *mpt);
135 static uint32_t raid_handler_id = MPT_HANDLER_ID_NONE;
138 mpt_vol_type(struct mpt_raid_volume *vol)
140 switch (vol->config_page->VolumeType) {
141 case MPI_RAID_VOL_TYPE_IS:
143 case MPI_RAID_VOL_TYPE_IME:
145 case MPI_RAID_VOL_TYPE_IM:
153 mpt_vol_state(struct mpt_raid_volume *vol)
155 switch (vol->config_page->VolumeStatus.State) {
156 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
158 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
160 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
168 mpt_disk_state(struct mpt_raid_disk *disk)
170 switch (disk->config_page.PhysDiskStatus.State) {
171 case MPI_PHYSDISK0_STATUS_ONLINE:
173 case MPI_PHYSDISK0_STATUS_MISSING:
175 case MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE:
176 return ("Incompatible");
177 case MPI_PHYSDISK0_STATUS_FAILED:
179 case MPI_PHYSDISK0_STATUS_INITIALIZING:
180 return ("Initializing");
181 case MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED:
182 return ("Offline Requested");
183 case MPI_PHYSDISK0_STATUS_FAILED_REQUESTED:
184 return ("Failed per Host Request");
185 case MPI_PHYSDISK0_STATUS_OTHER_OFFLINE:
193 mpt_vol_prt(struct mpt_softc *mpt, struct mpt_raid_volume *vol,
194 const char *fmt, ...)
198 kprintf("%s:vol%d(%s:%d:%d): ", device_get_nameunit(mpt->dev),
199 (u_int)(vol - mpt->raid_volumes), device_get_nameunit(mpt->dev),
200 vol->config_page->VolumeBus, vol->config_page->VolumeID);
207 mpt_disk_prt(struct mpt_softc *mpt, struct mpt_raid_disk *disk,
208 const char *fmt, ...)
212 if (disk->volume != NULL) {
213 kprintf("(%s:vol%d:%d): ",
214 device_get_nameunit(mpt->dev),
215 disk->volume->config_page->VolumeID,
216 disk->member_number);
218 kprintf("(%s:%d:%d): ", device_get_nameunit(mpt->dev),
219 disk->config_page.PhysDiskBus,
220 disk->config_page.PhysDiskID);
228 mpt_raid_async(void *callback_arg, u_int32_t code,
229 struct cam_path *path, void *arg)
231 struct mpt_softc *mpt;
233 mpt = (struct mpt_softc*)callback_arg;
235 case AC_FOUND_DEVICE:
237 struct ccb_getdev *cgd;
238 struct mpt_raid_volume *mpt_vol;
240 cgd = (struct ccb_getdev *)arg;
245 mpt_lprt(mpt, MPT_PRT_DEBUG, "Callback for %d\n",
246 cgd->ccb_h.target_id);
248 RAID_VOL_FOREACH(mpt, mpt_vol) {
249 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
252 if (mpt_vol->config_page->VolumeID
253 == cgd->ccb_h.target_id) {
254 mpt_adjust_queue_depth(mpt, mpt_vol, path);
265 mpt_raid_probe(struct mpt_softc *mpt)
268 if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) {
275 mpt_raid_attach(struct mpt_softc *mpt)
277 struct ccb_setasync csa;
278 mpt_handler_t handler;
281 mpt_callout_init(mpt, &mpt->raid_timer);
283 error = mpt_spawn_raid_thread(mpt);
285 mpt_prt(mpt, "Unable to spawn RAID thread!\n");
290 handler.reply_handler = mpt_raid_reply_handler;
291 error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
294 mpt_prt(mpt, "Unable to register RAID haandler!\n");
298 xpt_setup_ccb(&csa.ccb_h, mpt->path, 5);
299 csa.ccb_h.func_code = XPT_SASYNC_CB;
300 csa.event_enable = AC_FOUND_DEVICE;
301 csa.callback = mpt_raid_async;
302 csa.callback_arg = mpt;
303 xpt_action((union ccb *)&csa);
304 if (csa.ccb_h.status != CAM_REQ_CMP) {
305 mpt_prt(mpt, "mpt_raid_attach: Unable to register "
306 "CAM async handler.\n");
310 mpt_raid_sysctl_attach(mpt);
314 mpt_raid_detach(mpt);
319 mpt_raid_enable(struct mpt_softc *mpt)
326 mpt_raid_detach(struct mpt_softc *mpt)
328 struct ccb_setasync csa;
329 mpt_handler_t handler;
331 callout_stop(&mpt->raid_timer);
334 mpt_terminate_raid_thread(mpt);
335 handler.reply_handler = mpt_raid_reply_handler;
336 mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
338 xpt_setup_ccb(&csa.ccb_h, mpt->path, /*priority*/5);
339 csa.ccb_h.func_code = XPT_SASYNC_CB;
340 csa.event_enable = 0;
341 csa.callback = mpt_raid_async;
342 csa.callback_arg = mpt;
343 xpt_action((union ccb *)&csa);
348 mpt_raid_ioc_reset(struct mpt_softc *mpt, int type)
351 /* Nothing to do yet. */
354 static const char *raid_event_txt[] =
358 "Volume Settings Changed",
359 "Volume Status Changed",
360 "Volume Physical Disk Membership Changed",
361 "Physical Disk Created",
362 "Physical Disk Deleted",
363 "Physical Disk Settings Changed",
364 "Physical Disk Status Changed",
365 "Domain Validation Required",
366 "SMART Data Received",
367 "Replace Action Started",
371 mpt_raid_event(struct mpt_softc *mpt, request_t *req,
372 MSG_EVENT_NOTIFY_REPLY *msg)
374 EVENT_DATA_RAID *raid_event;
375 struct mpt_raid_volume *mpt_vol;
376 struct mpt_raid_disk *mpt_disk;
377 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
381 if (msg->Event != MPI_EVENT_INTEGRATED_RAID) {
385 raid_event = (EVENT_DATA_RAID *)&msg->Data;
389 if (mpt->raid_volumes != NULL && mpt->ioc_page2 != NULL) {
390 for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
391 mpt_vol = &mpt->raid_volumes[i];
392 vol_pg = mpt_vol->config_page;
394 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
397 if (vol_pg->VolumeID == raid_event->VolumeID
398 && vol_pg->VolumeBus == raid_event->VolumeBus)
401 if (i >= mpt->ioc_page2->MaxVolumes) {
408 if (raid_event->PhysDiskNum != 0xFF && mpt->raid_disks != NULL) {
409 mpt_disk = mpt->raid_disks + raid_event->PhysDiskNum;
410 if ((mpt_disk->flags & MPT_RDF_ACTIVE) == 0) {
416 switch(raid_event->ReasonCode) {
417 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
418 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
420 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
421 if (mpt_vol != NULL) {
422 if ((mpt_vol->flags & MPT_RVF_UP2DATE) != 0) {
423 mpt_vol->flags &= ~MPT_RVF_UP2DATE;
426 * Coalesce status messages into one
427 * per background run of our RAID thread.
428 * This removes "spurious" status messages
435 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
436 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
438 if (mpt_vol != NULL) {
439 mpt_vol->flags &= ~(MPT_RVF_UP2DATE|MPT_RVF_ANNOUNCED);
442 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
443 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
446 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
447 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
449 if (mpt_disk != NULL) {
450 mpt_disk->flags &= ~MPT_RDF_UP2DATE;
453 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
456 case MPI_EVENT_RAID_RC_SMART_DATA:
457 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
462 if (mpt_disk != NULL) {
463 mpt_disk_prt(mpt, mpt_disk, "%s", "");
464 } else if (mpt_vol != NULL) {
465 mpt_vol_prt(mpt, mpt_vol, "%s", "");
467 mpt_prt(mpt, "Volume(%d:%d", raid_event->VolumeBus,
468 raid_event->VolumeID);
470 if (raid_event->PhysDiskNum != 0xFF)
471 mpt_prtc(mpt, ":%d): ",
472 raid_event->PhysDiskNum);
474 mpt_prtc(mpt, "): ");
477 if (raid_event->ReasonCode >= NUM_ELEMENTS(raid_event_txt))
478 mpt_prtc(mpt, "Unhandled RaidEvent %#x\n",
479 raid_event->ReasonCode);
481 mpt_prtc(mpt, "%s\n",
482 raid_event_txt[raid_event->ReasonCode]);
485 if (raid_event->ReasonCode == MPI_EVENT_RAID_RC_SMART_DATA) {
486 /* XXX Use CAM's print sense for this... */
487 if (mpt_disk != NULL)
488 mpt_disk_prt(mpt, mpt_disk, "%s", "");
490 mpt_prt(mpt, "Volume(%d:%d:%d: ",
491 raid_event->VolumeBus, raid_event->VolumeID,
492 raid_event->PhysDiskNum);
493 mpt_prtc(mpt, "ASC 0x%x, ASCQ 0x%x)\n",
494 raid_event->ASC, raid_event->ASCQ);
497 mpt_raid_wakeup(mpt);
502 mpt_raid_shutdown(struct mpt_softc *mpt)
504 struct mpt_raid_volume *mpt_vol;
506 if (mpt->raid_mwce_setting != MPT_RAID_MWCE_REBUILD_ONLY) {
510 mpt->raid_mwce_setting = MPT_RAID_MWCE_OFF;
511 RAID_VOL_FOREACH(mpt, mpt_vol) {
512 mpt_verify_mwce(mpt, mpt_vol);
517 mpt_raid_reply_handler(struct mpt_softc *mpt, request_t *req,
518 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
526 if (reply_frame != NULL)
527 free_req = mpt_raid_reply_frame_handler(mpt, req, reply_frame);
529 else if (req->ccb != NULL) {
530 /* Complete Quiesce CCB with error... */
534 req->state &= ~REQ_STATE_QUEUED;
535 req->state |= REQ_STATE_DONE;
536 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
538 if ((req->state & REQ_STATE_NEED_WAKEUP) != 0) {
540 } else if (free_req) {
541 mpt_free_request(mpt, req);
548 * Parse additional completion information in the reply
549 * frame for RAID I/O requests.
552 mpt_raid_reply_frame_handler(struct mpt_softc *mpt, request_t *req,
553 MSG_DEFAULT_REPLY *reply_frame)
555 MSG_RAID_ACTION_REPLY *reply;
556 struct mpt_raid_action_result *action_result;
557 MSG_RAID_ACTION_REQUEST *rap;
559 reply = (MSG_RAID_ACTION_REPLY *)reply_frame;
560 req->IOCStatus = le16toh(reply->IOCStatus);
561 rap = (MSG_RAID_ACTION_REQUEST *)req->req_vbuf;
563 switch (rap->Action) {
564 case MPI_RAID_ACTION_QUIESCE_PHYS_IO:
565 mpt_prt(mpt, "QUIESCE PHYSIO DONE\n");
567 case MPI_RAID_ACTION_ENABLE_PHYS_IO:
568 mpt_prt(mpt, "ENABLY PHYSIO DONE\n");
573 action_result = REQ_TO_RAID_ACTION_RESULT(req);
574 memcpy(&action_result->action_data, &reply->ActionData,
575 sizeof(action_result->action_data));
576 action_result->action_status = le16toh(reply->ActionStatus);
581 * Utiltity routine to perform a RAID action command;
584 mpt_issue_raid_req(struct mpt_softc *mpt, struct mpt_raid_volume *vol,
585 struct mpt_raid_disk *disk, request_t *req, u_int Action,
586 uint32_t ActionDataWord, bus_addr_t addr, bus_size_t len,
589 MSG_RAID_ACTION_REQUEST *rap;
593 memset(rap, 0, sizeof *rap);
594 rap->Action = Action;
595 rap->ActionDataWord = htole32(ActionDataWord);
596 rap->Function = MPI_FUNCTION_RAID_ACTION;
597 rap->VolumeID = vol->config_page->VolumeID;
598 rap->VolumeBus = vol->config_page->VolumeBus;
600 rap->PhysDiskNum = disk->config_page.PhysDiskNum;
602 rap->PhysDiskNum = 0xFF;
603 se = (SGE_SIMPLE32 *)&rap->ActionDataSGE;
604 se->Address = htole32(addr);
605 MPI_pSGE_SET_LENGTH(se, len);
606 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
607 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
608 MPI_SGE_FLAGS_END_OF_LIST |
609 write ? MPI_SGE_FLAGS_HOST_TO_IOC : MPI_SGE_FLAGS_IOC_TO_HOST));
610 se->FlagsLength = htole32(se->FlagsLength);
611 rap->MsgContext = htole32(req->index | raid_handler_id);
613 mpt_check_doorbell(mpt);
614 mpt_send_cmd(mpt, req);
617 return (mpt_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE,
618 /*sleep_ok*/FALSE, /*time_ms*/2000));
624 /*************************** RAID Status Monitoring ***************************/
626 mpt_spawn_raid_thread(struct mpt_softc *mpt)
631 * Freeze out any CAM transactions until our thread
632 * is able to run at least once. We need to update
633 * our RAID pages before acception I/O or we may
634 * reject I/O to an ID we later determine is for a
638 xpt_freeze_simq(mpt->phydisk_sim, 1);
640 error = mpt_kthread_create(mpt_raid_thread, mpt,
641 &mpt->raid_thread, /*flags*/0, /*altstack*/0,
642 "mpt_raid%d", mpt->unit);
645 xpt_release_simq(mpt->phydisk_sim, /*run_queue*/FALSE);
652 mpt_terminate_raid_thread(struct mpt_softc *mpt)
655 if (mpt->raid_thread == NULL) {
658 mpt->shutdwn_raid = 1;
659 wakeup(&mpt->raid_volumes);
661 * Sleep on a slightly different location
662 * for this interlock just for added safety.
664 mpt_sleep(mpt, &mpt->raid_thread, 0, "thtrm", 0);
668 mpt_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
670 xpt_free_path(ccb->ccb_h.path);
675 mpt_raid_thread(void *arg)
677 struct mpt_softc *mpt;
680 mpt = (struct mpt_softc *)arg;
683 while (mpt->shutdwn_raid == 0) {
685 if (mpt->raid_wakeup == 0) {
686 mpt_sleep(mpt, &mpt->raid_volumes, 0, "idle", 0);
690 mpt->raid_wakeup = 0;
692 if (mpt_refresh_raid_data(mpt)) {
693 mpt_schedule_raid_refresh(mpt); /* XX NOT QUITE RIGHT */
698 * Now that we have our first snapshot of RAID data,
699 * allow CAM to access our physical disk bus.
703 MPTLOCK_2_CAMLOCK(mpt);
704 xpt_release_simq(mpt->phydisk_sim, TRUE);
705 CAMLOCK_2_MPTLOCK(mpt);
708 if (mpt->raid_rescan != 0) {
712 mpt->raid_rescan = 0;
715 ccb = kmalloc(sizeof(union ccb), M_TEMP,
719 error = xpt_create_path(&ccb->ccb_h.path, xpt_periph,
720 cam_sim_path(mpt->phydisk_sim),
721 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
722 if (error != CAM_REQ_CMP) {
724 mpt_prt(mpt, "Unable to rescan RAID Bus!\n");
726 xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path,
727 5/*priority (low)*/);
728 ccb->ccb_h.func_code = XPT_SCAN_BUS;
729 ccb->ccb_h.cbfcnp = mpt_cam_rescan_callback;
730 ccb->crcn.flags = CAM_FLAG_NONE;
733 /* scan is now in progress */
737 mpt->raid_thread = NULL;
738 wakeup(&mpt->raid_thread);
745 mpt_raid_quiesce_timeout(void *arg)
748 /* Complete the CCB with error */
752 static timeout_t mpt_raid_quiesce_timeout;
754 mpt_raid_quiesce_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk,
760 if ((mpt_disk->flags & MPT_RDF_QUIESCED) != 0)
761 return (CAM_REQ_CMP);
763 if ((mpt_disk->flags & MPT_RDF_QUIESCING) == 0) {
766 mpt_disk->flags |= MPT_RDF_QUIESCING;
767 xpt_freeze_devq(ccb->ccb_h.path, 1);
769 rv = mpt_issue_raid_req(mpt, mpt_disk->volume, mpt_disk, req,
770 MPI_RAID_ACTION_QUIESCE_PHYS_IO,
771 /*ActionData*/0, /*addr*/0,
772 /*len*/0, /*write*/FALSE,
775 return (CAM_REQ_CMP_ERR);
777 mpt_req_timeout(req, mpt_raid_quiesce_timeout, ccb, 5 * hz);
779 if (rv == ETIMEDOUT) {
780 mpt_disk_prt(mpt, mpt_disk, "mpt_raid_quiesce_disk: "
781 "Quiece Timed-out\n");
782 xpt_release_devq(ccb->ccb_h.path, 1, /*run*/0);
783 return (CAM_REQ_CMP_ERR);
786 ar = REQ_TO_RAID_ACTION_RESULT(req);
788 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
789 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
790 mpt_disk_prt(mpt, mpt_disk, "Quiece Failed"
791 "%d:%x:%x\n", rv, req->IOCStatus,
793 xpt_release_devq(ccb->ccb_h.path, 1, /*run*/0);
794 return (CAM_REQ_CMP_ERR);
797 return (CAM_REQ_INPROG);
799 return (CAM_REQUEUE_REQ);
803 /* XXX Ignores that there may be multiple busses/IOCs involved. */
805 mpt_map_physdisk(struct mpt_softc *mpt, union ccb *ccb, target_id_t *tgt)
807 struct mpt_raid_disk *mpt_disk;
809 mpt_disk = mpt->raid_disks + ccb->ccb_h.target_id;
810 if (ccb->ccb_h.target_id < mpt->raid_max_disks
811 && (mpt_disk->flags & MPT_RDF_ACTIVE) != 0) {
812 *tgt = mpt_disk->config_page.PhysDiskID;
815 mpt_lprt(mpt, MPT_PRT_DEBUG1, "mpt_map_physdisk(%d) - Not Active\n",
816 ccb->ccb_h.target_id);
820 /* XXX Ignores that there may be multiple busses/IOCs involved. */
822 mpt_is_raid_member(struct mpt_softc *mpt, target_id_t tgt)
824 struct mpt_raid_disk *mpt_disk;
827 if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0)
829 for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++) {
830 mpt_disk = &mpt->raid_disks[i];
831 if ((mpt_disk->flags & MPT_RDF_ACTIVE) != 0 &&
832 mpt_disk->config_page.PhysDiskID == tgt)
839 /* XXX Ignores that there may be multiple busses/IOCs involved. */
841 mpt_is_raid_volume(struct mpt_softc *mpt, target_id_t tgt)
843 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol;
844 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_last_vol;
846 if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) {
849 ioc_vol = mpt->ioc_page2->RaidVolume;
850 ioc_last_vol = ioc_vol + mpt->ioc_page2->NumActiveVolumes;
851 for (;ioc_vol != ioc_last_vol; ioc_vol++) {
852 if (ioc_vol->VolumeID == tgt) {
861 mpt_enable_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
865 struct mpt_raid_action_result *ar;
866 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
870 vol_pg = mpt_vol->config_page;
871 enabled = vol_pg->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED;
874 * If the setting matches the configuration,
875 * there is nothing to do.
877 if ((enabled && enable)
878 || (!enabled && !enable))
881 req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
883 mpt_vol_prt(mpt, mpt_vol,
884 "mpt_enable_vol: Get request failed!\n");
888 rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
889 enable ? MPI_RAID_ACTION_ENABLE_VOLUME
890 : MPI_RAID_ACTION_DISABLE_VOLUME,
891 /*data*/0, /*addr*/0, /*len*/0,
892 /*write*/FALSE, /*wait*/TRUE);
893 if (rv == ETIMEDOUT) {
894 mpt_vol_prt(mpt, mpt_vol, "mpt_enable_vol: "
895 "%s Volume Timed-out\n",
896 enable ? "Enable" : "Disable");
899 ar = REQ_TO_RAID_ACTION_RESULT(req);
901 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
902 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
903 mpt_vol_prt(mpt, mpt_vol, "%s Volume Failed: %d:%x:%x\n",
904 enable ? "Enable" : "Disable",
905 rv, req->IOCStatus, ar->action_status);
908 mpt_free_request(mpt, req);
913 mpt_verify_mwce(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
916 struct mpt_raid_action_result *ar;
917 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
923 vol_pg = mpt_vol->config_page;
924 resyncing = vol_pg->VolumeStatus.Flags
925 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS;
926 mwce = vol_pg->VolumeSettings.Settings
927 & MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
930 * If the setting matches the configuration,
931 * there is nothing to do.
933 switch (mpt->raid_mwce_setting) {
934 case MPT_RAID_MWCE_REBUILD_ONLY:
935 if ((resyncing && mwce) || (!resyncing && !mwce)) {
938 mpt_vol->flags ^= MPT_RVF_WCE_CHANGED;
939 if ((mpt_vol->flags & MPT_RVF_WCE_CHANGED) == 0) {
941 * Wait one more status update to see if
942 * resyncing gets enabled. It gets disabled
943 * temporarilly when WCE is changed.
948 case MPT_RAID_MWCE_ON:
952 case MPT_RAID_MWCE_OFF:
956 case MPT_RAID_MWCE_NC:
960 req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
962 mpt_vol_prt(mpt, mpt_vol,
963 "mpt_verify_mwce: Get request failed!\n");
967 vol_pg->VolumeSettings.Settings ^=
968 MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
969 memcpy(&data, &vol_pg->VolumeSettings, sizeof(data));
970 vol_pg->VolumeSettings.Settings ^=
971 MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
972 rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
973 MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS,
974 data, /*addr*/0, /*len*/0,
975 /*write*/FALSE, /*wait*/TRUE);
976 if (rv == ETIMEDOUT) {
977 mpt_vol_prt(mpt, mpt_vol, "mpt_verify_mwce: "
978 "Write Cache Enable Timed-out\n");
981 ar = REQ_TO_RAID_ACTION_RESULT(req);
983 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
984 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
985 mpt_vol_prt(mpt, mpt_vol, "Write Cache Enable Failed: "
986 "%d:%x:%x\n", rv, req->IOCStatus,
989 vol_pg->VolumeSettings.Settings ^=
990 MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
992 mpt_free_request(mpt, req);
996 mpt_verify_resync_rate(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
999 struct mpt_raid_action_result *ar;
1000 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
1004 vol_pg = mpt_vol->config_page;
1006 if (mpt->raid_resync_rate == MPT_RAID_RESYNC_RATE_NC)
1010 * If the current RAID resync rate does not
1011 * match our configured rate, update it.
1013 prio = vol_pg->VolumeSettings.Settings
1014 & MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
1015 if (vol_pg->ResyncRate != 0
1016 && vol_pg->ResyncRate != mpt->raid_resync_rate) {
1018 req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
1020 mpt_vol_prt(mpt, mpt_vol, "mpt_verify_resync_rate: "
1021 "Get request failed!\n");
1025 rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
1026 MPI_RAID_ACTION_SET_RESYNC_RATE,
1027 mpt->raid_resync_rate, /*addr*/0,
1028 /*len*/0, /*write*/FALSE, /*wait*/TRUE);
1029 if (rv == ETIMEDOUT) {
1030 mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_data: "
1031 "Resync Rate Setting Timed-out\n");
1035 ar = REQ_TO_RAID_ACTION_RESULT(req);
1037 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
1038 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
1039 mpt_vol_prt(mpt, mpt_vol, "Resync Rate Setting Failed: "
1040 "%d:%x:%x\n", rv, req->IOCStatus,
1043 vol_pg->ResyncRate = mpt->raid_resync_rate;
1044 mpt_free_request(mpt, req);
1045 } else if ((prio && mpt->raid_resync_rate < 128)
1046 || (!prio && mpt->raid_resync_rate >= 128)) {
1049 req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
1051 mpt_vol_prt(mpt, mpt_vol, "mpt_verify_resync_rate: "
1052 "Get request failed!\n");
1056 vol_pg->VolumeSettings.Settings ^=
1057 MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
1058 memcpy(&data, &vol_pg->VolumeSettings, sizeof(data));
1059 vol_pg->VolumeSettings.Settings ^=
1060 MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
1061 rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
1062 MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS,
1063 data, /*addr*/0, /*len*/0,
1064 /*write*/FALSE, /*wait*/TRUE);
1065 if (rv == ETIMEDOUT) {
1066 mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_data: "
1067 "Resync Rate Setting Timed-out\n");
1070 ar = REQ_TO_RAID_ACTION_RESULT(req);
1072 || REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
1073 || (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
1074 mpt_vol_prt(mpt, mpt_vol, "Resync Rate Setting Failed: "
1075 "%d:%x:%x\n", rv, req->IOCStatus,
1078 vol_pg->VolumeSettings.Settings ^=
1079 MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
1082 mpt_free_request(mpt, req);
1087 mpt_adjust_queue_depth(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
1088 struct cam_path *path)
1090 struct ccb_relsim crs;
1092 xpt_setup_ccb(&crs.ccb_h, path, /*priority*/5);
1093 crs.ccb_h.func_code = XPT_REL_SIMQ;
1094 crs.ccb_h.flags = CAM_DEV_QFREEZE;
1095 crs.release_flags = RELSIM_ADJUST_OPENINGS;
1096 crs.openings = mpt->raid_queue_depth;
1097 xpt_action((union ccb *)&crs);
1098 if (crs.ccb_h.status != CAM_REQ_CMP)
1099 mpt_vol_prt(mpt, mpt_vol, "mpt_adjust_queue_depth failed "
1100 "with CAM status %#x\n", crs.ccb_h.status);
1104 mpt_announce_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
1106 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
1109 vol_pg = mpt_vol->config_page;
1110 mpt_vol_prt(mpt, mpt_vol, "Settings (");
1111 for (i = 1; i <= 0x8000; i <<= 1) {
1112 switch (vol_pg->VolumeSettings.Settings & i) {
1113 case MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE:
1114 mpt_prtc(mpt, " Member-WCE");
1116 case MPI_RAIDVOL0_SETTING_OFFLINE_ON_SMART:
1117 mpt_prtc(mpt, " Offline-On-SMART-Err");
1119 case MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE:
1120 mpt_prtc(mpt, " Hot-Plug-Spares");
1122 case MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC:
1123 mpt_prtc(mpt, " High-Priority-ReSync");
1129 mpt_prtc(mpt, " )\n");
1130 if (vol_pg->VolumeSettings.HotSparePool != 0) {
1131 mpt_vol_prt(mpt, mpt_vol, "Using Spare Pool%s",
1132 powerof2(vol_pg->VolumeSettings.HotSparePool)
1134 for (i = 0; i < 8; i++) {
1138 if ((vol_pg->VolumeSettings.HotSparePool & mask) == 0)
1140 mpt_prtc(mpt, " %d", i);
1142 mpt_prtc(mpt, "\n");
1144 mpt_vol_prt(mpt, mpt_vol, "%d Members:\n", vol_pg->NumPhysDisks);
1145 for (i = 0; i < vol_pg->NumPhysDisks; i++){
1146 struct mpt_raid_disk *mpt_disk;
1147 CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
1148 int pt_bus = cam_sim_bus(mpt->phydisk_sim);
1151 mpt_disk = mpt->raid_disks + vol_pg->PhysDisk[i].PhysDiskNum;
1152 disk_pg = &mpt_disk->config_page;
1154 mpt_prtc(mpt, "(%s:%d:%d:0): ", device_get_nameunit(mpt->dev),
1155 pt_bus, disk_pg->PhysDiskID);
1156 if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM) {
1157 mpt_prtc(mpt, "%s", mpt_disk->member_number == 0?
1158 "Primary" : "Secondary");
1160 mpt_prtc(mpt, "Stripe Position %d",
1161 mpt_disk->member_number);
1163 f = disk_pg->PhysDiskStatus.Flags;
1164 s = disk_pg->PhysDiskStatus.State;
1165 if (f & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC) {
1166 mpt_prtc(mpt, " Out of Sync");
1168 if (f & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED) {
1169 mpt_prtc(mpt, " Quiesced");
1171 if (f & MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME) {
1172 mpt_prtc(mpt, " Inactive");
1174 if (f & MPI_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS) {
1175 mpt_prtc(mpt, " Was Optimal");
1177 if (f & MPI_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS) {
1178 mpt_prtc(mpt, " Was Non-Optimal");
1181 case MPI_PHYSDISK0_STATUS_ONLINE:
1182 mpt_prtc(mpt, " Online");
1184 case MPI_PHYSDISK0_STATUS_MISSING:
1185 mpt_prtc(mpt, " Missing");
1187 case MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE:
1188 mpt_prtc(mpt, " Incompatible");
1190 case MPI_PHYSDISK0_STATUS_FAILED:
1191 mpt_prtc(mpt, " Failed");
1193 case MPI_PHYSDISK0_STATUS_INITIALIZING:
1194 mpt_prtc(mpt, " Initializing");
1196 case MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED:
1197 mpt_prtc(mpt, " Requested Offline");
1199 case MPI_PHYSDISK0_STATUS_FAILED_REQUESTED:
1200 mpt_prtc(mpt, " Requested Failed");
1202 case MPI_PHYSDISK0_STATUS_OTHER_OFFLINE:
1204 mpt_prtc(mpt, " Offline Other (%x)", s);
1207 mpt_prtc(mpt, "\n");
1212 mpt_announce_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk)
1214 CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
1215 int rd_bus = cam_sim_bus(mpt->sim);
1216 int pt_bus = cam_sim_bus(mpt->phydisk_sim);
1219 disk_pg = &mpt_disk->config_page;
1220 mpt_disk_prt(mpt, mpt_disk,
1221 "Physical (%s:%d:%d:0), Pass-thru (%s:%d:%d:0)\n",
1222 device_get_nameunit(mpt->dev), rd_bus,
1223 disk_pg->PhysDiskID, device_get_nameunit(mpt->dev),
1224 pt_bus, (int)(mpt_disk - mpt->raid_disks));
1225 if (disk_pg->PhysDiskSettings.HotSparePool == 0)
1227 mpt_disk_prt(mpt, mpt_disk, "Member of Hot Spare Pool%s",
1228 powerof2(disk_pg->PhysDiskSettings.HotSparePool)
1230 for (i = 0; i < 8; i++) {
1234 if ((disk_pg->PhysDiskSettings.HotSparePool & mask) == 0)
1236 mpt_prtc(mpt, " %d", i);
1238 mpt_prtc(mpt, "\n");
1242 mpt_refresh_raid_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk,
1243 IOC_3_PHYS_DISK *ioc_disk)
1247 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK,
1248 /*PageNumber*/0, ioc_disk->PhysDiskNum,
1249 &mpt_disk->config_page.Header,
1250 /*sleep_ok*/TRUE, /*timeout_ms*/5000);
1252 mpt_prt(mpt, "mpt_refresh_raid_disk: "
1253 "Failed to read RAID Disk Hdr(%d)\n",
1254 ioc_disk->PhysDiskNum);
1257 rv = mpt_read_cur_cfg_page(mpt, ioc_disk->PhysDiskNum,
1258 &mpt_disk->config_page.Header,
1259 sizeof(mpt_disk->config_page),
1260 /*sleep_ok*/TRUE, /*timeout_ms*/5000);
1262 mpt_prt(mpt, "mpt_refresh_raid_disk: "
1263 "Failed to read RAID Disk Page(%d)\n",
1264 ioc_disk->PhysDiskNum);
1265 mpt2host_config_page_raid_phys_disk_0(&mpt_disk->config_page);
1269 mpt_refresh_raid_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
1270 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol)
1272 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
1273 struct mpt_raid_action_result *ar;
1278 vol_pg = mpt_vol->config_page;
1279 mpt_vol->flags &= ~MPT_RVF_UP2DATE;
1281 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 0,
1282 ioc_vol->VolumePageNumber, &vol_pg->Header, TRUE, 5000);
1284 mpt_vol_prt(mpt, mpt_vol,
1285 "mpt_refresh_raid_vol: Failed to read RAID Vol Hdr(%d)\n",
1286 ioc_vol->VolumePageNumber);
1290 rv = mpt_read_cur_cfg_page(mpt, ioc_vol->VolumePageNumber,
1291 &vol_pg->Header, mpt->raid_page0_len, TRUE, 5000);
1293 mpt_vol_prt(mpt, mpt_vol,
1294 "mpt_refresh_raid_vol: Failed to read RAID Vol Page(%d)\n",
1295 ioc_vol->VolumePageNumber);
1298 mpt2host_config_page_raid_vol_0(vol_pg);
1300 mpt_vol->flags |= MPT_RVF_ACTIVE;
1302 /* Update disk entry array data. */
1303 for (i = 0; i < vol_pg->NumPhysDisks; i++) {
1304 struct mpt_raid_disk *mpt_disk;
1305 mpt_disk = mpt->raid_disks + vol_pg->PhysDisk[i].PhysDiskNum;
1306 mpt_disk->volume = mpt_vol;
1307 mpt_disk->member_number = vol_pg->PhysDisk[i].PhysDiskMap;
1308 if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM) {
1309 mpt_disk->member_number--;
1313 if ((vol_pg->VolumeStatus.Flags
1314 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) == 0)
1317 req = mpt_get_request(mpt, TRUE);
1319 mpt_vol_prt(mpt, mpt_vol,
1320 "mpt_refresh_raid_vol: Get request failed!\n");
1323 rv = mpt_issue_raid_req(mpt, mpt_vol, NULL, req,
1324 MPI_RAID_ACTION_INDICATOR_STRUCT, 0, 0, 0, FALSE, TRUE);
1325 if (rv == ETIMEDOUT) {
1326 mpt_vol_prt(mpt, mpt_vol,
1327 "mpt_refresh_raid_vol: Progress Indicator fetch timeout\n");
1328 mpt_free_request(mpt, req);
1332 ar = REQ_TO_RAID_ACTION_RESULT(req);
1334 && ar->action_status == MPI_RAID_ACTION_ASTATUS_SUCCESS
1335 && REQ_IOCSTATUS(req) == MPI_IOCSTATUS_SUCCESS) {
1336 memcpy(&mpt_vol->sync_progress,
1337 &ar->action_data.indicator_struct,
1338 sizeof(mpt_vol->sync_progress));
1339 mpt2host_mpi_raid_vol_indicator(&mpt_vol->sync_progress);
1341 mpt_vol_prt(mpt, mpt_vol,
1342 "mpt_refresh_raid_vol: Progress indicator fetch failed!\n");
1344 mpt_free_request(mpt, req);
1348 * Update in-core information about RAID support. We update any entries
1349 * that didn't previously exists or have been marked as needing to
1350 * be updated by our event handler. Interesting changes are displayed
1354 mpt_refresh_raid_data(struct mpt_softc *mpt)
1356 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol;
1357 CONFIG_PAGE_IOC_2_RAID_VOL *ioc_last_vol;
1358 IOC_3_PHYS_DISK *ioc_disk;
1359 IOC_3_PHYS_DISK *ioc_last_disk;
1360 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
1364 u_int nonopt_volumes;
1366 if (mpt->ioc_page2 == NULL || mpt->ioc_page3 == NULL) {
1371 * Mark all items as unreferenced by the configuration.
1372 * This allows us to find, report, and discard stale
1375 for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++) {
1376 mpt->raid_disks[i].flags &= ~MPT_RDF_REFERENCED;
1378 for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
1379 mpt->raid_volumes[i].flags &= ~MPT_RVF_REFERENCED;
1383 * Get Physical Disk information.
1385 len = mpt->ioc_page3->Header.PageLength * sizeof(uint32_t);
1386 rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
1387 &mpt->ioc_page3->Header, len,
1388 /*sleep_ok*/TRUE, /*timeout_ms*/5000);
1391 "mpt_refresh_raid_data: Failed to read IOC Page 3\n");
1394 mpt2host_config_page_ioc3(mpt->ioc_page3);
1396 ioc_disk = mpt->ioc_page3->PhysDisk;
1397 ioc_last_disk = ioc_disk + mpt->ioc_page3->NumPhysDisks;
1398 for (; ioc_disk != ioc_last_disk; ioc_disk++) {
1399 struct mpt_raid_disk *mpt_disk;
1401 mpt_disk = mpt->raid_disks + ioc_disk->PhysDiskNum;
1402 mpt_disk->flags |= MPT_RDF_REFERENCED;
1403 if ((mpt_disk->flags & (MPT_RDF_ACTIVE|MPT_RDF_UP2DATE))
1404 != (MPT_RDF_ACTIVE|MPT_RDF_UP2DATE)) {
1406 mpt_refresh_raid_disk(mpt, mpt_disk, ioc_disk);
1409 mpt_disk->flags |= MPT_RDF_ACTIVE;
1414 * Refresh volume data.
1416 len = mpt->ioc_page2->Header.PageLength * sizeof(uint32_t);
1417 rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
1418 &mpt->ioc_page2->Header, len,
1419 /*sleep_ok*/TRUE, /*timeout_ms*/5000);
1421 mpt_prt(mpt, "mpt_refresh_raid_data: "
1422 "Failed to read IOC Page 2\n");
1425 mpt2host_config_page_ioc2(mpt->ioc_page2);
1427 ioc_vol = mpt->ioc_page2->RaidVolume;
1428 ioc_last_vol = ioc_vol + mpt->ioc_page2->NumActiveVolumes;
1429 for (;ioc_vol != ioc_last_vol; ioc_vol++) {
1430 struct mpt_raid_volume *mpt_vol;
1432 mpt_vol = mpt->raid_volumes + ioc_vol->VolumePageNumber;
1433 mpt_vol->flags |= MPT_RVF_REFERENCED;
1434 vol_pg = mpt_vol->config_page;
1437 if (((mpt_vol->flags & (MPT_RVF_ACTIVE|MPT_RVF_UP2DATE))
1438 != (MPT_RVF_ACTIVE|MPT_RVF_UP2DATE))
1439 || (vol_pg->VolumeStatus.Flags
1440 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) != 0) {
1442 mpt_refresh_raid_vol(mpt, mpt_vol, ioc_vol);
1444 mpt_vol->flags |= MPT_RVF_ACTIVE;
1448 for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
1449 struct mpt_raid_volume *mpt_vol;
1455 mpt_vol = &mpt->raid_volumes[i];
1457 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0) {
1461 vol_pg = mpt_vol->config_page;
1462 if ((mpt_vol->flags & (MPT_RVF_REFERENCED|MPT_RVF_ANNOUNCED))
1463 == MPT_RVF_ANNOUNCED) {
1464 mpt_vol_prt(mpt, mpt_vol, "No longer configured\n");
1469 if ((mpt_vol->flags & MPT_RVF_ANNOUNCED) == 0) {
1470 mpt_announce_vol(mpt, mpt_vol);
1471 mpt_vol->flags |= MPT_RVF_ANNOUNCED;
1474 if (vol_pg->VolumeStatus.State !=
1475 MPI_RAIDVOL0_STATUS_STATE_OPTIMAL)
1478 if ((mpt_vol->flags & MPT_RVF_UP2DATE) != 0)
1481 mpt_vol->flags |= MPT_RVF_UP2DATE;
1482 mpt_vol_prt(mpt, mpt_vol, "%s - %s\n",
1483 mpt_vol_type(mpt_vol), mpt_vol_state(mpt_vol));
1484 mpt_verify_mwce(mpt, mpt_vol);
1486 if (vol_pg->VolumeStatus.Flags == 0) {
1490 mpt_vol_prt(mpt, mpt_vol, "Status (");
1491 for (m = 1; m <= 0x80; m <<= 1) {
1492 switch (vol_pg->VolumeStatus.Flags & m) {
1493 case MPI_RAIDVOL0_STATUS_FLAG_ENABLED:
1494 mpt_prtc(mpt, " Enabled");
1496 case MPI_RAIDVOL0_STATUS_FLAG_QUIESCED:
1497 mpt_prtc(mpt, " Quiesced");
1499 case MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS:
1500 mpt_prtc(mpt, " Re-Syncing");
1502 case MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE:
1503 mpt_prtc(mpt, " Inactive");
1509 mpt_prtc(mpt, " )\n");
1511 if ((vol_pg->VolumeStatus.Flags
1512 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) == 0)
1515 mpt_verify_resync_rate(mpt, mpt_vol);
1517 left = MPT_U64_2_SCALAR(mpt_vol->sync_progress.BlocksRemaining);
1518 total = MPT_U64_2_SCALAR(mpt_vol->sync_progress.TotalBlocks);
1519 if (vol_pg->ResyncRate != 0) {
1521 prio = ((u_int)vol_pg->ResyncRate * 100000) / 0xFF;
1522 mpt_vol_prt(mpt, mpt_vol, "Rate %d.%d%%\n",
1523 prio / 1000, prio % 1000);
1525 prio = vol_pg->VolumeSettings.Settings
1526 & MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
1527 mpt_vol_prt(mpt, mpt_vol, "%s Priority Re-Sync\n",
1528 prio ? "High" : "Low");
1530 mpt_vol_prt(mpt, mpt_vol, "%ju of %ju "
1531 "blocks remaining\n", (uintmax_t)left,
1534 /* Periodically report on sync progress. */
1535 mpt_schedule_raid_refresh(mpt);
1538 for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++) {
1539 struct mpt_raid_disk *mpt_disk;
1540 CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
1543 mpt_disk = &mpt->raid_disks[i];
1544 disk_pg = &mpt_disk->config_page;
1546 if ((mpt_disk->flags & MPT_RDF_ACTIVE) == 0)
1549 if ((mpt_disk->flags & (MPT_RDF_REFERENCED|MPT_RDF_ANNOUNCED))
1550 == MPT_RDF_ANNOUNCED) {
1551 mpt_disk_prt(mpt, mpt_disk, "No longer configured\n");
1552 mpt_disk->flags = 0;
1557 if ((mpt_disk->flags & MPT_RDF_ANNOUNCED) == 0) {
1559 mpt_announce_disk(mpt, mpt_disk);
1560 mpt_disk->flags |= MPT_RVF_ANNOUNCED;
1563 if ((mpt_disk->flags & MPT_RDF_UP2DATE) != 0)
1566 mpt_disk->flags |= MPT_RDF_UP2DATE;
1567 mpt_disk_prt(mpt, mpt_disk, "%s\n", mpt_disk_state(mpt_disk));
1568 if (disk_pg->PhysDiskStatus.Flags == 0)
1571 mpt_disk_prt(mpt, mpt_disk, "Status (");
1572 for (m = 1; m <= 0x80; m <<= 1) {
1573 switch (disk_pg->PhysDiskStatus.Flags & m) {
1574 case MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC:
1575 mpt_prtc(mpt, " Out-Of-Sync");
1577 case MPI_PHYSDISK0_STATUS_FLAG_QUIESCED:
1578 mpt_prtc(mpt, " Quiesced");
1584 mpt_prtc(mpt, " )\n");
1587 mpt->raid_nonopt_volumes = nonopt_volumes;
1592 mpt_raid_timer(void *arg)
1594 struct mpt_softc *mpt;
1596 mpt = (struct mpt_softc *)arg;
1597 MPT_LOCK_ASSERT(mpt);
1598 mpt_raid_wakeup(mpt);
1602 mpt_schedule_raid_refresh(struct mpt_softc *mpt)
1605 callout_reset(&mpt->raid_timer, MPT_RAID_SYNC_REPORT_INTERVAL,
1606 mpt_raid_timer, mpt);
1610 mpt_raid_free_mem(struct mpt_softc *mpt)
1613 if (mpt->raid_volumes) {
1614 struct mpt_raid_volume *mpt_raid;
1616 for (i = 0; i < mpt->raid_max_volumes; i++) {
1617 mpt_raid = &mpt->raid_volumes[i];
1618 if (mpt_raid->config_page) {
1619 kfree(mpt_raid->config_page, M_DEVBUF);
1620 mpt_raid->config_page = NULL;
1623 kfree(mpt->raid_volumes, M_DEVBUF);
1624 mpt->raid_volumes = NULL;
1626 if (mpt->raid_disks) {
1627 kfree(mpt->raid_disks, M_DEVBUF);
1628 mpt->raid_disks = NULL;
1630 if (mpt->ioc_page2) {
1631 kfree(mpt->ioc_page2, M_DEVBUF);
1632 mpt->ioc_page2 = NULL;
1634 if (mpt->ioc_page3) {
1635 kfree(mpt->ioc_page3, M_DEVBUF);
1636 mpt->ioc_page3 = NULL;
1638 mpt->raid_max_volumes = 0;
1639 mpt->raid_max_disks = 0;
1643 mpt_raid_set_vol_resync_rate(struct mpt_softc *mpt, u_int rate)
1645 struct mpt_raid_volume *mpt_vol;
1647 if ((rate > MPT_RAID_RESYNC_RATE_MAX
1648 || rate < MPT_RAID_RESYNC_RATE_MIN)
1649 && rate != MPT_RAID_RESYNC_RATE_NC)
1653 mpt->raid_resync_rate = rate;
1654 RAID_VOL_FOREACH(mpt, mpt_vol) {
1655 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0) {
1658 mpt_verify_resync_rate(mpt, mpt_vol);
1665 mpt_raid_set_vol_queue_depth(struct mpt_softc *mpt, u_int vol_queue_depth)
1667 struct mpt_raid_volume *mpt_vol;
1669 if (vol_queue_depth > 255 || vol_queue_depth < 1)
1673 mpt->raid_queue_depth = vol_queue_depth;
1674 RAID_VOL_FOREACH(mpt, mpt_vol) {
1675 struct cam_path *path;
1678 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
1681 mpt->raid_rescan = 0;
1683 MPTLOCK_2_CAMLOCK(mpt);
1684 error = xpt_create_path(&path, xpt_periph,
1685 cam_sim_path(mpt->sim),
1686 mpt_vol->config_page->VolumeID,
1688 if (error != CAM_REQ_CMP) {
1689 CAMLOCK_2_MPTLOCK(mpt);
1690 mpt_vol_prt(mpt, mpt_vol, "Unable to allocate path!\n");
1693 mpt_adjust_queue_depth(mpt, mpt_vol, path);
1694 xpt_free_path(path);
1695 CAMLOCK_2_MPTLOCK(mpt);
1702 mpt_raid_set_vol_mwce(struct mpt_softc *mpt, mpt_raid_mwce_t mwce)
1704 struct mpt_raid_volume *mpt_vol;
1705 int force_full_resync;
1708 if (mwce == mpt->raid_mwce_setting) {
1714 * Catch MWCE being left on due to a failed shutdown. Since
1715 * sysctls cannot be set by the loader, we treat the first
1716 * setting of this varible specially and force a full volume
1717 * resync if MWCE is enabled and a resync is in progress.
1719 force_full_resync = 0;
1720 if (mpt->raid_mwce_set == 0
1721 && mpt->raid_mwce_setting == MPT_RAID_MWCE_NC
1722 && mwce == MPT_RAID_MWCE_REBUILD_ONLY)
1723 force_full_resync = 1;
1725 mpt->raid_mwce_setting = mwce;
1726 RAID_VOL_FOREACH(mpt, mpt_vol) {
1727 CONFIG_PAGE_RAID_VOL_0 *vol_pg;
1731 if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
1734 vol_pg = mpt_vol->config_page;
1735 resyncing = vol_pg->VolumeStatus.Flags
1736 & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS;
1737 mwce = vol_pg->VolumeSettings.Settings
1738 & MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
1739 if (force_full_resync && resyncing && mwce) {
1742 * XXX disable/enable volume should force a resync,
1743 * but we'll need to queice, drain, and restart
1746 mpt_vol_prt(mpt, mpt_vol, "WARNING - Unsafe shutdown "
1747 "detected. Suggest full resync.\n");
1749 mpt_verify_mwce(mpt, mpt_vol);
1751 mpt->raid_mwce_set = 1;
1756 static const char *mpt_vol_mwce_strs[] =
1760 "On-During-Rebuild",
1765 mpt_raid_sysctl_vol_member_wce(SYSCTL_HANDLER_ARGS)
1768 struct mpt_softc *mpt;
1774 mpt = (struct mpt_softc *)arg1;
1775 str = mpt_vol_mwce_strs[mpt->raid_mwce_setting];
1776 error = SYSCTL_OUT(req, str, strlen(str) + 1);
1777 if (error || !req->newptr) {
1781 size = req->newlen - req->newidx;
1782 if (size >= sizeof(inbuf)) {
1786 error = SYSCTL_IN(req, inbuf, size);
1791 for (i = 0; i < NUM_ELEMENTS(mpt_vol_mwce_strs); i++) {
1792 if (strcmp(mpt_vol_mwce_strs[i], inbuf) == 0) {
1793 return (mpt_raid_set_vol_mwce(mpt, i));
1800 mpt_raid_sysctl_vol_resync_rate(SYSCTL_HANDLER_ARGS)
1802 struct mpt_softc *mpt;
1803 u_int raid_resync_rate;
1806 mpt = (struct mpt_softc *)arg1;
1807 raid_resync_rate = mpt->raid_resync_rate;
1809 error = sysctl_handle_int(oidp, &raid_resync_rate, 0, req);
1810 if (error || !req->newptr) {
1814 return (mpt_raid_set_vol_resync_rate(mpt, raid_resync_rate));
1818 mpt_raid_sysctl_vol_queue_depth(SYSCTL_HANDLER_ARGS)
1820 struct mpt_softc *mpt;
1821 u_int raid_queue_depth;
1824 mpt = (struct mpt_softc *)arg1;
1825 raid_queue_depth = mpt->raid_queue_depth;
1827 error = sysctl_handle_int(oidp, &raid_queue_depth, 0, req);
1828 if (error || !req->newptr) {
1832 return (mpt_raid_set_vol_queue_depth(mpt, raid_queue_depth));
1836 mpt_raid_sysctl_attach(struct mpt_softc *mpt)
1838 SYSCTL_ADD_PROC(&mpt->mpt_sysctl_ctx,
1839 SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO,
1840 "vol_member_wce", CTLTYPE_STRING | CTLFLAG_RW, mpt, 0,
1841 mpt_raid_sysctl_vol_member_wce, "A",
1842 "volume member WCE(On,Off,On-During-Rebuild,NC)");
1844 SYSCTL_ADD_PROC(&mpt->mpt_sysctl_ctx,
1845 SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO,
1846 "vol_queue_depth", CTLTYPE_INT | CTLFLAG_RW, mpt, 0,
1847 mpt_raid_sysctl_vol_queue_depth, "I",
1848 "default volume queue depth");
1850 SYSCTL_ADD_PROC(&mpt->mpt_sysctl_ctx,
1851 SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO,
1852 "vol_resync_rate", CTLTYPE_INT | CTLFLAG_RW, mpt, 0,
1853 mpt_raid_sysctl_vol_resync_rate, "I",
1854 "volume resync priority (0 == NC, 1 - 255)");
1855 SYSCTL_ADD_UINT(&mpt->mpt_sysctl_ctx,
1856 SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO,
1857 "nonoptimal_volumes", CTLFLAG_RD,
1858 &mpt->raid_nonopt_volumes, 0,
1859 "number of nonoptimal volumes");