Print this page
4031 scsa1394 violates DDI scsi_pkt(9S) allocation rules
@@ -54,12 +54,10 @@
static void scsa1394_detach_1394(scsa1394_state_t *);
static int scsa1394_attach_threads(scsa1394_state_t *);
static void scsa1394_detach_threads(scsa1394_state_t *);
static int scsa1394_attach_scsa(scsa1394_state_t *);
static void scsa1394_detach_scsa(scsa1394_state_t *);
-static int scsa1394_create_cmd_cache(scsa1394_state_t *);
-static void scsa1394_destroy_cmd_cache(scsa1394_state_t *);
static int scsa1394_add_events(scsa1394_state_t *);
static void scsa1394_remove_events(scsa1394_state_t *);
/* device configuration */
static int scsa1394_scsi_bus_config(dev_info_t *, uint_t,
@@ -96,15 +94,10 @@
static void scsa1394_scsi_dmafree(struct scsi_address *, struct scsi_pkt *);
static void scsa1394_scsi_sync_pkt(struct scsi_address *,
struct scsi_pkt *);
/* pkt resource allocation routines */
-static int scsa1394_cmd_cache_constructor(void *, void *, int);
-static void scsa1394_cmd_cache_destructor(void *, void *);
-static int scsa1394_cmd_ext_alloc(scsa1394_state_t *, scsa1394_cmd_t *,
- int);
-static void scsa1394_cmd_ext_free(scsa1394_state_t *, scsa1394_cmd_t *);
static int scsa1394_cmd_cdb_dma_alloc(scsa1394_state_t *, scsa1394_cmd_t *,
int, int (*)(), caddr_t);
static void scsa1394_cmd_cdb_dma_free(scsa1394_state_t *, scsa1394_cmd_t *);
static int scsa1394_cmd_buf_dma_alloc(scsa1394_state_t *, scsa1394_cmd_t *,
int, int (*)(), caddr_t, struct buf *);
@@ -304,17 +297,12 @@
if (scsa1394_attach_scsa(sp) != DDI_SUCCESS) {
scsa1394_cleanup(sp, 4);
return (DDI_FAILURE);
}
- if (scsa1394_create_cmd_cache(sp) != DDI_SUCCESS) {
- scsa1394_cleanup(sp, 5);
- return (DDI_FAILURE);
- }
-
if (scsa1394_add_events(sp) != DDI_SUCCESS) {
- scsa1394_cleanup(sp, 6);
+ scsa1394_cleanup(sp, 5);
return (DDI_FAILURE);
}
/* prevent async PM changes until we are done */
(void) pm_busy_component(dip, 0);
@@ -457,15 +445,12 @@
switch (level) {
default:
scsa1394_remove_events(sp);
/* FALLTHRU */
- case 6:
- scsa1394_detach_scsa(sp);
- /* FALLTHRU */
case 5:
- scsa1394_destroy_cmd_cache(sp);
+ scsa1394_detach_scsa(sp);
/* FALLTHRU */
case 4:
scsa1394_detach_threads(sp);
/* FALLTHRU */
case 3:
@@ -595,30 +580,10 @@
scsi_hba_tran_free(sp->s_tran);
}
static int
-scsa1394_create_cmd_cache(scsa1394_state_t *sp)
-{
- char name[64];
-
- (void) sprintf(name, "scsa1394%d_cache", sp->s_instance);
- sp->s_cmd_cache = kmem_cache_create(name,
- SCSA1394_CMD_SIZE, sizeof (void *),
- scsa1394_cmd_cache_constructor, scsa1394_cmd_cache_destructor,
- NULL, (void *)sp, NULL, 0);
-
- return ((sp->s_cmd_cache == NULL) ? DDI_FAILURE : DDI_SUCCESS);
-}
-
-static void
-scsa1394_destroy_cmd_cache(scsa1394_state_t *sp)
-{
- kmem_cache_destroy(sp->s_cmd_cache);
-}
-
-static int
scsa1394_add_events(scsa1394_state_t *sp)
{
ddi_eventcookie_t br_evc, rem_evc, ins_evc;
if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_BUS_RESET_EVENT,
@@ -1293,40 +1258,21 @@
/*
* allocate cmd space
*/
if (pkt == NULL) {
is_new = B_TRUE;
- if ((cmd = kmem_cache_alloc(sp->s_cmd_cache, kf)) == NULL) {
+ pkt = scsi_hba_pkt_alloc(NULL, ap, max(SCSI_CDB_SIZE, cmdlen),
+ statuslen, tgtlen, sizeof (scsa1394_cmd_t), callback, arg);
+ if (!pkt)
return (NULL);
- }
/* initialize cmd */
- pkt = &cmd->sc_scsi_pkt;
- pkt->pkt_ha_private = cmd;
- pkt->pkt_address = *ap;
- pkt->pkt_private = cmd->sc_priv;
- pkt->pkt_scbp = (uchar_t *)&cmd->sc_scb;
- pkt->pkt_cdbp = (uchar_t *)&cmd->sc_pkt_cdb;
- pkt->pkt_resid = 0;
-
+ cmd = pkt->pkt_ha_private;
cmd->sc_lun = lp;
cmd->sc_pkt = pkt;
- cmd->sc_cdb_len = cmdlen;
- cmd->sc_scb_len = statuslen;
- cmd->sc_priv_len = tgtlen;
-
- /* need external space? */
- if ((cmdlen > sizeof (cmd->sc_pkt_cdb)) ||
- (statuslen > sizeof (cmd->sc_scb)) ||
- (tgtlen > sizeof (cmd->sc_priv))) {
- if (scsa1394_cmd_ext_alloc(sp, cmd, kf) !=
- DDI_SUCCESS) {
- kmem_cache_free(sp->s_cmd_cache, cmd);
- lp->l_stat.stat_err_pkt_kmem_alloc++;
- return (NULL);
- }
- }
+ cmd->sc_orig_cdblen = cmdlen;
+ cmd->sc_task.ts_drv_priv = cmd;
/* allocate DMA resources for CDB */
if (scsa1394_cmd_cdb_dma_alloc(sp, cmd, flags, callback, arg) !=
DDI_SUCCESS) {
scsa1394_scsi_destroy_pkt(ap, pkt);
@@ -1387,15 +1333,12 @@
}
if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) {
bp_mapout(cmd->sc_bp);
cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_MAPIN;
}
- if (cmd->sc_flags & SCSA1394_CMD_EXT) {
- scsa1394_cmd_ext_free(sp, cmd);
- }
- kmem_cache_free(sp->s_cmd_cache, cmd);
+ scsi_hba_pkt_free(ap, pkt);
}
static void
scsa1394_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
{
@@ -1411,85 +1354,10 @@
}
}
/*ARGSUSED*/
static int
-scsa1394_cmd_cache_constructor(void *buf, void *cdrarg, int kf)
-{
- scsa1394_cmd_t *cmd = buf;
-
- bzero(buf, SCSA1394_CMD_SIZE);
- cmd->sc_task.ts_drv_priv = cmd;
-
- return (0);
-}
-
-/*ARGSUSED*/
-static void
-scsa1394_cmd_cache_destructor(void *buf, void *cdrarg)
-{
-}
-
-/*
- * allocate and deallocate external cmd space (ie. not part of scsa1394_cmd_t)
- * for non-standard length cdb, pkt_private, status areas
- */
-static int
-scsa1394_cmd_ext_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, int kf)
-{
- struct scsi_pkt *pkt = cmd->sc_pkt;
- void *buf;
-
- if (cmd->sc_cdb_len > sizeof (cmd->sc_pkt_cdb)) {
- if ((buf = kmem_zalloc(cmd->sc_cdb_len, kf)) == NULL) {
- return (DDI_FAILURE);
- }
- pkt->pkt_cdbp = buf;
- cmd->sc_flags |= SCSA1394_CMD_CDB_EXT;
- }
-
- if (cmd->sc_scb_len > sizeof (cmd->sc_scb)) {
- if ((buf = kmem_zalloc(cmd->sc_scb_len, kf)) == NULL) {
- scsa1394_cmd_ext_free(sp, cmd);
- return (DDI_FAILURE);
- }
- pkt->pkt_scbp = buf;
- cmd->sc_flags |= SCSA1394_CMD_SCB_EXT;
- }
-
- if (cmd->sc_priv_len > sizeof (cmd->sc_priv)) {
- if ((buf = kmem_zalloc(cmd->sc_priv_len, kf)) == NULL) {
- scsa1394_cmd_ext_free(sp, cmd);
- return (DDI_FAILURE);
- }
- pkt->pkt_private = buf;
- cmd->sc_flags |= SCSA1394_CMD_PRIV_EXT;
- }
-
- return (DDI_SUCCESS);
-}
-
-/*ARGSUSED*/
-static void
-scsa1394_cmd_ext_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
-{
- struct scsi_pkt *pkt = cmd->sc_pkt;
-
- if (cmd->sc_flags & SCSA1394_CMD_CDB_EXT) {
- kmem_free(pkt->pkt_cdbp, cmd->sc_cdb_len);
- }
- if (cmd->sc_flags & SCSA1394_CMD_SCB_EXT) {
- kmem_free(pkt->pkt_scbp, cmd->sc_scb_len);
- }
- if (cmd->sc_flags & SCSA1394_CMD_PRIV_EXT) {
- kmem_free(pkt->pkt_private, cmd->sc_priv_len);
- }
- cmd->sc_flags &= ~SCSA1394_CMD_EXT;
-}
-
-/*ARGSUSED*/
-static int
scsa1394_cmd_cdb_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd,
int flags, int (*callback)(), caddr_t arg)
{
if (sbp2_task_orb_alloc(cmd->sc_lun->l_lun, &cmd->sc_task,
sizeof (scsa1394_cmd_orb_t)) != SBP2_SUCCESS) {
@@ -2039,12 +1907,10 @@
}
static void
scsa1394_cmd_fill_cdb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
{
- cmd->sc_cdb_actual_len = cmd->sc_cdb_len;
-
mutex_enter(&lp->l_mutex);
switch (lp->l_dtype_orig) {
case DTYPE_DIRECT:
case DTYPE_RODIRECT:
@@ -2078,17 +1944,17 @@
case SCMD_READ:
/* RBC only supports 10-byte read/write */
lba = SCSA1394_LBA_6BYTE(pkt);
len = SCSA1394_LEN_6BYTE(pkt);
opcode = SCMD_READ_G1;
- cmd->sc_cdb_actual_len = CDB_GROUP1;
+ cmd->sc_orig_cdblen = CDB_GROUP1;
break;
case SCMD_WRITE:
lba = SCSA1394_LBA_6BYTE(pkt);
len = SCSA1394_LEN_6BYTE(pkt);
opcode = SCMD_WRITE_G1;
- cmd->sc_cdb_actual_len = CDB_GROUP1;
+ cmd->sc_orig_cdblen = CDB_GROUP1;
break;
case SCMD_READ_G1:
case SCMD_READ_LONG:
lba = SCSA1394_LBA_10BYTE(pkt);
len = SCSA1394_LEN_10BYTE(pkt);
@@ -2143,22 +2009,17 @@
/*
* We rewrite READ/WRITE G0 commands as READ/WRITE G1.
* Build new cdb from scatch.
* The lba and length fields is updated below.
*/
- bzero(cmd->sc_cdb, cmd->sc_cdb_actual_len);
+ bzero(pkt->pkt_cdbp, cmd->sc_orig_cdblen);
break;
default:
- /*
- * Copy the non lba/len fields.
- * The lba and length fields is updated below.
- */
- bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_actual_len);
break;
}
- cmd->sc_cdb[0] = (uchar_t)opcode;
+ pkt->pkt_cdbp[0] = (uchar_t)opcode;
scsa1394_cmd_fill_cdb_lba(cmd, lba);
switch (opcode) {
case SCMD_READ_CD:
scsa1394_cmd_fill_read_cd_cdb_len(cmd, len);
break;
@@ -2174,55 +2035,59 @@
/*ARGSUSED*/
static void
scsa1394_cmd_fill_cdb_other(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
{
- struct scsi_pkt *pkt = CMD2PKT(cmd);
-
cmd->sc_xfer_bytes = cmd->sc_win_len;
cmd->sc_xfer_blks = cmd->sc_xfer_bytes / lp->l_lba_size;
cmd->sc_total_blks = cmd->sc_xfer_blks;
cmd->sc_lba = 0;
-
- bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_len);
}
/*
* fill up parts of CDB
*/
static void
scsa1394_cmd_fill_cdb_len(scsa1394_cmd_t *cmd, int len)
{
- cmd->sc_cdb[7] = len >> 8;
- cmd->sc_cdb[8] = (uchar_t)len;
+ struct scsi_pkt *pkt = CMD2PKT(cmd);
+
+ pkt->pkt_cdbp[7] = len >> 8;
+ pkt->pkt_cdbp[8] = (uchar_t)len;
}
static void
scsa1394_cmd_fill_cdb_lba(scsa1394_cmd_t *cmd, int lba)
{
- cmd->sc_cdb[2] = lba >> 24;
- cmd->sc_cdb[3] = lba >> 16;
- cmd->sc_cdb[4] = lba >> 8;
- cmd->sc_cdb[5] = (uchar_t)lba;
+ struct scsi_pkt *pkt = CMD2PKT(cmd);
+
+ pkt->pkt_cdbp[2] = lba >> 24;
+ pkt->pkt_cdbp[3] = lba >> 16;
+ pkt->pkt_cdbp[4] = lba >> 8;
+ pkt->pkt_cdbp[5] = (uchar_t)lba;
cmd->sc_lba = lba;
}
static void
scsa1394_cmd_fill_12byte_cdb_len(scsa1394_cmd_t *cmd, int len)
{
- cmd->sc_cdb[6] = len >> 24;
- cmd->sc_cdb[7] = len >> 16;
- cmd->sc_cdb[8] = len >> 8;
- cmd->sc_cdb[9] = (uchar_t)len;
+ struct scsi_pkt *pkt = CMD2PKT(cmd);
+
+ pkt->pkt_cdbp[6] = len >> 24;
+ pkt->pkt_cdbp[7] = len >> 16;
+ pkt->pkt_cdbp[8] = len >> 8;
+ pkt->pkt_cdbp[9] = (uchar_t)len;
}
static void
scsa1394_cmd_fill_read_cd_cdb_len(scsa1394_cmd_t *cmd, int len)
{
- cmd->sc_cdb[6] = len >> 16;
- cmd->sc_cdb[7] = len >> 8;
- cmd->sc_cdb[8] = (uchar_t)len;
+ struct scsi_pkt *pkt = CMD2PKT(cmd);
+
+ pkt->pkt_cdbp[6] = len >> 16;
+ pkt->pkt_cdbp[7] = len >> 8;
+ pkt->pkt_cdbp[8] = (uchar_t)len;
}
/*
* For SCMD_READ_CD, figure out the block size based on expected sector type.
* See MMC SCSI Specs section 6.1.15
@@ -2446,11 +2311,11 @@
/* limit xfer length for Symbios workaround */
if (len * cmd->sc_blk_size > scsa1394_symbios_size_max) {
len = scsa1394_symbios_size_max / cmd->sc_blk_size;
}
- switch (cmd->sc_cdb[0]) {
+ switch (cmd->sc_pkt->pkt_cdbp[0]) {
case SCMD_READ_CD:
scsa1394_cmd_fill_read_cd_cdb_len(cmd, len);
break;
case SCMD_WRITE_G5:
case SCMD_READ_G5: