2 * Copyright (c) 2008 Yahoo!, Inc.
4 * Written by: John Baldwin <jhb@FreeBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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 * 3. Neither the name of the author nor the names of any co-contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * LSI MPT-Fusion Host Adapter FreeBSD userland interface
32 * $FreeBSD: src/sys/dev/mpt/mpt_user.c,v 1.4 2009/05/20 17:29:21 imp Exp $
35 #include <sys/param.h>
37 #include <sys/errno.h>
38 #include <sys/ioccom.h>
39 #include <sys/device.h>
40 #include <sys/mpt_ioctl.h>
42 #include <dev/disk/mpt/mpt.h>
44 struct mpt_user_raid_action_result {
45 uint32_t volume_status;
46 uint32_t action_data[4];
47 uint16_t action_status;
50 struct mpt_page_memory {
57 static mpt_probe_handler_t mpt_user_probe;
58 static mpt_attach_handler_t mpt_user_attach;
59 static mpt_enable_handler_t mpt_user_enable;
60 static mpt_ready_handler_t mpt_user_ready;
61 static mpt_event_handler_t mpt_user_event;
62 static mpt_reset_handler_t mpt_user_reset;
63 static mpt_detach_handler_t mpt_user_detach;
65 static struct mpt_personality mpt_user_personality = {
67 .probe = mpt_user_probe,
68 .attach = mpt_user_attach,
69 .enable = mpt_user_enable,
70 .ready = mpt_user_ready,
71 .event = mpt_user_event,
72 .reset = mpt_user_reset,
73 .detach = mpt_user_detach,
76 DECLARE_MPT_PERSONALITY(mpt_user, SI_ORDER_SECOND);
78 static mpt_reply_handler_t mpt_user_reply_handler;
80 static int mpt_open(struct dev_open_args *ap);
81 static int mpt_close(struct dev_close_args *ap);
82 static int mpt_ioctl(struct dev_ioctl_args *ap);
84 static struct dev_ops mpt_cdevsw = {
90 static MALLOC_DEFINE(M_MPTUSER, "mpt_user", "Buffers for mpt(4) ioctls");
92 static uint32_t user_handler_id = MPT_HANDLER_ID_NONE;
95 mpt_user_probe(struct mpt_softc *mpt)
98 /* Attach to every controller. */
103 mpt_user_attach(struct mpt_softc *mpt)
105 mpt_handler_t handler;
109 handler.reply_handler = mpt_user_reply_handler;
110 error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
114 mpt_prt(mpt, "Unable to register user handler!\n");
117 unit = device_get_unit(mpt->dev);
118 mpt->cdev = make_dev(&mpt_cdevsw, unit, UID_ROOT, GID_OPERATOR, 0640,
120 if (mpt->cdev == NULL) {
122 mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
127 mpt->cdev->si_drv1 = mpt;
132 mpt_user_enable(struct mpt_softc *mpt)
139 mpt_user_ready(struct mpt_softc *mpt)
144 mpt_user_event(struct mpt_softc *mpt, request_t *req,
145 MSG_EVENT_NOTIFY_REPLY *msg)
148 /* Someday we may want to let a user daemon listen for events? */
153 mpt_user_reset(struct mpt_softc *mpt, int type)
158 mpt_user_detach(struct mpt_softc *mpt)
160 mpt_handler_t handler;
162 /* XXX: do a purge of pending requests? */
163 destroy_dev(mpt->cdev);
166 handler.reply_handler = mpt_user_reply_handler;
167 mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
173 mpt_open(struct dev_open_args *ap)
180 mpt_close(struct dev_close_args *ap)
187 mpt_alloc_buffer(struct mpt_softc *mpt, struct mpt_page_memory *page_mem,
190 struct mpt_map_info mi;
193 page_mem->vaddr = NULL;
195 /* Limit requests to 16M. */
196 if (len > 16 * 1024 * 1024)
198 error = mpt_dma_tag_create(mpt, mpt->parent_dmat, 1, 0,
199 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
200 len, 1, len, 0, &page_mem->tag);
203 error = bus_dmamem_alloc(page_mem->tag, &page_mem->vaddr,
204 BUS_DMA_NOWAIT, &page_mem->map);
206 bus_dma_tag_destroy(page_mem->tag);
210 error = bus_dmamap_load(page_mem->tag, page_mem->map, page_mem->vaddr,
211 len, mpt_map_rquest, &mi, BUS_DMA_NOWAIT);
215 bus_dmamem_free(page_mem->tag, page_mem->vaddr, page_mem->map);
216 bus_dma_tag_destroy(page_mem->tag);
217 page_mem->vaddr = NULL;
220 page_mem->paddr = mi.phys;
225 mpt_free_buffer(struct mpt_page_memory *page_mem)
228 if (page_mem->vaddr == NULL)
230 bus_dmamap_unload(page_mem->tag, page_mem->map);
231 bus_dmamem_free(page_mem->tag, page_mem->vaddr, page_mem->map);
232 bus_dma_tag_destroy(page_mem->tag);
233 page_mem->vaddr = NULL;
237 mpt_user_read_cfg_header(struct mpt_softc *mpt,
238 struct mpt_cfg_page_req *page_req)
245 req = mpt_get_request(mpt, TRUE);
247 mpt_prt(mpt, "mpt_user_read_cfg_header: Get request failed!\n");
251 params.Action = MPI_CONFIG_ACTION_PAGE_HEADER;
252 params.PageVersion = 0;
253 params.PageLength = 0;
254 params.PageNumber = page_req->header.PageNumber;
255 params.PageType = page_req->header.PageType;
256 params.PageAddress = le32toh(page_req->page_address);
257 error = mpt_issue_cfg_req(mpt, req, ¶ms, /*addr*/0, /*len*/0,
261 * Leave the request. Without resetting the chip, it's
262 * still owned by it and we'll just get into trouble
263 * freeing it now. Mark it as abandoned so that if it
264 * shows up later it can be freed.
266 mpt_prt(mpt, "read_cfg_header timed out\n");
270 page_req->ioc_status = htole16(req->IOCStatus);
271 if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) {
272 cfgp = req->req_vbuf;
273 bcopy(&cfgp->Header, &page_req->header,
274 sizeof(page_req->header));
276 mpt_free_request(mpt, req);
281 mpt_user_read_cfg_page(struct mpt_softc *mpt, struct mpt_cfg_page_req *page_req,
282 struct mpt_page_memory *mpt_page)
284 CONFIG_PAGE_HEADER *hdr;
289 req = mpt_get_request(mpt, TRUE);
291 mpt_prt(mpt, "mpt_user_read_cfg_page: Get request failed!\n");
295 hdr = mpt_page->vaddr;
296 params.Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
297 params.PageVersion = hdr->PageVersion;
298 params.PageLength = hdr->PageLength;
299 params.PageNumber = hdr->PageNumber;
300 params.PageType = hdr->PageType & MPI_CONFIG_PAGETYPE_MASK;
301 params.PageAddress = le32toh(page_req->page_address);
302 error = mpt_issue_cfg_req(mpt, req, ¶ms, mpt_page->paddr,
303 le32toh(page_req->len), TRUE, 5000);
305 mpt_prt(mpt, "mpt_user_read_cfg_page timed out\n");
309 page_req->ioc_status = htole16(req->IOCStatus);
310 if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS)
311 bus_dmamap_sync(mpt_page->tag, mpt_page->map,
312 BUS_DMASYNC_POSTREAD);
313 mpt_free_request(mpt, req);
318 mpt_user_read_extcfg_header(struct mpt_softc *mpt,
319 struct mpt_ext_cfg_page_req *ext_page_req)
323 MSG_CONFIG_REPLY *cfgp;
326 req = mpt_get_request(mpt, TRUE);
328 mpt_prt(mpt, "mpt_user_read_extcfg_header: Get request failed!\n");
332 params.Action = MPI_CONFIG_ACTION_PAGE_HEADER;
333 params.PageVersion = ext_page_req->header.PageVersion;
334 params.PageLength = 0;
335 params.PageNumber = ext_page_req->header.PageNumber;
336 params.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
337 params.PageAddress = le32toh(ext_page_req->page_address);
338 params.ExtPageType = ext_page_req->header.ExtPageType;
339 params.ExtPageLength = 0;
340 error = mpt_issue_cfg_req(mpt, req, ¶ms, /*addr*/0, /*len*/0,
344 * Leave the request. Without resetting the chip, it's
345 * still owned by it and we'll just get into trouble
346 * freeing it now. Mark it as abandoned so that if it
347 * shows up later it can be freed.
349 mpt_prt(mpt, "mpt_user_read_extcfg_header timed out\n");
353 ext_page_req->ioc_status = htole16(req->IOCStatus);
354 if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) {
355 cfgp = req->req_vbuf;
356 ext_page_req->header.PageVersion = cfgp->Header.PageVersion;
357 ext_page_req->header.PageNumber = cfgp->Header.PageNumber;
358 ext_page_req->header.PageType = cfgp->Header.PageType;
359 ext_page_req->header.ExtPageLength = cfgp->ExtPageLength;
360 ext_page_req->header.ExtPageType = cfgp->ExtPageType;
362 mpt_free_request(mpt, req);
367 mpt_user_read_extcfg_page(struct mpt_softc *mpt,
368 struct mpt_ext_cfg_page_req *ext_page_req, struct mpt_page_memory *mpt_page)
370 CONFIG_EXTENDED_PAGE_HEADER *hdr;
375 req = mpt_get_request(mpt, TRUE);
377 mpt_prt(mpt, "mpt_user_read_extcfg_page: Get request failed!\n");
381 hdr = mpt_page->vaddr;
382 params.Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
383 params.PageVersion = hdr->PageVersion;
384 params.PageLength = 0;
385 params.PageNumber = hdr->PageNumber;
386 params.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
387 params.PageAddress = le32toh(ext_page_req->page_address);
388 params.ExtPageType = hdr->ExtPageType;
389 params.ExtPageLength = hdr->ExtPageLength;
390 error = mpt_issue_cfg_req(mpt, req, ¶ms, mpt_page->paddr,
391 le32toh(ext_page_req->len), TRUE, 5000);
393 mpt_prt(mpt, "mpt_user_read_extcfg_page timed out\n");
397 ext_page_req->ioc_status = htole16(req->IOCStatus);
398 if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS)
399 bus_dmamap_sync(mpt_page->tag, mpt_page->map,
400 BUS_DMASYNC_POSTREAD);
401 mpt_free_request(mpt, req);
406 mpt_user_write_cfg_page(struct mpt_softc *mpt,
407 struct mpt_cfg_page_req *page_req, struct mpt_page_memory *mpt_page)
409 CONFIG_PAGE_HEADER *hdr;
415 hdr = mpt_page->vaddr;
416 hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK;
417 if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE &&
418 hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) {
419 mpt_prt(mpt, "page type 0x%x not changeable\n",
420 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
426 * We shouldn't mask off other bits here.
428 hdr->PageType &= ~MPI_CONFIG_PAGETYPE_MASK;
431 req = mpt_get_request(mpt, TRUE);
435 bus_dmamap_sync(mpt_page->tag, mpt_page->map, BUS_DMASYNC_PREWRITE);
438 * There isn't any point in restoring stripped out attributes
439 * if you then mask them going down to issue the request.
442 params.Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
443 params.PageVersion = hdr->PageVersion;
444 params.PageLength = hdr->PageLength;
445 params.PageNumber = hdr->PageNumber;
446 params.PageAddress = le32toh(page_req->page_address);
448 /* Restore stripped out attributes */
449 hdr->PageType |= hdr_attr;
450 params.PageType = hdr->PageType & MPI_CONFIG_PAGETYPE_MASK;
452 params.PageType = hdr->PageType;
454 error = mpt_issue_cfg_req(mpt, req, ¶ms, mpt_page->paddr,
455 le32toh(page_req->len), TRUE, 5000);
457 mpt_prt(mpt, "mpt_write_cfg_page timed out\n");
461 page_req->ioc_status = htole16(req->IOCStatus);
462 mpt_free_request(mpt, req);
467 mpt_user_reply_handler(struct mpt_softc *mpt, request_t *req,
468 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
470 MSG_RAID_ACTION_REPLY *reply;
471 struct mpt_user_raid_action_result *res;
476 if (reply_frame != NULL) {
477 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
478 BUS_DMASYNC_POSTREAD);
479 reply = (MSG_RAID_ACTION_REPLY *)reply_frame;
480 req->IOCStatus = le16toh(reply->IOCStatus);
481 res = (struct mpt_user_raid_action_result *)
482 (((uint8_t *)req->req_vbuf) + MPT_RQSL(mpt));
483 res->action_status = reply->ActionStatus;
484 res->volume_status = reply->VolumeStatus;
485 bcopy(&reply->ActionData, res->action_data,
486 sizeof(res->action_data));
489 req->state &= ~REQ_STATE_QUEUED;
490 req->state |= REQ_STATE_DONE;
491 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
493 if ((req->state & REQ_STATE_NEED_WAKEUP) != 0) {
495 } else if ((req->state & REQ_STATE_TIMEDOUT) != 0) {
497 * Whew- we can free this request (late completion)
499 mpt_free_request(mpt, req);
506 * We use the first part of the request buffer after the request frame
507 * to hold the action data and action status from the RAID reply. The
508 * rest of the request buffer is used to hold the buffer for the
512 mpt_user_raid_action(struct mpt_softc *mpt, struct mpt_raid_action *raid_act,
513 struct mpt_page_memory *mpt_page)
516 struct mpt_user_raid_action_result *res;
517 MSG_RAID_ACTION_REQUEST *rap;
521 req = mpt_get_request(mpt, TRUE);
525 memset(rap, 0, sizeof *rap);
526 rap->Action = raid_act->action;
527 rap->ActionDataWord = raid_act->action_data_word;
528 rap->Function = MPI_FUNCTION_RAID_ACTION;
529 rap->VolumeID = raid_act->volume_id;
530 rap->VolumeBus = raid_act->volume_bus;
531 rap->PhysDiskNum = raid_act->phys_disk_num;
532 se = (SGE_SIMPLE32 *)&rap->ActionDataSGE;
533 if (mpt_page->vaddr != NULL && raid_act->len != 0) {
534 bus_dmamap_sync(mpt_page->tag, mpt_page->map,
535 BUS_DMASYNC_PREWRITE);
536 se->Address = htole32(mpt_page->paddr);
537 MPI_pSGE_SET_LENGTH(se, le32toh(raid_act->len));
538 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
539 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
540 MPI_SGE_FLAGS_END_OF_LIST |
541 raid_act->write ? MPI_SGE_FLAGS_HOST_TO_IOC :
542 MPI_SGE_FLAGS_IOC_TO_HOST));
544 se->FlagsLength = htole32(se->FlagsLength);
545 rap->MsgContext = htole32(req->index | user_handler_id);
547 mpt_check_doorbell(mpt);
548 mpt_send_cmd(mpt, req);
550 error = mpt_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, TRUE,
554 * Leave request so it can be cleaned up later.
556 mpt_prt(mpt, "mpt_user_raid_action timed out\n");
560 raid_act->ioc_status = htole16(req->IOCStatus);
561 if ((req->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
562 mpt_free_request(mpt, req);
566 res = (struct mpt_user_raid_action_result *)
567 (((uint8_t *)req->req_vbuf) + MPT_RQSL(mpt));
568 raid_act->volume_status = res->volume_status;
569 raid_act->action_status = res->action_status;
570 bcopy(res->action_data, raid_act->action_data,
571 sizeof(res->action_data));
572 if (mpt_page->vaddr != NULL)
573 bus_dmamap_sync(mpt_page->tag, mpt_page->map,
574 BUS_DMASYNC_POSTREAD);
575 mpt_free_request(mpt, req);
580 #define PTRIN(p) ((void *)(uintptr_t)(p))
581 #define PTROUT(v) ((u_int32_t)(uintptr_t)(v))
585 mpt_ioctl(struct dev_ioctl_args *ap)
587 struct mpt_softc *mpt;
588 struct mpt_cfg_page_req *page_req;
589 struct mpt_ext_cfg_page_req *ext_page_req;
590 struct mpt_raid_action *raid_act;
591 struct mpt_page_memory mpt_page;
593 struct mpt_cfg_page_req32 *page_req32;
594 struct mpt_cfg_page_req page_req_swab;
595 struct mpt_ext_cfg_page_req32 *ext_page_req32;
596 struct mpt_ext_cfg_page_req ext_page_req_swab;
597 struct mpt_raid_action32 *raid_act32;
598 struct mpt_raid_action raid_act_swab;
600 u_long cmd = ap->a_cmd;
601 caddr_t arg = ap->a_data;
602 struct cdev *kdev = ap->a_head.a_dev;
606 page_req = (void *)arg;
607 ext_page_req = (void *)arg;
608 raid_act = (void *)arg;
609 mpt_page.vaddr = NULL;
612 /* Convert 32-bit structs to native ones. */
613 page_req32 = (void *)arg;
614 ext_page_req32 = (void *)arg;
615 raid_act32 = (void *)arg;
617 case MPTIO_READ_CFG_HEADER32:
618 case MPTIO_READ_CFG_PAGE32:
619 case MPTIO_WRITE_CFG_PAGE32:
620 page_req = &page_req_swab;
621 page_req->header = page_req32->header;
622 page_req->page_address = page_req32->page_address;
623 page_req->buf = PTRIN(page_req32->buf);
624 page_req->len = page_req32->len;
625 page_req->ioc_status = page_req32->ioc_status;
627 case MPTIO_READ_EXT_CFG_HEADER32:
628 case MPTIO_READ_EXT_CFG_PAGE32:
629 ext_page_req = &ext_page_req_swab;
630 ext_page_req->header = ext_page_req32->header;
631 ext_page_req->page_address = ext_page_req32->page_address;
632 ext_page_req->buf = PTRIN(ext_page_req32->buf);
633 ext_page_req->len = ext_page_req32->len;
634 ext_page_req->ioc_status = ext_page_req32->ioc_status;
636 case MPTIO_RAID_ACTION32:
637 raid_act = &raid_act_swab;
638 raid_act->action = raid_act32->action;
639 raid_act->volume_bus = raid_act32->volume_bus;
640 raid_act->volume_id = raid_act32->volume_id;
641 raid_act->phys_disk_num = raid_act32->phys_disk_num;
642 raid_act->action_data_word = raid_act32->action_data_word;
643 raid_act->buf = PTRIN(raid_act32->buf);
644 raid_act->len = raid_act32->len;
645 raid_act->volume_status = raid_act32->volume_status;
646 bcopy(raid_act32->action_data, raid_act->action_data,
647 sizeof(raid_act->action_data));
648 raid_act->action_status = raid_act32->action_status;
649 raid_act->ioc_status = raid_act32->ioc_status;
650 raid_act->write = raid_act32->write;
657 case MPTIO_READ_CFG_HEADER32:
659 case MPTIO_READ_CFG_HEADER:
661 error = mpt_user_read_cfg_header(mpt, page_req);
665 case MPTIO_READ_CFG_PAGE32:
667 case MPTIO_READ_CFG_PAGE:
668 error = mpt_alloc_buffer(mpt, &mpt_page, page_req->len);
671 error = copyin(page_req->buf, mpt_page.vaddr,
672 sizeof(CONFIG_PAGE_HEADER));
676 error = mpt_user_read_cfg_page(mpt, page_req, &mpt_page);
680 error = copyout(mpt_page.vaddr, page_req->buf, page_req->len);
683 case MPTIO_READ_EXT_CFG_HEADER32:
685 case MPTIO_READ_EXT_CFG_HEADER:
687 error = mpt_user_read_extcfg_header(mpt, ext_page_req);
691 case MPTIO_READ_EXT_CFG_PAGE32:
693 case MPTIO_READ_EXT_CFG_PAGE:
694 error = mpt_alloc_buffer(mpt, &mpt_page, ext_page_req->len);
697 error = copyin(ext_page_req->buf, mpt_page.vaddr,
698 sizeof(CONFIG_EXTENDED_PAGE_HEADER));
702 error = mpt_user_read_extcfg_page(mpt, ext_page_req, &mpt_page);
706 error = copyout(mpt_page.vaddr, ext_page_req->buf,
710 case MPTIO_WRITE_CFG_PAGE32:
712 case MPTIO_WRITE_CFG_PAGE:
713 error = mpt_alloc_buffer(mpt, &mpt_page, page_req->len);
716 error = copyin(page_req->buf, mpt_page.vaddr, page_req->len);
720 error = mpt_user_write_cfg_page(mpt, page_req, &mpt_page);
724 case MPTIO_RAID_ACTION32:
726 case MPTIO_RAID_ACTION:
727 if (raid_act->buf != NULL) {
728 error = mpt_alloc_buffer(mpt, &mpt_page, raid_act->len);
731 error = copyin(raid_act->buf, mpt_page.vaddr,
737 error = mpt_user_raid_action(mpt, raid_act, &mpt_page);
741 if (raid_act->buf != NULL)
742 error = copyout(mpt_page.vaddr, raid_act->buf,
750 mpt_free_buffer(&mpt_page);
756 /* Convert native structs to 32-bit ones. */
758 case MPTIO_READ_CFG_HEADER32:
759 case MPTIO_READ_CFG_PAGE32:
760 case MPTIO_WRITE_CFG_PAGE32:
761 page_req32->header = page_req->header;
762 page_req32->page_address = page_req->page_address;
763 page_req32->buf = PTROUT(page_req->buf);
764 page_req32->len = page_req->len;
765 page_req32->ioc_status = page_req->ioc_status;
767 case MPTIO_READ_EXT_CFG_HEADER32:
768 case MPTIO_READ_EXT_CFG_PAGE32:
769 ext_page_req32->header = ext_page_req->header;
770 ext_page_req32->page_address = ext_page_req->page_address;
771 ext_page_req32->buf = PTROUT(ext_page_req->buf);
772 ext_page_req32->len = ext_page_req->len;
773 ext_page_req32->ioc_status = ext_page_req->ioc_status;
775 case MPTIO_RAID_ACTION32:
776 raid_act32->action = raid_act->action;
777 raid_act32->volume_bus = raid_act->volume_bus;
778 raid_act32->volume_id = raid_act->volume_id;
779 raid_act32->phys_disk_num = raid_act->phys_disk_num;
780 raid_act32->action_data_word = raid_act->action_data_word;
781 raid_act32->buf = PTROUT(raid_act->buf);
782 raid_act32->len = raid_act->len;
783 raid_act32->volume_status = raid_act->volume_status;
784 bcopy(raid_act->action_data, raid_act32->action_data,
785 sizeof(raid_act->action_data));
786 raid_act32->action_status = raid_act->action_status;
787 raid_act32->ioc_status = raid_act->ioc_status;
788 raid_act32->write = raid_act->write;