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: head/sys/dev/mpt/mpt_user.c 251187 2013-05-31 17:27:44Z delphij $
35 #include <sys/param.h>
37 #include <sys/device.h>
38 #include <sys/errno.h>
39 #include <sys/mpt_ioctl.h>
41 #include <dev/disk/mpt/mpt.h>
43 struct mpt_user_raid_action_result
{
44 uint32_t volume_status
;
45 uint32_t action_data
[4];
46 uint16_t action_status
;
49 struct mpt_page_memory
{
56 static mpt_probe_handler_t mpt_user_probe
;
57 static mpt_attach_handler_t mpt_user_attach
;
58 static mpt_enable_handler_t mpt_user_enable
;
59 static mpt_ready_handler_t mpt_user_ready
;
60 static mpt_event_handler_t mpt_user_event
;
61 static mpt_reset_handler_t mpt_user_reset
;
62 static mpt_detach_handler_t mpt_user_detach
;
64 static struct mpt_personality mpt_user_personality
= {
66 .probe
= mpt_user_probe
,
67 .attach
= mpt_user_attach
,
68 .enable
= mpt_user_enable
,
69 .ready
= mpt_user_ready
,
70 .event
= mpt_user_event
,
71 .reset
= mpt_user_reset
,
72 .detach
= mpt_user_detach
,
75 DECLARE_MPT_PERSONALITY(mpt_user
, SI_ORDER_SECOND
);
77 static mpt_reply_handler_t mpt_user_reply_handler
;
79 static d_open_t mpt_open
;
80 static d_close_t mpt_close
;
81 static d_ioctl_t mpt_ioctl
;
83 static struct dev_ops mpt_ops
= {
84 { "mpt", 0, D_MPSAFE
},
90 static uint32_t user_handler_id
= MPT_HANDLER_ID_NONE
;
93 mpt_user_probe(struct mpt_softc
*mpt
)
96 /* Attach to every controller. */
101 mpt_user_attach(struct mpt_softc
*mpt
)
103 mpt_handler_t handler
;
107 handler
.reply_handler
= mpt_user_reply_handler
;
108 error
= mpt_register_handler(mpt
, MPT_HANDLER_REPLY
, handler
,
112 mpt_prt(mpt
, "Unable to register user handler!\n");
115 unit
= device_get_unit(mpt
->dev
);
116 mpt
->cdev
= make_dev(&mpt_ops
, unit
, UID_ROOT
, GID_OPERATOR
, 0640,
118 if (mpt
->cdev
== NULL
) {
120 mpt_deregister_handler(mpt
, MPT_HANDLER_REPLY
, handler
,
125 mpt
->cdev
->si_drv1
= mpt
;
130 mpt_user_enable(struct mpt_softc
*mpt
)
137 mpt_user_ready(struct mpt_softc
*mpt
)
143 mpt_user_event(struct mpt_softc
*mpt
, request_t
*req
,
144 MSG_EVENT_NOTIFY_REPLY
*msg
)
147 /* Someday we may want to let a user daemon listen for events? */
152 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
| BUS_DMA_COHERENT
, &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 bus_dmamap_sync(mpt_page
->tag
, mpt_page
->map
,
303 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
304 error
= mpt_issue_cfg_req(mpt
, req
, ¶ms
, mpt_page
->paddr
,
305 le32toh(page_req
->len
), TRUE
, 5000);
307 mpt_prt(mpt
, "mpt_user_read_cfg_page timed out\n");
311 page_req
->ioc_status
= htole16(req
->IOCStatus
);
312 if ((req
->IOCStatus
& MPI_IOCSTATUS_MASK
) == MPI_IOCSTATUS_SUCCESS
)
313 bus_dmamap_sync(mpt_page
->tag
, mpt_page
->map
,
314 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
315 mpt_free_request(mpt
, req
);
320 mpt_user_read_extcfg_header(struct mpt_softc
*mpt
,
321 struct mpt_ext_cfg_page_req
*ext_page_req
)
325 MSG_CONFIG_REPLY
*cfgp
;
328 req
= mpt_get_request(mpt
, TRUE
);
330 mpt_prt(mpt
, "mpt_user_read_extcfg_header: Get request failed!\n");
334 params
.Action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
335 params
.PageVersion
= ext_page_req
->header
.PageVersion
;
336 params
.PageLength
= 0;
337 params
.PageNumber
= ext_page_req
->header
.PageNumber
;
338 params
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
339 params
.PageAddress
= le32toh(ext_page_req
->page_address
);
340 params
.ExtPageType
= ext_page_req
->header
.ExtPageType
;
341 params
.ExtPageLength
= 0;
342 error
= mpt_issue_cfg_req(mpt
, req
, ¶ms
, /*addr*/0, /*len*/0,
346 * Leave the request. Without resetting the chip, it's
347 * still owned by it and we'll just get into trouble
348 * freeing it now. Mark it as abandoned so that if it
349 * shows up later it can be freed.
351 mpt_prt(mpt
, "mpt_user_read_extcfg_header timed out\n");
355 ext_page_req
->ioc_status
= htole16(req
->IOCStatus
);
356 if ((req
->IOCStatus
& MPI_IOCSTATUS_MASK
) == MPI_IOCSTATUS_SUCCESS
) {
357 cfgp
= req
->req_vbuf
;
358 ext_page_req
->header
.PageVersion
= cfgp
->Header
.PageVersion
;
359 ext_page_req
->header
.PageNumber
= cfgp
->Header
.PageNumber
;
360 ext_page_req
->header
.PageType
= cfgp
->Header
.PageType
;
361 ext_page_req
->header
.ExtPageLength
= cfgp
->ExtPageLength
;
362 ext_page_req
->header
.ExtPageType
= cfgp
->ExtPageType
;
364 mpt_free_request(mpt
, req
);
369 mpt_user_read_extcfg_page(struct mpt_softc
*mpt
,
370 struct mpt_ext_cfg_page_req
*ext_page_req
, struct mpt_page_memory
*mpt_page
)
372 CONFIG_EXTENDED_PAGE_HEADER
*hdr
;
377 req
= mpt_get_request(mpt
, TRUE
);
379 mpt_prt(mpt
, "mpt_user_read_extcfg_page: Get request failed!\n");
383 hdr
= mpt_page
->vaddr
;
384 params
.Action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
385 params
.PageVersion
= hdr
->PageVersion
;
386 params
.PageLength
= 0;
387 params
.PageNumber
= hdr
->PageNumber
;
388 params
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
389 params
.PageAddress
= le32toh(ext_page_req
->page_address
);
390 params
.ExtPageType
= hdr
->ExtPageType
;
391 params
.ExtPageLength
= hdr
->ExtPageLength
;
392 bus_dmamap_sync(mpt_page
->tag
, mpt_page
->map
,
393 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
394 error
= mpt_issue_cfg_req(mpt
, req
, ¶ms
, mpt_page
->paddr
,
395 le32toh(ext_page_req
->len
), TRUE
, 5000);
397 mpt_prt(mpt
, "mpt_user_read_extcfg_page timed out\n");
401 ext_page_req
->ioc_status
= htole16(req
->IOCStatus
);
402 if ((req
->IOCStatus
& MPI_IOCSTATUS_MASK
) == MPI_IOCSTATUS_SUCCESS
)
403 bus_dmamap_sync(mpt_page
->tag
, mpt_page
->map
,
404 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
405 mpt_free_request(mpt
, req
);
410 mpt_user_write_cfg_page(struct mpt_softc
*mpt
,
411 struct mpt_cfg_page_req
*page_req
, struct mpt_page_memory
*mpt_page
)
413 CONFIG_PAGE_HEADER
*hdr
;
419 hdr
= mpt_page
->vaddr
;
420 hdr_attr
= hdr
->PageType
& MPI_CONFIG_PAGEATTR_MASK
;
421 if (hdr_attr
!= MPI_CONFIG_PAGEATTR_CHANGEABLE
&&
422 hdr_attr
!= MPI_CONFIG_PAGEATTR_PERSISTENT
) {
423 mpt_prt(mpt
, "page type 0x%x not changeable\n",
424 hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
430 * We shouldn't mask off other bits here.
432 hdr
->PageType
&= ~MPI_CONFIG_PAGETYPE_MASK
;
435 req
= mpt_get_request(mpt
, TRUE
);
439 bus_dmamap_sync(mpt_page
->tag
, mpt_page
->map
, BUS_DMASYNC_PREREAD
|
440 BUS_DMASYNC_PREWRITE
);
443 * There isn't any point in restoring stripped out attributes
444 * if you then mask them going down to issue the request.
447 params
.Action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
448 params
.PageVersion
= hdr
->PageVersion
;
449 params
.PageLength
= hdr
->PageLength
;
450 params
.PageNumber
= hdr
->PageNumber
;
451 params
.PageAddress
= le32toh(page_req
->page_address
);
453 /* Restore stripped out attributes */
454 hdr
->PageType
|= hdr_attr
;
455 params
.PageType
= hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
;
457 params
.PageType
= hdr
->PageType
;
459 error
= mpt_issue_cfg_req(mpt
, req
, ¶ms
, mpt_page
->paddr
,
460 le32toh(page_req
->len
), TRUE
, 5000);
462 mpt_prt(mpt
, "mpt_write_cfg_page timed out\n");
466 page_req
->ioc_status
= htole16(req
->IOCStatus
);
467 bus_dmamap_sync(mpt_page
->tag
, mpt_page
->map
, BUS_DMASYNC_POSTREAD
|
468 BUS_DMASYNC_POSTWRITE
);
469 mpt_free_request(mpt
, req
);
474 mpt_user_reply_handler(struct mpt_softc
*mpt
, request_t
*req
,
475 uint32_t reply_desc
, MSG_DEFAULT_REPLY
*reply_frame
)
477 MSG_RAID_ACTION_REPLY
*reply
;
478 struct mpt_user_raid_action_result
*res
;
483 if (reply_frame
!= NULL
) {
484 reply
= (MSG_RAID_ACTION_REPLY
*)reply_frame
;
485 req
->IOCStatus
= le16toh(reply
->IOCStatus
);
486 res
= (struct mpt_user_raid_action_result
*)
487 (((uint8_t *)req
->req_vbuf
) + MPT_RQSL(mpt
));
488 res
->action_status
= reply
->ActionStatus
;
489 res
->volume_status
= reply
->VolumeStatus
;
490 bcopy(&reply
->ActionData
, res
->action_data
,
491 sizeof(res
->action_data
));
494 req
->state
&= ~REQ_STATE_QUEUED
;
495 req
->state
|= REQ_STATE_DONE
;
496 TAILQ_REMOVE(&mpt
->request_pending_list
, req
, links
);
498 if ((req
->state
& REQ_STATE_NEED_WAKEUP
) != 0) {
500 } else if ((req
->state
& REQ_STATE_TIMEDOUT
) != 0) {
502 * Whew- we can free this request (late completion)
504 mpt_free_request(mpt
, req
);
511 * We use the first part of the request buffer after the request frame
512 * to hold the action data and action status from the RAID reply. The
513 * rest of the request buffer is used to hold the buffer for the
517 mpt_user_raid_action(struct mpt_softc
*mpt
, struct mpt_raid_action
*raid_act
,
518 struct mpt_page_memory
*mpt_page
)
521 struct mpt_user_raid_action_result
*res
;
522 MSG_RAID_ACTION_REQUEST
*rap
;
526 req
= mpt_get_request(mpt
, TRUE
);
530 memset(rap
, 0, sizeof *rap
);
531 rap
->Action
= raid_act
->action
;
532 rap
->ActionDataWord
= raid_act
->action_data_word
;
533 rap
->Function
= MPI_FUNCTION_RAID_ACTION
;
534 rap
->VolumeID
= raid_act
->volume_id
;
535 rap
->VolumeBus
= raid_act
->volume_bus
;
536 rap
->PhysDiskNum
= raid_act
->phys_disk_num
;
537 se
= (SGE_SIMPLE32
*)&rap
->ActionDataSGE
;
538 if (mpt_page
->vaddr
!= NULL
&& raid_act
->len
!= 0) {
539 bus_dmamap_sync(mpt_page
->tag
, mpt_page
->map
,
540 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
541 se
->Address
= htole32(mpt_page
->paddr
);
542 MPI_pSGE_SET_LENGTH(se
, le32toh(raid_act
->len
));
543 MPI_pSGE_SET_FLAGS(se
, (MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
544 MPI_SGE_FLAGS_LAST_ELEMENT
| MPI_SGE_FLAGS_END_OF_BUFFER
|
545 MPI_SGE_FLAGS_END_OF_LIST
|
546 (raid_act
->write
? MPI_SGE_FLAGS_HOST_TO_IOC
:
547 MPI_SGE_FLAGS_IOC_TO_HOST
)));
549 se
->FlagsLength
= htole32(se
->FlagsLength
);
550 rap
->MsgContext
= htole32(req
->index
| user_handler_id
);
552 mpt_check_doorbell(mpt
);
553 mpt_send_cmd(mpt
, req
);
555 error
= mpt_wait_req(mpt
, req
, REQ_STATE_DONE
, REQ_STATE_DONE
, TRUE
,
559 * Leave request so it can be cleaned up later.
561 mpt_prt(mpt
, "mpt_user_raid_action timed out\n");
565 raid_act
->ioc_status
= htole16(req
->IOCStatus
);
566 if ((req
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
567 mpt_free_request(mpt
, req
);
571 res
= (struct mpt_user_raid_action_result
*)
572 (((uint8_t *)req
->req_vbuf
) + MPT_RQSL(mpt
));
573 raid_act
->volume_status
= res
->volume_status
;
574 raid_act
->action_status
= res
->action_status
;
575 bcopy(res
->action_data
, raid_act
->action_data
,
576 sizeof(res
->action_data
));
577 if (mpt_page
->vaddr
!= NULL
)
578 bus_dmamap_sync(mpt_page
->tag
, mpt_page
->map
,
579 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
580 mpt_free_request(mpt
, req
);
585 #define PTRIN(p) ((void *)(uintptr_t)(p))
586 #define PTROUT(v) ((u_int32_t)(uintptr_t)(v))
590 mpt_ioctl(struct dev_ioctl_args
*ap
)
592 cdev_t dev
= ap
->a_head
.a_dev
;
593 u_long cmd
= ap
->a_cmd
;
594 caddr_t arg
= ap
->a_data
;
595 struct mpt_softc
*mpt
;
596 struct mpt_cfg_page_req
*page_req
;
597 struct mpt_ext_cfg_page_req
*ext_page_req
;
598 struct mpt_raid_action
*raid_act
;
599 struct mpt_page_memory mpt_page
;
601 struct mpt_cfg_page_req32
*page_req32
;
602 struct mpt_cfg_page_req page_req_swab
;
603 struct mpt_ext_cfg_page_req32
*ext_page_req32
;
604 struct mpt_ext_cfg_page_req ext_page_req_swab
;
605 struct mpt_raid_action32
*raid_act32
;
606 struct mpt_raid_action raid_act_swab
;
611 page_req
= (void *)arg
;
612 ext_page_req
= (void *)arg
;
613 raid_act
= (void *)arg
;
614 mpt_page
.vaddr
= NULL
;
617 /* Convert 32-bit structs to native ones. */
618 page_req32
= (void *)arg
;
619 ext_page_req32
= (void *)arg
;
620 raid_act32
= (void *)arg
;
622 case MPTIO_READ_CFG_HEADER32
:
623 case MPTIO_READ_CFG_PAGE32
:
624 case MPTIO_WRITE_CFG_PAGE32
:
625 page_req
= &page_req_swab
;
626 page_req
->header
= page_req32
->header
;
627 page_req
->page_address
= page_req32
->page_address
;
628 page_req
->buf
= PTRIN(page_req32
->buf
);
629 page_req
->len
= page_req32
->len
;
630 page_req
->ioc_status
= page_req32
->ioc_status
;
632 case MPTIO_READ_EXT_CFG_HEADER32
:
633 case MPTIO_READ_EXT_CFG_PAGE32
:
634 ext_page_req
= &ext_page_req_swab
;
635 ext_page_req
->header
= ext_page_req32
->header
;
636 ext_page_req
->page_address
= ext_page_req32
->page_address
;
637 ext_page_req
->buf
= PTRIN(ext_page_req32
->buf
);
638 ext_page_req
->len
= ext_page_req32
->len
;
639 ext_page_req
->ioc_status
= ext_page_req32
->ioc_status
;
641 case MPTIO_RAID_ACTION32
:
642 raid_act
= &raid_act_swab
;
643 raid_act
->action
= raid_act32
->action
;
644 raid_act
->volume_bus
= raid_act32
->volume_bus
;
645 raid_act
->volume_id
= raid_act32
->volume_id
;
646 raid_act
->phys_disk_num
= raid_act32
->phys_disk_num
;
647 raid_act
->action_data_word
= raid_act32
->action_data_word
;
648 raid_act
->buf
= PTRIN(raid_act32
->buf
);
649 raid_act
->len
= raid_act32
->len
;
650 raid_act
->volume_status
= raid_act32
->volume_status
;
651 bcopy(raid_act32
->action_data
, raid_act
->action_data
,
652 sizeof(raid_act
->action_data
));
653 raid_act
->action_status
= raid_act32
->action_status
;
654 raid_act
->ioc_status
= raid_act32
->ioc_status
;
655 raid_act
->write
= raid_act32
->write
;
662 case MPTIO_READ_CFG_HEADER32
:
664 case MPTIO_READ_CFG_HEADER
:
666 error
= mpt_user_read_cfg_header(mpt
, page_req
);
670 case MPTIO_READ_CFG_PAGE32
:
672 case MPTIO_READ_CFG_PAGE
:
673 error
= mpt_alloc_buffer(mpt
, &mpt_page
, page_req
->len
);
676 error
= copyin(page_req
->buf
, mpt_page
.vaddr
,
677 sizeof(CONFIG_PAGE_HEADER
));
681 error
= mpt_user_read_cfg_page(mpt
, page_req
, &mpt_page
);
685 error
= copyout(mpt_page
.vaddr
, page_req
->buf
, page_req
->len
);
688 case MPTIO_READ_EXT_CFG_HEADER32
:
690 case MPTIO_READ_EXT_CFG_HEADER
:
692 error
= mpt_user_read_extcfg_header(mpt
, ext_page_req
);
696 case MPTIO_READ_EXT_CFG_PAGE32
:
698 case MPTIO_READ_EXT_CFG_PAGE
:
699 error
= mpt_alloc_buffer(mpt
, &mpt_page
, ext_page_req
->len
);
702 error
= copyin(ext_page_req
->buf
, mpt_page
.vaddr
,
703 sizeof(CONFIG_EXTENDED_PAGE_HEADER
));
707 error
= mpt_user_read_extcfg_page(mpt
, ext_page_req
, &mpt_page
);
711 error
= copyout(mpt_page
.vaddr
, ext_page_req
->buf
,
715 case MPTIO_WRITE_CFG_PAGE32
:
717 case MPTIO_WRITE_CFG_PAGE
:
718 error
= mpt_alloc_buffer(mpt
, &mpt_page
, page_req
->len
);
721 error
= copyin(page_req
->buf
, mpt_page
.vaddr
, page_req
->len
);
725 error
= mpt_user_write_cfg_page(mpt
, page_req
, &mpt_page
);
729 case MPTIO_RAID_ACTION32
:
731 case MPTIO_RAID_ACTION
:
732 if (raid_act
->buf
!= NULL
) {
733 error
= mpt_alloc_buffer(mpt
, &mpt_page
, raid_act
->len
);
736 error
= copyin(raid_act
->buf
, mpt_page
.vaddr
,
742 error
= mpt_user_raid_action(mpt
, raid_act
, &mpt_page
);
746 if (raid_act
->buf
!= NULL
)
747 error
= copyout(mpt_page
.vaddr
, raid_act
->buf
,
755 mpt_free_buffer(&mpt_page
);
761 /* Convert native structs to 32-bit ones. */
763 case MPTIO_READ_CFG_HEADER32
:
764 case MPTIO_READ_CFG_PAGE32
:
765 case MPTIO_WRITE_CFG_PAGE32
:
766 page_req32
->header
= page_req
->header
;
767 page_req32
->page_address
= page_req
->page_address
;
768 page_req32
->buf
= PTROUT(page_req
->buf
);
769 page_req32
->len
= page_req
->len
;
770 page_req32
->ioc_status
= page_req
->ioc_status
;
772 case MPTIO_READ_EXT_CFG_HEADER32
:
773 case MPTIO_READ_EXT_CFG_PAGE32
:
774 ext_page_req32
->header
= ext_page_req
->header
;
775 ext_page_req32
->page_address
= ext_page_req
->page_address
;
776 ext_page_req32
->buf
= PTROUT(ext_page_req
->buf
);
777 ext_page_req32
->len
= ext_page_req
->len
;
778 ext_page_req32
->ioc_status
= ext_page_req
->ioc_status
;
780 case MPTIO_RAID_ACTION32
:
781 raid_act32
->action
= raid_act
->action
;
782 raid_act32
->volume_bus
= raid_act
->volume_bus
;
783 raid_act32
->volume_id
= raid_act
->volume_id
;
784 raid_act32
->phys_disk_num
= raid_act
->phys_disk_num
;
785 raid_act32
->action_data_word
= raid_act
->action_data_word
;
786 raid_act32
->buf
= PTROUT(raid_act
->buf
);
787 raid_act32
->len
= raid_act
->len
;
788 raid_act32
->volume_status
= raid_act
->volume_status
;
789 bcopy(raid_act
->action_data
, raid_act32
->action_data
,
790 sizeof(raid_act
->action_data
));
791 raid_act32
->action_status
= raid_act
->action_status
;
792 raid_act32
->ioc_status
= raid_act
->ioc_status
;
793 raid_act32
->write
= raid_act
->write
;