Sync driver with Yahoo:
- Implement MSI support (MSIX support was already there) - Use a table to drive MSI/MSIX exceptions - Pre-calculate the command address instead of wasting cycles doing the calculation on every i/o.
This commit is contained in:
parent
744c0d23ea
commit
2fdaa90df8
@ -279,8 +279,10 @@ TUNABLE_INT("hw.ciss.force_interrupt", &ciss_force_interrupt);
|
||||
* stick with matching against subvendor/subdevice, and thus have to
|
||||
* be updated for every new CISS adapter that appears.
|
||||
*/
|
||||
#define CISS_BOARD_SA5 (1<<0)
|
||||
#define CISS_BOARD_SA5B (1<<1)
|
||||
#define CISS_BOARD_UNKNWON 0
|
||||
#define CISS_BOARD_SA5 1
|
||||
#define CISS_BOARD_SA5B 2
|
||||
#define CISS_BOARD_NOMSI (1<<4)
|
||||
|
||||
static struct
|
||||
{
|
||||
@ -289,10 +291,10 @@ static struct
|
||||
int flags;
|
||||
char *desc;
|
||||
} ciss_vendor_data[] = {
|
||||
{ 0x0e11, 0x4070, CISS_BOARD_SA5, "Compaq Smart Array 5300" },
|
||||
{ 0x0e11, 0x4080, CISS_BOARD_SA5B, "Compaq Smart Array 5i" },
|
||||
{ 0x0e11, 0x4082, CISS_BOARD_SA5B, "Compaq Smart Array 532" },
|
||||
{ 0x0e11, 0x4083, CISS_BOARD_SA5B, "HP Smart Array 5312" },
|
||||
{ 0x0e11, 0x4070, CISS_BOARD_SA5|CISS_BOARD_NOMSI, "Compaq Smart Array 5300" },
|
||||
{ 0x0e11, 0x4080, CISS_BOARD_SA5B|CISS_BOARD_NOMSI, "Compaq Smart Array 5i" },
|
||||
{ 0x0e11, 0x4082, CISS_BOARD_SA5B|CISS_BOARD_NOMSI, "Compaq Smart Array 532" },
|
||||
{ 0x0e11, 0x4083, CISS_BOARD_SA5B|CISS_BOARD_NOMSI, "HP Smart Array 5312" },
|
||||
{ 0x0e11, 0x4091, CISS_BOARD_SA5, "HP Smart Array 6i" },
|
||||
{ 0x0e11, 0x409A, CISS_BOARD_SA5, "HP Smart Array 641" },
|
||||
{ 0x0e11, 0x409B, CISS_BOARD_SA5, "HP Smart Array 642" },
|
||||
@ -661,7 +663,6 @@ ciss_init_pci(struct ciss_softc *sc)
|
||||
(CISS_TRANSPORT_METHOD_SIMPLE | CISS_TRANSPORT_METHOD_PERF))) {
|
||||
ciss_printf(sc, "No supported transport layers: 0x%x\n",
|
||||
sc->ciss_cfg->supported_methods);
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
switch (ciss_force_transport) {
|
||||
@ -677,7 +678,7 @@ ciss_init_pci(struct ciss_softc *sc)
|
||||
}
|
||||
|
||||
setup:
|
||||
if (supported_methods & CISS_TRANSPORT_METHOD_PERF) {
|
||||
if ((supported_methods & CISS_TRANSPORT_METHOD_PERF) != 0) {
|
||||
method = CISS_TRANSPORT_METHOD_PERF;
|
||||
sc->ciss_perf = (struct ciss_perf_config *)(cbase + cofs +
|
||||
sc->ciss_cfg->transport_offset);
|
||||
@ -744,7 +745,7 @@ ciss_init_pci(struct ciss_softc *sc)
|
||||
* controller. Hopefully enabling this bit universally will work OK.
|
||||
* It seems to work fine for SA6i controllers.
|
||||
*/
|
||||
sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ | CISS_TL_PERF_INTR_MSI;
|
||||
sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ | CISS_TL_PERF_INTR_MSI;
|
||||
|
||||
} else {
|
||||
ciss_printf(sc, "SIMPLE Transport\n");
|
||||
@ -792,7 +793,7 @@ ciss_init_pci(struct ciss_softc *sc)
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
|
||||
CISS_COMMAND_SG_LENGTH, /* nsegments */
|
||||
CISS_MAX_SG_ELEMENTS, /* nsegments */
|
||||
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
|
||||
0, /* flags */
|
||||
NULL, NULL, /* lockfunc, lockarg */
|
||||
@ -810,7 +811,7 @@ ciss_init_pci(struct ciss_softc *sc)
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
MAXBSIZE, CISS_COMMAND_SG_LENGTH, /* maxsize, nsegments */
|
||||
MAXBSIZE, CISS_MAX_SG_ELEMENTS, /* maxsize, nsegments */
|
||||
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
|
||||
BUS_DMA_ALLOCNOW, /* flags */
|
||||
busdma_lock_mutex, &sc->ciss_mtx, /* lockfunc, lockarg */
|
||||
@ -823,32 +824,42 @@ ciss_init_pci(struct ciss_softc *sc)
|
||||
|
||||
/************************************************************************
|
||||
* Setup MSI/MSIX operation (Performant only)
|
||||
* Four interrupts are available, but we only use 1 right now.
|
||||
* Four interrupts are available, but we only use 1 right now. If MSI-X
|
||||
* isn't avaialble, try using MSI instead.
|
||||
*/
|
||||
static int
|
||||
ciss_setup_msix(struct ciss_softc *sc)
|
||||
{
|
||||
uint32_t id;
|
||||
int val, i;
|
||||
|
||||
/* Weed out devices that don't actually support MSI */
|
||||
id = (pci_get_subvendor(sc->ciss_dev) << 16) |
|
||||
pci_get_subdevice(sc->ciss_dev);
|
||||
if ((id == 0x0e114070) || (id == 0x0e114080) || (id == 0x0e114082) ||
|
||||
(id == 0x0e114083))
|
||||
i = ciss_lookup(sc->ciss_dev);
|
||||
if (ciss_vendor_data[i].flags & CISS_BOARD_NOMSI)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* Only need to use the minimum number of MSI vectors, as the driver
|
||||
* doesn't support directed MSIX interrupts.
|
||||
*/
|
||||
val = pci_msix_count(sc->ciss_dev);
|
||||
if (val < CISS_MSI_COUNT)
|
||||
return (EINVAL);
|
||||
if (val < CISS_MSI_COUNT) {
|
||||
val = pci_msi_count(sc->ciss_dev);
|
||||
device_printf(sc->ciss_dev, "got %d MSI messages]\n", val);
|
||||
if (val < CISS_MSI_COUNT)
|
||||
return (EINVAL);
|
||||
}
|
||||
val = MIN(val, CISS_MSI_COUNT);
|
||||
if (pci_alloc_msix(sc->ciss_dev, &val) != 0)
|
||||
return (EINVAL);
|
||||
if (pci_alloc_msix(sc->ciss_dev, &val) != 0) {
|
||||
if (pci_alloc_msi(sc->ciss_dev, &val) != 0)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
sc->ciss_msi = val;
|
||||
ciss_printf(sc, "Using MSIX interrupt\n");
|
||||
if (bootverbose)
|
||||
ciss_printf(sc, "Using %d MSIX interrupt%s\n", val,
|
||||
(val != 1) ? "s" : "");
|
||||
|
||||
for (i = 0; i < CISS_MSI_COUNT; i++)
|
||||
for (i = 0; i < val; i++)
|
||||
sc->ciss_irq_rid[i] = i + 1;
|
||||
|
||||
return (0);
|
||||
@ -1031,7 +1042,7 @@ ciss_soft_reset(struct ciss_softc *sc)
|
||||
NULL, 0)) != 0)
|
||||
break;
|
||||
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.address = sc->ciss_controllers[i];
|
||||
|
||||
if ((error = ciss_synch_request(cr, 60 * 1000)) != 0)
|
||||
@ -1104,6 +1115,9 @@ ciss_init_requests(struct ciss_softc *sc)
|
||||
cr = &sc->ciss_request[i];
|
||||
cr->cr_sc = sc;
|
||||
cr->cr_tag = i;
|
||||
cr->cr_cc = (struct ciss_command *)((uintptr_t)sc->ciss_command +
|
||||
CISS_COMMAND_ALLOC_SIZE * i);
|
||||
cr->cr_ccphys = sc->ciss_command_phys + CISS_COMMAND_ALLOC_SIZE * i;
|
||||
bus_dmamap_create(sc->ciss_buffer_dmat, 0, &cr->cr_datamap);
|
||||
ciss_enqueue_free(cr);
|
||||
}
|
||||
@ -1257,7 +1271,7 @@ ciss_report_luns(struct ciss_softc *sc, int opcode, int nunits)
|
||||
/*
|
||||
* Build the Report Logical/Physical LUNs command.
|
||||
*/
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cr->cr_data = cll;
|
||||
cr->cr_length = report_size;
|
||||
cr->cr_flags = CISS_REQ_DATAIN;
|
||||
@ -1582,7 +1596,7 @@ ciss_inquiry_logical(struct ciss_softc *sc, struct ciss_ldrive *ld)
|
||||
if ((error = ciss_get_request(sc, &cr)) != 0)
|
||||
goto out;
|
||||
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cr->cr_data = &ld->cl_geometry;
|
||||
cr->cr_length = sizeof(ld->cl_geometry);
|
||||
cr->cr_flags = CISS_REQ_DATAIN;
|
||||
@ -1646,7 +1660,7 @@ ciss_identify_logical(struct ciss_softc *sc, struct ciss_ldrive *ld)
|
||||
(void **)&ld->cl_ldrive,
|
||||
sizeof(*ld->cl_ldrive))) != 0)
|
||||
goto out;
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.address = *ld->cl_controller; /* target controller */
|
||||
cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
|
||||
cbc->log_drive = CISS_LUN_TO_TARGET(ld->cl_address.logical.lun);
|
||||
@ -1742,7 +1756,7 @@ ciss_get_ldrive_status(struct ciss_softc *sc, struct ciss_ldrive *ld)
|
||||
(void **)&ld->cl_lstatus,
|
||||
sizeof(*ld->cl_lstatus))) != 0)
|
||||
goto out;
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.address = *ld->cl_controller; /* target controller */
|
||||
cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
|
||||
cbc->log_drive = CISS_LUN_TO_TARGET(ld->cl_address.logical.lun);
|
||||
@ -1832,7 +1846,7 @@ ciss_accept_media(struct ciss_softc *sc, struct ciss_ldrive *ld)
|
||||
if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ACCEPT_MEDIA,
|
||||
NULL, 0)) != 0)
|
||||
goto out;
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.address = *ld->cl_controller; /* target controller */
|
||||
cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
|
||||
cbc->log_drive = ldrive;
|
||||
@ -2000,7 +2014,7 @@ ciss_start(struct ciss_request *cr)
|
||||
struct ciss_command *cc; /* XXX debugging only */
|
||||
int error;
|
||||
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
debug(2, "post command %d tag %d ", cr->cr_tag, cc->header.host_tag);
|
||||
|
||||
/*
|
||||
@ -2056,7 +2070,7 @@ ciss_done(struct ciss_softc *sc, cr_qhead_t *qh)
|
||||
continue;
|
||||
}
|
||||
cr = &(sc->ciss_request[index]);
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.host_tag = tag; /* not updated by adapter */
|
||||
ciss_enqueue_complete(cr, qh);
|
||||
}
|
||||
@ -2085,7 +2099,7 @@ ciss_perf_done(struct ciss_softc *sc, cr_qhead_t *qh)
|
||||
(tag & CISS_HDR_HOST_TAG_ERROR) ? " with error" : "");
|
||||
if (index < sc->ciss_max_requests) {
|
||||
cr = &(sc->ciss_request[index]);
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.host_tag = tag; /* not updated by adapter */
|
||||
ciss_enqueue_complete(cr, qh);
|
||||
} else {
|
||||
@ -2222,7 +2236,7 @@ _ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_sta
|
||||
|
||||
debug_called(2);
|
||||
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
ce = (struct ciss_error_info *)&(cc->sg[0]);
|
||||
|
||||
/*
|
||||
@ -2369,7 +2383,7 @@ ciss_abort_request(struct ciss_request *ar)
|
||||
return(error);
|
||||
|
||||
/* build the abort command */
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.address.mode.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL; /* addressing? */
|
||||
cc->header.address.physical.target = 0;
|
||||
cc->header.address.physical.bus = 0;
|
||||
@ -2438,12 +2452,12 @@ ciss_preen_command(struct ciss_request *cr)
|
||||
* Note that we set up the error_info structure here, since the
|
||||
* length can be overwritten by any command.
|
||||
*/
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.sg_in_list = 0; /* kinda inefficient this way */
|
||||
cc->header.sg_total = 0;
|
||||
cc->header.host_tag = cr->cr_tag << 2;
|
||||
cc->header.host_tag_zeroes = 0;
|
||||
cmdphys = CISS_FIND_COMMANDPHYS(cr);
|
||||
cmdphys = cr->cr_ccphys;
|
||||
cc->error_info.error_info_address = cmdphys + sizeof(struct ciss_command);
|
||||
cc->error_info.error_info_length = CISS_COMMAND_ALLOC_SIZE - sizeof(struct ciss_command);
|
||||
}
|
||||
@ -2514,7 +2528,7 @@ ciss_get_bmic_request(struct ciss_softc *sc, struct ciss_request **crp,
|
||||
if (!dataout)
|
||||
cr->cr_flags = CISS_REQ_DATAIN;
|
||||
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
|
||||
cc->header.address.physical.bus = 0;
|
||||
cc->header.address.physical.target = 0;
|
||||
@ -2562,7 +2576,7 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
|
||||
*/
|
||||
while (ciss_get_request(sc, &cr) != 0)
|
||||
msleep(sc, &sc->ciss_mtx, PPAUSE, "cissREQ", hz);
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
|
||||
/*
|
||||
* Allocate an in-kernel databuffer if required, copy in user data.
|
||||
@ -2667,7 +2681,7 @@ ciss_map_request(struct ciss_request *cr)
|
||||
if (sc->ciss_perf)
|
||||
CISS_TL_PERF_POST_CMD(sc, cr);
|
||||
else
|
||||
CISS_TL_SIMPLE_POST_CMD(sc, CISS_FIND_COMMANDPHYS(cr));
|
||||
CISS_TL_SIMPLE_POST_CMD(sc, cr->cr_ccphys);
|
||||
}
|
||||
|
||||
return(0);
|
||||
@ -2685,7 +2699,7 @@ ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||
|
||||
cr = (struct ciss_request *)arg;
|
||||
sc = cr->cr_sc;
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
|
||||
for (i = 0; i < nseg; i++) {
|
||||
cc->sg[i].address = segs[i].ds_addr;
|
||||
@ -2725,7 +2739,7 @@ ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||
if (sc->ciss_perf)
|
||||
CISS_TL_PERF_POST_CMD(sc, cr);
|
||||
else
|
||||
CISS_TL_SIMPLE_POST_CMD(sc, CISS_FIND_COMMANDPHYS(cr));
|
||||
CISS_TL_SIMPLE_POST_CMD(sc, cr->cr_ccphys);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
@ -3091,7 +3105,7 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
|
||||
/*
|
||||
* Build the command.
|
||||
*/
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cr->cr_data = csio->data_ptr;
|
||||
cr->cr_length = csio->dxfer_len;
|
||||
cr->cr_complete = ciss_cam_complete;
|
||||
@ -3235,7 +3249,7 @@ ciss_cam_complete(struct ciss_request *cr)
|
||||
debug_called(2);
|
||||
|
||||
sc = cr->cr_sc;
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
ce = (struct ciss_error_info *)&(cc->sg[0]);
|
||||
csio = (struct ccb_scsiio *)cr->cr_private;
|
||||
|
||||
@ -3414,7 +3428,7 @@ ciss_periodic(void *arg)
|
||||
* Send the NOP message and wait for a response.
|
||||
*/
|
||||
if (ciss_nop_message_heartbeat != 0 && (error = ciss_get_request(sc, &cr)) == 0) {
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cr->cr_complete = ciss_nop_complete;
|
||||
cc->cdb.cdb_length = 1;
|
||||
cc->cdb.type = CISS_CDB_TYPE_MESSAGE;
|
||||
@ -3484,7 +3498,7 @@ ciss_disable_adapter(struct ciss_softc *sc)
|
||||
if ((cr->cr_flags & CISS_REQ_BUSY) == 0)
|
||||
continue;
|
||||
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
ce = (struct ciss_error_info *)&(cc->sg[0]);
|
||||
ce->command_status = CISS_CMD_STATUS_HARDWARE_ERROR;
|
||||
ciss_enqueue_complete(cr, &qh);
|
||||
@ -3561,7 +3575,7 @@ ciss_notify_event(struct ciss_softc *sc)
|
||||
ciss_preen_command(cr);
|
||||
|
||||
/* (re)build the notify event command */
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
|
||||
cc->header.address.physical.bus = 0;
|
||||
cc->header.address.physical.target = 0;
|
||||
@ -3615,7 +3629,7 @@ ciss_notify_complete(struct ciss_request *cr)
|
||||
int command_status;
|
||||
debug_called(1);
|
||||
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cn = (struct ciss_notify *)cr->cr_data;
|
||||
sc = cr->cr_sc;
|
||||
|
||||
@ -3715,7 +3729,7 @@ ciss_notify_abort(struct ciss_softc *sc)
|
||||
cr->cr_length = CISS_NOTIFY_DATA_SIZE;
|
||||
|
||||
/* build the CDB */
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
|
||||
cc->header.address.physical.bus = 0;
|
||||
cc->header.address.physical.target = 0;
|
||||
@ -4174,7 +4188,7 @@ ciss_print_request(struct ciss_request *cr)
|
||||
int i;
|
||||
|
||||
sc = cr->cr_sc;
|
||||
cc = CISS_FIND_COMMAND(cr);
|
||||
cc = cr->cr_cc;
|
||||
|
||||
ciss_printf(sc, "REQUEST @ %p\n", cr);
|
||||
ciss_printf(sc, " data %p/%d tag %d flags %b\n",
|
||||
|
@ -731,7 +731,7 @@ struct ciss_bmic_flush_cache {
|
||||
#define CISS_TL_PERF_INTR_OPQ (CISS_TL_SIMPLE_INTR_OPQ_SA5 | CISS_TL_SIMPLE_INTR_OPQ_SA5B)
|
||||
#define CISS_TL_PERF_INTR_MSI 0x01
|
||||
|
||||
#define CISS_TL_PERF_POST_CMD(sc, cr) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IPQ, CISS_FIND_COMMANDPHYS(cr) | (cr)->cr_sg_tag)
|
||||
#define CISS_TL_PERF_POST_CMD(sc, cr) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IPQ, cr->cr_ccphys | (cr)->cr_sg_tag)
|
||||
#define CISS_TL_PERF_FLUSH_INT(sc) CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_OSR)
|
||||
#define CISS_TL_PERF_CLEAR_INT(sc) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_ODC, CISS_TL_SIMPLE_ODC_CLEAR)
|
||||
#define CISS_CYCLE_MASK 0x00000001
|
||||
@ -747,4 +747,5 @@ struct ciss_bmic_flush_cache {
|
||||
CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IMR) & ~(sc)->ciss_interrupt_mask)
|
||||
|
||||
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
@ -103,6 +103,8 @@ struct ciss_request
|
||||
void *cr_data; /* data buffer */
|
||||
u_int32_t cr_length; /* data length */
|
||||
bus_dmamap_t cr_datamap; /* DMA map for data */
|
||||
struct ciss_command *cr_cc;
|
||||
uint32_t cr_ccphys;
|
||||
int cr_tag;
|
||||
int cr_flags;
|
||||
#define CISS_REQ_MAPPED (1<<0) /* data mapped */
|
||||
@ -131,18 +133,16 @@ struct ciss_request
|
||||
* scatter-gather list, and we also want to avoid having commands
|
||||
* cross page boundaries.
|
||||
*
|
||||
* Note that 512 bytes yields 28 scatter/gather entries, or the
|
||||
* ability to map (26 * PAGE_SIZE) + 2 bytes of data. On x86, this is
|
||||
* 104kB. 256 bytes would only yield 12 entries, giving a mere 40kB,
|
||||
* too small.
|
||||
* The size of the ciss_command is 52 bytes. 65 s/g elements are reserved
|
||||
* to allow a max i/o size of 256k. This gives a total command size of
|
||||
* 1120 bytes, including the 32 byte alignment padding. Modern controllers
|
||||
* seem to saturate nicely at this value.
|
||||
*/
|
||||
|
||||
#define CISS_COMMAND_ALLOC_SIZE 512 /* XXX tune to get sensible s/g list length */
|
||||
#define CISS_COMMAND_SG_LENGTH ((CISS_COMMAND_ALLOC_SIZE - sizeof(struct ciss_command)) \
|
||||
/ sizeof(struct ciss_sg_entry))
|
||||
|
||||
/* XXX Prep for increasing max i/o */
|
||||
#define CISS_MAX_SG_ELEMENTS 17
|
||||
#define CISS_MAX_SG_ELEMENTS 65
|
||||
#define CISS_COMMAND_ALIGN 32
|
||||
#define CISS_COMMAND_SG_LENGTH (sizeof(struct ciss_sg_entry) * CISS_MAX_SG_ELEMENTS)
|
||||
#define CISS_COMMAND_ALLOC_SIZE (roundup2(sizeof(struct ciss_command) + CISS_COMMAND_SG_LENGTH, CISS_COMMAND_ALIGN))
|
||||
|
||||
/*
|
||||
* Per-logical-drive data.
|
||||
@ -259,20 +259,6 @@ struct ciss_softc
|
||||
struct ciss_qstat ciss_qstat[CISSQ_COUNT]; /* queue statistics */
|
||||
};
|
||||
|
||||
/*
|
||||
* Given a request tag, find the corresponding command in virtual or
|
||||
* physical space.
|
||||
*
|
||||
* The arithmetic here is due to the allocation of ciss_command structures
|
||||
* inside CISS_COMMAND_ALLOC_SIZE blocks. See the comment at the definition
|
||||
* of CISS_COMMAND_ALLOC_SIZE above.
|
||||
*/
|
||||
#define CISS_FIND_COMMAND(cr) \
|
||||
(struct ciss_command *)((u_int8_t *)(cr)->cr_sc->ciss_command + \
|
||||
((cr)->cr_tag * CISS_COMMAND_ALLOC_SIZE))
|
||||
#define CISS_FIND_COMMANDPHYS(cr) ((cr)->cr_sc->ciss_command_phys + \
|
||||
((cr)->cr_tag * CISS_COMMAND_ALLOC_SIZE))
|
||||
|
||||
/************************************************************************
|
||||
* Debugging/diagnostic output.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user