39#include <sys/malloc.h>
41#include <sys/libkern.h>
42#include <sys/kernel.h>
44#include <sys/kthread.h>
46#include <sys/module.h>
48#include <sys/eventhandler.h>
50#include <sys/taskqueue.h>
51#include <sys/ioccom.h>
53#include <machine/resource.h>
54#include <machine/bus.h>
55#include <machine/stdarg.h>
61#include <dev/pci/pcireg.h>
62#include <dev/pci/pcivar.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>
83 u_int32_t msg, u_int32_t millisec);
127 bus_dma_segment_t *segs,
int nsegs);
130 bus_dma_segment_t *segs,
int nsegs);
133 bus_dma_segment_t *segs,
int nsegs);
149static void hptiop_action(
struct cam_sim *sim,
union ccb *ccb);
151static void hptiop_async(
void *callback_arg, u_int32_t code,
152 struct cam_path *path,
void *arg);
165 .d_version = D_VERSION,
168#define hba_from_dev(dev) \
169 ((struct hpt_iop_hba *)devclass_get_softc(hptiop_devclass, dev2unit(dev)))
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))
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))
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))
235 if (outbound_tail != outbound_head) {
236 bus_space_read_region_4(hba->
bar2t, hba->
bar2h,
238 outbound_q[outbound_tail]),
255 u_int32_t head = inbound_head + 1;
260 bus_space_write_region_4(hba->
bar2t, hba->
bar2h,
293 for (i = 0; i < millisec; i++) {
333 u_int32_t result, temp, dxfer;
339 srb = hba->
srb[index & ~(u_int32_t)
348 srb = hba->
srb[index &
358 temp = bus_space_read_4(hba->
bar0t, hba->
bar0h, index +
360 result = bus_space_read_4(hba->
bar0t, hba->
bar0h, index +
366 bus_space_write_region_4(hba->
bar0t, hba->
bar0h, index +
368 (u_int32_t *)&temp64, 2);
369 wakeup((
void *)((
unsigned long)hba->
u.
itl.
mu + index));
374 bus_space_read_region_4(hba->
bar0t, hba->
bar0h, index +
376 (u_int32_t *)&temp64, 2);
382 ccb = (
union ccb *)srb->
ccb;
383 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
384 cdb = ccb->csio.cdb_io.cdb_ptr;
386 cdb = ccb->csio.cdb_io.cdb_bytes;
388 if (cdb[0] == SYNCHRONIZE_CACHE) {
389 ccb->ccb_h.status = CAM_REQ_CMP;
395 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
398 srb->
dma_map, BUS_DMASYNC_POSTREAD);
403 srb->
dma_map, BUS_DMASYNC_POSTWRITE);
408 ccb->ccb_h.status = CAM_REQ_CMP;
412 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
415 ccb->ccb_h.status = CAM_BUSY;
418 ccb->ccb_h.status = CAM_REQ_INVALID;
421 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
424 ccb->ccb_h.status = CAM_BUSY;
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 -
433 ccb->csio.sense_resid = 0;
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)));
440 memcpy(&ccb->csio.sense_data, &req->
sg_list,
441 MIN(dxfer,
sizeof(ccb->csio.sense_data)));
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;
448 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
455 ccb->csio.resid = ccb->csio.dxfer_len - dxfer;
471 temp = bus_space_read_4(hba->
bar0t,
477 bus_space_read_region_4(hba->
bar0t,
481 (u_int32_t *)&temp64, 2);
486 bus_space_write_region_4(hba->
bar0t,
490 (u_int32_t *)&temp64, 2);
507 KdPrint((
"hptiop: received outbound msg %x\n", msg));
524 u_int32_t context = (u_int32_t)_tag;
534 ccb = (
union ccb *)srb->
ccb;
535 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
536 cdb = ccb->csio.cdb_io.cdb_ptr;
538 cdb = ccb->csio.cdb_io.cdb_bytes;
540 if (cdb[0] == SYNCHRONIZE_CACHE) {
541 ccb->ccb_h.status = CAM_REQ_CMP;
549 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
552 srb->
dma_map, BUS_DMASYNC_POSTREAD);
557 srb->
dma_map, BUS_DMASYNC_POSTWRITE);
561 ccb->ccb_h.status = CAM_REQ_CMP;
564 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
567 ccb->ccb_h.status = CAM_BUSY;
570 ccb->ccb_h.status = CAM_REQ_INVALID;
573 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
576 ccb->ccb_h.status = CAM_BUSY;
579 memset(&ccb->csio.sense_data, 0,
580 sizeof(ccb->csio.sense_data));
582 ccb->csio.sense_resid = ccb->csio.sense_len -
585 ccb->csio.sense_resid = 0;
586 memcpy(&ccb->csio.sense_data, &req->
sg_list,
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;
593 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
613 device_printf(hba->
pcidev,
"wrong callback type\n");
620 u_int32_t req_type = _tag & 0xf;
634 srb = hba->
srb[(_tag >> 4) & 0xff];
637 ccb = (
union ccb *)srb->
ccb;
641 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
642 cdb = ccb->csio.cdb_io.cdb_ptr;
644 cdb = ccb->csio.cdb_io.cdb_bytes;
646 if (cdb[0] == SYNCHRONIZE_CACHE) {
647 ccb->ccb_h.status = CAM_REQ_CMP;
656 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
659 srb->
dma_map, BUS_DMASYNC_POSTREAD);
664 srb->
dma_map, BUS_DMASYNC_POSTWRITE);
668 ccb->ccb_h.status = CAM_REQ_CMP;
671 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
674 ccb->ccb_h.status = CAM_BUSY;
677 ccb->ccb_h.status = CAM_REQ_INVALID;
680 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
683 ccb->ccb_h.status = CAM_BUSY;
686 memset(&ccb->csio.sense_data, 0,
687 sizeof(ccb->csio.sense_data));
689 ccb->csio.sense_resid = ccb->csio.sense_len -
692 ccb->csio.sense_resid = 0;
693 memcpy(&ccb->csio.sense_data, &req->
sg_list,
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;
700 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
717 device_printf(hba->
pcidev,
"wrong callback type\n");
747 KdPrint((
"hptiop: received outbound msg %x\n", msg));
762 u_int32_t status, _tag, cptr;
805 u_int32_t req32, u_int32_t millisec)
813 for (i = 0; i < millisec; i++) {
815 bus_space_read_region_4(hba->
bar0t, hba->
bar0h, req32 +
817 (u_int32_t *)&temp64, 2);
827 void *req, u_int32_t millisec)
841 for (i = 0; i < millisec; i++) {
851 void *req, u_int32_t millisec)
864 | ((phy_addr >> 16) & 0xffff0000);
865 reqhdr->
context = ((phy_addr & 0xffffffff) << 32 )
883 for (i = 0; i < millisec; i++) {
893 u_int32_t msg, u_int32_t millisec)
900 for (i=0; i<millisec; i++) {
925 bus_space_write_region_4(hba->
bar0t, hba->
bar0h,
926 req32, (u_int32_t *)config,
930 KdPrint((
"hptiop: get config send cmd failed"));
934 bus_space_read_region_4(hba->
bar0t, hba->
bar0h,
935 req32, (u_int32_t *)config,
958 KdPrint((
"hptiop: get config send cmd failed"));
973 KdPrint((
"hptiop: header size %x/%x type %x/%x",
989 KdPrint((
"hptiop: maxreq %x reqsz %x datalen %x maxdev %x sdram %x",
1013 bus_space_write_region_4(hba->
bar0t, hba->
bar0h, req32,
1014 (u_int32_t *)config,
1018 KdPrint((
"hptiop: set config send cmd failed"));
1047 KdPrint((
"hptiop: set config send cmd failed"));
1072 KdPrint((
"hptiop: set config send cmd failed"));
1089 device_printf(hba->
pcidev,
"request size beyond max value");
1104 bus_space_write_region_4(hba->
bar0t, hba->
bar0h, req32, (u_int32_t *)&req,
1112 bus_space_read_region_4(hba->
bar0t, hba->
bar0h, req32 +
1114 (u_int32_t *)&temp64, 2);
1120 bus_space_read_region_4(hba->
bar0t, hba->
bar0h,req32 +
1123 (u_int32_t *)&temp64, 2);
1131 void *user,
int size)
1136 for (i=0; i<size; i++) {
1137 if (copyin((u_int8_t *)user + i, &
byte, 1))
1139 bus_space_write_1(hba->
bar0t, hba->
bar0h, bus + i,
byte);
1146 void *user,
int size)
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))
1183 result = bus_space_read_4(hba->
bar0t, hba->
bar0h, req32 +
1223 device_printf(hba->
pcidev,
"request size beyond max value");
1237 size = imin(3, size);
1273 if (copyout(req->
buf +
1305 device_printf(hba->
pcidev,
"request size beyond max value");
1321 | ((phy_addr >> 16) & 0xffff0000);
1370 if (copyout(req->
buf +
1394 if ((ccb = xpt_alloc_ccb()) == NULL)
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) {
1414 SYS_RES_MEMORY, &hba->
bar0_rid, RF_ACTIVE);
1417 device_printf(hba->
pcidev,
1418 "failed to get iop base adrress.\n");
1427 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1429 device_printf(hba->
pcidev,
"alloc mem res failed\n");
1440 SYS_RES_MEMORY, &hba->
bar0_rid, RF_ACTIVE);
1443 device_printf(hba->
pcidev,
"failed to get iop bar0.\n");
1452 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1454 device_printf(hba->
pcidev,
"alloc bar0 mem res failed\n");
1460 SYS_RES_MEMORY, &hba->
bar2_rid, RF_ACTIVE);
1463 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1465 device_printf(hba->
pcidev,
"failed to get iop bar2.\n");
1473 if (!hba->
u.
mv.
mu) {
1474 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1476 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1478 device_printf(hba->
pcidev,
"alloc mem bar2 res failed\n");
1489 SYS_RES_MEMORY, &hba->
bar0_rid, RF_ACTIVE);
1492 device_printf(hba->
pcidev,
"failed to get iop bar0.\n");
1501 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1503 device_printf(hba->
pcidev,
"alloc bar0 mem res failed\n");
1509 SYS_RES_MEMORY, &hba->
bar2_rid, RF_ACTIVE);
1512 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1514 device_printf(hba->
pcidev,
"failed to get iop bar2.\n");
1524 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1526 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1528 device_printf(hba->
pcidev,
"alloc mem bar2 res failed\n");
1538 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1545 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1548 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1555 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1558 bus_release_resource(hba->
pcidev, SYS_RES_MEMORY,
1567 BUS_SPACE_MAXADDR_32BIT,
1572 BUS_SPACE_MAXSIZE_32BIT,
1577 device_printf(hba->
pcidev,
"alloc ctlcfg_dmat failed\n");
1582 BUS_DMA_WAITOK | BUS_DMA_COHERENT,
1584 device_printf(hba->
pcidev,
1585 "bus_dmamem_alloc failed!\n");
1594 device_printf(hba->
pcidev,
"bus_dmamap_load failed!\n");
1612 if (list_count == 0) {
1624 BUS_SPACE_MAXADDR_32BIT,
1629 BUS_SPACE_MAXSIZE_32BIT,
1634 device_printf(hba->
pcidev,
"alloc ctlcfg_dmat failed\n");
1639 BUS_DMA_WAITOK | BUS_DMA_COHERENT,
1641 device_printf(hba->
pcidev,
1642 "bus_dmamem_alloc failed!\n");
1651 device_printf(hba->
pcidev,
"bus_dmamap_load failed!\n");
1742 .internal_memalloc = 0,
1806 static char buf[256];
1810 if (pci_get_vendor(dev) != 0x1103)
1813 id = pci_get_device(dev);
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));
1859 sprintf(buf,
"RocketRAID %x %s Controller\n",
1860 id, sas ?
"SAS" :
"SATA");
1861 device_set_desc_copy(dev, buf);
1863 hba = (
struct hpt_iop_hba *)device_get_softc(dev);
1877 struct cam_devq *devq;
1878 struct ccb_setasync ccb;
1879 u_int32_t unit = device_get_unit(dev);
1881 device_printf(dev,
"%d RocketRAID 3xxx/4xxx controller driver %s\n",
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));
1888 pci_enable_busmaster(dev);
1896 device_printf(dev,
"adapter is not ready\n");
1897 goto release_pci_res;
1900 mtx_init(&hba->
lock,
"hptioplock", NULL, MTX_DEF);
1902 if (bus_dma_tag_create(bus_get_dma_tag(dev),
1908 BUS_SPACE_MAXSIZE_32BIT,
1909 BUS_SPACE_UNRESTRICTED,
1910 BUS_SPACE_MAXSIZE_32BIT,
1916 device_printf(dev,
"alloc parent_dmat failed\n");
1917 goto release_pci_res;
1922 device_printf(dev,
"alloc srb_dmat failed\n");
1923 goto destroy_parent_tag;
1928 device_printf(dev,
"get iop config failed.\n");
1929 goto get_config_failed;
1941 device_printf(dev,
"alloc srb_dmat failed\n");
1942 goto destroy_parent_tag;
1945 device_printf(dev,
"reset comm failed\n");
1946 goto get_config_failed;
1952 BUS_SPACE_MAXADDR_32BIT+1,
1964 device_printf(dev,
"alloc io_dmat failed\n");
1965 goto get_config_failed;
1971 BUS_SPACE_MAXADDR_32BIT,
1976 BUS_SPACE_MAXSIZE_32BIT,
1982 device_printf(dev,
"alloc srb_dmat failed\n");
1983 goto destroy_io_dmat;
1987 BUS_DMA_WAITOK | BUS_DMA_COHERENT,
1990 device_printf(dev,
"srb bus_dmamem_alloc failed!\n");
1991 goto destroy_srb_dmat;
1999 device_printf(dev,
"bus_dmamap_load failed!\n");
2000 goto srb_dmamem_free;
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;
2011 device_printf(dev,
"cam_sim_alloc failed\n");
2012 cam_simq_free(devq);
2013 goto srb_dmamap_unload;
2016 if (xpt_bus_register(hba->
sim, dev, 0) != CAM_SUCCESS)
2018 device_printf(dev,
"xpt_bus_register failed\n");
2022 if (xpt_create_path(&hba->
path, 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;
2030 bzero(&set_config,
sizeof(set_config));
2031 set_config.
iop_id = unit;
2036 device_printf(dev,
"set iop config failed.\n");
2040 memset(&ccb, 0,
sizeof(ccb));
2041 xpt_setup_ccb(&ccb.ccb_h, hba->
path, 5);
2042 ccb.ccb_h.func_code = XPT_SASYNC_CB;
2043 ccb.event_enable = (AC_FOUND_DEVICE | AC_LOST_DEVICE);
2045 ccb.callback_arg = hba->
sim;
2046 xpt_action((
union ccb *)&ccb);
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");
2055 if (bus_setup_intr(hba->
pcidev, hba->
irq_res, INTR_TYPE_CAM | INTR_MPSAFE,
2058 device_printf(dev,
"allocate intr function failed!\n");
2059 goto free_irq_resource;
2064 device_printf(dev,
"fail to start background task\n");
2065 goto teartown_irq_resource;
2072 UID_ROOT, GID_WHEEL ,
2079teartown_irq_resource:
2083 bus_release_resource(dev, SYS_RES_IRQ, 0, hba->
irq_res);
2087 xpt_free_path(hba->
path);
2090 xpt_bus_deregister(cam_sim_path(hba->
sim));
2093 cam_sim_free(hba->
sim, TRUE);
2107 bus_dma_tag_destroy(hba->
srb_dmat);
2111 bus_dma_tag_destroy(hba->
io_dmat);
2136 device_printf(dev,
"%d file system is busy. id=%d",
2162 device_printf(dev,
"%d device is busy", hba->
pciunit);
2186 hba = cam_sim_softc(
sim);
2191 struct cam_path *
path,
void * arg)
2291 switch (
ccb->ccb_h.func_code) {
2294 if (
ccb->ccb_h.target_lun != 0 ||
2296 (
ccb->ccb_h.flags & CAM_CDB_PHYS))
2298 ccb->ccb_h.status = CAM_TID_INVALID;
2304 device_printf(
hba->
pcidev,
"srb allocated failed");
2305 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2318 if (error && error != EINPROGRESS) {
2320 "%d bus_dmamap_load error %d",
2322 xpt_freeze_simq(
hba->
sim, 1);
2323 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2332 device_printf(
hba->
pcidev,
"reset adapter");
2337 case XPT_GET_TRAN_SETTINGS:
2338 case XPT_SET_TRAN_SETTINGS:
2339 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
2342 case XPT_CALC_GEOMETRY:
2343 cam_calc_geometry(&
ccb->ccg, 1);
2348 struct ccb_pathinq *cpi = &ccb->cpi;
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;
2357 cpi->unit_number = cam_sim_unit(sim);
2358 cpi->bus_id = cam_sim_bus(sim);
2360 cpi->base_transfer_speed = 3300;
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;
2374 ccb->ccb_h.status = CAM_REQ_INVALID;
2384 bus_dma_segment_t *segs,
int nsegs)
2387 union ccb *ccb = srb->
ccb;
2390 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
2391 cdb = ccb->csio.cdb_io.cdb_ptr;
2393 cdb = ccb->csio.cdb_io.cdb_bytes;
2396 ccb, *(u_int32_t *)cdb, *((u_int32_t *)cdb+1), *((u_int32_t *)cdb+2)));
2399 u_int32_t iop_req32;
2405 device_printf(hba->
pcidev,
"invalid req offset\n");
2406 ccb->ccb_h.status = CAM_BUSY;
2413 if (ccb->csio.dxfer_len && nsegs > 0) {
2415 for (idx = 0; idx < nsegs; idx++, psg++) {
2417 psg->
size = segs[idx].ds_len;
2423 bcopy(cdb, req.
cdb, ccb->csio.cdb_len);
2434 req.
target = ccb->ccb_h.target_id;
2435 req.
lun = ccb->ccb_h.target_lun;
2437 bus_space_write_region_1(hba->
bar0t, hba->
bar0h, iop_req32,
2440 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2442 srb->
dma_map, BUS_DMASYNC_PREREAD);
2444 else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2446 srb->
dma_map, BUS_DMASYNC_PREWRITE);
2453 if (ccb->csio.dxfer_len && nsegs > 0) {
2455 for (idx = 0; idx < nsegs; idx++, psg++) {
2457 (u_int64_t)segs[idx].ds_addr;
2458 psg->
size = segs[idx].ds_len;
2464 bcopy(cdb, req->
cdb, ccb->csio.cdb_len);
2470 req->
target = ccb->ccb_h.target_id;
2471 req->
lun = ccb->ccb_h.target_lun;
2479 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2481 srb->
dma_map, BUS_DMASYNC_PREREAD);
2482 }
else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
2484 srb->
dma_map, BUS_DMASYNC_PREWRITE);
2489 u_int32_t size_bits;
2500 (u_int32_t)srb->
phy_addr | size_bits);
2509 bus_dma_segment_t *segs,
int nsegs)
2512 union ccb *ccb = srb->
ccb;
2520 if (ccb->csio.dxfer_len && nsegs > 0) {
2522 for (idx = 0; idx < nsegs; idx++, psg++) {
2524 psg->
size = segs[idx].ds_len;
2529 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
2530 cdb = ccb->csio.cdb_io.cdb_ptr;
2532 cdb = ccb->csio.cdb_io.cdb_bytes;
2534 bcopy(cdb, req->
cdb, ccb->csio.cdb_len);
2539 req->
target = ccb->ccb_h.target_id;
2540 req->
lun = ccb->ccb_h.target_lun;
2544 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2546 srb->
dma_map, BUS_DMASYNC_PREREAD);
2548 else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2550 srb->
dma_map, BUS_DMASYNC_PREWRITE);
2558 | imin(3,
size), hba);
2563 bus_dma_segment_t *segs,
int nsegs)
2566 union ccb *ccb = srb->
ccb;
2574 if (ccb->csio.dxfer_len && nsegs > 0) {
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;
2583 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
2584 cdb = ccb->csio.cdb_io.cdb_ptr;
2586 cdb = ccb->csio.cdb_io.cdb_bytes;
2588 bcopy(cdb, req->
cdb, ccb->csio.cdb_len);
2593 req->
target = ccb->ccb_h.target_id;
2594 req->
lun = ccb->ccb_h.target_lun;
2598 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2600 srb->
dma_map, BUS_DMASYNC_PREREAD);
2602 else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2604 srb->
dma_map, BUS_DMASYNC_PREWRITE);
2608 | ((req_phy >> 16) & 0xffff0000);
2634 int nsegs,
int error)
2637 union ccb *ccb = srb->
ccb;
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;
2656 int nsegs,
int error)
2666 int nsegs,
int error)
2673 phy = ((u_int64_t)segs->ds_addr + 0x1F)
2675 p = (u_int8_t *)(((
unsigned long)hba->
ctlcfg_ptr + 0x1F)
2701 int nsegs,
int error)
2704 bus_addr_t phy_addr = (segs->ds_addr + 0x1F) & ~(bus_addr_t)0x1F;
2708 if (error || nsegs == 0) {
2709 device_printf(
hba->
pcidev,
"hptiop_map_srb error");
2716 & ~(
unsigned long)0x1F);
2721 if (((
unsigned long)tmp_srb & 0x1F) == 0) {
2724 device_printf(
hba->
pcidev,
"dmamap create failed");
2732 tmp_srb->
phy_addr = (u_int64_t)(u_int32_t)
2747 device_printf(
hba->
pcidev,
"invalid alignment");
2761 struct cam_periph *periph = NULL;
2762 struct cam_path *path;
2763 int status, retval = 0;
2765 status = xpt_create_path(&path, NULL, hba->
sim->path_id, target_id, 0);
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 ,"
2773 hba->
pciunit, target_id, periph->refcount);
2777 xpt_free_path(path);
2790 struct ccb_setasync ccb;
2792 memset(&ccb, 0,
sizeof(ccb));
2793 xpt_setup_ccb(&ccb.ccb_h, hba->
path, 5);
2794 ccb.ccb_h.func_code = XPT_SASYNC_CB;
2795 ccb.event_enable = 0;
2797 ccb.callback_arg = hba->
sim;
2798 xpt_action((
union ccb *)&ccb);
2799 xpt_free_path(hba->
path);
2807 xpt_bus_deregister(cam_sim_path(hba->
sim));
2808 cam_sim_free(hba->
sim, TRUE);
2839 bus_release_resource(
hba->
pcidev, SYS_RES_IRQ,
2843 bus_release_resource(
hba->
pcidev, SYS_RES_MEMORY,
2846 bus_release_resource(
hba->
pcidev, SYS_RES_MEMORY,
static d_ioctl_t hptiop_ioctl
static void hptiop_poll(struct cam_sim *sim)
static d_close_t hptiop_close
static int hptiop_send_sync_msg(struct hpt_iop_hba *hba, u_int32_t msg, u_int32_t millisec)
static int hptiop_set_config_mvfrey(struct hpt_iop_hba *hba, struct hpt_iop_request_set_config *config)
static int hptiop_intr_mvfrey(struct hpt_iop_hba *hba)
static int hptiop_internal_memfree_mv(struct hpt_iop_hba *hba)
static int hptiop_get_config_mv(struct hpt_iop_hba *hba, struct hpt_iop_request_get_config *config)
#define BUS_SPACE_RD4_MV2(offset)
static void hptiop_post_req_mv(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs)
static int hptiop_detach(device_t dev)
static void hptiop_enable_intr_mvfrey(struct hpt_iop_hba *hba)
static int hptiop_set_config_mv(struct hpt_iop_hba *hba, struct hpt_iop_request_set_config *config)
#define BUS_SPACE_RD4_MVFREY2(offset)
static int hptiop_intr_itl(struct hpt_iop_hba *hba)
static void hptiop_enable_intr_mv(struct hpt_iop_hba *hba)
static void hptiop_release_pci_res_mvfrey(struct hpt_iop_hba *hba)
static int hptiop_post_ioctl_command_itl(struct hpt_iop_hba *hba, u_int32_t req32, struct hpt_iop_ioctl_param *pParams)
static void hptiop_drain_outbound_queue_mv(struct hpt_iop_hba *hba)
static u_int64_t hptiop_mv_outbound_read(struct hpt_iop_hba *hba)
static void hptiop_release_pci_res_itl(struct hpt_iop_hba *hba)
static int hptiop_internal_memalloc_mv(struct hpt_iop_hba *hba)
static int hptiop_alloc_pci_res_mv(struct hpt_iop_hba *hba)
static const char driver_name[]
static int hptiop_probe(device_t dev)
static int hptiop_wait_ready_itl(struct hpt_iop_hba *hba, u_int32_t millisec)
static int hptiop_do_ioctl_mv(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams)
static void hptiop_request_callback_mv(struct hpt_iop_hba *hba, u_int64_t req)
static void hptiop_release_resource(struct hpt_iop_hba *hba)
static void hptiop_os_message_callback(struct hpt_iop_hba *hba, u_int32_t msg)
static void hptiop_post_msg_mv(struct hpt_iop_hba *hba, u_int32_t msg)
static bus_dmamap_callback_t hptiop_mv_map_ctlcfg
#define BUS_SPACE_WRT4_ITL(offset, value)
static int hptiop_send_sync_request_mv(struct hpt_iop_hba *hba, void *req, u_int32_t millisec)
static int hptiop_wait_ready_mv(struct hpt_iop_hba *hba, u_int32_t millisec)
#define hba_from_dev(dev)
static int hptiop_do_ioctl_mvfrey(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams)
static bus_dmamap_callback_t hptiop_mvfrey_map_ctlcfg
static void hptiop_mv_inbound_write(u_int64_t p, struct hpt_iop_hba *hba)
static void hptiop_post_msg_itl(struct hpt_iop_hba *hba, u_int32_t msg)
static void hptiop_request_callback_mvfrey(struct hpt_iop_hba *hba, u_int32_t req)
static struct hptiop_adapter_ops hptiop_itl_ops
static int hptiop_attach(device_t dev)
static struct hptiop_adapter_ops hptiop_mvfrey_ops
static void hptiop_disable_intr_itl(struct hpt_iop_hba *hba)
static bus_dmamap_callback_t hptiop_map_srb
#define BUS_SPACE_RD4_MV0(offset)
static struct cdevsw hptiop_cdevsw
static void hptiop_reset_adapter(void *argv)
static int hptiop_do_ioctl_itl(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams)
static int hptiop_intr_mv(struct hpt_iop_hba *hba)
static int hptiop_send_sync_request_mvfrey(struct hpt_iop_hba *hba, void *req, u_int32_t millisec)
static int hptiop_internal_memfree_mvfrey(struct hpt_iop_hba *hba)
static int hptiop_rescan_bus(struct hpt_iop_hba *hba)
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)
static int hptiop_wait_ready_mvfrey(struct hpt_iop_hba *hba, u_int32_t millisec)
static int hptiop_reset_comm_mvfrey(struct hpt_iop_hba *hba)
static void hptiop_post_req_itl(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs)
static int hptiop_bus_space_copyin(struct hpt_iop_hba *hba, u_int32_t bus, void *user, int size)
static int hptiop_shutdown(device_t dev)
#define BUS_SPACE_RD4_ITL(offset)
static void hptiop_drain_outbound_queue_itl(struct hpt_iop_hba *hba)
#define BUS_SPACE_WRT4_MV2(offset, value)
MODULE_DEPEND(hptiop, cam, 1, 1, 1)
static void hptiop_enable_intr_itl(struct hpt_iop_hba *hba)
static struct hptiop_adapter_ops hptiop_mv_ops
static void * hptiop_get_srb(struct hpt_iop_hba *hba)
static d_open_t hptiop_open
static bus_dmamap_callback_t hptiop_post_scsi_command
static void hptiop_release_pci_res_mv(struct hpt_iop_hba *hba)
static driver_t hptiop_pci_driver
static void hptiop_pci_intr(void *arg)
static int hptiop_get_config_itl(struct hpt_iop_hba *hba, struct hpt_iop_request_get_config *config)
static int hptiop_send_sync_request_itl(struct hpt_iop_hba *hba, u_int32_t req32, u_int32_t millisec)
static int hptiop_get_config_mvfrey(struct hpt_iop_hba *hba, struct hpt_iop_request_get_config *config)
static void hptiop_action(struct cam_sim *sim, union ccb *ccb)
static void hptiop_request_callback_itl(struct hpt_iop_hba *hba, u_int32_t req)
static int hptiop_set_config_itl(struct hpt_iop_hba *hba, struct hpt_iop_request_set_config *config)
static int hptiop_alloc_pci_res_itl(struct hpt_iop_hba *hba)
#define BUS_SPACE_WRT4_MV0(offset, value)
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)
static const char driver_version[]
static void hptiop_async(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
static void hptiop_disable_intr_mvfrey(struct hpt_iop_hba *hba)
static devclass_t hptiop_devclass
static int hptiop_internal_memalloc_mvfrey(struct hpt_iop_hba *hba)
static int hptiop_os_query_remove_device(struct hpt_iop_hba *hba, int tid)
static void hptiop_post_msg_mvfrey(struct hpt_iop_hba *hba, u_int32_t msg)
#define BUS_SPACE_WRT4_MVFREY2(offset, value)
static int hptiop_alloc_pci_res_mvfrey(struct hpt_iop_hba *hba)
static void hptiop_free_srb(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb)
static int hptiop_internal_memfree_itl(struct hpt_iop_hba *hba)
static void hptiop_post_req_mvfrey(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs)
static device_method_t driver_methods[]
static void hptiop_disable_intr_mv(struct hpt_iop_hba *hba)
static int hptiop_bus_space_copyout(struct hpt_iop_hba *hba, u_int32_t bus, void *user, int size)
#define HPT_IOCTL_FLAG_OPEN
#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT
#define MVIOP_MU_QUEUE_REQUEST_RESULT_BIT
#define MVIOP_IOCTLCFG_SIZE
#define IOPMU_QUEUE_EMPTY
#define MVIOP_MU_QUEUE_ADDR_HOST_BIT
#define IOPMU_OUTBOUND_INT_POSTQUEUE
#define HPT_CTL_CODE_BSD_TO_IOP(x)
#define IOP_REQUEST_FLAG_ADDR_BITS
#define IOPMU_QUEUE_MASK_HOST_BITS
#define IOPMU_QUEUE_ADDR_HOST_BIT
#define HPT_SRB_FLAG_HIGH_MEM_ACESS
#define MVFREYIOPMU_QUEUE_REQUEST_RESULT_BIT
#define IOPMU_OUTBOUND_INT_MSG0
#define MVIOP_CMD_TYPE_SCSI
#define IOP_REQUEST_FLAG_SYNC_REQUEST
#define MVIOP_MU_OUTBOUND_INT_MSG
struct cdev * ioctl_dev_t
#define offsetof(TYPE, MEM)
#define MVIOP_CMD_TYPE_IOCTL
#define IOPMU_MAX_MEM_SUPPORT_MASK_32G
#define CPU_TO_F0_DRBL_MSG_A_BIT
@ IOPMU_INBOUND_MSG0_RESET
@ IOPMU_INBOUND_MSG0_RESET_COMM
@ IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK
@ IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK
@ IOPMU_INBOUND_MSG0_SHUTDOWN
#define hptiop_lock_adapter(hba)
static __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident, int priority, const char *wmesg, int timo)
#define HPT_SRB_MAX_REQ_SIZE
#define MVIOP_CMD_TYPE_SET_CONFIG
#define MVIOP_REQUEST_NUMBER_START_BIT
#define CL_POINTER_TOGGLE
#define hptiop_unlock_adapter(hba)
@ IOP_REQUEST_TYPE_SCSI_COMMAND
@ IOP_REQUEST_TYPE_IOCTL_COMMAND
@ IOP_REQUEST_TYPE_GET_CONFIG
@ IOP_REQUEST_TYPE_SET_CONFIG
struct thread * ioctl_thread_t
#define IOPMU_QUEUE_REQUEST_SIZE_BIT
#define HPT_IOCTL_MAGIC32
#define HPT_SRB_MAX_QUEUE_SIZE
@ IOP_RESULT_CHECK_CONDITION
@ IOP_RESULT_INVALID_REQUEST
#define MVIOP_CMD_TYPE_GET_CONFIG
#define MVIOP_MU_QUEUE_REQUEST_RETURN_CONTEXT
#define MVIOP_MU_OUTBOUND_INT_POSTQUEUE
#define MVIOP_MU_INBOUND_INT_POSTQUEUE
#define MVIOP_MU_INBOUND_INT_MSG
#define IOPMU_QUEUE_REQUEST_RESULT_BIT
struct hpt_iop_request_get_config * config
struct hpt_iop_hba::@0::@2 mv
bus_dma_tag_t ctlcfg_dmat
struct resource * bar0_res
struct hpt_iop_hba::@0::@3 mvfrey
bus_dmamap_t ctlcfg_dmamap
struct mvfrey_outlist_entry * outlist
struct hptiop_adapter_ops * ops
struct mvfrey_inlist_entry * inlist
struct resource * irq_res
struct hpt_iop_srb * srb[HPT_SRB_MAX_QUEUE_SIZE]
struct hpt_iop_srb * srb_list
struct hpt_iopmv_regs * regs
struct hpt_iopmu_itl * mu
u_int32_t interface_version
u_int32_t firmware_version
struct resource * bar2_res
struct hpt_iop_hba::@0::@1 itl
bus_dma_tag_t parent_dmat
u_int64_t outlist_cptr_phy
u_int32_t max_request_size
unsigned long lpOutBuffer
u_int32_t dwIoControlCode
unsigned long lpBytesReturned
u_int32_t interface_version
u_int32_t firmware_version
struct hpt_iop_request_header header
u_int32_t data_transfer_length
struct hpt_iop_request_header header
u_int32_t dataxfer_length
struct hpt_iopsg sg_list[1]
struct hpt_iop_request_header header
struct hpt_iop_request_header header
u_int16_t max_host_request_size
struct hpt_iop_srb * next
u_int32_t inbound_conf_ctl
int(* internal_memalloc)(struct hpt_iop_hba *hba)
int(* reset_comm)(struct hpt_iop_hba *hba)
int(* iop_wait_ready)(struct hpt_iop_hba *hba, u_int32_t millisec)
int(* set_config)(struct hpt_iop_hba *hba, struct hpt_iop_request_set_config *config)
int(* internal_memfree)(struct hpt_iop_hba *hba)
void(* post_msg)(struct hpt_iop_hba *hba, u_int32_t msg)
int(* get_config)(struct hpt_iop_hba *hba, struct hpt_iop_request_get_config *config)
int(* do_ioctl)(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams)
void(* enable_intr)(struct hpt_iop_hba *hba)
enum hptiop_family family
int(* alloc_pci_res)(struct hpt_iop_hba *hba)
void(* disable_intr)(struct hpt_iop_hba *hba)
int(* iop_intr)(struct hpt_iop_hba *hba)
void(* release_pci_res)(struct hpt_iop_hba *hba)
void(* post_req)(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs)