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: