Print this page
4031 scsa1394 violates DDI scsi_pkt(9S) allocation rules
*** 54,65 ****
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,
--- 54,63 ----
*** 96,110 ****
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 *);
--- 94,103 ----
*** 304,320 ****
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);
return (DDI_FAILURE);
}
/* prevent async PM changes until we are done */
(void) pm_busy_component(dip, 0);
--- 297,308 ----
if (scsa1394_attach_scsa(sp) != DDI_SUCCESS) {
scsa1394_cleanup(sp, 4);
return (DDI_FAILURE);
}
if (scsa1394_add_events(sp) != DDI_SUCCESS) {
! scsa1394_cleanup(sp, 5);
return (DDI_FAILURE);
}
/* prevent async PM changes until we are done */
(void) pm_busy_component(dip, 0);
*** 457,471 ****
switch (level) {
default:
scsa1394_remove_events(sp);
/* FALLTHRU */
- case 6:
- scsa1394_detach_scsa(sp);
- /* FALLTHRU */
case 5:
! scsa1394_destroy_cmd_cache(sp);
/* FALLTHRU */
case 4:
scsa1394_detach_threads(sp);
/* FALLTHRU */
case 3:
--- 445,456 ----
switch (level) {
default:
scsa1394_remove_events(sp);
/* FALLTHRU */
case 5:
! scsa1394_detach_scsa(sp);
/* FALLTHRU */
case 4:
scsa1394_detach_threads(sp);
/* FALLTHRU */
case 3:
*** 595,624 ****
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,
--- 580,589 ----
*** 1293,1332 ****
/*
* allocate cmd space
*/
if (pkt == NULL) {
is_new = B_TRUE;
! if ((cmd = kmem_cache_alloc(sp->s_cmd_cache, kf)) == NULL) {
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->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);
! }
! }
/* allocate DMA resources for CDB */
if (scsa1394_cmd_cdb_dma_alloc(sp, cmd, flags, callback, arg) !=
DDI_SUCCESS) {
scsa1394_scsi_destroy_pkt(ap, pkt);
--- 1258,1278 ----
/*
* allocate cmd space
*/
if (pkt == NULL) {
is_new = B_TRUE;
! 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 */
! cmd = pkt->pkt_ha_private;
cmd->sc_lun = lp;
cmd->sc_pkt = pkt;
! 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,1401 ****
}
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);
}
static void
scsa1394_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
{
--- 1333,1344 ----
}
if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) {
bp_mapout(cmd->sc_bp);
cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_MAPIN;
}
! scsi_hba_pkt_free(ap, pkt);
}
static void
scsa1394_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
{
*** 1411,1495 ****
}
}
/*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) {
--- 1354,1363 ----
*** 2039,2050 ****
}
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:
--- 1907,1916 ----
*** 2078,2094 ****
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;
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;
break;
case SCMD_READ_G1:
case SCMD_READ_LONG:
lba = SCSA1394_LBA_10BYTE(pkt);
len = SCSA1394_LEN_10BYTE(pkt);
--- 1944,1960 ----
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_orig_cdblen = CDB_GROUP1;
break;
case SCMD_WRITE:
lba = SCSA1394_LBA_6BYTE(pkt);
len = SCSA1394_LEN_6BYTE(pkt);
opcode = SCMD_WRITE_G1;
! 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,2164 ****
/*
* 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);
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;
scsa1394_cmd_fill_cdb_lba(cmd, lba);
switch (opcode) {
case SCMD_READ_CD:
scsa1394_cmd_fill_read_cd_cdb_len(cmd, len);
break;
--- 2009,2025 ----
/*
* We rewrite READ/WRITE G0 commands as READ/WRITE G1.
* Build new cdb from scatch.
* The lba and length fields is updated below.
*/
! bzero(pkt->pkt_cdbp, cmd->sc_orig_cdblen);
break;
default:
break;
}
! 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,2228 ****
/*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;
}
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;
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;
}
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;
}
/*
* For SCMD_READ_CD, figure out the block size based on expected sector type.
* See MMC SCSI Specs section 6.1.15
--- 2035,2093 ----
/*ARGSUSED*/
static void
scsa1394_cmd_fill_cdb_other(scsa1394_lun_t *lp, scsa1394_cmd_t *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;
}
/*
* fill up parts of CDB
*/
static void
scsa1394_cmd_fill_cdb_len(scsa1394_cmd_t *cmd, int 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)
{
! 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)
{
! 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)
{
! 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,2456 ****
/* 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]) {
case SCMD_READ_CD:
scsa1394_cmd_fill_read_cd_cdb_len(cmd, len);
break;
case SCMD_WRITE_G5:
case SCMD_READ_G5:
--- 2311,2321 ----
/* 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_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: