summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/io')
-rw-r--r--usr/src/uts/common/io/1394/s1394_hotplug.c4
-rw-r--r--usr/src/uts/common/io/1394/targets/scsa1394/hba.c2
-rw-r--r--usr/src/uts/common/io/consconfig_dacf.c2
-rw-r--r--usr/src/uts/common/io/devinfo.c2
-rw-r--r--usr/src/uts/common/io/dktp/dcdev/dadk.c140
-rw-r--r--usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c10
-rw-r--r--usr/src/uts/common/io/hotplug/pcihp/pcihp.c2
-rw-r--r--usr/src/uts/common/io/i2o/pci_to_i2o.c2
-rw-r--r--usr/src/uts/common/io/i8042.c4
-rw-r--r--usr/src/uts/common/io/ib/ibnex/ibnex.c2
-rw-r--r--usr/src/uts/common/io/openprom.c46
-rw-r--r--usr/src/uts/common/io/pcmcia/pcmem.c7
-rw-r--r--usr/src/uts/common/io/scsi/targets/sd.c321
-rw-r--r--usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c2
-rw-r--r--usr/src/uts/common/io/usb/usba/usba.c2
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,