diff options
Diffstat (limited to 'usr/src/uts/common/io')
-rw-r--r-- | usr/src/uts/common/io/1394/s1394_hotplug.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/io/1394/targets/scsa1394/hba.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/consconfig_dacf.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/devinfo.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/dktp/dcdev/dadk.c | 140 | ||||
-rw-r--r-- | usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/io/hotplug/pcihp/pcihp.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/i2o/pci_to_i2o.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/i8042.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/io/ib/ibnex/ibnex.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/openprom.c | 46 | ||||
-rw-r--r-- | usr/src/uts/common/io/pcmcia/pcmem.c | 7 | ||||
-rw-r--r-- | usr/src/uts/common/io/scsi/targets/sd.c | 321 | ||||
-rw-r--r-- | usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/usb/usba/usba.c | 2 |
15 files changed, 468 insertions, 80 deletions
diff --git a/usr/src/uts/common/io/1394/s1394_hotplug.c b/usr/src/uts/common/io/1394/s1394_hotplug.c index 9aa9850d48..40c2e19022 100644 --- a/usr/src/uts/common/io/1394/s1394_hotplug.c +++ b/usr/src/uts/common/io/1394/s1394_hotplug.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -164,7 +164,7 @@ s1394_create_devinfo(s1394_hal_t *hal, s1394_node_t *node, uint32_t *unit_dir, hal_dip = hal->halinfo.dip; /* Allocate and init a new device node instance. */ - result = ndi_devi_alloc(hal_dip, "unit", (dnode_t)DEVI_SID_NODEID, + result = ndi_devi_alloc(hal_dip, "unit", (pnode_t)DEVI_SID_NODEID, &target_dip); if (result != NDI_SUCCESS) { diff --git a/usr/src/uts/common/io/1394/targets/scsa1394/hba.c b/usr/src/uts/common/io/1394/targets/scsa1394/hba.c index d0c31e8250..84829dcc2e 100644 --- a/usr/src/uts/common/io/1394/targets/scsa1394/hba.c +++ b/usr/src/uts/common/io/1394/targets/scsa1394/hba.c @@ -717,7 +717,7 @@ scsa1394_create_children(scsa1394_state_t *sp) scsa1394_dtype2name(dtype, &node_name, &driver_name); ndi_devi_alloc_sleep(sp->s_dip, node_name, - (dnode_t)DEVI_SID_NODEID, &cdip); + (pnode_t)DEVI_SID_NODEID, &cdip); ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "target", 0); if (ret != DDI_PROP_SUCCESS) { diff --git a/usr/src/uts/common/io/consconfig_dacf.c b/usr/src/uts/common/io/consconfig_dacf.c index cae6a1754b..7ff3c0bbe7 100644 --- a/usr/src/uts/common/io/consconfig_dacf.c +++ b/usr/src/uts/common/io/consconfig_dacf.c @@ -314,7 +314,7 @@ consconfig_dprintf(int l, const char *fmt, ...) char * get_alias(char *alias, char *buf) { - dnode_t node; + pnode_t node; /* OBP >= 2.4 has /aliases */ if ((node = prom_alias_node()) == OBP_BADNODE) diff --git a/usr/src/uts/common/io/devinfo.c b/usr/src/uts/common/io/devinfo.c index ec6ba40b05..4fa54bc3e5 100644 --- a/usr/src/uts/common/io/devinfo.c +++ b/usr/src/uts/common/io/devinfo.c @@ -157,7 +157,7 @@ struct di_dkey { dev_info_t *dk_dip; major_t dk_major; int dk_inst; - dnode_t dk_nodeid; + pnode_t dk_nodeid; }; struct di_pkey { diff --git a/usr/src/uts/common/io/dktp/dcdev/dadk.c b/usr/src/uts/common/io/dktp/dcdev/dadk.c index 0e43bf3a1d..3e7c6bbaa4 100644 --- a/usr/src/uts/common/io/dktp/dcdev/dadk.c +++ b/usr/src/uts/common/io/dktp/dcdev/dadk.c @@ -159,6 +159,7 @@ static char *dadk_cmds[] = { "\030cdrom read offset", /* DCMD_READOFFSET 24 */ "\031cdrom read mode 2", /* DCMD_READMODE2 25 */ "\032cdrom volume control", /* DCMD_VOLCTRL 26 */ + "\033flush cache", /* DCMD_FLUSH_CACHE 27 */ NULL }; @@ -384,6 +385,8 @@ int dadk_open(opaque_t objp, int flag) { struct dadk *dadkp = (struct dadk *)objp; + int error; + int wce; if (!dadkp->dad_rmb) { if (dadkp->dad_phyg.g_cap) { @@ -409,6 +412,23 @@ dadk_open(opaque_t objp, int flag) mutex_exit(&dadkp->dad_mutex); } + /* + * get write cache enable state + * If there is an error, must assume that write cache + * is enabled. + * NOTE: Since there is currently no Solaris mechanism to + * change the state of the Write Cache Enable feature, + * this code just checks the value of the WCE bit + * obtained at device init time. If a mechanism + * is added to the driver to change WCE, dad_wce + * must be updated appropriately. + */ + error = CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETWCE, + (uintptr_t)&wce, 0); + mutex_enter(&dadkp->dad_mutex); + dadkp->dad_wce = (error != 0) || (wce != 0); + mutex_exit(&dadkp->dad_mutex); + /* logical disk geometry */ CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETGEOM, (uintptr_t)&dadkp->dad_logg, 0); @@ -625,6 +645,91 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag, return (EINVAL); } } + case DKIOCFLUSHWRITECACHE: + { + struct buf *bp; + int err = 0; + struct dk_callback *dkc = (struct dk_callback *)arg; + struct cmpkt *pktp; + int is_sync = 1; + + mutex_enter(&dadkp->dad_mutex); + if (dadkp->dad_noflush || ! dadkp->dad_wce) { + err = dadkp->dad_noflush ? ENOTSUP : 0; + mutex_exit(&dadkp->dad_mutex); + /* + * If a callback was requested: a + * callback will always be done if the + * caller saw the DKIOCFLUSHWRITECACHE + * ioctl return 0, and never done if the + * caller saw the ioctl return an error. + */ + if ((flag & FKIOCTL) && dkc != NULL && + dkc->dkc_callback != NULL) { + (*dkc->dkc_callback)(dkc->dkc_cookie, + err); + /* + * Did callback and reported error. + * Since we did a callback, ioctl + * should return 0. + */ + err = 0; + } + return (err); + } + mutex_exit(&dadkp->dad_mutex); + + bp = getrbuf(KM_SLEEP); + + bp->b_edev = dev; + bp->b_dev = cmpdev(dev); + bp->b_flags = B_BUSY; + bp->b_resid = 0; + bp->b_bcount = 0; + SET_BP_SEC(bp, 0); + + if ((flag & FKIOCTL) && dkc != NULL && + dkc->dkc_callback != NULL) { + struct dk_callback *dkc2 = + (struct dk_callback *)kmem_zalloc( + sizeof (struct dk_callback), KM_SLEEP); + + bcopy(dkc, dkc2, sizeof (*dkc2)); + /* + * Borrow b_list to carry private data + * to the b_iodone func. + */ + bp->b_list = (struct buf *)dkc2; + bp->b_iodone = dadk_flushdone; + is_sync = 0; + } + + /* + * Setup command pkt + * dadk_pktprep() can't fail since DDI_DMA_SLEEP set + */ + pktp = dadk_pktprep(dadkp, NULL, bp, + dadk_iodone, DDI_DMA_SLEEP, NULL); + + pktp->cp_time = DADK_FLUSH_CACHE_TIME; + + *((char *)(pktp->cp_cdbp)) = DCMD_FLUSH_CACHE; + pktp->cp_byteleft = 0; + pktp->cp_private = NULL; + pktp->cp_secleft = 0; + pktp->cp_srtsec = -1; + pktp->cp_bytexfer = 0; + + CTL_IOSETUP(dadkp->dad_ctlobjp, pktp); + + FLC_ENQUE(dadkp->dad_flcobjp, bp); + + if (is_sync) { + err = biowait(bp); + freerbuf(bp); + } + return (err); + } default: if (!dadkp->dad_rmb) return (CTL_IOCTL(dadkp->dad_ctlobjp, cmd, arg, flag)); @@ -705,6 +810,20 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag, } int +dadk_flushdone(struct buf *bp) +{ + struct dk_callback *dkc = (struct dk_callback *)bp->b_list; + + ASSERT(dkc != NULL && dkc->dkc_callback != NULL); + + (*dkc->dkc_callback)(dkc->dkc_cookie, geterror(bp)); + + kmem_free(dkc, sizeof (*dkc)); + freerbuf(bp); + return (0); +} + +int dadk_getphygeom(opaque_t objp, struct tgdk_geom *dkgeom_p) { struct dadk *dadkp = (struct dadk *)objp; @@ -957,11 +1076,10 @@ static int dadk_ioretry(struct cmpkt *pktp, int action) { struct buf *bp; - struct dadk *dadkp; + struct dadk *dadkp = PKT2DADK(pktp); switch (action) { case QUE_COMMAND: - dadkp = PKT2DADK(pktp); if (pktp->cp_retry++ < DADK_RETRY_COUNT) { CTL_IOSETUP(dadkp->dad_ctlobjp, pktp); if (CTL_TRANSPORT(dadkp->dad_ctlobjp, pktp) == @@ -981,8 +1099,22 @@ dadk_ioretry(struct cmpkt *pktp, int action) bp = pktp->cp_bp; bp->b_resid += pktp->cp_byteleft - pktp->cp_bytexfer + pktp->cp_resid; - if (geterror(bp) == 0) - bioerror(bp, EIO); + if (geterror(bp) == 0) { + if ((*((char *)(pktp->cp_cdbp)) == DCMD_FLUSH_CACHE) && + (pktp->cp_dev_private == (opaque_t)dadkp) && + ((int)(*(char *)pktp->cp_scbp) == DERR_ABORT)) { + /* + * Flag "unimplemented" responses for + * DCMD_FLUSH_CACHE as ENOTSUP + */ + bioerror(bp, ENOTSUP); + mutex_enter(&dadkp->dad_mutex); + dadkp->dad_noflush = 1; + mutex_exit(&dadkp->dad_mutex); + } else { + bioerror(bp, EIO); + } + } /*FALLTHROUGH*/ case COMMAND_DONE: default: diff --git a/usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c b/usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c index 6a740dcf97..90979eca9e 100644 --- a/usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c +++ b/usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c @@ -558,7 +558,7 @@ pcicfg_configure(dev_info_t *devi, uint_t device) bus = pci_bus_range.lo; /* primary bus number of this bus node */ ndi_devi_alloc_sleep(devi, "hp_attachment", - (dnode_t)DEVI_SID_NODEID, &attach_point); + (pnode_t)DEVI_SID_NODEID, &attach_point); ndi_devi_enter(devi, &circ); for (func = 0; func < PCICFG_MAX_FUNCTION; func++) { @@ -776,7 +776,7 @@ pcicfg_configure_ntbridge(dev_info_t *new_device, uint_t bus, uint_t device) for (devno = pcicfg_start_devno; devno < max_devs; devno++) { ndi_devi_alloc_sleep(new_device, DEVI_PSEUDO_NEXNAME, - (dnode_t)DEVI_SID_NODEID, &new_ntbridgechild); + (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild); if (pcicfg_add_config_reg(new_ntbridgechild, next_bus, devno, 0) != DDI_PROP_SUCCESS) { @@ -1104,7 +1104,7 @@ pcicfg_ntbridge_unconfigure_child(dev_info_t *new_device, uint_t devno) bus = pci_bus_range.lo; /* primary bus number of this bus node */ ndi_devi_alloc_sleep(new_device, DEVI_PSEUDO_NEXNAME, - (dnode_t)DEVI_SID_NODEID, &new_ntbridgechild); + (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild); if (pcicfg_add_config_reg(new_ntbridgechild, bus, devno, 0) != DDI_PROP_SUCCESS) { @@ -3255,7 +3255,7 @@ pcicfg_probe_children(dev_info_t *parent, uint_t bus, ndi_devi_enter(parent, &circ); ndi_devi_alloc_sleep(parent, DEVI_PSEUDO_NEXNAME, - (dnode_t)DEVI_SID_NODEID, &new_child); + (pnode_t)DEVI_SID_NODEID, &new_child); if (pcicfg_add_config_reg(new_child, bus, device, func) != DDI_SUCCESS) { @@ -3908,7 +3908,7 @@ pcicfg_create_ac_child(dev_info_t *dip) dev_info_t *cdip; char *compat[1]; - ndi_devi_alloc_sleep(dip, "se", (dnode_t)DEVI_SID_NODEID, &cdip); + ndi_devi_alloc_sleep(dip, "se", (pnode_t)DEVI_SID_NODEID, &cdip); compat[0] = kmem_alloc(strlen("acse") + 1, KM_SLEEP); (void) strcpy(compat[0], "acse"); if (ndi_prop_update_string_array(DDI_DEV_T_NONE, cdip, diff --git a/usr/src/uts/common/io/hotplug/pcihp/pcihp.c b/usr/src/uts/common/io/hotplug/pcihp/pcihp.c index 196abddadc..46dbcd10a2 100644 --- a/usr/src/uts/common/io/hotplug/pcihp/pcihp.c +++ b/usr/src/uts/common/io/hotplug/pcihp/pcihp.c @@ -3563,7 +3563,7 @@ pcihp_config_setup(dev_info_t **dip, ddi_acc_handle_t *handle, bus = pci_bus_range.lo; if (ndi_devi_alloc(pdip, DEVI_PSEUDO_NEXNAME, - (dnode_t)DEVI_SID_NODEID, dip) != NDI_SUCCESS) { + (pnode_t)DEVI_SID_NODEID, dip) != NDI_SUCCESS) { PCIHP_DEBUG((CE_NOTE, "Failed to alloc probe node\n")); return (PCIHP_FAILURE); diff --git a/usr/src/uts/common/io/i2o/pci_to_i2o.c b/usr/src/uts/common/io/i2o/pci_to_i2o.c index 7da3a13a48..0dc8105d0e 100644 --- a/usr/src/uts/common/io/i2o/pci_to_i2o.c +++ b/usr/src/uts/common/io/i2o/pci_to_i2o.c @@ -866,7 +866,7 @@ i2o_create_devinfo(iop_nexus_instance_t *iop) /* create the devinfo node */ if (ndi_devi_alloc(iop->dip, nodename, - (dnode_t)DEVI_SID_NODEID, &cdip) != NDI_SUCCESS) { + (pnode_t)DEVI_SID_NODEID, &cdip) != NDI_SUCCESS) { cmn_err(CE_WARN, "i2o_create_devinfo: ndi_devi_alloc failed"); goto fail; diff --git a/usr/src/uts/common/io/i8042.c b/usr/src/uts/common/io/i8042.c index e5884400ab..ea8be871a8 100644 --- a/usr/src/uts/common/io/i8042.c +++ b/usr/src/uts/common/io/i8042.c @@ -1041,7 +1041,7 @@ alloc_kb_mouse(dev_info_t *i8042_dip) /* mouse */ ndi_devi_alloc_sleep(i8042_dip, "mouse", - (dnode_t)DEVI_SID_NODEID, &xdip); + (pnode_t)DEVI_SID_NODEID, &xdip); (void) ndi_prop_update_int(DDI_DEV_T_NONE, xdip, "reg", 1); (void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip, @@ -1052,7 +1052,7 @@ alloc_kb_mouse(dev_info_t *i8042_dip) /* keyboard */ ndi_devi_alloc_sleep(i8042_dip, "keyboard", - (dnode_t)DEVI_SID_NODEID, &xdip); + (pnode_t)DEVI_SID_NODEID, &xdip); (void) ndi_prop_update_int(DDI_DEV_T_NONE, xdip, "reg", 0); (void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip, diff --git a/usr/src/uts/common/io/ib/ibnex/ibnex.c b/usr/src/uts/common/io/ib/ibnex/ibnex.c index a62c669f83..8610834fad 100644 --- a/usr/src/uts/common/io/ib/ibnex/ibnex.c +++ b/usr/src/uts/common/io/ib/ibnex/ibnex.c @@ -2910,7 +2910,7 @@ ibnex_commsvc_initnode(dev_info_t *parent, ibdm_port_attr_t *port_attr, node_data->node_state = IBNEX_CFGADM_CONFIGURING; ndi_devi_alloc_sleep(parent, - IBNEX_IBPORT_CNAME, (dnode_t)DEVI_SID_NODEID, &cdip); + IBNEX_IBPORT_CNAME, (pnode_t)DEVI_SID_NODEID, &cdip); node_data->node_dip = cdip; ddi_set_parent_data(cdip, node_data); diff --git a/usr/src/uts/common/io/openprom.c b/usr/src/uts/common/io/openprom.c index ee0bbe5883..f01dd0b033 100644 --- a/usr/src/uts/common/io/openprom.c +++ b/usr/src/uts/common/io/openprom.c @@ -73,7 +73,7 @@ extern int plat_stdin_is_keyboard(void); * XXX Make this dynamic.. or (better still) make the interface stateless */ static struct oprom_state { - dnode_t current_id; /* node we're fetching props from */ + pnode_t current_id; /* node we're fetching props from */ int16_t already_open; /* if true, this instance is 'active' */ int16_t ioc_state; /* snapshot ioctl state */ char *snapshot; /* snapshot of all prom nodes */ @@ -93,9 +93,9 @@ static int opattach(dev_info_t *, ddi_attach_cmd_t cmd); static int opdetach(dev_info_t *, ddi_detach_cmd_t cmd); /* help functions */ -static int oprom_checknodeid(dnode_t, dnode_t); +static int oprom_checknodeid(pnode_t, pnode_t); static int oprom_copyinstr(intptr_t, char *, size_t, size_t); -static int oprom_copynode(dnode_t, uint_t, char **, size_t *); +static int oprom_copynode(pnode_t, uint_t, char **, size_t *); static int oprom_snapshot(struct oprom_state *, intptr_t); static int oprom_copyout(struct oprom_state *, intptr_t); static int oprom_setstate(struct oprom_state *, int16_t); @@ -182,7 +182,7 @@ _fini(void) } static dev_info_t *opdip; -static dnode_t options_nodeid; +static pnode_t options_nodeid; /*ARGSUSED*/ static int @@ -269,7 +269,7 @@ opromopen(dev_t *devp, int flag, int otyp, cred_t *credp) /* * It's ours. */ - st->current_id = (dnode_t)0; + st->current_id = (pnode_t)0; ASSERT(st->snapshot == NULL && st->size == 0); ASSERT(st->ioc_state == IOC_IDLE); break; @@ -339,7 +339,7 @@ opromioctl_cb(void *avp, int has_changed) char *valbuf; int error = 0; uint_t userbufsize; - dnode_t node_id; + pnode_t node_id; char propname[OBP_MAXPROPNAME]; st = argp->st; @@ -621,25 +621,25 @@ opromioctl_cb(void *avp, int has_changed) case OPROMSETNODEID: if (prom_is_openprom() == 0 || - userbufsize < sizeof (dnode_t)) { + userbufsize < sizeof (pnode_t)) { error = EINVAL; break; } /* - * The argument is a phandle. (aka dnode_t) + * The argument is a phandle. (aka pnode_t) */ if (copyin(((caddr_t)arg + sizeof (uint_t)), - opp->oprom_array, sizeof (dnode_t)) != 0) { + opp->oprom_array, sizeof (pnode_t)) != 0) { error = EFAULT; break; } /* - * If dnode_t from userland is garbage, we + * If pnode_t from userland is garbage, we * could confuse the PROM. */ - node_id = *(dnode_t *)opp->oprom_array; + node_id = *(pnode_t *)opp->oprom_array; if (oprom_checknodeid(node_id, st->current_id) == 0) { cmn_err(CE_NOTE, "!nodeid 0x%x not found", (int)node_id); @@ -657,11 +657,11 @@ opromioctl_cb(void *avp, int has_changed) break; } - opp->oprom_size = sizeof (dnode_t); - *(dnode_t *)opp->oprom_array = st->current_id; + opp->oprom_size = sizeof (pnode_t); + *(pnode_t *)opp->oprom_array = st->current_id; if (copyout(opp, (void *)arg, - sizeof (dnode_t) + sizeof (uint_t)) != 0) + sizeof (pnode_t) + sizeof (uint_t)) != 0) error = EFAULT; break; @@ -929,7 +929,7 @@ opromioctl_cb(void *avp, int has_changed) struct openprom_opr64 *opr = (struct openprom_opr64 *)opp->oprom_array; int i; - dnode_t id; + pnode_t id; if (userbufsize < sizeof (*opr)) { error = EINVAL; @@ -1071,13 +1071,13 @@ oprom_copyinstr(intptr_t arg, char *buf, size_t bufsize, size_t maxsize) } /* - * Check dnode_t passed in from userland + * Check pnode_t passed in from userland */ static int -oprom_checknodeid(dnode_t node_id, dnode_t current_id) +oprom_checknodeid(pnode_t node_id, pnode_t current_id) { int depth; - dnode_t id[OBP_STACKDEPTH]; + pnode_t id[OBP_STACKDEPTH]; /* * optimized path @@ -1098,7 +1098,7 @@ oprom_checknodeid(dnode_t node_id, dnode_t current_id) * long path: walk from root till we find node_id */ depth = 1; - id[0] = prom_nextnode((dnode_t)0); + id[0] = prom_nextnode((pnode_t)0); while (depth) { if (id[depth - 1] == node_id) @@ -1191,7 +1191,7 @@ oprom_copyout(struct oprom_state *st, intptr_t arg) * Copy all properties of nodeid into a single packed nvlist */ static int -oprom_copyprop(dnode_t nodeid, uint_t flag, nvlist_t *nvl) +oprom_copyprop(pnode_t nodeid, uint_t flag, nvlist_t *nvl) { int proplen; char *propname, *propval, *buf1, *buf2; @@ -1253,10 +1253,10 @@ oprom_copyprop(dnode_t nodeid, uint_t flag, nvlist_t *nvl) * Copy all children and descendents into a a packed nvlist */ static int -oprom_copychild(dnode_t nodeid, uint_t flag, char **buf, size_t *size) +oprom_copychild(pnode_t nodeid, uint_t flag, char **buf, size_t *size) { nvlist_t *nvl; - dnode_t child = prom_childnode(nodeid); + pnode_t child = prom_childnode(nodeid); if (child == 0) return (0); @@ -1285,7 +1285,7 @@ oprom_copychild(dnode_t nodeid, uint_t flag, char **buf, size_t *size) * Copy a node into a packed nvlist */ static int -oprom_copynode(dnode_t nodeid, uint_t flag, char **buf, size_t *size) +oprom_copynode(pnode_t nodeid, uint_t flag, char **buf, size_t *size) { int error = 0; nvlist_t *nvl; diff --git a/usr/src/uts/common/io/pcmcia/pcmem.c b/usr/src/uts/common/io/pcmcia/pcmem.c index d056d4138e..092f6da2b9 100644 --- a/usr/src/uts/common/io/pcmcia/pcmem.c +++ b/usr/src/uts/common/io/pcmcia/pcmem.c @@ -20,13 +20,12 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" - /* * PCMCIA Memory Nexus Driver * @@ -304,7 +303,7 @@ pcmem_create_pcram_node(dev_info_t *dip) PCMEM_DEBUG((CE_CONT, "pcmem_create_pcram_node dip=%p\n", (void *)dip)); - if (ndi_devi_alloc(dip, "pcram", (dnode_t)DEVI_SID_NODEID, &child) != + if (ndi_devi_alloc(dip, "pcram", (pnode_t)DEVI_SID_NODEID, &child) != NDI_SUCCESS) { cmn_err(CE_WARN, "pcmem: unable to create node [%s]\n", "pcram"); diff --git a/usr/src/uts/common/io/scsi/targets/sd.c b/usr/src/uts/common/io/scsi/targets/sd.c index 288b0768a4..ee1d098f73 100644 --- a/usr/src/uts/common/io/scsi/targets/sd.c +++ b/usr/src/uts/common/io/scsi/targets/sd.c @@ -67,10 +67,10 @@ * Loadable module info. */ #if (defined(__fibre)) -#define SD_MODULE_NAME "SCSI SSA/FCAL Disk Driver %I%" +#define SD_MODULE_NAME "SCSI SSA/FCAL Disk Driver 1.471" char _depends_on[] = "misc/scsi drv/fcp"; #else -#define SD_MODULE_NAME "SCSI Disk Driver %I%" +#define SD_MODULE_NAME "SCSI Disk Driver 1.471" char _depends_on[] = "misc/scsi"; #endif @@ -810,6 +810,7 @@ static int sd_pm_idletime = 1; #define sd_init_event_callbacks ssd_init_event_callbacks #define sd_event_callback ssd_event_callback #define sd_disable_caching ssd_disable_caching +#define sd_get_write_cache_enabled ssd_get_write_cache_enabled #define sd_make_device ssd_make_device #define sdopen ssdopen #define sdclose ssdclose @@ -932,6 +933,8 @@ static int sd_pm_idletime = 1; #define sd_send_scsi_PERSISTENT_RESERVE_OUT \ ssd_send_scsi_PERSISTENT_RESERVE_OUT #define sd_send_scsi_SYNCHRONIZE_CACHE ssd_send_scsi_SYNCHRONIZE_CACHE +#define sd_send_scsi_SYNCHRONIZE_CACHE_biodone \ + ssd_send_scsi_SYNCHRONIZE_CACHE_biodone #define sd_send_scsi_MODE_SENSE ssd_send_scsi_MODE_SENSE #define sd_send_scsi_MODE_SELECT ssd_send_scsi_MODE_SELECT #define sd_send_scsi_RDWR ssd_send_scsi_RDWR @@ -1147,6 +1150,7 @@ static void sd_event_callback(dev_info_t *, ddi_eventcookie_t, void *, void *); static int sd_disable_caching(struct sd_lun *un); +static int sd_get_write_cache_enabled(struct sd_lun *un, int *is_enabled); static dev_t sd_make_device(dev_info_t *devi); static void sd_update_block_info(struct sd_lun *un, uint32_t lbasize, @@ -1375,7 +1379,9 @@ static int sd_send_scsi_PERSISTENT_RESERVE_IN(struct sd_lun *un, uchar_t usr_cmd, uint16_t data_len, uchar_t *data_bufp); static int sd_send_scsi_PERSISTENT_RESERVE_OUT(struct sd_lun *un, uchar_t usr_cmd, uchar_t *usr_bufp); -static int sd_send_scsi_SYNCHRONIZE_CACHE(struct sd_lun *un); +static int sd_send_scsi_SYNCHRONIZE_CACHE(struct sd_lun *un, + struct dk_callback *dkc); +static int sd_send_scsi_SYNCHRONIZE_CACHE_biodone(struct buf *bp); static int sd_send_scsi_GET_CONFIGURATION(struct sd_lun *un, struct uscsi_cmd *ucmdbuf, uchar_t *rqbuf, uint_t rqbuflen, uchar_t *bufaddr, uint_t buflen); @@ -7626,6 +7632,7 @@ sd_unit_attach(dev_info_t *devi) int reservation_flag = SD_TARGET_IS_UNRESERVED; int instance; int rval; + int wc_enabled; uint64_t capacity; uint_t lbasize; @@ -8488,6 +8495,19 @@ sd_unit_attach(dev_info_t *devi) } /* + * NOTE: Since there is currently no mechanism to + * change the state of the Write Cache Enable mode select, + * this code just checks the value of the WCE bit + * at device attach time. If a mechanism + * is added to the driver to change WCE, un_f_write_cache_enabled + * must be updated appropriately. + */ + (void) sd_get_write_cache_enabled(un, &wc_enabled); + mutex_enter(SD_MUTEX(un)); + un->un_f_write_cache_enabled = (wc_enabled != 0); + mutex_exit(SD_MUTEX(un)); + + /* * Set the pstat and error stat values here, so data obtained during the * previous attach-time routines is available. * @@ -9716,6 +9736,115 @@ sd_disable_caching(struct sd_lun *un) /* + * Function: sd_get_write_cache_enabled() + * + * Description: This routine is the driver entry point for determining if + * write caching is enabled. It examines the WCE (write cache + * enable) bits of mode page 8 (MODEPAGE_CACHING). + * + * Arguments: un - driver soft state (unit) structure + * is_enabled - pointer to int where write cache enabled state + * is returned (non-zero -> write cache enabled) + * + * + * Return Code: EIO + * code returned by sd_send_scsi_MODE_SENSE + * + * Context: Kernel Thread + * + * NOTE: If ioctl is added to disable write cache, this sequence should + * be followed so that no locking is required for accesses to + * un->un_f_write_cache_enabled: + * do mode select to clear wce + * do synchronize cache to flush cache + * set un->un_f_write_cache_enabled = FALSE + * + * Conversely, an ioctl to enable the write cache should be done + * in this order: + * set un->un_f_write_cache_enabled = TRUE + * do mode select to set wce + */ + +static int +sd_get_write_cache_enabled(struct sd_lun *un, int *is_enabled) +{ + struct mode_caching *mode_caching_page; + uchar_t *header; + size_t buflen; + int hdrlen; + int bd_len; + int rval = 0; + + ASSERT(un != NULL); + ASSERT(is_enabled != NULL); + + /* in case of error, flag as enabled */ + *is_enabled = TRUE; + + /* + * Do a test unit ready, otherwise a mode sense may not work if this + * is the first command sent to the device after boot. + */ + (void) sd_send_scsi_TEST_UNIT_READY(un, 0); + + if (un->un_f_cfg_is_atapi == TRUE) { + hdrlen = MODE_HEADER_LENGTH_GRP2; + } else { + hdrlen = MODE_HEADER_LENGTH; + } + + /* + * Allocate memory for the retrieved mode page and its headers. Set + * a pointer to the page itself. + */ + buflen = hdrlen + MODE_BLK_DESC_LENGTH + sizeof (struct mode_caching); + header = kmem_zalloc(buflen, KM_SLEEP); + + /* Get the information from the device. */ + if (un->un_f_cfg_is_atapi == TRUE) { + rval = sd_send_scsi_MODE_SENSE(un, CDB_GROUP1, header, buflen, + MODEPAGE_CACHING, SD_PATH_DIRECT); + } else { + rval = sd_send_scsi_MODE_SENSE(un, CDB_GROUP0, header, buflen, + MODEPAGE_CACHING, SD_PATH_DIRECT); + } + if (rval != 0) { + SD_ERROR(SD_LOG_IOCTL_RMMEDIA, un, + "sd_get_write_cache_enabled: Mode Sense Failed\n"); + kmem_free(header, buflen); + return (rval); + } + + /* + * Determine size of Block Descriptors in order to locate + * the mode page data. ATAPI devices return 0, SCSI devices + * should return MODE_BLK_DESC_LENGTH. + */ + if (un->un_f_cfg_is_atapi == TRUE) { + struct mode_header_grp2 *mhp; + mhp = (struct mode_header_grp2 *)header; + bd_len = (mhp->bdesc_length_hi << 8) | mhp->bdesc_length_lo; + } else { + bd_len = ((struct mode_header *)header)->bdesc_length; + } + + if (bd_len > MODE_BLK_DESC_LENGTH) { + scsi_log(SD_DEVINFO(un), sd_label, CE_WARN, + "sd_get_write_cache_enabled: Mode Sense returned invalid " + "block descriptor length\n"); + kmem_free(header, buflen); + return (EIO); + } + + mode_caching_page = (struct mode_caching *)(header + hdrlen + bd_len); + *is_enabled = mode_caching_page->wce; + + kmem_free(header, buflen); + return (0); +} + + +/* * Function: sd_make_device * * Description: Utility routine to return the Solaris device number from @@ -10348,8 +10477,13 @@ sdclose(dev_t dev, int flag, int otyp, cred_t *cred_p) #endif mutex_exit(SD_MUTEX(un)); if (sd_pm_entry(un) == DDI_SUCCESS) { - if (sd_send_scsi_SYNCHRONIZE_CACHE(un) - != 0) { + rval = + sd_send_scsi_SYNCHRONIZE_CACHE(un, + NULL); + /* ignore error if not supported */ + if (rval == ENOTSUP) { + rval = 0; + } else if (rval != 0) { rval = EIO; } sd_pm_exit(un); @@ -11887,6 +12021,8 @@ sd_uscsi_iodone(int index, struct sd_lun *un, struct buf *bp) SD_INFO(SD_LOG_IO, un, "sd_uscsi_iodone: entry.\n"); + bp->b_private = xp->xb_private; + mutex_enter(SD_MUTEX(un)); /* @@ -19827,52 +19963,127 @@ sd_send_scsi_PERSISTENT_RESERVE_OUT(struct sd_lun *un, uchar_t usr_cmd, */ static int -sd_send_scsi_SYNCHRONIZE_CACHE(struct sd_lun *un) +sd_send_scsi_SYNCHRONIZE_CACHE(struct sd_lun *un, struct dk_callback *dkc) { - struct scsi_extended_sense sense_buf; - union scsi_cdb cdb; - struct uscsi_cmd ucmd_buf; - int status; + struct sd_uscsi_info *uip; + struct uscsi_cmd *uscmd; + union scsi_cdb *cdb; + struct buf *bp; + int rval = 0; + + SD_TRACE(SD_LOG_IO, un, + "sd_send_scsi_SYNCHRONIZE_CACHE: entry: un:0x%p\n", un); ASSERT(un != NULL); ASSERT(!mutex_owned(SD_MUTEX(un))); - SD_TRACE(SD_LOG_IO, un, - "sd_send_scsi_SYNCHRONIZE_CACHE: entry: un:0x%p\n", un); + cdb = kmem_zalloc(CDB_GROUP1, KM_SLEEP); + cdb->scc_cmd = SCMD_SYNCHRONIZE_CACHE; - bzero(&cdb, sizeof (cdb)); - bzero(&ucmd_buf, sizeof (ucmd_buf)); - bzero(&sense_buf, sizeof (struct scsi_extended_sense)); + /* + * First get some memory for the uscsi_cmd struct and cdb + * and initialize for SYNCHRONIZE_CACHE cmd. + */ + uscmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP); + uscmd->uscsi_cdblen = CDB_GROUP1; + uscmd->uscsi_cdb = (caddr_t)cdb; + uscmd->uscsi_bufaddr = NULL; + uscmd->uscsi_buflen = 0; + uscmd->uscsi_rqbuf = kmem_zalloc(SENSE_LENGTH, KM_SLEEP); + uscmd->uscsi_rqlen = SENSE_LENGTH; + uscmd->uscsi_rqresid = SENSE_LENGTH; + uscmd->uscsi_flags = USCSI_RQENABLE | USCSI_SILENT; + uscmd->uscsi_timeout = sd_io_time; + + /* + * Allocate an sd_uscsi_info struct and fill it with the info + * needed by sd_initpkt_for_uscsi(). Then put the pointer into + * b_private in the buf for sd_initpkt_for_uscsi(). Note that + * since we allocate the buf here in this function, we do not + * need to preserve the prior contents of b_private. + * The sd_uscsi_info struct is also used by sd_uscsi_strategy() + */ + uip = kmem_zalloc(sizeof (struct sd_uscsi_info), KM_SLEEP); + uip->ui_flags = SD_PATH_DIRECT; + uip->ui_cmdp = uscmd; - cdb.scc_cmd = SCMD_SYNCHRONIZE_CACHE; + bp = getrbuf(KM_SLEEP); + bp->b_private = uip; - ucmd_buf.uscsi_cdb = (char *)&cdb; - ucmd_buf.uscsi_cdblen = CDB_GROUP1; - ucmd_buf.uscsi_bufaddr = NULL; - ucmd_buf.uscsi_buflen = 0; - ucmd_buf.uscsi_rqbuf = (caddr_t)&sense_buf; - ucmd_buf.uscsi_rqlen = sizeof (struct scsi_extended_sense); - ucmd_buf.uscsi_flags = USCSI_RQENABLE | USCSI_SILENT; - ucmd_buf.uscsi_timeout = 240; + /* + * Setup buffer to carry uscsi request. + */ + bp->b_flags = B_BUSY; + bp->b_bcount = 0; + bp->b_blkno = 0; - status = sd_send_scsi_cmd(SD_GET_DEV(un), &ucmd_buf, UIO_SYSSPACE, - UIO_SYSSPACE, UIO_SYSSPACE, SD_PATH_DIRECT); + if (dkc != NULL) { + bp->b_iodone = sd_send_scsi_SYNCHRONIZE_CACHE_biodone; + uip->ui_dkc = *dkc; + } + + bp->b_edev = SD_GET_DEV(un); + bp->b_dev = cmpdev(bp->b_edev); /* maybe unnecessary? */ + + (void) sd_uscsi_strategy(bp); + + /* + * If synchronous request, wait for completion + * If async just return and let b_iodone callback + * cleanup. + * NOTE: On return, u_ncmds_in_driver will be decremented, + * but it was also incremented in sd_uscsi_strategy(), so + * we should be ok. + */ + if (dkc == NULL) { + (void) biowait(bp); + rval = sd_send_scsi_SYNCHRONIZE_CACHE_biodone(bp); + } + + return (rval); +} + + +static int +sd_send_scsi_SYNCHRONIZE_CACHE_biodone(struct buf *bp) +{ + struct sd_uscsi_info *uip; + struct uscsi_cmd *uscmd; + struct scsi_extended_sense *sense_buf; + struct sd_lun *un; + int status; + uip = (struct sd_uscsi_info *)(bp->b_private); + ASSERT(uip != NULL); + + uscmd = uip->ui_cmdp; + ASSERT(uscmd != NULL); + + sense_buf = (struct scsi_extended_sense *)uscmd->uscsi_rqbuf; + ASSERT(sense_buf != NULL); + + un = ddi_get_soft_state(sd_state, SD_GET_INSTANCE_FROM_BUF(bp)); + ASSERT(un != NULL); + + status = geterror(bp); switch (status) { case 0: break; /* Success! */ case EIO: - switch (ucmd_buf.uscsi_status) { + switch (uscmd->uscsi_status) { case STATUS_RESERVATION_CONFLICT: /* Ignore reservation conflict */ status = 0; goto done; case STATUS_CHECK: - if ((ucmd_buf.uscsi_rqstatus == STATUS_GOOD) && - (sense_buf.es_key == KEY_ILLEGAL_REQUEST)) { + if ((uscmd->uscsi_rqstatus == STATUS_GOOD) && + (sense_buf->es_key == KEY_ILLEGAL_REQUEST)) { /* Ignore Illegal Request error */ - status = 0; + mutex_enter(SD_MUTEX(un)); + un->un_f_sync_cache_unsupported = TRUE; + mutex_exit(SD_MUTEX(un)); + status = ENOTSUP; goto done; } break; @@ -19881,7 +20092,7 @@ sd_send_scsi_SYNCHRONIZE_CACHE(struct sd_lun *un) } /* FALLTHRU */ default: - /* Ignore error if the media is not present. */ + /* Ignore error if the media is not present */ if (sd_send_scsi_TEST_UNIT_READY(un, 0) != 0) { status = 0; goto done; @@ -19893,7 +20104,16 @@ sd_send_scsi_SYNCHRONIZE_CACHE(struct sd_lun *un) } done: - SD_TRACE(SD_LOG_IO, un, "sd_send_scsi_SYNCHRONIZE_CACHE: exit\n"); + if (uip->ui_dkc.dkc_callback != NULL) { + (*uip->ui_dkc.dkc_callback)(uip->ui_dkc.dkc_cookie, status); + } + + ASSERT((bp->b_flags & B_REMAPPED) == 0); + freerbuf(bp); + kmem_free(uip, sizeof (struct sd_uscsi_info)); + kmem_free(uscmd->uscsi_rqbuf, SENSE_LENGTH); + kmem_free(uscmd->uscsi_cdb, (size_t)uscmd->uscsi_cdblen); + kmem_free(uscmd, sizeof (struct uscsi_cmd)); return (status); } @@ -20641,6 +20861,7 @@ sdioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p) case DKIOCSVTOC: case DKIOCSETEFI: case DKIOCSMBOOT: + case DKIOCFLUSHWRITECACHE: mutex_exit(SD_MUTEX(un)); err = sd_send_scsi_TEST_UNIT_READY(un, 0); if (err != 0) { @@ -21517,6 +21738,42 @@ skip_ready_valid: #endif /* SD_FAULT_INJECTION */ + case DKIOCFLUSHWRITECACHE: + { + struct dk_callback *dkc = (struct dk_callback *)arg; + + mutex_enter(SD_MUTEX(un)); + if (un->un_f_sync_cache_unsupported || + ! un->un_f_write_cache_enabled) { + err = un->un_f_sync_cache_unsupported ? + ENOTSUP : 0; + mutex_exit(SD_MUTEX(un)); + if ((flag & FKIOCTL) && dkc != NULL && + dkc->dkc_callback != NULL) { + (*dkc->dkc_callback)(dkc->dkc_cookie, + err); + /* + * Did callback and reported error. + * Since we did a callback, ioctl + * should return 0. + */ + err = 0; + } + break; + } + mutex_exit(SD_MUTEX(un)); + + if ((flag & FKIOCTL) && dkc != NULL && + dkc->dkc_callback != NULL) { + /* async SYNC CACHE request */ + err = sd_send_scsi_SYNCHRONIZE_CACHE(un, dkc); + } else { + /* synchronous SYNC CACHE request */ + err = sd_send_scsi_SYNCHRONIZE_CACHE(un, NULL); + } + } + break; + default: err = ENOTTY; break; diff --git a/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c b/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c index 0569d64f1c..84e8d15ce5 100644 --- a/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c +++ b/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c @@ -1750,7 +1750,7 @@ scsa2usb_create_luns(scsa2usb_state_t *scsa2usbp) } ndi_devi_alloc_sleep(scsa2usbp->scsa2usb_dip, node_name, - (dnode_t)DEVI_SID_NODEID, &cdip); + (pnode_t)DEVI_SID_NODEID, &cdip); /* attach target & lun properties */ rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "target", 0); diff --git a/usr/src/uts/common/io/usb/usba/usba.c b/usr/src/uts/common/io/usb/usba/usba.c index d25ed5bf22..f4abdbd69b 100644 --- a/usr/src/uts/common/io/usb/usba/usba.c +++ b/usr/src/uts/common/io/usb/usba/usba.c @@ -822,7 +822,7 @@ usba_create_child_devi(dev_info_t *dip, "port status=0x%x", node_name, (void *)usba_device, port_status); - ndi_devi_alloc_sleep(dip, node_name, (dnode_t)DEVI_SID_NODEID, + ndi_devi_alloc_sleep(dip, node_name, (pnode_t)DEVI_SID_NODEID, child_dip); USB_DPRINTF_L3(DPRINT_MASK_USBA, usba_log_handle, |