FreeBSD kernel HPTIOP device code
hptiop.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * HighPoint RR3xxx/4xxx RAID Driver for FreeBSD
5 * Copyright (C) 2007-2012 HighPoint Technologies, Inc. All Rights Reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD$");
31
32#include <sys/param.h>
33#include <sys/types.h>
34#include <sys/cons.h>
35#include <sys/time.h>
36#include <sys/systm.h>
37
38#include <sys/stat.h>
39#include <sys/malloc.h>
40#include <sys/conf.h>
41#include <sys/libkern.h>
42#include <sys/kernel.h>
43
44#include <sys/kthread.h>
45#include <sys/mutex.h>
46#include <sys/module.h>
47
48#include <sys/eventhandler.h>
49#include <sys/bus.h>
50#include <sys/taskqueue.h>
51#include <sys/ioccom.h>
52
53#include <machine/resource.h>
54#include <machine/bus.h>
55#include <machine/stdarg.h>
56#include <sys/rman.h>
57
58#include <vm/vm.h>
59#include <vm/pmap.h>
60
61#include <dev/pci/pcireg.h>
62#include <dev/pci/pcivar.h>
63
64
65#include <cam/cam.h>
66#include <cam/cam_ccb.h>
67#include <cam/cam_sim.h>
68#include <cam/cam_xpt_sim.h>
69#include <cam/cam_debug.h>
70#include <cam/cam_periph.h>
71#include <cam/scsi/scsi_all.h>
72#include <cam/scsi/scsi_message.h>
73
74
75#include <dev/hptiop/hptiop.h>
76
77static const char driver_name[] = "hptiop";
78static const char driver_version[] = "v1.9";
79
80static devclass_t hptiop_devclass;
81
82static int hptiop_send_sync_msg(struct hpt_iop_hba *hba,
83 u_int32_t msg, u_int32_t millisec);
84static void hptiop_request_callback_itl(struct hpt_iop_hba *hba,
85 u_int32_t req);
86static void hptiop_request_callback_mv(struct hpt_iop_hba *hba, u_int64_t req);
87static void hptiop_request_callback_mvfrey(struct hpt_iop_hba *hba,
88 u_int32_t req);
89static void hptiop_os_message_callback(struct hpt_iop_hba *hba, u_int32_t msg);
90static int hptiop_do_ioctl_itl(struct hpt_iop_hba *hba,
91 struct hpt_iop_ioctl_param *pParams);
92static int hptiop_do_ioctl_mv(struct hpt_iop_hba *hba,
93 struct hpt_iop_ioctl_param *pParams);
94static int hptiop_do_ioctl_mvfrey(struct hpt_iop_hba *hba,
95 struct hpt_iop_ioctl_param *pParams);
96static int hptiop_rescan_bus(struct hpt_iop_hba *hba);
97static int hptiop_alloc_pci_res_itl(struct hpt_iop_hba *hba);
98static int hptiop_alloc_pci_res_mv(struct hpt_iop_hba *hba);
99static int hptiop_alloc_pci_res_mvfrey(struct hpt_iop_hba *hba);
100static int hptiop_get_config_itl(struct hpt_iop_hba *hba,
101 struct hpt_iop_request_get_config *config);
102static int hptiop_get_config_mv(struct hpt_iop_hba *hba,
103 struct hpt_iop_request_get_config *config);
104static int hptiop_get_config_mvfrey(struct hpt_iop_hba *hba,
105 struct hpt_iop_request_get_config *config);
106static int hptiop_set_config_itl(struct hpt_iop_hba *hba,
107 struct hpt_iop_request_set_config *config);
108static int hptiop_set_config_mv(struct hpt_iop_hba *hba,
109 struct hpt_iop_request_set_config *config);
110static int hptiop_set_config_mvfrey(struct hpt_iop_hba *hba,
111 struct hpt_iop_request_set_config *config);
112static int hptiop_internal_memalloc_mv(struct hpt_iop_hba *hba);
113static int hptiop_internal_memalloc_mvfrey(struct hpt_iop_hba *hba);
114static int hptiop_internal_memfree_itl(struct hpt_iop_hba *hba);
115static int hptiop_internal_memfree_mv(struct hpt_iop_hba *hba);
116static int hptiop_internal_memfree_mvfrey(struct hpt_iop_hba *hba);
117static int hptiop_post_ioctl_command_itl(struct hpt_iop_hba *hba,
118 u_int32_t req32, struct hpt_iop_ioctl_param *pParams);
119static int hptiop_post_ioctl_command_mv(struct hpt_iop_hba *hba,
121 struct hpt_iop_ioctl_param *pParams);
122static int hptiop_post_ioctl_command_mvfrey(struct hpt_iop_hba *hba,
124 struct hpt_iop_ioctl_param *pParams);
125static void hptiop_post_req_itl(struct hpt_iop_hba *hba,
126 struct hpt_iop_srb *srb,
127 bus_dma_segment_t *segs, int nsegs);
128static void hptiop_post_req_mv(struct hpt_iop_hba *hba,
129 struct hpt_iop_srb *srb,
130 bus_dma_segment_t *segs, int nsegs);
131static void hptiop_post_req_mvfrey(struct hpt_iop_hba *hba,
132 struct hpt_iop_srb *srb,
133 bus_dma_segment_t *segs, int nsegs);
134static void hptiop_post_msg_itl(struct hpt_iop_hba *hba, u_int32_t msg);
135static void hptiop_post_msg_mv(struct hpt_iop_hba *hba, u_int32_t msg);
136static void hptiop_post_msg_mvfrey(struct hpt_iop_hba *hba, u_int32_t msg);
137static void hptiop_enable_intr_itl(struct hpt_iop_hba *hba);
138static void hptiop_enable_intr_mv(struct hpt_iop_hba *hba);
139static void hptiop_enable_intr_mvfrey(struct hpt_iop_hba *hba);
140static void hptiop_disable_intr_itl(struct hpt_iop_hba *hba);
141static void hptiop_disable_intr_mv(struct hpt_iop_hba *hba);
142static void hptiop_disable_intr_mvfrey(struct hpt_iop_hba *hba);
143static void hptiop_free_srb(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb);
144static int hptiop_os_query_remove_device(struct hpt_iop_hba *hba, int tid);
145static int hptiop_probe(device_t dev);
146static int hptiop_attach(device_t dev);
147static int hptiop_detach(device_t dev);
148static int hptiop_shutdown(device_t dev);
149static void hptiop_action(struct cam_sim *sim, union ccb *ccb);
150static void hptiop_poll(struct cam_sim *sim);
151static void hptiop_async(void *callback_arg, u_int32_t code,
152 struct cam_path *path, void *arg);
153static void hptiop_pci_intr(void *arg);
154static void hptiop_release_resource(struct hpt_iop_hba *hba);
155static void hptiop_reset_adapter(void *argv);
156static d_open_t hptiop_open;
157static d_close_t hptiop_close;
158static d_ioctl_t hptiop_ioctl;
159
160static struct cdevsw hptiop_cdevsw = {
161 .d_open = hptiop_open,
162 .d_close = hptiop_close,
163 .d_ioctl = hptiop_ioctl,
164 .d_name = driver_name,
165 .d_version = D_VERSION,
166};
167
168#define hba_from_dev(dev) \
169 ((struct hpt_iop_hba *)devclass_get_softc(hptiop_devclass, dev2unit(dev)))
170
171#define BUS_SPACE_WRT4_ITL(offset, value) bus_space_write_4(hba->bar0t,\
172 hba->bar0h, offsetof(struct hpt_iopmu_itl, offset), (value))
173#define BUS_SPACE_RD4_ITL(offset) bus_space_read_4(hba->bar0t,\
174 hba->bar0h, offsetof(struct hpt_iopmu_itl, offset))
175
176#define BUS_SPACE_WRT4_MV0(offset, value) bus_space_write_4(hba->bar0t,\
177 hba->bar0h, offsetof(struct hpt_iopmv_regs, offset), value)
178#define BUS_SPACE_RD4_MV0(offset) bus_space_read_4(hba->bar0t,\
179 hba->bar0h, offsetof(struct hpt_iopmv_regs, offset))
180#define BUS_SPACE_WRT4_MV2(offset, value) bus_space_write_4(hba->bar2t,\
181 hba->bar2h, offsetof(struct hpt_iopmu_mv, offset), value)
182#define BUS_SPACE_RD4_MV2(offset) bus_space_read_4(hba->bar2t,\
183 hba->bar2h, offsetof(struct hpt_iopmu_mv, offset))
184
185#define BUS_SPACE_WRT4_MVFREY2(offset, value) bus_space_write_4(hba->bar2t,\
186 hba->bar2h, offsetof(struct hpt_iopmu_mvfrey, offset), value)
187#define BUS_SPACE_RD4_MVFREY2(offset) bus_space_read_4(hba->bar2t,\
188 hba->bar2h, offsetof(struct hpt_iopmu_mvfrey, offset))
189
190static int hptiop_open(ioctl_dev_t dev, int flags,
191 int devtype, ioctl_thread_t proc)
192{
193 struct hpt_iop_hba *hba = hba_from_dev(dev);
194
195 if (hba==NULL)
196 return ENXIO;
197 if (hba->flag & HPT_IOCTL_FLAG_OPEN)
198 return EBUSY;
200 return 0;
201}
202
203static int hptiop_close(ioctl_dev_t dev, int flags,
204 int devtype, ioctl_thread_t proc)
205{
206 struct hpt_iop_hba *hba = hba_from_dev(dev);
207 hba->flag &= ~(u_int32_t)HPT_IOCTL_FLAG_OPEN;
208 return 0;
209}
210
211static int hptiop_ioctl(ioctl_dev_t dev, u_long cmd, caddr_t data,
212 int flags, ioctl_thread_t proc)
213{
214 int ret = EFAULT;
215 struct hpt_iop_hba *hba = hba_from_dev(dev);
216
217 switch (cmd) {
218 case HPT_DO_IOCONTROL:
219 ret = hba->ops->do_ioctl(hba,
220 (struct hpt_iop_ioctl_param *)data);
221 break;
222 case HPT_SCAN_BUS:
223 ret = hptiop_rescan_bus(hba);
224 break;
225 }
226 return ret;
227}
228
229static u_int64_t hptiop_mv_outbound_read(struct hpt_iop_hba *hba)
230{
231 u_int64_t p;
232 u_int32_t outbound_tail = BUS_SPACE_RD4_MV2(outbound_tail);
233 u_int32_t outbound_head = BUS_SPACE_RD4_MV2(outbound_head);
234
235 if (outbound_tail != outbound_head) {
236 bus_space_read_region_4(hba->bar2t, hba->bar2h,
237 offsetof(struct hpt_iopmu_mv,
238 outbound_q[outbound_tail]),
239 (u_int32_t *)&p, 2);
240
241 outbound_tail++;
242
243 if (outbound_tail == MVIOP_QUEUE_LEN)
244 outbound_tail = 0;
245
246 BUS_SPACE_WRT4_MV2(outbound_tail, outbound_tail);
247 return p;
248 } else
249 return 0;
250}
251
252static void hptiop_mv_inbound_write(u_int64_t p, struct hpt_iop_hba *hba)
253{
254 u_int32_t inbound_head = BUS_SPACE_RD4_MV2(inbound_head);
255 u_int32_t head = inbound_head + 1;
256
257 if (head == MVIOP_QUEUE_LEN)
258 head = 0;
259
260 bus_space_write_region_4(hba->bar2t, hba->bar2h,
261 offsetof(struct hpt_iopmu_mv, inbound_q[inbound_head]),
262 (u_int32_t *)&p, 2);
263 BUS_SPACE_WRT4_MV2(inbound_head, head);
265}
266
267static void hptiop_post_msg_itl(struct hpt_iop_hba *hba, u_int32_t msg)
268{
269 BUS_SPACE_WRT4_ITL(inbound_msgaddr0, msg);
270 BUS_SPACE_RD4_ITL(outbound_intstatus);
271}
272
273static void hptiop_post_msg_mv(struct hpt_iop_hba *hba, u_int32_t msg)
274{
275
276 BUS_SPACE_WRT4_MV2(inbound_msg, msg);
278
279 BUS_SPACE_RD4_MV0(outbound_intmask);
280}
281
282static void hptiop_post_msg_mvfrey(struct hpt_iop_hba *hba, u_int32_t msg)
283{
284 BUS_SPACE_WRT4_MVFREY2(f0_to_cpu_msg_a, msg);
285 BUS_SPACE_RD4_MVFREY2(f0_to_cpu_msg_a);
286}
287
288static int hptiop_wait_ready_itl(struct hpt_iop_hba * hba, u_int32_t millisec)
289{
290 u_int32_t req=0;
291 int i;
292
293 for (i = 0; i < millisec; i++) {
294 req = BUS_SPACE_RD4_ITL(inbound_queue);
295 if (req != IOPMU_QUEUE_EMPTY)
296 break;
297 DELAY(1000);
298 }
299
300 if (req!=IOPMU_QUEUE_EMPTY) {
301 BUS_SPACE_WRT4_ITL(outbound_queue, req);
302 BUS_SPACE_RD4_ITL(outbound_intstatus);
303 return 0;
304 }
305
306 return -1;
307}
308
309static int hptiop_wait_ready_mv(struct hpt_iop_hba * hba, u_int32_t millisec)
310{
312 return -1;
313
314 return 0;
315}
316
317static int hptiop_wait_ready_mvfrey(struct hpt_iop_hba * hba,
318 u_int32_t millisec)
319{
321 return -1;
322
323 return 0;
324}
325
327 u_int32_t index)
328{
329 struct hpt_iop_srb *srb;
330 struct hpt_iop_request_scsi_command *req=NULL;
331 union ccb *ccb;
332 u_int8_t *cdb;
333 u_int32_t result, temp, dxfer;
334 u_int64_t temp64;
335
336 if (index & IOPMU_QUEUE_MASK_HOST_BITS) { /*host req*/
337 if (hba->firmware_version > 0x01020000 ||
338 hba->interface_version > 0x01020000) {
339 srb = hba->srb[index & ~(u_int32_t)
342 req = (struct hpt_iop_request_scsi_command *)srb;
344 result = IOP_RESULT_SUCCESS;
345 else
346 result = req->header.result;
347 } else {
348 srb = hba->srb[index &
349 ~(u_int32_t)IOPMU_QUEUE_ADDR_HOST_BIT];
350 req = (struct hpt_iop_request_scsi_command *)srb;
351 result = req->header.result;
352 }
353 dxfer = req->dataxfer_length;
354 goto srb_complete;
355 }
356
357 /*iop req*/
358 temp = bus_space_read_4(hba->bar0t, hba->bar0h, index +
359 offsetof(struct hpt_iop_request_header, type));
360 result = bus_space_read_4(hba->bar0t, hba->bar0h, index +
361 offsetof(struct hpt_iop_request_header, result));
362 switch(temp) {
364 {
365 temp64 = 0;
366 bus_space_write_region_4(hba->bar0t, hba->bar0h, index +
367 offsetof(struct hpt_iop_request_header, context),
368 (u_int32_t *)&temp64, 2);
369 wakeup((void *)((unsigned long)hba->u.itl.mu + index));
370 break;
371 }
372
374 bus_space_read_region_4(hba->bar0t, hba->bar0h, index +
375 offsetof(struct hpt_iop_request_header, context),
376 (u_int32_t *)&temp64, 2);
377 srb = (struct hpt_iop_srb *)(unsigned long)temp64;
378 dxfer = bus_space_read_4(hba->bar0t, hba->bar0h,
380 dataxfer_length));
381srb_complete:
382 ccb = (union ccb *)srb->ccb;
383 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
384 cdb = ccb->csio.cdb_io.cdb_ptr;
385 else
386 cdb = ccb->csio.cdb_io.cdb_bytes;
387
388 if (cdb[0] == SYNCHRONIZE_CACHE) { /* ??? */
389 ccb->ccb_h.status = CAM_REQ_CMP;
390 goto scsi_done;
391 }
392
393 switch (result) {
395 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
396 case CAM_DIR_IN:
397 bus_dmamap_sync(hba->io_dmat,
398 srb->dma_map, BUS_DMASYNC_POSTREAD);
399 bus_dmamap_unload(hba->io_dmat, srb->dma_map);
400 break;
401 case CAM_DIR_OUT:
402 bus_dmamap_sync(hba->io_dmat,
403 srb->dma_map, BUS_DMASYNC_POSTWRITE);
404 bus_dmamap_unload(hba->io_dmat, srb->dma_map);
405 break;
406 }
407
408 ccb->ccb_h.status = CAM_REQ_CMP;
409 break;
410
412 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
413 break;
414 case IOP_RESULT_BUSY:
415 ccb->ccb_h.status = CAM_BUSY;
416 break;
418 ccb->ccb_h.status = CAM_REQ_INVALID;
419 break;
420 case IOP_RESULT_FAIL:
421 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
422 break;
423 case IOP_RESULT_RESET:
424 ccb->ccb_h.status = CAM_BUSY;
425 break;
427 memset(&ccb->csio.sense_data, 0,
428 sizeof(ccb->csio.sense_data));
429 if (dxfer < ccb->csio.sense_len)
430 ccb->csio.sense_resid = ccb->csio.sense_len -
431 dxfer;
432 else
433 ccb->csio.sense_resid = 0;
434 if (srb->srb_flag & HPT_SRB_FLAG_HIGH_MEM_ACESS) {/*iop*/
435 bus_space_read_region_1(hba->bar0t, hba->bar0h,
437 sg_list), (u_int8_t *)&ccb->csio.sense_data,
438 MIN(dxfer, sizeof(ccb->csio.sense_data)));
439 } else {
440 memcpy(&ccb->csio.sense_data, &req->sg_list,
441 MIN(dxfer, sizeof(ccb->csio.sense_data)));
442 }
443 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
444 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
445 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
446 break;
447 default:
448 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
449 break;
450 }
451scsi_done:
453 BUS_SPACE_WRT4_ITL(outbound_queue, index);
454
455 ccb->csio.resid = ccb->csio.dxfer_len - dxfer;
456
457 hptiop_free_srb(hba, srb);
458 xpt_done(ccb);
459 break;
460 }
461}
462
464{
465 u_int32_t req, temp;
466
467 while ((req = BUS_SPACE_RD4_ITL(outbound_queue)) !=IOPMU_QUEUE_EMPTY) {
470 else {
471 temp = bus_space_read_4(hba->bar0t,
472 hba->bar0h,req +
474 flags));
476 u_int64_t temp64;
477 bus_space_read_region_4(hba->bar0t,
478 hba->bar0h,req +
480 context),
481 (u_int32_t *)&temp64, 2);
482 if (temp64) {
484 } else {
485 temp64 = 1;
486 bus_space_write_region_4(hba->bar0t,
487 hba->bar0h,req +
489 context),
490 (u_int32_t *)&temp64, 2);
491 }
492 } else
494 }
495 }
496}
497
498static int hptiop_intr_itl(struct hpt_iop_hba * hba)
499{
500 u_int32_t status;
501 int ret = 0;
502
503 status = BUS_SPACE_RD4_ITL(outbound_intstatus);
504
505 if (status & IOPMU_OUTBOUND_INT_MSG0) {
506 u_int32_t msg = BUS_SPACE_RD4_ITL(outbound_msgaddr0);
507 KdPrint(("hptiop: received outbound msg %x\n", msg));
508 BUS_SPACE_WRT4_ITL(outbound_intstatus, IOPMU_OUTBOUND_INT_MSG0);
510 ret = 1;
511 }
512
513 if (status & IOPMU_OUTBOUND_INT_POSTQUEUE) {
515 ret = 1;
516 }
517
518 return ret;
519}
520
522 u_int64_t _tag)
523{
524 u_int32_t context = (u_int32_t)_tag;
525
526 if (context & MVIOP_CMD_TYPE_SCSI) {
527 struct hpt_iop_srb *srb;
529 union ccb *ccb;
530 u_int8_t *cdb;
531
532 srb = hba->srb[context >> MVIOP_REQUEST_NUMBER_START_BIT];
533 req = (struct hpt_iop_request_scsi_command *)srb;
534 ccb = (union ccb *)srb->ccb;
535 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
536 cdb = ccb->csio.cdb_io.cdb_ptr;
537 else
538 cdb = ccb->csio.cdb_io.cdb_bytes;
539
540 if (cdb[0] == SYNCHRONIZE_CACHE) { /* ??? */
541 ccb->ccb_h.status = CAM_REQ_CMP;
542 goto scsi_done;
543 }
546
547 switch (req->header.result) {
549 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
550 case CAM_DIR_IN:
551 bus_dmamap_sync(hba->io_dmat,
552 srb->dma_map, BUS_DMASYNC_POSTREAD);
553 bus_dmamap_unload(hba->io_dmat, srb->dma_map);
554 break;
555 case CAM_DIR_OUT:
556 bus_dmamap_sync(hba->io_dmat,
557 srb->dma_map, BUS_DMASYNC_POSTWRITE);
558 bus_dmamap_unload(hba->io_dmat, srb->dma_map);
559 break;
560 }
561 ccb->ccb_h.status = CAM_REQ_CMP;
562 break;
564 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
565 break;
566 case IOP_RESULT_BUSY:
567 ccb->ccb_h.status = CAM_BUSY;
568 break;
570 ccb->ccb_h.status = CAM_REQ_INVALID;
571 break;
572 case IOP_RESULT_FAIL:
573 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
574 break;
575 case IOP_RESULT_RESET:
576 ccb->ccb_h.status = CAM_BUSY;
577 break;
579 memset(&ccb->csio.sense_data, 0,
580 sizeof(ccb->csio.sense_data));
581 if (req->dataxfer_length < ccb->csio.sense_len)
582 ccb->csio.sense_resid = ccb->csio.sense_len -
583 req->dataxfer_length;
584 else
585 ccb->csio.sense_resid = 0;
586 memcpy(&ccb->csio.sense_data, &req->sg_list,
587 MIN(req->dataxfer_length, sizeof(ccb->csio.sense_data)));
588 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
589 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
590 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
591 break;
592 default:
593 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
594 break;
595 }
596scsi_done:
597 ccb->csio.resid = ccb->csio.dxfer_len - req->dataxfer_length;
598
599 hptiop_free_srb(hba, srb);
600 xpt_done(ccb);
601 } else if (context & MVIOP_CMD_TYPE_IOCTL) {
602 struct hpt_iop_request_ioctl_command *req = hba->ctlcfg_ptr;
604 hba->config_done = 1;
605 else
606 hba->config_done = -1;
607 wakeup(req);
608 } else if (context &
611 hba->config_done = 1;
612 else {
613 device_printf(hba->pcidev, "wrong callback type\n");
614 }
615}
616
618 u_int32_t _tag)
619{
620 u_int32_t req_type = _tag & 0xf;
621
622 struct hpt_iop_srb *srb;
624 union ccb *ccb;
625 u_int8_t *cdb;
626
627 switch (req_type) {
630 hba->config_done = 1;
631 break;
632
634 srb = hba->srb[(_tag >> 4) & 0xff];
635 req = (struct hpt_iop_request_scsi_command *)srb;
636
637 ccb = (union ccb *)srb->ccb;
638
639 callout_stop(&srb->timeout);
640
641 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
642 cdb = ccb->csio.cdb_io.cdb_ptr;
643 else
644 cdb = ccb->csio.cdb_io.cdb_bytes;
645
646 if (cdb[0] == SYNCHRONIZE_CACHE) { /* ??? */
647 ccb->ccb_h.status = CAM_REQ_CMP;
648 goto scsi_done;
649 }
650
653
654 switch (req->header.result) {
656 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
657 case CAM_DIR_IN:
658 bus_dmamap_sync(hba->io_dmat,
659 srb->dma_map, BUS_DMASYNC_POSTREAD);
660 bus_dmamap_unload(hba->io_dmat, srb->dma_map);
661 break;
662 case CAM_DIR_OUT:
663 bus_dmamap_sync(hba->io_dmat,
664 srb->dma_map, BUS_DMASYNC_POSTWRITE);
665 bus_dmamap_unload(hba->io_dmat, srb->dma_map);
666 break;
667 }
668 ccb->ccb_h.status = CAM_REQ_CMP;
669 break;
671 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
672 break;
673 case IOP_RESULT_BUSY:
674 ccb->ccb_h.status = CAM_BUSY;
675 break;
677 ccb->ccb_h.status = CAM_REQ_INVALID;
678 break;
679 case IOP_RESULT_FAIL:
680 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
681 break;
682 case IOP_RESULT_RESET:
683 ccb->ccb_h.status = CAM_BUSY;
684 break;
686 memset(&ccb->csio.sense_data, 0,
687 sizeof(ccb->csio.sense_data));
688 if (req->dataxfer_length < ccb->csio.sense_len)
689 ccb->csio.sense_resid = ccb->csio.sense_len -
690 req->dataxfer_length;
691 else
692 ccb->csio.sense_resid = 0;
693 memcpy(&ccb->csio.sense_data, &req->sg_list,
694 MIN(req->dataxfer_length, sizeof(ccb->csio.sense_data)));
695 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
696 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
697 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
698 break;
699 default:
700 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
701 break;
702 }
703scsi_done:
704 ccb->csio.resid = ccb->csio.dxfer_len - req->dataxfer_length;
705
706 hptiop_free_srb(hba, srb);
707 xpt_done(ccb);
708 break;
711 hba->config_done = 1;
712 else
713 hba->config_done = -1;
714 wakeup((struct hpt_iop_request_ioctl_command *)hba->ctlcfg_ptr);
715 break;
716 default:
717 device_printf(hba->pcidev, "wrong callback type\n");
718 break;
719 }
720}
721
723{
724 u_int64_t req;
725
726 while ((req = hptiop_mv_outbound_read(hba))) {
730 }
731 }
732 }
733}
734
735static int hptiop_intr_mv(struct hpt_iop_hba * hba)
736{
737 u_int32_t status;
738 int ret = 0;
739
740 status = BUS_SPACE_RD4_MV0(outbound_doorbell);
741
742 if (status)
743 BUS_SPACE_WRT4_MV0(outbound_doorbell, ~status);
744
745 if (status & MVIOP_MU_OUTBOUND_INT_MSG) {
746 u_int32_t msg = BUS_SPACE_RD4_MV2(outbound_msg);
747 KdPrint(("hptiop: received outbound msg %x\n", msg));
749 ret = 1;
750 }
751
752 if (status & MVIOP_MU_OUTBOUND_INT_POSTQUEUE) {
754 ret = 1;
755 }
756
757 return ret;
758}
759
760static int hptiop_intr_mvfrey(struct hpt_iop_hba * hba)
761{
762 u_int32_t status, _tag, cptr;
763 int ret = 0;
764
765 if (hba->initialized) {
766 BUS_SPACE_WRT4_MVFREY2(pcie_f0_int_enable, 0);
767 }
768
769 status = BUS_SPACE_RD4_MVFREY2(f0_doorbell);
770 if (status) {
771 BUS_SPACE_WRT4_MVFREY2(f0_doorbell, status);
772 if (status & CPU_TO_F0_DRBL_MSG_A_BIT) {
773 u_int32_t msg = BUS_SPACE_RD4_MVFREY2(cpu_to_f0_msg_a);
775 }
776 ret = 1;
777 }
778
779 status = BUS_SPACE_RD4_MVFREY2(isr_cause);
780 if (status) {
781 BUS_SPACE_WRT4_MVFREY2(isr_cause, status);
782 do {
783 cptr = *hba->u.mvfrey.outlist_cptr & 0xff;
784 while (hba->u.mvfrey.outlist_rptr != cptr) {
785 hba->u.mvfrey.outlist_rptr++;
786 if (hba->u.mvfrey.outlist_rptr == hba->u.mvfrey.list_count) {
787 hba->u.mvfrey.outlist_rptr = 0;
788 }
789
790 _tag = hba->u.mvfrey.outlist[hba->u.mvfrey.outlist_rptr].val;
792 ret = 2;
793 }
794 } while (cptr != (*hba->u.mvfrey.outlist_cptr & 0xff));
795 }
796
797 if (hba->initialized) {
798 BUS_SPACE_WRT4_MVFREY2(pcie_f0_int_enable, 0x1010);
799 }
800
801 return ret;
802}
803
805 u_int32_t req32, u_int32_t millisec)
806{
807 u_int32_t i;
808 u_int64_t temp64;
809
810 BUS_SPACE_WRT4_ITL(inbound_queue, req32);
811 BUS_SPACE_RD4_ITL(outbound_intstatus);
812
813 for (i = 0; i < millisec; i++) {
814 hptiop_intr_itl(hba);
815 bus_space_read_region_4(hba->bar0t, hba->bar0h, req32 +
816 offsetof(struct hpt_iop_request_header, context),
817 (u_int32_t *)&temp64, 2);
818 if (temp64)
819 return 0;
820 DELAY(1000);
821 }
822
823 return -1;
824}
825
827 void *req, u_int32_t millisec)
828{
829 u_int32_t i;
830 u_int64_t phy_addr;
831 hba->config_done = 0;
832
833 phy_addr = hba->ctlcfgcmd_phy |
835 ((struct hpt_iop_request_get_config *)req)->header.flags |=
838 hptiop_mv_inbound_write(phy_addr, hba);
839 BUS_SPACE_RD4_MV0(outbound_intmask);
840
841 for (i = 0; i < millisec; i++) {
842 hptiop_intr_mv(hba);
843 if (hba->config_done)
844 return 0;
845 DELAY(1000);
846 }
847 return -1;
848}
849
851 void *req, u_int32_t millisec)
852{
853 u_int32_t i, index;
854 u_int64_t phy_addr;
855 struct hpt_iop_request_header *reqhdr =
856 (struct hpt_iop_request_header *)req;
857
858 hba->config_done = 0;
859
860 phy_addr = hba->ctlcfgcmd_phy;
864 | ((phy_addr >> 16) & 0xffff0000);
865 reqhdr->context = ((phy_addr & 0xffffffff) << 32 )
867
868 hba->u.mvfrey.inlist_wptr++;
869 index = hba->u.mvfrey.inlist_wptr & 0x3fff;
870
871 if (index == hba->u.mvfrey.list_count) {
872 index = 0;
873 hba->u.mvfrey.inlist_wptr &= ~0x3fff;
875 }
876
877 hba->u.mvfrey.inlist[index].addr = phy_addr;
878 hba->u.mvfrey.inlist[index].intrfc_len = (reqhdr->size + 3) / 4;
879
880 BUS_SPACE_WRT4_MVFREY2(inbound_write_ptr, hba->u.mvfrey.inlist_wptr);
881 BUS_SPACE_RD4_MVFREY2(inbound_write_ptr);
882
883 for (i = 0; i < millisec; i++) {
885 if (hba->config_done)
886 return 0;
887 DELAY(1000);
888 }
889 return -1;
890}
891
892static int hptiop_send_sync_msg(struct hpt_iop_hba *hba,
893 u_int32_t msg, u_int32_t millisec)
894{
895 u_int32_t i;
896
897 hba->msg_done = 0;
898 hba->ops->post_msg(hba, msg);
899
900 for (i=0; i<millisec; i++) {
901 hba->ops->iop_intr(hba);
902 if (hba->msg_done)
903 break;
904 DELAY(1000);
905 }
906
907 return hba->msg_done? 0 : -1;
908}
909
910static int hptiop_get_config_itl(struct hpt_iop_hba * hba,
911 struct hpt_iop_request_get_config * config)
912{
913 u_int32_t req32;
914
915 config->header.size = sizeof(struct hpt_iop_request_get_config);
919 config->header.context = 0;
920
921 req32 = BUS_SPACE_RD4_ITL(inbound_queue);
922 if (req32 == IOPMU_QUEUE_EMPTY)
923 return -1;
924
925 bus_space_write_region_4(hba->bar0t, hba->bar0h,
926 req32, (u_int32_t *)config,
927 sizeof(struct hpt_iop_request_header) >> 2);
928
929 if (hptiop_send_sync_request_itl(hba, req32, 20000)) {
930 KdPrint(("hptiop: get config send cmd failed"));
931 return -1;
932 }
933
934 bus_space_read_region_4(hba->bar0t, hba->bar0h,
935 req32, (u_int32_t *)config,
936 sizeof(struct hpt_iop_request_get_config) >> 2);
937
938 BUS_SPACE_WRT4_ITL(outbound_queue, req32);
939
940 return 0;
941}
942
943static int hptiop_get_config_mv(struct hpt_iop_hba * hba,
944 struct hpt_iop_request_get_config * config)
945{
946 struct hpt_iop_request_get_config *req;
947
948 if (!(req = hba->ctlcfg_ptr))
949 return -1;
950
951 req->header.flags = 0;
953 req->header.size = sizeof(struct hpt_iop_request_get_config);
956
957 if (hptiop_send_sync_request_mv(hba, req, 20000)) {
958 KdPrint(("hptiop: get config send cmd failed"));
959 return -1;
960 }
961
962 *config = *req;
963 return 0;
964}
965
966static int hptiop_get_config_mvfrey(struct hpt_iop_hba * hba,
967 struct hpt_iop_request_get_config * config)
968{
969 struct hpt_iop_request_get_config *info = hba->u.mvfrey.config;
970
971 if (info->header.size != sizeof(struct hpt_iop_request_get_config) ||
973 KdPrint(("hptiop: header size %x/%x type %x/%x",
974 info->header.size, (int)sizeof(struct hpt_iop_request_get_config),
976 return -1;
977 }
978
979 config->interface_version = info->interface_version;
980 config->firmware_version = info->firmware_version;
981 config->max_requests = info->max_requests;
982 config->request_size = info->request_size;
983 config->max_sg_count = info->max_sg_count;
985 config->alignment_mask = info->alignment_mask;
986 config->max_devices = info->max_devices;
987 config->sdram_size = info->sdram_size;
988
989 KdPrint(("hptiop: maxreq %x reqsz %x datalen %x maxdev %x sdram %x",
990 config->max_requests, config->request_size,
991 config->data_transfer_length, config->max_devices,
992 config->sdram_size));
993
994 return 0;
995}
996
997static int hptiop_set_config_itl(struct hpt_iop_hba *hba,
998 struct hpt_iop_request_set_config *config)
999{
1000 u_int32_t req32;
1001
1002 req32 = BUS_SPACE_RD4_ITL(inbound_queue);
1003
1004 if (req32 == IOPMU_QUEUE_EMPTY)
1005 return -1;
1006
1007 config->header.size = sizeof(struct hpt_iop_request_set_config);
1011 config->header.context = 0;
1012
1013 bus_space_write_region_4(hba->bar0t, hba->bar0h, req32,
1014 (u_int32_t *)config,
1015 sizeof(struct hpt_iop_request_set_config) >> 2);
1016
1017 if (hptiop_send_sync_request_itl(hba, req32, 20000)) {
1018 KdPrint(("hptiop: set config send cmd failed"));
1019 return -1;
1020 }
1021
1022 BUS_SPACE_WRT4_ITL(outbound_queue, req32);
1023
1024 return 0;
1025}
1026
1027static int hptiop_set_config_mv(struct hpt_iop_hba *hba,
1028 struct hpt_iop_request_set_config *config)
1029{
1030 struct hpt_iop_request_set_config *req;
1031
1032 if (!(req = hba->ctlcfg_ptr))
1033 return -1;
1034
1035 memcpy((u_int8_t *)req + sizeof(struct hpt_iop_request_header),
1036 (u_int8_t *)config + sizeof(struct hpt_iop_request_header),
1037 sizeof(struct hpt_iop_request_set_config) -
1038 sizeof(struct hpt_iop_request_header));
1039
1040 req->header.flags = 0;
1042 req->header.size = sizeof(struct hpt_iop_request_set_config);
1045
1046 if (hptiop_send_sync_request_mv(hba, req, 20000)) {
1047 KdPrint(("hptiop: set config send cmd failed"));
1048 return -1;
1049 }
1050
1051 return 0;
1052}
1053
1055 struct hpt_iop_request_set_config *config)
1056{
1057 struct hpt_iop_request_set_config *req;
1058
1059 if (!(req = hba->ctlcfg_ptr))
1060 return -1;
1061
1062 memcpy((u_int8_t *)req + sizeof(struct hpt_iop_request_header),
1063 (u_int8_t *)config + sizeof(struct hpt_iop_request_header),
1064 sizeof(struct hpt_iop_request_set_config) -
1065 sizeof(struct hpt_iop_request_header));
1066
1068 req->header.size = sizeof(struct hpt_iop_request_set_config);
1070
1071 if (hptiop_send_sync_request_mvfrey(hba, req, 20000)) {
1072 KdPrint(("hptiop: set config send cmd failed"));
1073 return -1;
1074 }
1075
1076 return 0;
1077}
1078
1080 u_int32_t req32,
1081 struct hpt_iop_ioctl_param *pParams)
1082{
1083 u_int64_t temp64;
1085
1086 if ((((pParams->nInBufferSize + 3) & ~3) + pParams->nOutBufferSize) >
1087 (hba->max_request_size -
1089 device_printf(hba->pcidev, "request size beyond max value");
1090 return -1;
1091 }
1092
1094 + pParams->nInBufferSize;
1098 req.header.context = req32 + (u_int64_t)(unsigned long)hba->u.itl.mu;
1100 req.inbuf_size = pParams->nInBufferSize;
1101 req.outbuf_size = pParams->nOutBufferSize;
1102 req.bytes_returned = 0;
1103
1104 bus_space_write_region_4(hba->bar0t, hba->bar0h, req32, (u_int32_t *)&req,
1106
1108
1109 BUS_SPACE_WRT4_ITL(inbound_queue, req32);
1110 BUS_SPACE_RD4_ITL(outbound_intstatus);
1111
1112 bus_space_read_region_4(hba->bar0t, hba->bar0h, req32 +
1114 (u_int32_t *)&temp64, 2);
1115 while (temp64) {
1116 if (hptiop_sleep(hba, (void *)((unsigned long)hba->u.itl.mu + req32),
1117 PPAUSE, "hptctl", HPT_OSM_TIMEOUT)==0)
1118 break;
1120 bus_space_read_region_4(hba->bar0t, hba->bar0h,req32 +
1122 header.context),
1123 (u_int32_t *)&temp64, 2);
1124 }
1125
1127 return 0;
1128}
1129
1130static int hptiop_bus_space_copyin(struct hpt_iop_hba *hba, u_int32_t bus,
1131 void *user, int size)
1132{
1133 unsigned char byte;
1134 int i;
1135
1136 for (i=0; i<size; i++) {
1137 if (copyin((u_int8_t *)user + i, &byte, 1))
1138 return -1;
1139 bus_space_write_1(hba->bar0t, hba->bar0h, bus + i, byte);
1140 }
1141
1142 return 0;
1143}
1144
1145static int hptiop_bus_space_copyout(struct hpt_iop_hba *hba, u_int32_t bus,
1146 void *user, int size)
1147{
1148 unsigned char byte;
1149 int i;
1150
1151 for (i=0; i<size; i++) {
1152 byte = bus_space_read_1(hba->bar0t, hba->bar0h, bus + i);
1153 if (copyout(&byte, (u_int8_t *)user + i, 1))
1154 return -1;
1155 }
1156
1157 return 0;
1158}
1159
1160static int hptiop_do_ioctl_itl(struct hpt_iop_hba *hba,
1161 struct hpt_iop_ioctl_param * pParams)
1162{
1163 u_int32_t req32;
1164 u_int32_t result;
1165
1166 if ((pParams->Magic != HPT_IOCTL_MAGIC) &&
1167 (pParams->Magic != HPT_IOCTL_MAGIC32))
1168 return EFAULT;
1169
1170 req32 = BUS_SPACE_RD4_ITL(inbound_queue);
1171 if (req32 == IOPMU_QUEUE_EMPTY)
1172 return EFAULT;
1173
1174 if (pParams->nInBufferSize)
1175 if (hptiop_bus_space_copyin(hba, req32 +
1177 (void *)pParams->lpInBuffer, pParams->nInBufferSize))
1178 goto invalid;
1179
1180 if (hptiop_post_ioctl_command_itl(hba, req32, pParams))
1181 goto invalid;
1182
1183 result = bus_space_read_4(hba->bar0t, hba->bar0h, req32 +
1185 header.result));
1186
1187 if (result == IOP_RESULT_SUCCESS) {
1188 if (pParams->nOutBufferSize)
1189 if (hptiop_bus_space_copyout(hba, req32 +
1191 ((pParams->nInBufferSize + 3) & ~3),
1192 (void *)pParams->lpOutBuffer, pParams->nOutBufferSize))
1193 goto invalid;
1194
1195 if (pParams->lpBytesReturned) {
1196 if (hptiop_bus_space_copyout(hba, req32 +
1198 (void *)pParams->lpBytesReturned, sizeof(unsigned long)))
1199 goto invalid;
1200 }
1201
1202 BUS_SPACE_WRT4_ITL(outbound_queue, req32);
1203
1204 return 0;
1205 } else{
1206invalid:
1207 BUS_SPACE_WRT4_ITL(outbound_queue, req32);
1208
1209 return EFAULT;
1210 }
1211}
1212
1215 struct hpt_iop_ioctl_param *pParams)
1216{
1217 u_int64_t req_phy;
1218 int size = 0;
1219
1220 if ((((pParams->nInBufferSize + 3) & ~3) + pParams->nOutBufferSize) >
1221 (hba->max_request_size -
1223 device_printf(hba->pcidev, "request size beyond max value");
1224 return -1;
1225 }
1226
1228 req->inbuf_size = pParams->nInBufferSize;
1229 req->outbuf_size = pParams->nOutBufferSize;
1231 + pParams->nInBufferSize;
1232 req->header.context = (u_int64_t)MVIOP_CMD_TYPE_IOCTL;
1236 size = req->header.size >> 8;
1237 size = imin(3, size);
1238 req_phy = hba->ctlcfgcmd_phy | MVIOP_MU_QUEUE_ADDR_HOST_BIT | size;
1239 hptiop_mv_inbound_write(req_phy, hba);
1240
1241 BUS_SPACE_RD4_MV0(outbound_intmask);
1242
1243 while (hba->config_done == 0) {
1244 if (hptiop_sleep(hba, req, PPAUSE,
1245 "hptctl", HPT_OSM_TIMEOUT)==0)
1246 continue;
1248 }
1249 return 0;
1250}
1251
1252static int hptiop_do_ioctl_mv(struct hpt_iop_hba *hba,
1253 struct hpt_iop_ioctl_param *pParams)
1254{
1256
1257 if ((pParams->Magic != HPT_IOCTL_MAGIC) &&
1258 (pParams->Magic != HPT_IOCTL_MAGIC32))
1259 return EFAULT;
1260
1261 req = (struct hpt_iop_request_ioctl_command *)(hba->ctlcfg_ptr);
1262 hba->config_done = 0;
1264 if (pParams->nInBufferSize)
1265 if (copyin((void *)pParams->lpInBuffer,
1266 req->buf, pParams->nInBufferSize))
1267 goto invalid;
1268 if (hptiop_post_ioctl_command_mv(hba, req, pParams))
1269 goto invalid;
1270
1271 if (hba->config_done == 1) {
1272 if (pParams->nOutBufferSize)
1273 if (copyout(req->buf +
1274 ((pParams->nInBufferSize + 3) & ~3),
1275 (void *)pParams->lpOutBuffer,
1276 pParams->nOutBufferSize))
1277 goto invalid;
1278
1279 if (pParams->lpBytesReturned)
1280 if (copyout(&req->bytes_returned,
1281 (void*)pParams->lpBytesReturned,
1282 sizeof(u_int32_t)))
1283 goto invalid;
1285 return 0;
1286 } else{
1287invalid:
1289 return EFAULT;
1290 }
1291}
1292
1295 struct hpt_iop_ioctl_param *pParams)
1296{
1297 u_int64_t phy_addr;
1298 u_int32_t index;
1299
1300 phy_addr = hba->ctlcfgcmd_phy;
1301
1302 if ((((pParams->nInBufferSize + 3) & ~3) + pParams->nOutBufferSize) >
1303 (hba->max_request_size -
1305 device_printf(hba->pcidev, "request size beyond max value");
1306 return -1;
1307 }
1308
1310 req->inbuf_size = pParams->nInBufferSize;
1311 req->outbuf_size = pParams->nOutBufferSize;
1313 + pParams->nInBufferSize;
1314
1317
1321 | ((phy_addr >> 16) & 0xffff0000);
1322 req->header.context = ((phy_addr & 0xffffffff) << 32 )
1324
1325 hba->u.mvfrey.inlist_wptr++;
1326 index = hba->u.mvfrey.inlist_wptr & 0x3fff;
1327
1328 if (index == hba->u.mvfrey.list_count) {
1329 index = 0;
1330 hba->u.mvfrey.inlist_wptr &= ~0x3fff;
1332 }
1333
1334 hba->u.mvfrey.inlist[index].addr = phy_addr;
1335 hba->u.mvfrey.inlist[index].intrfc_len = (req->header.size + 3) / 4;
1336
1337 BUS_SPACE_WRT4_MVFREY2(inbound_write_ptr, hba->u.mvfrey.inlist_wptr);
1338 BUS_SPACE_RD4_MVFREY2(inbound_write_ptr);
1339
1340 while (hba->config_done == 0) {
1341 if (hptiop_sleep(hba, req, PPAUSE,
1342 "hptctl", HPT_OSM_TIMEOUT)==0)
1343 continue;
1345 }
1346 return 0;
1347}
1348
1350 struct hpt_iop_ioctl_param *pParams)
1351{
1353
1354 if ((pParams->Magic != HPT_IOCTL_MAGIC) &&
1355 (pParams->Magic != HPT_IOCTL_MAGIC32))
1356 return EFAULT;
1357
1358 req = (struct hpt_iop_request_ioctl_command *)(hba->ctlcfg_ptr);
1359 hba->config_done = 0;
1361 if (pParams->nInBufferSize)
1362 if (copyin((void *)pParams->lpInBuffer,
1363 req->buf, pParams->nInBufferSize))
1364 goto invalid;
1365 if (hptiop_post_ioctl_command_mvfrey(hba, req, pParams))
1366 goto invalid;
1367
1368 if (hba->config_done == 1) {
1369 if (pParams->nOutBufferSize)
1370 if (copyout(req->buf +
1371 ((pParams->nInBufferSize + 3) & ~3),
1372 (void *)pParams->lpOutBuffer,
1373 pParams->nOutBufferSize))
1374 goto invalid;
1375
1376 if (pParams->lpBytesReturned)
1377 if (copyout(&req->bytes_returned,
1378 (void*)pParams->lpBytesReturned,
1379 sizeof(u_int32_t)))
1380 goto invalid;
1382 return 0;
1383 } else{
1384invalid:
1386 return EFAULT;
1387 }
1388}
1389
1390static int hptiop_rescan_bus(struct hpt_iop_hba * hba)
1391{
1392 union ccb *ccb;
1393
1394 if ((ccb = xpt_alloc_ccb()) == NULL)
1395 return(ENOMEM);
1396 if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(hba->sim),
1397 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1398 xpt_free_ccb(ccb);
1399 return(EIO);
1400 }
1401 xpt_rescan(ccb);
1402 return(0);
1403}
1404
1405static bus_dmamap_callback_t hptiop_map_srb;
1406static bus_dmamap_callback_t hptiop_post_scsi_command;
1407static bus_dmamap_callback_t hptiop_mv_map_ctlcfg;
1408static bus_dmamap_callback_t hptiop_mvfrey_map_ctlcfg;
1409
1411{
1412 hba->bar0_rid = 0x10;
1413 hba->bar0_res = bus_alloc_resource_any(hba->pcidev,
1414 SYS_RES_MEMORY, &hba->bar0_rid, RF_ACTIVE);
1415
1416 if (hba->bar0_res == NULL) {
1417 device_printf(hba->pcidev,
1418 "failed to get iop base adrress.\n");
1419 return -1;
1420 }
1421 hba->bar0t = rman_get_bustag(hba->bar0_res);
1422 hba->bar0h = rman_get_bushandle(hba->bar0_res);
1423 hba->u.itl.mu = (struct hpt_iopmu_itl *)
1424 rman_get_virtual(hba->bar0_res);
1425
1426 if (!hba->u.itl.mu) {
1427 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1428 hba->bar0_rid, hba->bar0_res);
1429 device_printf(hba->pcidev, "alloc mem res failed\n");
1430 return -1;
1431 }
1432
1433 return 0;
1434}
1435
1437{
1438 hba->bar0_rid = 0x10;
1439 hba->bar0_res = bus_alloc_resource_any(hba->pcidev,
1440 SYS_RES_MEMORY, &hba->bar0_rid, RF_ACTIVE);
1441
1442 if (hba->bar0_res == NULL) {
1443 device_printf(hba->pcidev, "failed to get iop bar0.\n");
1444 return -1;
1445 }
1446 hba->bar0t = rman_get_bustag(hba->bar0_res);
1447 hba->bar0h = rman_get_bushandle(hba->bar0_res);
1448 hba->u.mv.regs = (struct hpt_iopmv_regs *)
1449 rman_get_virtual(hba->bar0_res);
1450
1451 if (!hba->u.mv.regs) {
1452 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1453 hba->bar0_rid, hba->bar0_res);
1454 device_printf(hba->pcidev, "alloc bar0 mem res failed\n");
1455 return -1;
1456 }
1457
1458 hba->bar2_rid = 0x18;
1459 hba->bar2_res = bus_alloc_resource_any(hba->pcidev,
1460 SYS_RES_MEMORY, &hba->bar2_rid, RF_ACTIVE);
1461
1462 if (hba->bar2_res == NULL) {
1463 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1464 hba->bar0_rid, hba->bar0_res);
1465 device_printf(hba->pcidev, "failed to get iop bar2.\n");
1466 return -1;
1467 }
1468
1469 hba->bar2t = rman_get_bustag(hba->bar2_res);
1470 hba->bar2h = rman_get_bushandle(hba->bar2_res);
1471 hba->u.mv.mu = (struct hpt_iopmu_mv *)rman_get_virtual(hba->bar2_res);
1472
1473 if (!hba->u.mv.mu) {
1474 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1475 hba->bar0_rid, hba->bar0_res);
1476 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1477 hba->bar2_rid, hba->bar2_res);
1478 device_printf(hba->pcidev, "alloc mem bar2 res failed\n");
1479 return -1;
1480 }
1481
1482 return 0;
1483}
1484
1486{
1487 hba->bar0_rid = 0x10;
1488 hba->bar0_res = bus_alloc_resource_any(hba->pcidev,
1489 SYS_RES_MEMORY, &hba->bar0_rid, RF_ACTIVE);
1490
1491 if (hba->bar0_res == NULL) {
1492 device_printf(hba->pcidev, "failed to get iop bar0.\n");
1493 return -1;
1494 }
1495 hba->bar0t = rman_get_bustag(hba->bar0_res);
1496 hba->bar0h = rman_get_bushandle(hba->bar0_res);
1497 hba->u.mvfrey.config = (struct hpt_iop_request_get_config *)
1498 rman_get_virtual(hba->bar0_res);
1499
1500 if (!hba->u.mvfrey.config) {
1501 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1502 hba->bar0_rid, hba->bar0_res);
1503 device_printf(hba->pcidev, "alloc bar0 mem res failed\n");
1504 return -1;
1505 }
1506
1507 hba->bar2_rid = 0x18;
1508 hba->bar2_res = bus_alloc_resource_any(hba->pcidev,
1509 SYS_RES_MEMORY, &hba->bar2_rid, RF_ACTIVE);
1510
1511 if (hba->bar2_res == NULL) {
1512 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1513 hba->bar0_rid, hba->bar0_res);
1514 device_printf(hba->pcidev, "failed to get iop bar2.\n");
1515 return -1;
1516 }
1517
1518 hba->bar2t = rman_get_bustag(hba->bar2_res);
1519 hba->bar2h = rman_get_bushandle(hba->bar2_res);
1520 hba->u.mvfrey.mu =
1521 (struct hpt_iopmu_mvfrey *)rman_get_virtual(hba->bar2_res);
1522
1523 if (!hba->u.mvfrey.mu) {
1524 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1525 hba->bar0_rid, hba->bar0_res);
1526 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1527 hba->bar2_rid, hba->bar2_res);
1528 device_printf(hba->pcidev, "alloc mem bar2 res failed\n");
1529 return -1;
1530 }
1531
1532 return 0;
1533}
1534
1536{
1537 if (hba->bar0_res)
1538 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1539 hba->bar0_rid, hba->bar0_res);
1540}
1541
1543{
1544 if (hba->bar0_res)
1545 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1546 hba->bar0_rid, hba->bar0_res);
1547 if (hba->bar2_res)
1548 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1549 hba->bar2_rid, hba->bar2_res);
1550}
1551
1553{
1554 if (hba->bar0_res)
1555 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1556 hba->bar0_rid, hba->bar0_res);
1557 if (hba->bar2_res)
1558 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
1559 hba->bar2_rid, hba->bar2_res);
1560}
1561
1563{
1564 if (bus_dma_tag_create(hba->parent_dmat,
1565 1,
1566 0,
1567 BUS_SPACE_MAXADDR_32BIT,
1568 BUS_SPACE_MAXADDR,
1569 NULL, NULL,
1570 0x800 - 0x8,
1571 1,
1572 BUS_SPACE_MAXSIZE_32BIT,
1573 BUS_DMA_ALLOCNOW,
1574 NULL,
1575 NULL,
1576 &hba->ctlcfg_dmat)) {
1577 device_printf(hba->pcidev, "alloc ctlcfg_dmat failed\n");
1578 return -1;
1579 }
1580
1581 if (bus_dmamem_alloc(hba->ctlcfg_dmat, (void **)&hba->ctlcfg_ptr,
1582 BUS_DMA_WAITOK | BUS_DMA_COHERENT,
1583 &hba->ctlcfg_dmamap) != 0) {
1584 device_printf(hba->pcidev,
1585 "bus_dmamem_alloc failed!\n");
1586 bus_dma_tag_destroy(hba->ctlcfg_dmat);
1587 return -1;
1588 }
1589
1590 if (bus_dmamap_load(hba->ctlcfg_dmat,
1591 hba->ctlcfg_dmamap, hba->ctlcfg_ptr,
1593 hptiop_mv_map_ctlcfg, hba, 0)) {
1594 device_printf(hba->pcidev, "bus_dmamap_load failed!\n");
1595 if (hba->ctlcfg_dmat) {
1596 bus_dmamem_free(hba->ctlcfg_dmat,
1597 hba->ctlcfg_ptr, hba->ctlcfg_dmamap);
1598 bus_dma_tag_destroy(hba->ctlcfg_dmat);
1599 }
1600 return -1;
1601 }
1602
1603 return 0;
1604}
1605
1607{
1608 u_int32_t list_count = BUS_SPACE_RD4_MVFREY2(inbound_conf_ctl);
1609
1610 list_count >>= 16;
1611
1612 if (list_count == 0) {
1613 return -1;
1614 }
1615
1616 hba->u.mvfrey.list_count = list_count;
1617 hba->u.mvfrey.internal_mem_size = 0x800
1618 + list_count * sizeof(struct mvfrey_inlist_entry)
1619 + list_count * sizeof(struct mvfrey_outlist_entry)
1620 + sizeof(int);
1621 if (bus_dma_tag_create(hba->parent_dmat,
1622 1,
1623 0,
1624 BUS_SPACE_MAXADDR_32BIT,
1625 BUS_SPACE_MAXADDR,
1626 NULL, NULL,
1628 1,
1629 BUS_SPACE_MAXSIZE_32BIT,
1630 BUS_DMA_ALLOCNOW,
1631 NULL,
1632 NULL,
1633 &hba->ctlcfg_dmat)) {
1634 device_printf(hba->pcidev, "alloc ctlcfg_dmat failed\n");
1635 return -1;
1636 }
1637
1638 if (bus_dmamem_alloc(hba->ctlcfg_dmat, (void **)&hba->ctlcfg_ptr,
1639 BUS_DMA_WAITOK | BUS_DMA_COHERENT,
1640 &hba->ctlcfg_dmamap) != 0) {
1641 device_printf(hba->pcidev,
1642 "bus_dmamem_alloc failed!\n");
1643 bus_dma_tag_destroy(hba->ctlcfg_dmat);
1644 return -1;
1645 }
1646
1647 if (bus_dmamap_load(hba->ctlcfg_dmat,
1648 hba->ctlcfg_dmamap, hba->ctlcfg_ptr,
1650 hptiop_mvfrey_map_ctlcfg, hba, 0)) {
1651 device_printf(hba->pcidev, "bus_dmamap_load failed!\n");
1652 if (hba->ctlcfg_dmat) {
1653 bus_dmamem_free(hba->ctlcfg_dmat,
1654 hba->ctlcfg_ptr, hba->ctlcfg_dmamap);
1655 bus_dma_tag_destroy(hba->ctlcfg_dmat);
1656 }
1657 return -1;
1658 }
1659
1660 return 0;
1661}
1662
1664 return 0;
1665}
1666
1668{
1669 if (hba->ctlcfg_dmat) {
1670 bus_dmamap_unload(hba->ctlcfg_dmat, hba->ctlcfg_dmamap);
1671 bus_dmamem_free(hba->ctlcfg_dmat,
1672 hba->ctlcfg_ptr, hba->ctlcfg_dmamap);
1673 bus_dma_tag_destroy(hba->ctlcfg_dmat);
1674 }
1675
1676 return 0;
1677}
1678
1680{
1681 if (hba->ctlcfg_dmat) {
1682 bus_dmamap_unload(hba->ctlcfg_dmat, hba->ctlcfg_dmamap);
1683 bus_dmamem_free(hba->ctlcfg_dmat,
1684 hba->ctlcfg_ptr, hba->ctlcfg_dmamap);
1685 bus_dma_tag_destroy(hba->ctlcfg_dmat);
1686 }
1687
1688 return 0;
1689}
1690
1692{
1693 u_int32_t i = 100;
1694
1696 return -1;
1697
1698 /* wait 100ms for MCU ready */
1699 while(i--) {
1700 DELAY(1000);
1701 }
1702
1703 BUS_SPACE_WRT4_MVFREY2(inbound_base,
1704 hba->u.mvfrey.inlist_phy & 0xffffffff);
1705 BUS_SPACE_WRT4_MVFREY2(inbound_base_high,
1706 (hba->u.mvfrey.inlist_phy >> 16) >> 16);
1707
1708 BUS_SPACE_WRT4_MVFREY2(outbound_base,
1709 hba->u.mvfrey.outlist_phy & 0xffffffff);
1710 BUS_SPACE_WRT4_MVFREY2(outbound_base_high,
1711 (hba->u.mvfrey.outlist_phy >> 16) >> 16);
1712
1713 BUS_SPACE_WRT4_MVFREY2(outbound_shadow_base,
1714 hba->u.mvfrey.outlist_cptr_phy & 0xffffffff);
1715 BUS_SPACE_WRT4_MVFREY2(outbound_shadow_base_high,
1716 (hba->u.mvfrey.outlist_cptr_phy >> 16) >> 16);
1717
1718 hba->u.mvfrey.inlist_wptr = (hba->u.mvfrey.list_count - 1)
1720 *hba->u.mvfrey.outlist_cptr = (hba->u.mvfrey.list_count - 1)
1722 hba->u.mvfrey.outlist_rptr = hba->u.mvfrey.list_count - 1;
1723
1724 return 0;
1725}
1726
1727/*
1728 * CAM driver interface
1729 */
1730static device_method_t driver_methods[] = {
1731 /* Device interface */
1732 DEVMETHOD(device_probe, hptiop_probe),
1733 DEVMETHOD(device_attach, hptiop_attach),
1734 DEVMETHOD(device_detach, hptiop_detach),
1735 DEVMETHOD(device_shutdown, hptiop_shutdown),
1736 { 0, 0 }
1737};
1738
1741 .iop_wait_ready = hptiop_wait_ready_itl,
1742 .internal_memalloc = 0,
1743 .internal_memfree = hptiop_internal_memfree_itl,
1744 .alloc_pci_res = hptiop_alloc_pci_res_itl,
1745 .release_pci_res = hptiop_release_pci_res_itl,
1746 .enable_intr = hptiop_enable_intr_itl,
1747 .disable_intr = hptiop_disable_intr_itl,
1748 .get_config = hptiop_get_config_itl,
1749 .set_config = hptiop_set_config_itl,
1750 .iop_intr = hptiop_intr_itl,
1751 .post_msg = hptiop_post_msg_itl,
1752 .post_req = hptiop_post_req_itl,
1753 .do_ioctl = hptiop_do_ioctl_itl,
1754 .reset_comm = 0,
1755};
1756
1759 .iop_wait_ready = hptiop_wait_ready_mv,
1760 .internal_memalloc = hptiop_internal_memalloc_mv,
1761 .internal_memfree = hptiop_internal_memfree_mv,
1762 .alloc_pci_res = hptiop_alloc_pci_res_mv,
1763 .release_pci_res = hptiop_release_pci_res_mv,
1764 .enable_intr = hptiop_enable_intr_mv,
1765 .disable_intr = hptiop_disable_intr_mv,
1766 .get_config = hptiop_get_config_mv,
1767 .set_config = hptiop_set_config_mv,
1768 .iop_intr = hptiop_intr_mv,
1769 .post_msg = hptiop_post_msg_mv,
1770 .post_req = hptiop_post_req_mv,
1771 .do_ioctl = hptiop_do_ioctl_mv,
1772 .reset_comm = 0,
1773};
1774
1777 .iop_wait_ready = hptiop_wait_ready_mvfrey,
1778 .internal_memalloc = hptiop_internal_memalloc_mvfrey,
1779 .internal_memfree = hptiop_internal_memfree_mvfrey,
1780 .alloc_pci_res = hptiop_alloc_pci_res_mvfrey,
1781 .release_pci_res = hptiop_release_pci_res_mvfrey,
1782 .enable_intr = hptiop_enable_intr_mvfrey,
1783 .disable_intr = hptiop_disable_intr_mvfrey,
1784 .get_config = hptiop_get_config_mvfrey,
1785 .set_config = hptiop_set_config_mvfrey,
1786 .iop_intr = hptiop_intr_mvfrey,
1787 .post_msg = hptiop_post_msg_mvfrey,
1788 .post_req = hptiop_post_req_mvfrey,
1789 .do_ioctl = hptiop_do_ioctl_mvfrey,
1790 .reset_comm = hptiop_reset_comm_mvfrey,
1791};
1792
1793static driver_t hptiop_pci_driver = {
1796 sizeof(struct hpt_iop_hba)
1797};
1798
1800MODULE_DEPEND(hptiop, cam, 1, 1, 1);
1801
1802static int hptiop_probe(device_t dev)
1803{
1804 struct hpt_iop_hba *hba;
1805 u_int32_t id;
1806 static char buf[256];
1807 int sas = 0;
1808 struct hptiop_adapter_ops *ops;
1809
1810 if (pci_get_vendor(dev) != 0x1103)
1811 return (ENXIO);
1812
1813 id = pci_get_device(dev);
1814
1815 switch (id) {
1816 case 0x4520:
1817 case 0x4521:
1818 case 0x4522:
1819 sas = 1;
1820 case 0x3620:
1821 case 0x3622:
1822 case 0x3640:
1823 ops = &hptiop_mvfrey_ops;
1824 break;
1825 case 0x4210:
1826 case 0x4211:
1827 case 0x4310:
1828 case 0x4311:
1829 case 0x4320:
1830 case 0x4321:
1831 case 0x4322:
1832 sas = 1;
1833 case 0x3220:
1834 case 0x3320:
1835 case 0x3410:
1836 case 0x3520:
1837 case 0x3510:
1838 case 0x3511:
1839 case 0x3521:
1840 case 0x3522:
1841 case 0x3530:
1842 case 0x3540:
1843 case 0x3560:
1844 ops = &hptiop_itl_ops;
1845 break;
1846 case 0x3020:
1847 case 0x3120:
1848 case 0x3122:
1849 ops = &hptiop_mv_ops;
1850 break;
1851 default:
1852 return (ENXIO);
1853 }
1854
1855 device_printf(dev, "adapter at PCI %d:%d:%d, IRQ %d\n",
1856 pci_get_bus(dev), pci_get_slot(dev),
1857 pci_get_function(dev), pci_get_irq(dev));
1858
1859 sprintf(buf, "RocketRAID %x %s Controller\n",
1860 id, sas ? "SAS" : "SATA");
1861 device_set_desc_copy(dev, buf);
1862
1863 hba = (struct hpt_iop_hba *)device_get_softc(dev);
1864 bzero(hba, sizeof(struct hpt_iop_hba));
1865 hba->ops = ops;
1866
1867 KdPrint(("hba->ops=%p\n", hba->ops));
1868 return 0;
1869}
1870
1871static int hptiop_attach(device_t dev)
1872{
1873 struct hpt_iop_hba *hba = (struct hpt_iop_hba *)device_get_softc(dev);
1874 struct hpt_iop_request_get_config iop_config;
1875 struct hpt_iop_request_set_config set_config;
1876 int rid = 0;
1877 struct cam_devq *devq;
1878 struct ccb_setasync ccb;
1879 u_int32_t unit = device_get_unit(dev);
1880
1881 device_printf(dev, "%d RocketRAID 3xxx/4xxx controller driver %s\n",
1882 unit, driver_version);
1883
1884 KdPrint(("hptiop: attach(%d, %d/%d/%d) ops=%p\n", unit,
1885 pci_get_bus(dev), pci_get_slot(dev),
1886 pci_get_function(dev), hba->ops));
1887
1888 pci_enable_busmaster(dev);
1889 hba->pcidev = dev;
1890 hba->pciunit = unit;
1891
1892 if (hba->ops->alloc_pci_res(hba))
1893 return ENXIO;
1894
1895 if (hba->ops->iop_wait_ready(hba, 2000)) {
1896 device_printf(dev, "adapter is not ready\n");
1897 goto release_pci_res;
1898 }
1899
1900 mtx_init(&hba->lock, "hptioplock", NULL, MTX_DEF);
1901
1902 if (bus_dma_tag_create(bus_get_dma_tag(dev),/* PCI parent */
1903 1, /* alignment */
1904 0, /* boundary */
1905 BUS_SPACE_MAXADDR, /* lowaddr */
1906 BUS_SPACE_MAXADDR, /* highaddr */
1907 NULL, NULL, /* filter, filterarg */
1908 BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
1909 BUS_SPACE_UNRESTRICTED, /* nsegments */
1910 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
1911 0, /* flags */
1912 NULL, /* lockfunc */
1913 NULL, /* lockfuncarg */
1914 &hba->parent_dmat /* tag */))
1915 {
1916 device_printf(dev, "alloc parent_dmat failed\n");
1917 goto release_pci_res;
1918 }
1919
1920 if (hba->ops->family == MV_BASED_IOP) {
1921 if (hba->ops->internal_memalloc(hba)) {
1922 device_printf(dev, "alloc srb_dmat failed\n");
1923 goto destroy_parent_tag;
1924 }
1925 }
1926
1927 if (hba->ops->get_config(hba, &iop_config)) {
1928 device_printf(dev, "get iop config failed.\n");
1929 goto get_config_failed;
1930 }
1931
1932 hba->firmware_version = iop_config.firmware_version;
1933 hba->interface_version = iop_config.interface_version;
1934 hba->max_requests = iop_config.max_requests;
1935 hba->max_devices = iop_config.max_devices;
1936 hba->max_request_size = iop_config.request_size;
1937 hba->max_sg_count = iop_config.max_sg_count;
1938
1939 if (hba->ops->family == MVFREY_BASED_IOP) {
1940 if (hba->ops->internal_memalloc(hba)) {
1941 device_printf(dev, "alloc srb_dmat failed\n");
1942 goto destroy_parent_tag;
1943 }
1944 if (hba->ops->reset_comm(hba)) {
1945 device_printf(dev, "reset comm failed\n");
1946 goto get_config_failed;
1947 }
1948 }
1949
1950 if (bus_dma_tag_create(hba->parent_dmat,/* parent */
1951 4, /* alignment */
1952 BUS_SPACE_MAXADDR_32BIT+1, /* boundary */
1953 BUS_SPACE_MAXADDR, /* lowaddr */
1954 BUS_SPACE_MAXADDR, /* highaddr */
1955 NULL, NULL, /* filter, filterarg */
1956 PAGE_SIZE * (hba->max_sg_count-1), /* maxsize */
1957 hba->max_sg_count, /* nsegments */
1958 0x20000, /* maxsegsize */
1959 BUS_DMA_ALLOCNOW, /* flags */
1960 busdma_lock_mutex, /* lockfunc */
1961 &hba->lock, /* lockfuncarg */
1962 &hba->io_dmat /* tag */))
1963 {
1964 device_printf(dev, "alloc io_dmat failed\n");
1965 goto get_config_failed;
1966 }
1967
1968 if (bus_dma_tag_create(hba->parent_dmat,/* parent */
1969 1, /* alignment */
1970 0, /* boundary */
1971 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
1972 BUS_SPACE_MAXADDR, /* highaddr */
1973 NULL, NULL, /* filter, filterarg */
1975 1, /* nsegments */
1976 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
1977 0, /* flags */
1978 NULL, /* lockfunc */
1979 NULL, /* lockfuncarg */
1980 &hba->srb_dmat /* tag */))
1981 {
1982 device_printf(dev, "alloc srb_dmat failed\n");
1983 goto destroy_io_dmat;
1984 }
1985
1986 if (bus_dmamem_alloc(hba->srb_dmat, (void **)&hba->uncached_ptr,
1987 BUS_DMA_WAITOK | BUS_DMA_COHERENT,
1988 &hba->srb_dmamap) != 0)
1989 {
1990 device_printf(dev, "srb bus_dmamem_alloc failed!\n");
1991 goto destroy_srb_dmat;
1992 }
1993
1994 if (bus_dmamap_load(hba->srb_dmat,
1995 hba->srb_dmamap, hba->uncached_ptr,
1997 hptiop_map_srb, hba, 0))
1998 {
1999 device_printf(dev, "bus_dmamap_load failed!\n");
2000 goto srb_dmamem_free;
2001 }
2002
2003 if ((devq = cam_simq_alloc(hba->max_requests - 1 )) == NULL) {
2004 device_printf(dev, "cam_simq_alloc failed\n");
2005 goto srb_dmamap_unload;
2006 }
2007
2008 hba->sim = cam_sim_alloc(hptiop_action, hptiop_poll, driver_name,
2009 hba, unit, &hba->lock, hba->max_requests - 1, 1, devq);
2010 if (!hba->sim) {
2011 device_printf(dev, "cam_sim_alloc failed\n");
2012 cam_simq_free(devq);
2013 goto srb_dmamap_unload;
2014 }
2016 if (xpt_bus_register(hba->sim, dev, 0) != CAM_SUCCESS)
2017 {
2018 device_printf(dev, "xpt_bus_register failed\n");
2019 goto free_cam_sim;
2020 }
2021
2022 if (xpt_create_path(&hba->path, /*periph */ NULL,
2023 cam_sim_path(hba->sim), CAM_TARGET_WILDCARD,
2024 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2025 device_printf(dev, "xpt_create_path failed\n");
2026 goto deregister_xpt_bus;
2027 }
2029
2030 bzero(&set_config, sizeof(set_config));
2031 set_config.iop_id = unit;
2032 set_config.vbus_id = cam_sim_path(hba->sim);
2034
2035 if (hba->ops->set_config(hba, &set_config)) {
2036 device_printf(dev, "set iop config failed.\n");
2037 goto free_hba_path;
2038 }
2039
2040 memset(&ccb, 0, sizeof(ccb));
2041 xpt_setup_ccb(&ccb.ccb_h, hba->path, /*priority*/5);
2042 ccb.ccb_h.func_code = XPT_SASYNC_CB;
2043 ccb.event_enable = (AC_FOUND_DEVICE | AC_LOST_DEVICE);
2044 ccb.callback = hptiop_async;
2045 ccb.callback_arg = hba->sim;
2046 xpt_action((union ccb *)&ccb);
2047
2048 rid = 0;
2049 if ((hba->irq_res = bus_alloc_resource_any(hba->pcidev, SYS_RES_IRQ,
2050 &rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
2051 device_printf(dev, "allocate irq failed!\n");
2052 goto free_hba_path;
2053 }
2054
2055 if (bus_setup_intr(hba->pcidev, hba->irq_res, INTR_TYPE_CAM | INTR_MPSAFE,
2056 NULL, hptiop_pci_intr, hba, &hba->irq_handle))
2057 {
2058 device_printf(dev, "allocate intr function failed!\n");
2059 goto free_irq_resource;
2060 }
2061
2062 if (hptiop_send_sync_msg(hba,
2064 device_printf(dev, "fail to start background task\n");
2065 goto teartown_irq_resource;
2066 }
2067
2068 hba->ops->enable_intr(hba);
2069 hba->initialized = 1;
2070
2071 hba->ioctl_dev = make_dev(&hptiop_cdevsw, unit,
2072 UID_ROOT, GID_WHEEL /*GID_OPERATOR*/,
2073 S_IRUSR | S_IWUSR, "%s%d", driver_name, unit);
2074
2075
2076 return 0;
2077
2078
2079teartown_irq_resource:
2080 bus_teardown_intr(dev, hba->irq_res, hba->irq_handle);
2081
2082free_irq_resource:
2083 bus_release_resource(dev, SYS_RES_IRQ, 0, hba->irq_res);
2084
2086free_hba_path:
2087 xpt_free_path(hba->path);
2088
2089deregister_xpt_bus:
2090 xpt_bus_deregister(cam_sim_path(hba->sim));
2091
2092free_cam_sim:
2093 cam_sim_free(hba->sim, /*free devq*/ TRUE);
2095
2096srb_dmamap_unload:
2097 if (hba->uncached_ptr)
2098 bus_dmamap_unload(hba->srb_dmat, hba->srb_dmamap);
2099
2100srb_dmamem_free:
2101 if (hba->uncached_ptr)
2102 bus_dmamem_free(hba->srb_dmat,
2103 hba->uncached_ptr, hba->srb_dmamap);
2104
2105destroy_srb_dmat:
2106 if (hba->srb_dmat)
2107 bus_dma_tag_destroy(hba->srb_dmat);
2108
2109destroy_io_dmat:
2110 if (hba->io_dmat)
2111 bus_dma_tag_destroy(hba->io_dmat);
2112
2113get_config_failed:
2114 hba->ops->internal_memfree(hba);
2115
2116destroy_parent_tag:
2117 if (hba->parent_dmat)
2118 bus_dma_tag_destroy(hba->parent_dmat);
2119
2120release_pci_res:
2121 if (hba->ops->release_pci_res)
2122 hba->ops->release_pci_res(hba);
2123
2124 return ENXIO;
2125}
2126
2127static int hptiop_detach(device_t dev)
2128{
2129 struct hpt_iop_hba * hba = (struct hpt_iop_hba *)device_get_softc(dev);
2130 int i;
2131 int error = EBUSY;
2132
2134 for (i = 0; i < hba->max_devices; i++)
2135 if (hptiop_os_query_remove_device(hba, i)) {
2136 device_printf(dev, "%d file system is busy. id=%d",
2137 hba->pciunit, i);
2138 goto out;
2139 }
2140
2141 if ((error = hptiop_shutdown(dev)) != 0)
2142 goto out;
2143 if (hptiop_send_sync_msg(hba,
2145 goto out;
2147
2149 return (0);
2150out:
2152 return error;
2153}
2154
2155static int hptiop_shutdown(device_t dev)
2156{
2157 struct hpt_iop_hba * hba = (struct hpt_iop_hba *)device_get_softc(dev);
2158
2159 int error = 0;
2160
2161 if (hba->flag & HPT_IOCTL_FLAG_OPEN) {
2162 device_printf(dev, "%d device is busy", hba->pciunit);
2163 return EBUSY;
2164 }
2165
2166 hba->ops->disable_intr(hba);
2167
2169 error = EBUSY;
2170
2171 return error;
2172}
2173
2174static void hptiop_pci_intr(void *arg)
2175{
2176 struct hpt_iop_hba * hba = (struct hpt_iop_hba *)arg;
2178 hba->ops->iop_intr(hba);
2180}
2181
2182static void hptiop_poll(struct cam_sim *sim)
2183{
2184 struct hpt_iop_hba *hba;
2185
2186 hba = cam_sim_softc(sim);
2187 hba->ops->iop_intr(hba);
2188}
2189
2190static void hptiop_async(void * callback_arg, u_int32_t code,
2191 struct cam_path * path, void * arg)
2192{
2193}
2194
2195static void hptiop_enable_intr_itl(struct hpt_iop_hba *hba)
2196{
2197 BUS_SPACE_WRT4_ITL(outbound_intmask,
2199}
2200
2201static void hptiop_enable_intr_mv(struct hpt_iop_hba *hba)
2202{
2203 u_int32_t int_mask;
2204
2205 int_mask = BUS_SPACE_RD4_MV0(outbound_intmask);
2206
2209 BUS_SPACE_WRT4_MV0(outbound_intmask,int_mask);
2210}
2211
2213{
2215 BUS_SPACE_RD4_MVFREY2(f0_doorbell_enable);
2216
2217 BUS_SPACE_WRT4_MVFREY2(isr_enable, 0x1);
2218 BUS_SPACE_RD4_MVFREY2(isr_enable);
2219
2220 BUS_SPACE_WRT4_MVFREY2(pcie_f0_int_enable, 0x1010);
2221 BUS_SPACE_RD4_MVFREY2(pcie_f0_int_enable);
2222}
2223
2224static void hptiop_disable_intr_itl(struct hpt_iop_hba *hba)
2225{
2226 u_int32_t int_mask;
2227
2228 int_mask = BUS_SPACE_RD4_ITL(outbound_intmask);
2229
2231 BUS_SPACE_WRT4_ITL(outbound_intmask, int_mask);
2232 BUS_SPACE_RD4_ITL(outbound_intstatus);
2233}
2234
2235static void hptiop_disable_intr_mv(struct hpt_iop_hba *hba)
2236{
2237 u_int32_t int_mask;
2238 int_mask = BUS_SPACE_RD4_MV0(outbound_intmask);
2239
2240 int_mask &= ~(MVIOP_MU_OUTBOUND_INT_MSG
2242 BUS_SPACE_WRT4_MV0(outbound_intmask,int_mask);
2243 BUS_SPACE_RD4_MV0(outbound_intmask);
2244}
2245
2247{
2248 BUS_SPACE_WRT4_MVFREY2(f0_doorbell_enable, 0);
2249 BUS_SPACE_RD4_MVFREY2(f0_doorbell_enable);
2250
2251 BUS_SPACE_WRT4_MVFREY2(isr_enable, 0);
2252 BUS_SPACE_RD4_MVFREY2(isr_enable);
2253
2254 BUS_SPACE_WRT4_MVFREY2(pcie_f0_int_enable, 0);
2255 BUS_SPACE_RD4_MVFREY2(pcie_f0_int_enable);
2256}
2257
2258static void hptiop_reset_adapter(void *argv)
2259{
2260 struct hpt_iop_hba * hba = (struct hpt_iop_hba *)argv;
2262 return;
2264}
2265
2266static void *hptiop_get_srb(struct hpt_iop_hba * hba)
2267{
2268 struct hpt_iop_srb * srb;
2269
2270 if (hba->srb_list) {
2271 srb = hba->srb_list;
2272 hba->srb_list = srb->next;
2273 return srb;
2274 }
2275
2276 return NULL;
2277}
2278
2279static void hptiop_free_srb(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb)
2280{
2281 srb->next = hba->srb_list;
2282 hba->srb_list = srb;
2283}
2284
2285static void hptiop_action(struct cam_sim *sim, union ccb *ccb)
2286{
2287 struct hpt_iop_hba * hba = (struct hpt_iop_hba *)cam_sim_softc(sim);
2288 struct hpt_iop_srb * srb;
2289 int error;
2290
2291 switch (ccb->ccb_h.func_code) {
2292
2293 case XPT_SCSI_IO:
2294 if (ccb->ccb_h.target_lun != 0 ||
2295 ccb->ccb_h.target_id >= hba->max_devices ||
2296 (ccb->ccb_h.flags & CAM_CDB_PHYS))
2297 {
2298 ccb->ccb_h.status = CAM_TID_INVALID;
2299 xpt_done(ccb);
2300 return;
2301 }
2302
2303 if ((srb = hptiop_get_srb(hba)) == NULL) {
2304 device_printf(hba->pcidev, "srb allocated failed");
2305 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2306 xpt_done(ccb);
2307 return;
2308 }
2309
2310 srb->ccb = ccb;
2311 error = bus_dmamap_load_ccb(hba->io_dmat,
2312 srb->dma_map,
2313 ccb,
2315 srb,
2316 0);
2317
2318 if (error && error != EINPROGRESS) {
2319 device_printf(hba->pcidev,
2320 "%d bus_dmamap_load error %d",
2321 hba->pciunit, error);
2322 xpt_freeze_simq(hba->sim, 1);
2323 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2324 hptiop_free_srb(hba, srb);
2325 xpt_done(ccb);
2326 return;
2327 }
2328
2329 return;
2330
2331 case XPT_RESET_BUS:
2332 device_printf(hba->pcidev, "reset adapter");
2333 hba->msg_done = 0;
2335 break;
2336
2337 case XPT_GET_TRAN_SETTINGS:
2338 case XPT_SET_TRAN_SETTINGS:
2339 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
2340 break;
2341
2342 case XPT_CALC_GEOMETRY:
2343 cam_calc_geometry(&ccb->ccg, 1);
2344 break;
2345
2346 case XPT_PATH_INQ:
2347 {
2348 struct ccb_pathinq *cpi = &ccb->cpi;
2349
2350 cpi->version_num = 1;
2351 cpi->hba_inquiry = PI_SDTR_ABLE;
2352 cpi->target_sprt = 0;
2353 cpi->hba_misc = PIM_NOBUSRESET;
2354 cpi->hba_eng_cnt = 0;
2355 cpi->max_target = hba->max_devices;
2356 cpi->max_lun = 0;
2357 cpi->unit_number = cam_sim_unit(sim);
2358 cpi->bus_id = cam_sim_bus(sim);
2359 cpi->initiator_id = hba->max_devices;
2360 cpi->base_transfer_speed = 3300;
2361
2362 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2363 strlcpy(cpi->hba_vid, "HPT ", HBA_IDLEN);
2364 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2365 cpi->transport = XPORT_SPI;
2366 cpi->transport_version = 2;
2367 cpi->protocol = PROTO_SCSI;
2368 cpi->protocol_version = SCSI_REV_2;
2369 cpi->ccb_h.status = CAM_REQ_CMP;
2370 break;
2371 }
2372
2373 default:
2374 ccb->ccb_h.status = CAM_REQ_INVALID;
2375 break;
2376 }
2377
2378 xpt_done(ccb);
2379 return;
2380}
2381
2382static void hptiop_post_req_itl(struct hpt_iop_hba *hba,
2383 struct hpt_iop_srb *srb,
2384 bus_dma_segment_t *segs, int nsegs)
2385{
2386 int idx;
2387 union ccb *ccb = srb->ccb;
2388 u_int8_t *cdb;
2389
2390 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
2391 cdb = ccb->csio.cdb_io.cdb_ptr;
2392 else
2393 cdb = ccb->csio.cdb_io.cdb_bytes;
2394
2395 KdPrint(("ccb=%p %x-%x-%x\n",
2396 ccb, *(u_int32_t *)cdb, *((u_int32_t *)cdb+1), *((u_int32_t *)cdb+2)));
2397
2399 u_int32_t iop_req32;
2401
2402 iop_req32 = BUS_SPACE_RD4_ITL(inbound_queue);
2403
2404 if (iop_req32 == IOPMU_QUEUE_EMPTY) {
2405 device_printf(hba->pcidev, "invalid req offset\n");
2406 ccb->ccb_h.status = CAM_BUSY;
2407 bus_dmamap_unload(hba->io_dmat, srb->dma_map);
2408 hptiop_free_srb(hba, srb);
2409 xpt_done(ccb);
2410 return;
2411 }
2412
2413 if (ccb->csio.dxfer_len && nsegs > 0) {
2414 struct hpt_iopsg *psg = req.sg_list;
2415 for (idx = 0; idx < nsegs; idx++, psg++) {
2416 psg->pci_address = (u_int64_t)segs[idx].ds_addr;
2417 psg->size = segs[idx].ds_len;
2418 psg->eot = 0;
2419 }
2420 psg[-1].eot = 1;
2421 }
2422
2423 bcopy(cdb, req.cdb, ccb->csio.cdb_len);
2424
2425 req.header.size =
2426 offsetof(struct hpt_iop_request_scsi_command, sg_list)
2427 + nsegs*sizeof(struct hpt_iopsg);
2429 req.header.flags = 0;
2431 req.header.context = (u_int64_t)(unsigned long)srb;
2432 req.dataxfer_length = ccb->csio.dxfer_len;
2433 req.channel = 0;
2434 req.target = ccb->ccb_h.target_id;
2435 req.lun = ccb->ccb_h.target_lun;
2436
2437 bus_space_write_region_1(hba->bar0t, hba->bar0h, iop_req32,
2438 (u_int8_t *)&req, req.header.size);
2439
2440 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2441 bus_dmamap_sync(hba->io_dmat,
2442 srb->dma_map, BUS_DMASYNC_PREREAD);
2443 }
2444 else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2445 bus_dmamap_sync(hba->io_dmat,
2446 srb->dma_map, BUS_DMASYNC_PREWRITE);
2447
2448 BUS_SPACE_WRT4_ITL(inbound_queue,iop_req32);
2449 } else {
2450 struct hpt_iop_request_scsi_command *req;
2451
2452 req = (struct hpt_iop_request_scsi_command *)srb;
2453 if (ccb->csio.dxfer_len && nsegs > 0) {
2454 struct hpt_iopsg *psg = req->sg_list;
2455 for (idx = 0; idx < nsegs; idx++, psg++) {
2456 psg->pci_address =
2457 (u_int64_t)segs[idx].ds_addr;
2458 psg->size = segs[idx].ds_len;
2459 psg->eot = 0;
2460 }
2461 psg[-1].eot = 1;
2462 }
2463
2464 bcopy(cdb, req->cdb, ccb->csio.cdb_len);
2465
2468 req->dataxfer_length = ccb->csio.dxfer_len;
2469 req->channel = 0;
2470 req->target = ccb->ccb_h.target_id;
2471 req->lun = ccb->ccb_h.target_lun;
2472 req->header.size =
2473 offsetof(struct hpt_iop_request_scsi_command, sg_list)
2474 + nsegs*sizeof(struct hpt_iopsg);
2475 req->header.context = (u_int64_t)srb->index |
2478
2479 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2480 bus_dmamap_sync(hba->io_dmat,
2481 srb->dma_map, BUS_DMASYNC_PREREAD);
2482 }else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
2483 bus_dmamap_sync(hba->io_dmat,
2484 srb->dma_map, BUS_DMASYNC_PREWRITE);
2485 }
2486
2487 if (hba->firmware_version > 0x01020000
2488 || hba->interface_version > 0x01020000) {
2489 u_int32_t size_bits;
2490
2491 if (req->header.size < 256)
2492 size_bits = IOPMU_QUEUE_REQUEST_SIZE_BIT;
2493 else if (req->header.size < 512)
2494 size_bits = IOPMU_QUEUE_ADDR_HOST_BIT;
2495 else
2498
2499 BUS_SPACE_WRT4_ITL(inbound_queue,
2500 (u_int32_t)srb->phy_addr | size_bits);
2501 } else
2502 BUS_SPACE_WRT4_ITL(inbound_queue, (u_int32_t)srb->phy_addr
2504 }
2505}
2506
2507static void hptiop_post_req_mv(struct hpt_iop_hba *hba,
2508 struct hpt_iop_srb *srb,
2509 bus_dma_segment_t *segs, int nsegs)
2510{
2511 int idx, size;
2512 union ccb *ccb = srb->ccb;
2513 u_int8_t *cdb;
2514 struct hpt_iop_request_scsi_command *req;
2515 u_int64_t req_phy;
2516
2517 req = (struct hpt_iop_request_scsi_command *)srb;
2518 req_phy = srb->phy_addr;
2519
2520 if (ccb->csio.dxfer_len && nsegs > 0) {
2521 struct hpt_iopsg *psg = req->sg_list;
2522 for (idx = 0; idx < nsegs; idx++, psg++) {
2523 psg->pci_address = (u_int64_t)segs[idx].ds_addr;
2524 psg->size = segs[idx].ds_len;
2525 psg->eot = 0;
2526 }
2527 psg[-1].eot = 1;
2528 }
2529 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
2530 cdb = ccb->csio.cdb_io.cdb_ptr;
2531 else
2532 cdb = ccb->csio.cdb_io.cdb_bytes;
2533
2534 bcopy(cdb, req->cdb, ccb->csio.cdb_len);
2537 req->dataxfer_length = ccb->csio.dxfer_len;
2538 req->channel = 0;
2539 req->target = ccb->ccb_h.target_id;
2540 req->lun = ccb->ccb_h.target_lun;
2541 req->header.size = sizeof(struct hpt_iop_request_scsi_command)
2542 - sizeof(struct hpt_iopsg)
2543 + nsegs * sizeof(struct hpt_iopsg);
2544 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2545 bus_dmamap_sync(hba->io_dmat,
2546 srb->dma_map, BUS_DMASYNC_PREREAD);
2547 }
2548 else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2549 bus_dmamap_sync(hba->io_dmat,
2550 srb->dma_map, BUS_DMASYNC_PREWRITE);
2551 req->header.context = (u_int64_t)srb->index
2555 size = req->header.size >> 8;
2558 | imin(3, size), hba);
2559}
2560
2561static void hptiop_post_req_mvfrey(struct hpt_iop_hba *hba,
2562 struct hpt_iop_srb *srb,
2563 bus_dma_segment_t *segs, int nsegs)
2564{
2565 int idx, index;
2566 union ccb *ccb = srb->ccb;
2567 u_int8_t *cdb;
2568 struct hpt_iop_request_scsi_command *req;
2569 u_int64_t req_phy;
2570
2571 req = (struct hpt_iop_request_scsi_command *)srb;
2572 req_phy = srb->phy_addr;
2573
2574 if (ccb->csio.dxfer_len && nsegs > 0) {
2575 struct hpt_iopsg *psg = req->sg_list;
2576 for (idx = 0; idx < nsegs; idx++, psg++) {
2577 psg->pci_address = (u_int64_t)segs[idx].ds_addr | 1;
2578 psg->size = segs[idx].ds_len;
2579 psg->eot = 0;
2580 }
2581 psg[-1].eot = 1;
2582 }
2583 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
2584 cdb = ccb->csio.cdb_io.cdb_ptr;
2585 else
2586 cdb = ccb->csio.cdb_io.cdb_bytes;
2587
2588 bcopy(cdb, req->cdb, ccb->csio.cdb_len);
2591 req->dataxfer_length = ccb->csio.dxfer_len;
2592 req->channel = 0;
2593 req->target = ccb->ccb_h.target_id;
2594 req->lun = ccb->ccb_h.target_lun;
2595 req->header.size = sizeof(struct hpt_iop_request_scsi_command)
2596 - sizeof(struct hpt_iopsg)
2597 + nsegs * sizeof(struct hpt_iopsg);
2598 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2599 bus_dmamap_sync(hba->io_dmat,
2600 srb->dma_map, BUS_DMASYNC_PREREAD);
2601 }
2602 else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2603 bus_dmamap_sync(hba->io_dmat,
2604 srb->dma_map, BUS_DMASYNC_PREWRITE);
2605
2608 | ((req_phy >> 16) & 0xffff0000);
2609 req->header.context = ((req_phy & 0xffffffff) << 32 )
2610 | srb->index << 4
2612
2613 hba->u.mvfrey.inlist_wptr++;
2614 index = hba->u.mvfrey.inlist_wptr & 0x3fff;
2615
2616 if (index == hba->u.mvfrey.list_count) {
2617 index = 0;
2618 hba->u.mvfrey.inlist_wptr &= ~0x3fff;
2620 }
2621
2622 hba->u.mvfrey.inlist[index].addr = req_phy;
2623 hba->u.mvfrey.inlist[index].intrfc_len = (req->header.size + 3) / 4;
2624
2625 BUS_SPACE_WRT4_MVFREY2(inbound_write_ptr, hba->u.mvfrey.inlist_wptr);
2626 BUS_SPACE_RD4_MVFREY2(inbound_write_ptr);
2627
2629 callout_reset(&srb->timeout, 20 * hz, hptiop_reset_adapter, hba);
2630 }
2631}
2632
2633static void hptiop_post_scsi_command(void *arg, bus_dma_segment_t *segs,
2634 int nsegs, int error)
2635{
2636 struct hpt_iop_srb *srb = (struct hpt_iop_srb *)arg;
2637 union ccb *ccb = srb->ccb;
2638 struct hpt_iop_hba *hba = srb->hba;
2639
2640 if (error || nsegs > hba->max_sg_count) {
2641 KdPrint(("hptiop: func_code=%x tid=%x lun=%jx nsegs=%d\n",
2642 ccb->ccb_h.func_code,
2643 ccb->ccb_h.target_id,
2644 (uintmax_t)ccb->ccb_h.target_lun, nsegs));
2645 ccb->ccb_h.status = CAM_BUSY;
2646 bus_dmamap_unload(hba->io_dmat, srb->dma_map);
2647 hptiop_free_srb(hba, srb);
2648 xpt_done(ccb);
2649 return;
2650 }
2651
2652 hba->ops->post_req(hba, srb, segs, nsegs);
2653}
2654
2655static void hptiop_mv_map_ctlcfg(void *arg, bus_dma_segment_t *segs,
2656 int nsegs, int error)
2657{
2658 struct hpt_iop_hba *hba = (struct hpt_iop_hba *)arg;
2659 hba->ctlcfgcmd_phy = ((u_int64_t)segs->ds_addr + 0x1F)
2660 & ~(u_int64_t)0x1F;
2661 hba->ctlcfg_ptr = (u_int8_t *)(((unsigned long)hba->ctlcfg_ptr + 0x1F)
2662 & ~0x1F);
2663}
2664
2665static void hptiop_mvfrey_map_ctlcfg(void *arg, bus_dma_segment_t *segs,
2666 int nsegs, int error)
2667{
2668 struct hpt_iop_hba *hba = (struct hpt_iop_hba *)arg;
2669 char *p;
2670 u_int64_t phy;
2671 u_int32_t list_count = hba->u.mvfrey.list_count;
2672
2673 phy = ((u_int64_t)segs->ds_addr + 0x1F)
2674 & ~(u_int64_t)0x1F;
2675 p = (u_int8_t *)(((unsigned long)hba->ctlcfg_ptr + 0x1F)
2676 & ~0x1F);
2677
2678 hba->ctlcfgcmd_phy = phy;
2679 hba->ctlcfg_ptr = p;
2680
2681 p += 0x800;
2682 phy += 0x800;
2683
2684 hba->u.mvfrey.inlist = (struct mvfrey_inlist_entry *)p;
2685 hba->u.mvfrey.inlist_phy = phy;
2686
2687 p += list_count * sizeof(struct mvfrey_inlist_entry);
2688 phy += list_count * sizeof(struct mvfrey_inlist_entry);
2689
2690 hba->u.mvfrey.outlist = (struct mvfrey_outlist_entry *)p;
2691 hba->u.mvfrey.outlist_phy = phy;
2692
2693 p += list_count * sizeof(struct mvfrey_outlist_entry);
2694 phy += list_count * sizeof(struct mvfrey_outlist_entry);
2695
2696 hba->u.mvfrey.outlist_cptr = (u_int32_t *)p;
2697 hba->u.mvfrey.outlist_cptr_phy = phy;
2698}
2699
2700static void hptiop_map_srb(void *arg, bus_dma_segment_t *segs,
2701 int nsegs, int error)
2702{
2703 struct hpt_iop_hba * hba = (struct hpt_iop_hba *)arg;
2704 bus_addr_t phy_addr = (segs->ds_addr + 0x1F) & ~(bus_addr_t)0x1F;
2705 struct hpt_iop_srb *srb, *tmp_srb;
2706 int i;
2707
2708 if (error || nsegs == 0) {
2709 device_printf(hba->pcidev, "hptiop_map_srb error");
2710 return;
2711 }
2712
2713 /* map srb */
2714 srb = (struct hpt_iop_srb *)
2715 (((unsigned long)hba->uncached_ptr + 0x1F)
2716 & ~(unsigned long)0x1F);
2717
2718 for (i = 0; i < HPT_SRB_MAX_QUEUE_SIZE; i++) {
2719 tmp_srb = (struct hpt_iop_srb *)
2720 ((char *)srb + i * HPT_SRB_MAX_SIZE);
2721 if (((unsigned long)tmp_srb & 0x1F) == 0) {
2722 if (bus_dmamap_create(hba->io_dmat,
2723 0, &tmp_srb->dma_map)) {
2724 device_printf(hba->pcidev, "dmamap create failed");
2725 return;
2726 }
2727
2728 bzero(tmp_srb, sizeof(struct hpt_iop_srb));
2729 tmp_srb->hba = hba;
2730 tmp_srb->index = i;
2731 if (hba->ctlcfg_ptr == 0) {/*itl iop*/
2732 tmp_srb->phy_addr = (u_int64_t)(u_int32_t)
2733 (phy_addr >> 5);
2735 tmp_srb->srb_flag =
2737 } else {
2738 tmp_srb->phy_addr = phy_addr;
2739 }
2740
2741 callout_init_mtx(&tmp_srb->timeout, &hba->lock, 0);
2742 hptiop_free_srb(hba, tmp_srb);
2743 hba->srb[i] = tmp_srb;
2745 }
2746 else {
2747 device_printf(hba->pcidev, "invalid alignment");
2748 return;
2749 }
2750 }
2751}
2752
2753static void hptiop_os_message_callback(struct hpt_iop_hba * hba, u_int32_t msg)
2754{
2755 hba->msg_done = 1;
2756}
2757
2759 int target_id)
2760{
2761 struct cam_periph *periph = NULL;
2762 struct cam_path *path;
2763 int status, retval = 0;
2764
2765 status = xpt_create_path(&path, NULL, hba->sim->path_id, target_id, 0);
2766
2767 if (status == CAM_REQ_CMP) {
2768 if ((periph = cam_periph_find(path, "da")) != NULL) {
2769 if (periph->refcount >= 1) {
2770 device_printf(hba->pcidev, "%d ,"
2771 "target_id=0x%x,"
2772 "refcount=%d",
2773 hba->pciunit, target_id, periph->refcount);
2774 retval = -1;
2775 }
2776 }
2777 xpt_free_path(path);
2778 }
2779 return retval;
2780}
2781
2782static void hptiop_release_resource(struct hpt_iop_hba *hba)
2783{
2784 int i;
2785
2786 if (hba->ioctl_dev)
2787 destroy_dev(hba->ioctl_dev);
2788
2789 if (hba->path) {
2790 struct ccb_setasync ccb;
2791
2792 memset(&ccb, 0, sizeof(ccb));
2793 xpt_setup_ccb(&ccb.ccb_h, hba->path, /*priority*/5);
2794 ccb.ccb_h.func_code = XPT_SASYNC_CB;
2795 ccb.event_enable = 0;
2796 ccb.callback = hptiop_async;
2797 ccb.callback_arg = hba->sim;
2798 xpt_action((union ccb *)&ccb);
2799 xpt_free_path(hba->path);
2800 }
2801
2802 if (hba->irq_handle)
2803 bus_teardown_intr(hba->pcidev, hba->irq_res, hba->irq_handle);
2804
2805 if (hba->sim) {
2807 xpt_bus_deregister(cam_sim_path(hba->sim));
2808 cam_sim_free(hba->sim, TRUE);
2810 }
2811
2812 if (hba->ctlcfg_dmat) {
2813 bus_dmamap_unload(hba->ctlcfg_dmat, hba->ctlcfg_dmamap);
2814 bus_dmamem_free(hba->ctlcfg_dmat,
2815 hba->ctlcfg_ptr, hba->ctlcfg_dmamap);
2816 bus_dma_tag_destroy(hba->ctlcfg_dmat);
2817 }
2818
2819 for (i = 0; i < HPT_SRB_MAX_QUEUE_SIZE; i++) {
2820 struct hpt_iop_srb *srb = hba->srb[i];
2821 if (srb->dma_map)
2822 bus_dmamap_destroy(hba->io_dmat, srb->dma_map);
2823 callout_drain(&srb->timeout);
2824 }
2825
2826 if (hba->srb_dmat) {
2827 bus_dmamap_unload(hba->srb_dmat, hba->srb_dmamap);
2828 bus_dmamap_destroy(hba->srb_dmat, hba->srb_dmamap);
2829 bus_dma_tag_destroy(hba->srb_dmat);
2830 }
2831
2832 if (hba->io_dmat)
2833 bus_dma_tag_destroy(hba->io_dmat);
2834
2835 if (hba->parent_dmat)
2836 bus_dma_tag_destroy(hba->parent_dmat);
2837
2838 if (hba->irq_res)
2839 bus_release_resource(hba->pcidev, SYS_RES_IRQ,
2840 0, hba->irq_res);
2841
2842 if (hba->bar0_res)
2843 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
2845 if (hba->bar2_res)
2846 bus_release_resource(hba->pcidev, SYS_RES_MEMORY,
2848 mtx_destroy(&hba->lock);
2849}
static d_ioctl_t hptiop_ioctl
Definition: hptiop.c:158
static void hptiop_poll(struct cam_sim *sim)
Definition: hptiop.c:2182
static d_close_t hptiop_close
Definition: hptiop.c:157
static int hptiop_send_sync_msg(struct hpt_iop_hba *hba, u_int32_t msg, u_int32_t millisec)
Definition: hptiop.c:892
static int hptiop_set_config_mvfrey(struct hpt_iop_hba *hba, struct hpt_iop_request_set_config *config)
Definition: hptiop.c:1054
static int hptiop_intr_mvfrey(struct hpt_iop_hba *hba)
Definition: hptiop.c:760
static int hptiop_internal_memfree_mv(struct hpt_iop_hba *hba)
Definition: hptiop.c:1667
static int hptiop_get_config_mv(struct hpt_iop_hba *hba, struct hpt_iop_request_get_config *config)
Definition: hptiop.c:943
#define BUS_SPACE_RD4_MV2(offset)
Definition: hptiop.c:182
static void hptiop_post_req_mv(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs)
Definition: hptiop.c:2507
static int hptiop_detach(device_t dev)
Definition: hptiop.c:2127
static void hptiop_enable_intr_mvfrey(struct hpt_iop_hba *hba)
Definition: hptiop.c:2212
static int hptiop_set_config_mv(struct hpt_iop_hba *hba, struct hpt_iop_request_set_config *config)
Definition: hptiop.c:1027
#define BUS_SPACE_RD4_MVFREY2(offset)
Definition: hptiop.c:187
static int hptiop_intr_itl(struct hpt_iop_hba *hba)
Definition: hptiop.c:498
static void hptiop_enable_intr_mv(struct hpt_iop_hba *hba)
Definition: hptiop.c:2201
static void hptiop_release_pci_res_mvfrey(struct hpt_iop_hba *hba)
Definition: hptiop.c:1552
static int hptiop_post_ioctl_command_itl(struct hpt_iop_hba *hba, u_int32_t req32, struct hpt_iop_ioctl_param *pParams)
Definition: hptiop.c:1079
static void hptiop_drain_outbound_queue_mv(struct hpt_iop_hba *hba)
Definition: hptiop.c:722
static u_int64_t hptiop_mv_outbound_read(struct hpt_iop_hba *hba)
Definition: hptiop.c:229
static void hptiop_release_pci_res_itl(struct hpt_iop_hba *hba)
Definition: hptiop.c:1535
static int hptiop_internal_memalloc_mv(struct hpt_iop_hba *hba)
Definition: hptiop.c:1562
static int hptiop_alloc_pci_res_mv(struct hpt_iop_hba *hba)
Definition: hptiop.c:1436
static const char driver_name[]
Definition: hptiop.c:77
static int hptiop_probe(device_t dev)
Definition: hptiop.c:1802
static int hptiop_wait_ready_itl(struct hpt_iop_hba *hba, u_int32_t millisec)
Definition: hptiop.c:288
static int hptiop_do_ioctl_mv(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams)
Definition: hptiop.c:1252
static void hptiop_request_callback_mv(struct hpt_iop_hba *hba, u_int64_t req)
Definition: hptiop.c:521
static void hptiop_release_resource(struct hpt_iop_hba *hba)
Definition: hptiop.c:2782
static void hptiop_os_message_callback(struct hpt_iop_hba *hba, u_int32_t msg)
Definition: hptiop.c:2753
static void hptiop_post_msg_mv(struct hpt_iop_hba *hba, u_int32_t msg)
Definition: hptiop.c:273
static bus_dmamap_callback_t hptiop_mv_map_ctlcfg
Definition: hptiop.c:1407
#define BUS_SPACE_WRT4_ITL(offset, value)
Definition: hptiop.c:171
static int hptiop_send_sync_request_mv(struct hpt_iop_hba *hba, void *req, u_int32_t millisec)
Definition: hptiop.c:826
static int hptiop_wait_ready_mv(struct hpt_iop_hba *hba, u_int32_t millisec)
Definition: hptiop.c:309
#define hba_from_dev(dev)
Definition: hptiop.c:168
static int hptiop_do_ioctl_mvfrey(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams)
Definition: hptiop.c:1349
static bus_dmamap_callback_t hptiop_mvfrey_map_ctlcfg
Definition: hptiop.c:1408
static void hptiop_mv_inbound_write(u_int64_t p, struct hpt_iop_hba *hba)
Definition: hptiop.c:252
static void hptiop_post_msg_itl(struct hpt_iop_hba *hba, u_int32_t msg)
Definition: hptiop.c:267
static void hptiop_request_callback_mvfrey(struct hpt_iop_hba *hba, u_int32_t req)
Definition: hptiop.c:617
static struct hptiop_adapter_ops hptiop_itl_ops
Definition: hptiop.c:1739
static int hptiop_attach(device_t dev)
Definition: hptiop.c:1871
static struct hptiop_adapter_ops hptiop_mvfrey_ops
Definition: hptiop.c:1775
static void hptiop_disable_intr_itl(struct hpt_iop_hba *hba)
Definition: hptiop.c:2224
static bus_dmamap_callback_t hptiop_map_srb
Definition: hptiop.c:1405
#define BUS_SPACE_RD4_MV0(offset)
Definition: hptiop.c:178
static struct cdevsw hptiop_cdevsw
Definition: hptiop.c:160
static void hptiop_reset_adapter(void *argv)
Definition: hptiop.c:2258
static int hptiop_do_ioctl_itl(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams)
Definition: hptiop.c:1160
static int hptiop_intr_mv(struct hpt_iop_hba *hba)
Definition: hptiop.c:735
static int hptiop_send_sync_request_mvfrey(struct hpt_iop_hba *hba, void *req, u_int32_t millisec)
Definition: hptiop.c:850
static int hptiop_internal_memfree_mvfrey(struct hpt_iop_hba *hba)
Definition: hptiop.c:1679
static int hptiop_rescan_bus(struct hpt_iop_hba *hba)
Definition: hptiop.c:1390
static int hptiop_post_ioctl_command_mvfrey(struct hpt_iop_hba *hba, struct hpt_iop_request_ioctl_command *req, struct hpt_iop_ioctl_param *pParams)
Definition: hptiop.c:1293
static int hptiop_wait_ready_mvfrey(struct hpt_iop_hba *hba, u_int32_t millisec)
Definition: hptiop.c:317
static int hptiop_reset_comm_mvfrey(struct hpt_iop_hba *hba)
Definition: hptiop.c:1691
static void hptiop_post_req_itl(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs)
Definition: hptiop.c:2382
__FBSDID("$FreeBSD$")
static int hptiop_bus_space_copyin(struct hpt_iop_hba *hba, u_int32_t bus, void *user, int size)
Definition: hptiop.c:1130
static int hptiop_shutdown(device_t dev)
Definition: hptiop.c:2155
#define BUS_SPACE_RD4_ITL(offset)
Definition: hptiop.c:173
static void hptiop_drain_outbound_queue_itl(struct hpt_iop_hba *hba)
Definition: hptiop.c:463
#define BUS_SPACE_WRT4_MV2(offset, value)
Definition: hptiop.c:180
MODULE_DEPEND(hptiop, cam, 1, 1, 1)
static void hptiop_enable_intr_itl(struct hpt_iop_hba *hba)
Definition: hptiop.c:2195
static struct hptiop_adapter_ops hptiop_mv_ops
Definition: hptiop.c:1757
static void * hptiop_get_srb(struct hpt_iop_hba *hba)
Definition: hptiop.c:2266
static d_open_t hptiop_open
Definition: hptiop.c:156
static bus_dmamap_callback_t hptiop_post_scsi_command
Definition: hptiop.c:1406
static void hptiop_release_pci_res_mv(struct hpt_iop_hba *hba)
Definition: hptiop.c:1542
static driver_t hptiop_pci_driver
Definition: hptiop.c:1793
static void hptiop_pci_intr(void *arg)
Definition: hptiop.c:2174
static int hptiop_get_config_itl(struct hpt_iop_hba *hba, struct hpt_iop_request_get_config *config)
Definition: hptiop.c:910
static int hptiop_send_sync_request_itl(struct hpt_iop_hba *hba, u_int32_t req32, u_int32_t millisec)
Definition: hptiop.c:804
static int hptiop_get_config_mvfrey(struct hpt_iop_hba *hba, struct hpt_iop_request_get_config *config)
Definition: hptiop.c:966
static void hptiop_action(struct cam_sim *sim, union ccb *ccb)
Definition: hptiop.c:2285
static void hptiop_request_callback_itl(struct hpt_iop_hba *hba, u_int32_t req)
Definition: hptiop.c:326
static int hptiop_set_config_itl(struct hpt_iop_hba *hba, struct hpt_iop_request_set_config *config)
Definition: hptiop.c:997
static int hptiop_alloc_pci_res_itl(struct hpt_iop_hba *hba)
Definition: hptiop.c:1410
#define BUS_SPACE_WRT4_MV0(offset, value)
Definition: hptiop.c:176
DRIVER_MODULE(hptiop, pci, hptiop_pci_driver, hptiop_devclass, 0, 0)
static int hptiop_post_ioctl_command_mv(struct hpt_iop_hba *hba, struct hpt_iop_request_ioctl_command *req, struct hpt_iop_ioctl_param *pParams)
Definition: hptiop.c:1213
static const char driver_version[]
Definition: hptiop.c:78
static void hptiop_async(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
Definition: hptiop.c:2190
static void hptiop_disable_intr_mvfrey(struct hpt_iop_hba *hba)
Definition: hptiop.c:2246
static devclass_t hptiop_devclass
Definition: hptiop.c:80
static int hptiop_internal_memalloc_mvfrey(struct hpt_iop_hba *hba)
Definition: hptiop.c:1606
static int hptiop_os_query_remove_device(struct hpt_iop_hba *hba, int tid)
Definition: hptiop.c:2758
static void hptiop_post_msg_mvfrey(struct hpt_iop_hba *hba, u_int32_t msg)
Definition: hptiop.c:282
#define BUS_SPACE_WRT4_MVFREY2(offset, value)
Definition: hptiop.c:185
static int hptiop_alloc_pci_res_mvfrey(struct hpt_iop_hba *hba)
Definition: hptiop.c:1485
static void hptiop_free_srb(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb)
Definition: hptiop.c:2279
static int hptiop_internal_memfree_itl(struct hpt_iop_hba *hba)
Definition: hptiop.c:1663
static void hptiop_post_req_mvfrey(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs)
Definition: hptiop.c:2561
static device_method_t driver_methods[]
Definition: hptiop.c:1730
static void hptiop_disable_intr_mv(struct hpt_iop_hba *hba)
Definition: hptiop.c:2235
static int hptiop_bus_space_copyout(struct hpt_iop_hba *hba, u_int32_t bus, void *user, int size)
Definition: hptiop.c:1145
#define HPT_IOCTL_FLAG_OPEN
Definition: hptiop.h:423
#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT
Definition: hptiop.h:227
#define HPT_SCAN_BUS
Definition: hptiop.h:474
@ MV_BASED_IOP
Definition: hptiop.h:431
@ MVFREY_BASED_IOP
Definition: hptiop.h:432
@ INTEL_BASED_IOP
Definition: hptiop.h:430
#define KdPrint(x)
Definition: hptiop.h:38
#define MVIOP_MU_QUEUE_REQUEST_RESULT_BIT
Definition: hptiop.h:187
#define MVIOP_IOCTLCFG_SIZE
Definition: hptiop.h:182
#define IOPMU_QUEUE_EMPTY
Definition: hptiop.h:79
#define MVIOP_MU_QUEUE_ADDR_HOST_BIT
Definition: hptiop.h:184
#define IOPMU_OUTBOUND_INT_POSTQUEUE
Definition: hptiop.h:90
#define HPT_CTL_CODE_BSD_TO_IOP(x)
Definition: hptiop.h:336
#define IOP_REQUEST_FLAG_ADDR_BITS
Definition: hptiop.h:229
#define IOPMU_QUEUE_MASK_HOST_BITS
Definition: hptiop.h:80
#define IOPMU_QUEUE_ADDR_HOST_BIT
Definition: hptiop.h:81
#define HPT_SRB_FLAG_HIGH_MEM_ACESS
Definition: hptiop.h:49
#define MVFREYIOPMU_QUEUE_REQUEST_RESULT_BIT
Definition: hptiop.h:203
#define IOPMU_OUTBOUND_INT_MSG0
Definition: hptiop.h:87
#define MIN(a, b)
Definition: hptiop.h:56
#define MVIOP_CMD_TYPE_SCSI
Definition: hptiop.h:197
#define HPT_IOCTL_MAGIC
Definition: hptiop.h:59
#define IOP_REQUEST_FLAG_SYNC_REQUEST
Definition: hptiop.h:224
#define HPT_SRB_MAX_SIZE
Definition: hptiop.h:50
#define MVIOP_MU_OUTBOUND_INT_MSG
Definition: hptiop.h:192
struct cdev * ioctl_dev_t
Definition: hptiop.h:338
#define offsetof(TYPE, MEM)
Definition: hptiop.h:52
#define MVIOP_CMD_TYPE_IOCTL
Definition: hptiop.h:198
#define IOPMU_MAX_MEM_SUPPORT_MASK_32G
Definition: hptiop.h:85
#define CPU_TO_F0_DRBL_MSG_A_BIT
Definition: hptiop.h:121
@ IOPMU_INBOUND_MSG0_RESET
Definition: hptiop.h:208
@ IOPMU_INBOUND_MSG0_RESET_COMM
Definition: hptiop.h:213
@ IOPMU_INBOUND_MSG0_NOP
Definition: hptiop.h:207
@ IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK
Definition: hptiop.h:211
@ IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK
Definition: hptiop.h:212
@ IOPMU_INBOUND_MSG0_SHUTDOWN
Definition: hptiop.h:210
#define hptiop_lock_adapter(hba)
Definition: hptiop.h:468
static __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident, int priority, const char *wmesg, int timo)
Definition: hptiop.h:476
#define MVIOP_QUEUE_LEN
Definition: hptiop.h:99
#define HPT_SRB_MAX_REQ_SIZE
Definition: hptiop.h:45
#define MVIOP_CMD_TYPE_SET_CONFIG
Definition: hptiop.h:196
#define MVIOP_REQUEST_NUMBER_START_BIT
Definition: hptiop.h:201
#define CL_POINTER_TOGGLE
Definition: hptiop.h:120
#define hptiop_unlock_adapter(hba)
Definition: hptiop.h:469
#define HPT_OSM_TIMEOUT
Definition: hptiop.h:471
@ IOP_REQUEST_TYPE_SCSI_COMMAND
Definition: hptiop.h:235
@ IOP_REQUEST_TYPE_IOCTL_COMMAND
Definition: hptiop.h:236
@ IOP_REQUEST_TYPE_GET_CONFIG
Definition: hptiop.h:232
@ IOP_REQUEST_TYPE_SET_CONFIG
Definition: hptiop.h:233
struct thread * ioctl_thread_t
Definition: hptiop.h:340
#define IOPMU_QUEUE_REQUEST_SIZE_BIT
Definition: hptiop.h:82
#define HPT_IOCTL_MAGIC32
Definition: hptiop.h:60
#define HPT_SRB_MAX_QUEUE_SIZE
Definition: hptiop.h:46
@ IOP_RESULT_FAIL
Definition: hptiop.h:243
@ IOP_RESULT_PENDING
Definition: hptiop.h:241
@ IOP_RESULT_RESET
Definition: hptiop.h:245
@ IOP_RESULT_CHECK_CONDITION
Definition: hptiop.h:248
@ IOP_RESULT_BUSY
Definition: hptiop.h:244
@ IOP_RESULT_INVALID_REQUEST
Definition: hptiop.h:246
@ IOP_RESULT_SUCCESS
Definition: hptiop.h:242
@ IOP_RESULT_BAD_TARGET
Definition: hptiop.h:247
#define MVIOP_CMD_TYPE_GET_CONFIG
Definition: hptiop.h:195
#define MVIOP_MU_QUEUE_REQUEST_RETURN_CONTEXT
Definition: hptiop.h:188
#define MVIOP_MU_OUTBOUND_INT_POSTQUEUE
Definition: hptiop.h:193
#define HPT_DO_IOCONTROL
Definition: hptiop.h:473
#define MVIOP_MU_INBOUND_INT_POSTQUEUE
Definition: hptiop.h:191
#define MVIOP_MU_INBOUND_INT_MSG
Definition: hptiop.h:190
#define IOPMU_QUEUE_REQUEST_RESULT_BIT
Definition: hptiop.h:83
ioctl_dev_t ioctl_dev
Definition: hptiop.h:382
u_int32_t flag
Definition: hptiop.h:424
struct hpt_iop_request_get_config * config
Definition: hptiop.h:353
u_int64_t inlist_phy
Definition: hptiop.h:359
bus_space_handle_t bar0h
Definition: hptiop.h:394
struct hpt_iop_hba::@0::@2 mv
bus_dma_tag_t ctlcfg_dmat
Definition: hptiop.h:387
u_int32_t outlist_rptr
Definition: hptiop.h:365
u_int32_t max_requests
Definition: hptiop.h:374
int bar2_rid
Definition: hptiop.h:400
u_int32_t msg_done
Definition: hptiop.h:378
struct resource * bar0_res
Definition: hptiop.h:392
void * ctlcfg_ptr
Definition: hptiop.h:404
u_int32_t inlist_wptr
Definition: hptiop.h:360
struct hpt_iop_hba::@0::@3 mvfrey
bus_dmamap_t ctlcfg_dmamap
Definition: hptiop.h:390
struct mvfrey_outlist_entry * outlist
Definition: hptiop.h:361
u_int64_t outlist_phy
Definition: hptiop.h:362
void * req
Definition: hptiop.h:421
bus_dmamap_t srb_dmamap
Definition: hptiop.h:389
struct hptiop_adapter_ops * ops
Definition: hptiop.h:343
bus_space_tag_t bar2t
Definition: hptiop.h:398
int list_count
Definition: hptiop.h:357
struct mvfrey_inlist_entry * inlist
Definition: hptiop.h:358
void * irq_handle
Definition: hptiop.h:409
struct resource * irq_res
Definition: hptiop.h:408
struct hpt_iop_srb * srb[HPT_SRB_MAX_QUEUE_SIZE]
Definition: hptiop.h:425
struct hpt_iop_srb * srb_list
Definition: hptiop.h:406
bus_dma_tag_t io_dmat
Definition: hptiop.h:385
struct hpt_iopmv_regs * regs
Definition: hptiop.h:349
struct hpt_iopmu_itl * mu
Definition: hptiop.h:346
int internal_mem_size
Definition: hptiop.h:356
u_int32_t max_devices
Definition: hptiop.h:373
u_int32_t interface_version
Definition: hptiop.h:372
bus_space_tag_t bar0t
Definition: hptiop.h:393
u_int32_t firmware_version
Definition: hptiop.h:371
struct mtx lock
Definition: hptiop.h:422
u_int32_t config_done
Definition: hptiop.h:415
union hpt_iop_hba::@0 u
device_t pcidev
Definition: hptiop.h:380
struct resource * bar2_res
Definition: hptiop.h:397
u_int32_t * outlist_cptr
Definition: hptiop.h:363
u_int32_t initialized
Definition: hptiop.h:416
u_int64_t ctlcfgcmd_phy
Definition: hptiop.h:414
int bar0_rid
Definition: hptiop.h:395
bus_dma_tag_t srb_dmat
Definition: hptiop.h:386
struct hpt_iop_hba::@0::@1 itl
bus_dma_tag_t parent_dmat
Definition: hptiop.h:384
u_int32_t pciunit
Definition: hptiop.h:381
u_int32_t max_sg_count
Definition: hptiop.h:376
struct cam_sim * sim
Definition: hptiop.h:419
u_int8_t * uncached_ptr
Definition: hptiop.h:403
u_int64_t outlist_cptr_phy
Definition: hptiop.h:364
struct cam_path * path
Definition: hptiop.h:420
u_int32_t max_request_size
Definition: hptiop.h:375
bus_space_handle_t bar2h
Definition: hptiop.h:399
unsigned long lpOutBuffer
Definition: hptiop.h:330
u_int32_t nInBufferSize
Definition: hptiop.h:329
u_int32_t Magic
Definition: hptiop.h:326
unsigned long lpInBuffer
Definition: hptiop.h:328
u_int32_t dwIoControlCode
Definition: hptiop.h:327
unsigned long lpBytesReturned
Definition: hptiop.h:332
u_int32_t nOutBufferSize
Definition: hptiop.h:331
u_int32_t interface_version
Definition: hptiop.h:262
u_int32_t firmware_version
Definition: hptiop.h:263
struct hpt_iop_request_header header
Definition: hptiop.h:261
u_int32_t alignment_mask
Definition: hptiop.h:268
u_int32_t data_transfer_length
Definition: hptiop.h:267
u_int64_t context
Definition: hptiop.h:257
u_int32_t result
Definition: hptiop.h:256
struct hpt_iop_request_header header
Definition: hptiop.h:316
struct hpt_iopsg sg_list[1]
Definition: hptiop.h:312
struct hpt_iop_request_header header
Definition: hptiop.h:305
struct hpt_iop_request_header header
Definition: hptiop.h:274
u_int16_t max_host_request_size
Definition: hptiop.h:277
struct hpt_iop_srb * next
Definition: hptiop.h:460
union ccb * ccb
Definition: hptiop.h:459
struct callout timeout
Definition: hptiop.h:465
bus_dmamap_t dma_map
Definition: hptiop.h:461
u_int32_t srb_flag
Definition: hptiop.h:463
u_int64_t phy_addr
Definition: hptiop.h:462
struct hpt_iop_hba * hba
Definition: hptiop.h:458
int index
Definition: hptiop.h:464
u_int32_t inbound_conf_ctl
Definition: hptiop.h:134
u_int32_t size
Definition: hptiop.h:282
u_int32_t eot
Definition: hptiop.h:283
u_int64_t pci_address
Definition: hptiop.h:284
int(* internal_memalloc)(struct hpt_iop_hba *hba)
Definition: hptiop.h:439
int(* reset_comm)(struct hpt_iop_hba *hba)
Definition: hptiop.h:453
int(* iop_wait_ready)(struct hpt_iop_hba *hba, u_int32_t millisec)
Definition: hptiop.h:438
int(* set_config)(struct hpt_iop_hba *hba, struct hpt_iop_request_set_config *config)
Definition: hptiop.h:447
int(* internal_memfree)(struct hpt_iop_hba *hba)
Definition: hptiop.h:440
void(* post_msg)(struct hpt_iop_hba *hba, u_int32_t msg)
Definition: hptiop.h:450
int(* get_config)(struct hpt_iop_hba *hba, struct hpt_iop_request_get_config *config)
Definition: hptiop.h:445
int(* do_ioctl)(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams)
Definition: hptiop.h:452
void(* enable_intr)(struct hpt_iop_hba *hba)
Definition: hptiop.h:443
enum hptiop_family family
Definition: hptiop.h:437
int(* alloc_pci_res)(struct hpt_iop_hba *hba)
Definition: hptiop.h:441
void(* disable_intr)(struct hpt_iop_hba *hba)
Definition: hptiop.h:444
int(* iop_intr)(struct hpt_iop_hba *hba)
Definition: hptiop.h:449
void(* release_pci_res)(struct hpt_iop_hba *hba)
Definition: hptiop.h:442
void(* post_req)(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs)
Definition: hptiop.h:451
Definition: hptiop.h:170
u_int64_t addr
Definition: hptiop.h:171
u_int32_t intrfc_len
Definition: hptiop.h:172
Definition: hptiop.h:176
u_int32_t val
Definition: hptiop.h:177