/* ARGSUSED */ static int sctp_listener_conf_del(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo, const char *ifname, const void* pval, uint_t flags) { sctp_listener_t *sl; long lport; sctp_stack_t *sctps = stack->netstack_sctp; if (flags & MOD_PROP_DEFAULT) return (ENOTSUP); if (ddi_strtol(pval, NULL, 10, &lport) != 0 || lport <= 0 || lport > USHRT_MAX) { return (EINVAL); } mutex_enter(&sctps->sctps_listener_conf_lock); for (sl = list_head(&sctps->sctps_listener_conf); sl != NULL; sl = list_next(&sctps->sctps_listener_conf, sl)) { if (sl->sl_port == lport) { list_remove(&sctps->sctps_listener_conf, sl); mutex_exit(&sctps->sctps_listener_conf_lock); kmem_free(sl, sizeof (sctp_listener_t)); return (0); } } mutex_exit(&sctps->sctps_listener_conf_lock); return (ESRCH); }
int _init(void) { int err; char tty_irq_param[9] = "ttyX-irq"; char *tty_irq; int i; if ((err = mod_install(&modlinkage)) != 0) return (err); /* Check if any tty irqs are overridden by eeprom config */ for (i = 0; i < num_BIOS_serial; i++) { tty_irq_param[3] = 'a' + i; if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS, tty_irq_param, &tty_irq) == DDI_PROP_SUCCESS) { long data; if (ddi_strtol(tty_irq, NULL, 0, &data) == 0) { asy_intrs[i] = (int)data; asy_intr_override |= 1<<i; } ddi_prop_free(tty_irq); } } impl_bus_add_probe(isa_enumerate); return (0); }
static int str2inet_addr(char *cp, ipaddr_t *addrp) { char *end; long byte; int i; ipaddr_t addr = 0; for (i = 0; i < 4; i++) { if (ddi_strtol(cp, &end, 10, &byte) != 0 || byte < 0 || byte > 255) { return (0); } addr = (addr << 8) | (uint8_t)byte; if (i < 3) { if (*end != '.') { return (0); } else { cp = end + 1; } } else { cp = end; } } *addrp = addr; return (1); }
/* ARGSUSED */ static int sctp_extra_priv_ports_del(queue_t *q, mblk_t *mp, char *value, caddr_t cp, cred_t *cr) { long new_value; int i; /* * Fail the request if the new value does not lie within the * port number limits. */ if (ddi_strtol(value, NULL, 10, &new_value) != 0 || new_value <= 0 || new_value >= 65536) { return (EINVAL); } mutex_enter(&sctp_epriv_port_lock); /* Check that the value is already in the list */ for (i = 0; i < sctp_g_num_epriv_ports; i++) { if (sctp_g_epriv_ports[i] == new_value) break; } if (i == sctp_g_num_epriv_ports) { mutex_exit(&sctp_epriv_port_lock); return (ESRCH); } /* Clear the value */ sctp_g_epriv_ports[i] = 0; mutex_exit(&sctp_epriv_port_lock); return (0); }
/* ARGSUSED */ static int tcp_listener_conf_del(void *cbarg, cred_t *cr, mod_prop_info_t *pinfo, const char *ifname, const void* pval, uint_t flags) { tcp_listener_t *tl; long lport; tcp_stack_t *tcps = (tcp_stack_t *)cbarg; if (flags & MOD_PROP_DEFAULT) return (ENOTSUP); if (ddi_strtol(pval, NULL, 10, &lport) != 0 || lport <= 0 || lport > USHRT_MAX) { return (EINVAL); } mutex_enter(&tcps->tcps_listener_conf_lock); for (tl = list_head(&tcps->tcps_listener_conf); tl != NULL; tl = list_next(&tcps->tcps_listener_conf, tl)) { if (tl->tl_port == lport) { list_remove(&tcps->tcps_listener_conf, tl); mutex_exit(&tcps->tcps_listener_conf_lock); kmem_free(tl, sizeof (tcp_listener_t)); return (0); } } mutex_exit(&tcps->tcps_listener_conf_lock); return (ESRCH); }
static int /*ARGSUSED*/ nl7c_uri_ttl_set(queue_t *q, mblk_t *mp, char *value, caddr_t nu, cred_t *cr) { if (ddi_strtol(value, NULL, 10, &nl7c_uri_ttl) != 0) return (EINVAL); return (0); }
/* ARGSUSED */ static int sctp_listener_conf_add(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo, const char *ifname, const void* pval, uint_t flags) { sctp_listener_t *new_sl; sctp_listener_t *sl; long lport; long ratio; char *colon; sctp_stack_t *sctps = stack->netstack_sctp; if (flags & MOD_PROP_DEFAULT) return (ENOTSUP); if (ddi_strtol(pval, &colon, 10, &lport) != 0 || lport <= 0 || lport > USHRT_MAX || *colon != ':') { return (EINVAL); } if (ddi_strtol(colon + 1, NULL, 10, &ratio) != 0 || ratio <= 0) return (EINVAL); mutex_enter(&sctps->sctps_listener_conf_lock); for (sl = list_head(&sctps->sctps_listener_conf); sl != NULL; sl = list_next(&sctps->sctps_listener_conf, sl)) { /* There is an existing entry, so update its ratio value. */ if (sl->sl_port == lport) { sl->sl_ratio = ratio; mutex_exit(&sctps->sctps_listener_conf_lock); return (0); } } if ((new_sl = kmem_alloc(sizeof (sctp_listener_t), KM_NOSLEEP)) == NULL) { mutex_exit(&sctps->sctps_listener_conf_lock); return (ENOMEM); } new_sl->sl_port = lport; new_sl->sl_ratio = ratio; list_insert_tail(&sctps->sctps_listener_conf, new_sl); mutex_exit(&sctps->sctps_listener_conf_lock); return (0); }
/* ARGSUSED */ static int sctp_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp, cred_t *cr) { long new_value; sctpparam_t *sctppa = (sctpparam_t *)cp; if (ddi_strtol(value, NULL, 10, &new_value) != 0 || new_value < sctppa->sctp_param_min || new_value > sctppa->sctp_param_max) { return (EINVAL); } sctppa->sctp_param_val = new_value; return (0); }
/* * function to set a private property. * Called from the set_prop GLD entry point * * dev - sofware handle to the device * name - string containing the property name * size - length of the string in name * val - pointer to a location where the value to set is stored * * return EINVAL => invalid value in val 0 => success */ static int oce_set_priv_prop(struct oce_dev *dev, const char *name, uint_t size, const void *val) { int ret = ENOTSUP; long result; _NOTE(ARGUNUSED(size)); if (NULL == val) { ret = EINVAL; return (ret); } if (strcmp(name, "_tx_bcopy_limit") == 0) { (void) ddi_strtol(val, (char **)NULL, 0, &result); if (result <= OCE_WQ_BUF_SIZE) { if (result != dev->tx_bcopy_limit) dev->tx_bcopy_limit = (uint32_t)result; ret = 0; } else { ret = EINVAL; } } if (strcmp(name, "_rx_bcopy_limit") == 0) { (void) ddi_strtol(val, (char **)NULL, 0, &result); if (result <= OCE_RQ_BUF_SIZE) { if (result != dev->rx_bcopy_limit) dev->rx_bcopy_limit = (uint32_t)result; ret = 0; } else { ret = EINVAL; } } return (ret); } /* oce_set_priv_prop */
static int /*ARGSUSED*/ nca_logging_on_set(queue_t *q, mblk_t *mp, char *value, caddr_t nu, cred_t *cr) { long new_value; if (ddi_strtol(value, NULL, 10, &new_value) != 0 || new_value < 0 || new_value > 1) { return (EINVAL); } if (nca_fio_cnt(nl7c_logd_fio) == 0) return (EINVAL); nl7c_logd_enabled = new_value; return (0); }
/* * Convert string to minor number. Some care must be taken * as we are processing user input. Catch cases like * /dev/pts/4foo and /dev/pts/-1 */ static int devpts_strtol(const char *nm, minor_t *mp) { long uminor = 0; char *endptr = NULL; if (nm == NULL || !isdigit(*nm)) return (EINVAL); *mp = 0; if (ddi_strtol(nm, &endptr, 10, &uminor) != 0 || *endptr != '\0' || uminor < 0) { return (EINVAL); } *mp = (minor_t)uminor; return (0); }
/* * sets master_ops_debug flag from propertyu passed by the boot */ static void set_master_ops_debug_flags() { char *prop; long flags; if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS, "master_ops_debug", &prop) == DDI_PROP_SUCCESS) { long data; if (ddi_strtol(prop, NULL, 0, &data) == 0) { master_ops_debug = (unsigned long)data; e_ddi_prop_remove(DDI_DEV_T_NONE, ddi_root_node(), "master_ops_debug"); e_ddi_prop_update_int(DDI_DEV_T_NONE, ddi_root_node(), "master_ops_debug", data); } ddi_prop_free(prop); } }
/* ARGSUSED */ static int sctp_wroff_xtra_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp, cred_t *cr) { long new_value; sctpparam_t *sctppa = (sctpparam_t *)cp; if (ddi_strtol(value, NULL, 10, &new_value) != 0 || new_value < sctppa->sctp_param_min || new_value > sctppa->sctp_param_max) { return (EINVAL); } /* * Need to make sure new_value is a multiple of 8. If it is not, * round it up. */ if (new_value & 0x7) { new_value = (new_value & ~0x7) + 0x8; } sctppa->sctp_param_val = new_value; return (0); }
/* ARGSUSED */ static int sctp_extra_priv_ports_add(queue_t *q, mblk_t *mp, char *value, caddr_t cp, cred_t *cr) { long new_value; int i; /* * Fail the request if the new value does not lie within the * port number limits. */ if (ddi_strtol(value, NULL, 10, &new_value) != 0 || new_value <= 0 || new_value >= 65536) { return (EINVAL); } mutex_enter(&sctp_epriv_port_lock); /* Check if the value is already in the list */ for (i = 0; i < sctp_g_num_epriv_ports; i++) { if (new_value == sctp_g_epriv_ports[i]) { mutex_exit(&sctp_epriv_port_lock); return (EEXIST); } } /* Find an empty slot */ for (i = 0; i < sctp_g_num_epriv_ports; i++) { if (sctp_g_epriv_ports[i] == 0) break; } if (i == sctp_g_num_epriv_ports) { mutex_exit(&sctp_epriv_port_lock); return (EOVERFLOW); } /* Set the new value */ sctp_g_epriv_ports[i] = (uint16_t)new_value; mutex_exit(&sctp_epriv_port_lock); return (0); }
/* ARGSUSED */ static int i40e_m_setprop_private(i40e_t *i40e, const char *pr_name, uint_t pr_valsize, const void *pr_val) { int ret; long val; char *eptr; ASSERT(MUTEX_HELD(&i40e->i40e_general_lock)); if ((ret = ddi_strtol(pr_val, &eptr, 10, &val)) != 0 || *eptr != '\0') { return (ret); } if (strcmp(pr_name, I40E_PROP_RX_DMA_THRESH) == 0) { if (val < I40E_MIN_RX_DMA_THRESH || val > I40E_MAX_RX_DMA_THRESH) { return (EINVAL); } i40e->i40e_rx_dma_min = (uint32_t)val; return (0); } if (strcmp(pr_name, I40E_PROP_TX_DMA_THRESH) == 0) { if (val < I40E_MIN_TX_DMA_THRESH || val > I40E_MAX_TX_DMA_THRESH) { return (EINVAL); } i40e->i40e_tx_dma_min = (uint32_t)val; return (0); } if (strcmp(pr_name, I40E_PROP_RX_ITR) == 0) { if (val < I40E_MIN_ITR || val > I40E_MAX_ITR) { return (EINVAL); } i40e->i40e_rx_itr = (uint32_t)val; i40e_intr_set_itr(i40e, I40E_ITR_INDEX_RX, i40e->i40e_rx_itr); return (0); } if (strcmp(pr_name, I40E_PROP_TX_ITR) == 0) { if (val < I40E_MIN_ITR || val > I40E_MAX_ITR) { return (EINVAL); } i40e->i40e_tx_itr = (uint32_t)val; i40e_intr_set_itr(i40e, I40E_ITR_INDEX_TX, i40e->i40e_tx_itr); return (0); } if (strcmp(pr_name, I40E_PROP_OTHER_ITR) == 0) { if (val < I40E_MIN_ITR || val > I40E_MAX_ITR) { return (EINVAL); } i40e->i40e_tx_itr = (uint32_t)val; i40e_intr_set_itr(i40e, I40E_ITR_INDEX_OTHER, i40e->i40e_other_itr); return (0); } return (ENOTSUP); }
/* * Process acpi-user-options property if present */ static void acpica_process_user_options() { static int processed = 0; int acpi_user_options; char *acpi_prop; /* * return if acpi-user-options has already been processed */ if (processed) return; else processed = 1; /* converts acpi-user-options from type string to int, if any */ if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS, "acpi-user-options", &acpi_prop) == DDI_PROP_SUCCESS) { long data; int ret; ret = ddi_strtol(acpi_prop, NULL, 0, &data); if (ret == 0) { e_ddi_prop_remove(DDI_DEV_T_NONE, ddi_root_node(), "acpi-user-options"); e_ddi_prop_update_int(DDI_DEV_T_NONE, ddi_root_node(), "acpi-user-options", data); } ddi_prop_free(acpi_prop); } /* * fetch the optional options property */ acpi_user_options = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS, "acpi-user-options", 0); /* * Note that 'off' has precedence over 'on' * Also note - all cases of ACPI_OUSER_MASK * provided here, no default: case is present */ switch (acpi_user_options & ACPI_OUSER_MASK) { case ACPI_OUSER_DFLT: acpica_enable = acpica_check_bios_date(1999, 1, 1); break; case ACPI_OUSER_ON: acpica_enable = TRUE; break; case ACPI_OUSER_OFF: case ACPI_OUSER_OFF | ACPI_OUSER_ON: acpica_enable = FALSE; break; } acpi_init_level = ACPI_FULL_INITIALIZATION; /* * special test here; may be generalized in the * future - test for a machines that are known to * work only in legacy mode, and set OUSER_LEGACY if * we're on one */ if (acpica_metro_old_bios()) acpi_user_options |= ACPI_OUSER_LEGACY; /* * If legacy mode is specified, set initialization * options to avoid entering ACPI mode and hooking SCI * - basically try to act like legacy acpi_intp */ if ((acpi_user_options & ACPI_OUSER_LEGACY) != 0) acpi_init_level |= (ACPI_NO_ACPI_ENABLE | ACPI_NO_HANDLER_INIT); /* * modify default ACPI CA debug output level for non-DEBUG builds * (to avoid BIOS debug chatter in /var/adm/messages) */ if (acpica_muzzle_debug_output) AcpiDbgLevel = 0; }
/* * inet_pton: This function takes string format IPv4 or IPv6 address and * converts it to binary form. The format of this function corresponds to * inet_pton() in the socket library. * * Return values: * 0 invalid IPv4 or IPv6 address * 1 successful conversion * -1 af is not AF_INET or AF_INET6 */ int __inet_pton(int af, char *inp, void *outp, int compat) { int i; long byte; char *end; switch (af) { case AF_INET: if (str2inet_addr(inp, (ipaddr_t *)outp) != 0) { if (!compat) *(uint32_t *)outp = htonl(*(uint32_t *)outp); return (1); } else { return (0); } case AF_INET6: { union v6buf_u { uint16_t v6words_u[8]; in6_addr_t v6addr_u; } v6buf, *v6outp; uint16_t *dbl_col = NULL; char lastbyte = NULL; v6outp = (union v6buf_u *)outp; if (strchr_w(inp, '.') != NULL) { /* v4 mapped or v4 compatable */ if (strncmp(inp, "::ffff:", 7) == 0) { ipaddr_t ipv4_all_zeroes = 0; /* mapped - first init prefix and then fill */ IN6_IPADDR_TO_V4MAPPED(ipv4_all_zeroes, &v6outp->v6addr_u); return (str2inet_addr(inp + 7, &(v6outp->v6addr_u.s6_addr32[3]))); } else if (strncmp(inp, "::", 2) == 0) { /* v4 compatable - prefix all zeroes */ bzero(&v6outp->v6addr_u, sizeof (in6_addr_t)); return (str2inet_addr(inp + 2, &(v6outp->v6addr_u.s6_addr32[3]))); } return (0); } for (i = 0; i < 8; i++) { int error; /* * if ddi_strtol() fails it could be because * the string is "::". That is valid and * checked for below so just set the value to * 0 and continue. */ if ((error = ddi_strtol(inp, &end, 16, &byte)) != 0) { if (error == ERANGE) return (0); byte = 0; } if (byte < 0 || byte > 0x0ffff) { return (0); } if (compat) { v6buf.v6words_u[i] = (uint16_t)byte; } else { v6buf.v6words_u[i] = htons((uint16_t)byte); } if (*end == NULL || i == 7) { inp = end; break; } if (inp == end) { /* not a number must be */ if (*inp == ':' && ((i == 0 && *(inp + 1) == ':') || lastbyte == ':')) { if (dbl_col) { return (0); } if (byte != 0) i++; dbl_col = &v6buf.v6words_u[i]; if (i == 0) inp++; } else if (*inp == NULL || *inp == ' ' || *inp == '\t') { break; } else { return (0); } } else { inp = end; } if (*inp != ':') { return (0); } inp++; if (*inp == NULL || *inp == ' ' || *inp == '\t') { break; } lastbyte = *inp; } if (*inp != NULL && *inp != ' ' && *inp != '\t') { return (0); } /* * v6words now contains the bytes we could translate * dbl_col points to the word (should be 0) where * a double colon was found */ if (i == 7) { v6outp->v6addr_u = v6buf.v6addr_u; } else { int rem; int word; int next; if (dbl_col == NULL) { return (0); } bzero(&v6outp->v6addr_u, sizeof (in6_addr_t)); rem = dbl_col - &v6buf.v6words_u[0]; for (next = 0; next < rem; next++) { v6outp->v6words_u[next] = v6buf.v6words_u[next]; } next++; /* skip dbl_col 0 */ rem = i - rem; word = 8 - rem; while (rem > 0) { v6outp->v6words_u[word] = v6buf.v6words_u[next]; word++; rem--; next++; } } return (1); /* Success */ } } /* switch */ return (-1); /* return -1 for default case */ }
/* * iscsi_create_sendtgts_list - Based upon the given data, build a * linked list of SendTarget information. The data passed into this * function is expected to be the data portion(s) of SendTarget text * response. */ static iscsi_status_t iscsi_create_sendtgts_list(iscsi_conn_t *icp, char *data, int data_len, iscsi_sendtgts_list_t *stl) { char *line = NULL; boolean_t targetname_added = B_FALSE; iscsi_sendtgts_entry_t *curr_ste = NULL, *prev_ste = NULL; struct hostent *hptr; int error_num; /* initialize number of targets found */ stl->stl_out_cnt = 0; if (data_len == 0) return (ISCSI_STATUS_SUCCESS); while ((line = iscsi_get_next_text(data, data_len, line)) != NULL) { if (strncmp(TARGETNAME, line, strlen(TARGETNAME)) == 0) { /* check if this is first targetname */ if (prev_ste != NULL) { stl->stl_out_cnt++; } if (stl->stl_out_cnt >= stl->stl_in_cnt) { /* * continue processing the data so that * the total number of targets are known * and the caller can retry with the correct * number of entries in the list */ continue; } curr_ste = &(stl->stl_list[stl->stl_out_cnt]); /* * This entry will use the IP address and port * that was passed into this routine. If the next * line that we receive is a TargetAddress we will * know to modify this entry with the new IP address, * port and portal group tag. If this state flag * is not set we'll just create a new entry using * only the previous entries targetname. */ (void) strncpy((char *)curr_ste->ste_name, line + strlen(TARGETNAME), sizeof (curr_ste->ste_name)); if (icp->conn_base_addr.sin.sa_family == AF_INET) { struct sockaddr_in *addr_in = &icp->conn_base_addr.sin4; curr_ste->ste_ipaddr.a_addr.i_insize = sizeof (struct in_addr); bcopy(&addr_in->sin_addr.s_addr, &curr_ste->ste_ipaddr.a_addr.i_addr, sizeof (struct in_addr)); curr_ste->ste_ipaddr.a_port = htons(addr_in->sin_port); } else { struct sockaddr_in6 *addr_in6 = &icp->conn_base_addr.sin6; curr_ste->ste_ipaddr.a_addr.i_insize = sizeof (struct in6_addr); bcopy(&addr_in6->sin6_addr.s6_addr, &curr_ste->ste_ipaddr.a_addr.i_addr, sizeof (struct in6_addr)); curr_ste->ste_ipaddr.a_port = htons(addr_in6->sin6_port); } curr_ste->ste_tpgt = -1; targetname_added = B_TRUE; } else if (strncmp(TARGETADDRESS, line, strlen(TARGETADDRESS)) == 0) { char *in_str, *tmp_buf, *addr_str, *port_str, *tpgt_str; int type, tmp_buf_len; long result; /* * If TARGETADDRESS is first line a SendTarget response * (i.e. no TARGETNAME lines preceding), treat as * an error. To check this an assumption is made that * at least one sendtarget_entry_t should exist prior * to entering this code. */ if (prev_ste == NULL) { cmn_err(CE_NOTE, "SendTargets protocol error: " "TARGETADDRESS first"); return (ISCSI_STATUS_PROTOCOL_ERROR); } /* * If we can't find an '=' then the sendtargets * response if invalid per spec. Return empty list. */ in_str = strchr(line, '='); if (in_str == NULL) { return (ISCSI_STATUS_PROTOCOL_ERROR); } /* move past the '=' */ in_str++; /* Copy addr, port, and tpgt into temporary buffer */ tmp_buf_len = strlen(in_str) + 1; tmp_buf = kmem_zalloc(tmp_buf_len, KM_SLEEP); (void) strncpy(tmp_buf, in_str, tmp_buf_len); /* * Parse the addr, port, and tpgt from * sendtarget response */ if (parse_addr_port_tpgt(tmp_buf, &addr_str, &type, &port_str, &tpgt_str) == B_FALSE) { /* Unable to extract addr */ kmem_free(tmp_buf, tmp_buf_len); return (ISCSI_STATUS_PROTOCOL_ERROR); } /* Now convert string addr to binary */ hptr = kgetipnodebyname(addr_str, type, AI_ALL, &error_num); if (!hptr) { /* Unable to get valid address */ kmem_free(tmp_buf, tmp_buf_len); return (ISCSI_STATUS_PROTOCOL_ERROR); } /* Check if space for response */ if (targetname_added == B_FALSE) { stl->stl_out_cnt++; if (stl->stl_out_cnt >= stl->stl_in_cnt) { /* * continue processing the data so that * the total number of targets are * known and the caller can retry with * the correct number of entries in * the list */ kfreehostent(hptr); kmem_free(tmp_buf, tmp_buf_len); continue; } curr_ste = &(stl->stl_list[stl->stl_out_cnt]); (void) strcpy((char *)curr_ste->ste_name, (char *)prev_ste->ste_name); } curr_ste->ste_ipaddr.a_addr.i_insize = hptr->h_length; bcopy(*hptr->h_addr_list, &(curr_ste->ste_ipaddr.a_addr.i_addr), curr_ste->ste_ipaddr.a_addr.i_insize); kfreehostent(hptr); if (port_str != NULL) { (void) ddi_strtol(port_str, NULL, 0, &result); curr_ste->ste_ipaddr.a_port = (short)result; } else { curr_ste->ste_ipaddr.a_port = ISCSI_LISTEN_PORT; } if (tpgt_str != NULL) { (void) ddi_strtol(tpgt_str, NULL, 0, &result); curr_ste->ste_tpgt = (short)result; } else { cmn_err(CE_NOTE, "SendTargets protocol error: " "TPGT not specified"); kmem_free(tmp_buf, tmp_buf_len); return (ISCSI_STATUS_PROTOCOL_ERROR); } kmem_free(tmp_buf, tmp_buf_len); targetname_added = B_FALSE; } else if (strlen(line) != 0) { /* * Any other string besides an empty string * is a protocol error */ cmn_err(CE_NOTE, "SendTargets protocol error: " "unexpected response"); return (ISCSI_STATUS_PROTOCOL_ERROR); } prev_ste = curr_ste; } /* * If target found increment out count one more time because * this is the total number of entries in the list not an index * like it was used above */ if (prev_ste != NULL) { stl->stl_out_cnt++; } return (ISCSI_STATUS_SUCCESS); }
/* * Create classes and major number bindings for the name of my root. * Called immediately before 'loadrootmodules' */ static void impl_create_root_class(void) { major_t major; size_t size; char *cp; /* * The name for the root nexus is exactly as the manufacturer * placed it in the prom name property. No translation. */ if ((major = ddi_name_to_major("rootnex")) == DDI_MAJOR_T_NONE) panic("Couldn't find major number for 'rootnex'"); /* * C OBP (Serengeti) does not include the NULL when returning * the length of the name property, while this violates 1275, * Solaris needs to work around this by allocating space for * an extra character. */ size = (size_t)BOP_GETPROPLEN(bootops, "mfg-name") + 1; rootname = kmem_zalloc(size, KM_SLEEP); (void) BOP_GETPROP(bootops, "mfg-name", rootname); /* * Fix conflict between OBP names and filesystem names. * Substitute '_' for '/' in the name. Ick. This is only * needed for the root node since '/' is not a legal name * character in an OBP device name. */ for (cp = rootname; *cp; cp++) if (*cp == '/') *cp = '_'; /* * Bind rootname to rootnex driver */ if (make_mbind(rootname, major, NULL, mb_hashtab) != 0) { cmn_err(CE_WARN, "A driver or driver alias has already " "registered the name \"%s\". The root nexus needs to " "use this name, and will override the existing entry. " "Please correct /etc/name_to_major and/or " "/etc/driver_aliases and reboot.", rootname); /* * Resort to the emergency measure of blowing away the * existing hash entry and replacing it with rootname's. */ delete_mbind(rootname, mb_hashtab); if (make_mbind(rootname, major, NULL, mb_hashtab) != 0) panic("mb_hashtab: inconsistent state."); } /* * The `platform' or `implementation architecture' name has been * translated by boot to be proper for file system use. It is * the `name' of the platform actually booted. Note the assumption * is that the name will `fit' in the buffer platform (which is * of size SYS_NMLN, which is far bigger than will actually ever * be needed). */ (void) BOP_GETPROP(bootops, "impl-arch-name", platform); /* * If boot-aoepath is defined, assume it's AoE boot and set bootpath to * aoeblk/blkdev device corresponding to specified shelf.slot numbers. */ size = (size_t)BOP_GETPROPLEN(bootops, "boot-aoepath"); if (size != -1) { char aoedev[MAXPATHLEN]; char *delim; int shelf, slot; aoepath_prop = kmem_zalloc(size, KM_SLEEP); (void) BOP_GETPROP(bootops, "boot-aoepath", aoepath_prop); /* * If boot-aoepath is set to "auto", device will be * configured later during AoE autoconfiguration. */ if (strcmp(aoepath_prop, "auto") != 0) { if ((delim = strchr(aoepath_prop, '.')) != NULL) *delim++ = '\0'; if (ddi_strtol(aoepath_prop, (char **)NULL, 10, (long *)&shelf) != 0) shelf = 0; if (delim == NULL || ddi_strtol(delim, (char **)NULL, 10, (long *)&slot) != 0) slot = 0; /* FIXME aoeblk@0,0 ?! */ (void) snprintf(aoedev, MAXPATHLEN, "/aoe/aoeblk@0,0/blkdev@%d,%d", shelf, slot); setbootpath(aoedev); } } #if defined(__x86) /* * Retrieve and honor the bootpath and optional fstype properties */ size = (size_t)BOP_GETPROPLEN(bootops, "bootpath"); if (size != -1) { bootpath_prop = kmem_zalloc(size, KM_SLEEP); (void) BOP_GETPROP(bootops, "bootpath", bootpath_prop); setbootpath(bootpath_prop); } size = (size_t)BOP_GETPROPLEN(bootops, "fstype"); if (size != -1) { fstype_prop = kmem_zalloc(size, KM_SLEEP); (void) BOP_GETPROP(bootops, "fstype", fstype_prop); setbootfstype(fstype_prop); } #endif }
/*ARGSUSED*/ static int opt_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, uint_t nattrs, kcpc_attr_t *attrs, void **data, void *token) { opt_pcbe_config_t *cfg; amd_event_t *evp; amd_event_t ev_raw = { "raw", 0}; amd_generic_event_t *gevp; int i; uint64_t evsel = 0, evsel_tmp = 0; /* * If we've been handed an existing configuration, we need only preset * the counter value. */ if (*data != NULL) { cfg = *data; cfg->opt_rawpic = preset & MASK48; return (0); } if (picnum >= 4) return (CPC_INVALID_PICNUM); if ((evp = find_event(event)) == NULL) { if ((gevp = find_generic_event(event)) != NULL) { evp = find_event(gevp->event); ASSERT(evp != NULL); if (nattrs > 0) return (CPC_ATTRIBUTE_OUT_OF_RANGE); evsel |= gevp->umask << OPT_PES_UMASK_SHIFT; } else { long tmp; /* * If ddi_strtol() likes this event, use it as a raw * event code. */ if (ddi_strtol(event, NULL, 0, &tmp) != 0) return (CPC_INVALID_EVENT); ev_raw.emask = tmp; evp = &ev_raw; } } /* * Configuration of EventSelect register. While on some families * certain bits might not be supported (e.g. Guest/Host on family * 11h), setting these bits is harmless */ /* Set GuestOnly bit to 0 and HostOnly bit to 1 */ evsel &= ~OPT_PES_HOST; evsel &= ~OPT_PES_GUEST; /* Set bits [35:32] for extended part of Event Select field */ evsel_tmp = evp->emask & 0x0f00; evsel |= evsel_tmp << 24; evsel |= evp->emask & 0x00ff; if (flags & CPC_COUNT_USER) evsel |= OPT_PES_USR; if (flags & CPC_COUNT_SYSTEM) evsel |= OPT_PES_OS; if (flags & CPC_OVF_NOTIFY_EMT) evsel |= OPT_PES_INT; for (i = 0; i < nattrs; i++) { if (strcmp(attrs[i].ka_name, "edge") == 0) { if (attrs[i].ka_val != 0) evsel |= OPT_PES_EDGE; } else if (strcmp(attrs[i].ka_name, "pc") == 0) { if (attrs[i].ka_val != 0) evsel |= OPT_PES_PC; } else if (strcmp(attrs[i].ka_name, "inv") == 0) { if (attrs[i].ka_val != 0) evsel |= OPT_PES_INV; } else if (strcmp(attrs[i].ka_name, "cmask") == 0) { if ((attrs[i].ka_val | OPT_PES_CMASK_MASK) != OPT_PES_CMASK_MASK) return (CPC_ATTRIBUTE_OUT_OF_RANGE); evsel |= attrs[i].ka_val << OPT_PES_CMASK_SHIFT; } else if (strcmp(attrs[i].ka_name, "umask") == 0) { if ((attrs[i].ka_val | OPT_PES_UMASK_MASK) != OPT_PES_UMASK_MASK) return (CPC_ATTRIBUTE_OUT_OF_RANGE); evsel |= attrs[i].ka_val << OPT_PES_UMASK_SHIFT; } else return (CPC_INVALID_ATTRIBUTE); } cfg = kmem_alloc(sizeof (*cfg), KM_SLEEP); cfg->opt_picno = picnum; cfg->opt_evsel = evsel; cfg->opt_rawpic = preset & MASK48; *data = cfg; return (0); }