# HG changeset patch # User Richard Lowe # Date 1284047203 14400 # Node ID 88e527ca878fe1fae9f4dc862169c9e3715da368 # Parent 5f6c3c1215604d45279a731aaf2ea04dad0d4597# Parent b23a4dab3d500aa3e57159dfbf2b3f9a5bbf4bd6 sync with onnv-gate 13149:b23a4dab3d50 Reviewed by: garrett@nexenta.com, gwr@nexenta.com Approved by: garrett@nexenta.com diff -r 5f6c3c121560 -r 88e527ca878f .hgtags --- a/.hgtags Fri Sep 03 23:10:16 2010 +0200 +++ b/.hgtags Thu Sep 09 11:46:43 2010 -0400 @@ -128,3 +128,4 @@ 96016f1d98371e79260cf42cd053532602fe964a onnv_144 87e07d18c459a7f43c3175ec35f4536eaf3f78cf onnv_145 51b1767a74cbfba539a0dfdd5df2cefd1964b2ce onnv_146 +67d1861e02c15565f9bc5a6e271fa99c13d0d4c8 onnv_147 diff -r 5f6c3c121560 -r 88e527ca878f usr/src/Makefile.buildnum --- a/usr/src/Makefile.buildnum Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/Makefile.buildnum Thu Sep 09 11:46:43 2010 -0400 @@ -37,4 +37,4 @@ # currently open build in the onnv-gate. # -ONNV_BUILDNUM= 147 +ONNV_BUILDNUM= 148 diff -r 5f6c3c121560 -r 88e527ca878f usr/src/cmd/cmd-inet/usr.lib/ilbd/ilbd.h --- a/usr/src/cmd/cmd-inet/usr.lib/ilbd/ilbd.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/cmd/cmd-inet/usr.lib/ilbd/ilbd.h Thu Sep 09 11:46:43 2010 -0400 @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _ILBD_H #define _ILBD_H @@ -284,7 +283,8 @@ * data. Not all events use all members of the structure. */ typedef struct audit_sg_event_data { - char *ed_server_address; /* server's IP address */ + int32_t ed_ipaddr_type; /* ADT_IPv4 or ADT_IPv6 */ + uint32_t ed_server_address[4]; /* server's IP address */ char *ed_serverid; /* serverid. */ uint16_t ed_minport; /* server's minport */ uint16_t ed_maxport; /* server's maxport */ @@ -421,11 +421,10 @@ const struct passwd *, ucred_t *), void *, void *); ilb_status_t ilbd_walk_hc_pgs(ilb_status_t (*)(const ilb_hc_info_t *, int, const struct passwd *, ucred_t *), void *, void *); -void ilbd_addr2str(struct in6_addr *, char *, size_t); -void addr2str(ilb_ip_addr_t, char *, size_t); void ilbd_algo_to_str(ilb_algo_t, char *); void ilbd_topo_to_str(ilb_topo_t, char *); void ilbd_ip_to_str(uint16_t, struct in6_addr *, char *); +void cvt_addr(uint32_t *, int32_t, struct in6_addr); int ilberror2auditerror(ilb_status_t); #ifdef __cplusplus diff -r 5f6c3c121560 -r 88e527ca878f usr/src/cmd/cmd-inet/usr.lib/ilbd/ilbd_rules.c --- a/usr/src/cmd/cmd-inet/usr.lib/ilbd/ilbd_rules.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/cmd/cmd-inet/usr.lib/ilbd/ilbd_rules.c Thu Sep 09 11:46:43 2010 -0400 @@ -512,10 +512,7 @@ char *valstr1 = NULL; char *valstr2 = NULL; char pbuf[PROTOCOL_LEN]; /* protocol */ - char pxbuf[ADDR_LEN]; /* prxy src range */ char hcpbuf[PORT_LEN]; /* hcport */ - char addrstr_buf[INET6_ADDRSTRLEN]; - char addrstr_buf1[INET6_ADDRSTRLEN]; int audit_error; if ((ucredp == NULL) && (cmd == ILBD_CREATE_RULE)) { @@ -577,12 +574,18 @@ event->adt_ilb_create_rule.auth_used = NET_ILB_CONFIG_AUTH; - /* Fill in virtual IP address */ - addrstr_buf[0] = '\0'; - ilbd_addr2str(&rlinfo->rl_vip, addrstr_buf, - sizeof (addrstr_buf)); - event->adt_ilb_create_rule.virtual_ipaddress = addrstr_buf; - + /* Fill in virtual IP address type */ + if (IN6_IS_ADDR_V4MAPPED(&rlinfo->rl_vip)) { + event->adt_ilb_create_rule.virtual_ipaddress_type = + ADT_IPv4; + cvt_addr(event->adt_ilb_create_rule.virtual_ipaddress, + ADT_IPv4, rlinfo->rl_vip); + } else { + event->adt_ilb_create_rule.virtual_ipaddress_type = + ADT_IPv6; + cvt_addr(event->adt_ilb_create_rule.virtual_ipaddress, + ADT_IPv6, rlinfo->rl_vip); + } /* Fill in port - could be a single value or a range */ event->adt_ilb_create_rule.min_port = ntohs(rlinfo->rl_minport); if (ntohs(rlinfo->rl_maxport) > ntohs(rlinfo->rl_minport)) { @@ -614,20 +617,53 @@ /* Fill in proxy-src for the NAT case */ if (rlinfo->rl_topo == ILB_TOPO_NAT) { - ilbd_addr2str(&rlinfo->rl_nat_src_start, addrstr_buf, - sizeof (addrstr_buf)); - if (&rlinfo->rl_nat_src_end == 0) { - /* Single address */ - (void) snprintf(pxbuf, ADDR_LEN, - "%s", addrstr_buf); + /* copy starting proxy-src address */ + if (IN6_IS_ADDR_V4MAPPED(&rlinfo->rl_nat_src_start)) { + /* V4 case */ + event->adt_ilb_create_rule.proxy_src_min_type = + ADT_IPv4; + cvt_addr( + event->adt_ilb_create_rule.proxy_src_min, + ADT_IPv4, rlinfo->rl_nat_src_start); } else { - /* address range */ - ilbd_addr2str(&rlinfo->rl_nat_src_end, - addrstr_buf1, sizeof (addrstr_buf1)); - (void) snprintf(pxbuf, ADDR_LEN, - "%s-%s", addrstr_buf, addrstr_buf1); + /* V6 case */ + event->adt_ilb_create_rule.proxy_src_min_type = + ADT_IPv6; + cvt_addr( + event->adt_ilb_create_rule.proxy_src_min, + ADT_IPv6, rlinfo->rl_nat_src_start); } - event->adt_ilb_create_rule.proxy_src = pxbuf; + + /* copy ending proxy-src address */ + if (&rlinfo->rl_nat_src_end == 0) { + /* proxy-src is a single address */ + event->adt_ilb_create_rule.proxy_src_max_type = + event-> + adt_ilb_create_rule.proxy_src_min_type; + (void) memcpy( + event->adt_ilb_create_rule.proxy_src_max, + event->adt_ilb_create_rule.proxy_src_min, + (4 * sizeof (uint32_t))); + } else if ( + IN6_IS_ADDR_V4MAPPED(&rlinfo->rl_nat_src_end)) { + /* + * proxy-src is a address range - copy ending + * proxy-src address + * V4 case + */ + event->adt_ilb_create_rule.proxy_src_max_type = + ADT_IPv4; + cvt_addr( + event->adt_ilb_create_rule.proxy_src_max, + ADT_IPv4, rlinfo->rl_nat_src_end); + } else { + /* V6 case */ + event->adt_ilb_create_rule.proxy_src_max_type = + ADT_IPv6; + cvt_addr( + event->adt_ilb_create_rule.proxy_src_max, + ADT_IPv6, rlinfo->rl_nat_src_end); + } } /* @@ -692,6 +728,24 @@ free(valstr2); (void) adt_end_session(ah); } +/* + * converts IP address from in6_addr format to uint32_t[4] + * This conversion is needed for recording IP address in + * audit records. + */ +void +cvt_addr(uint32_t *audit, int32_t type, struct in6_addr address) +{ + + if (type == ADT_IPv4) { + /* address is IPv4 */ + audit[0] = address._S6_un._S6_u32[3]; + } else { + /* address is IPv6 */ + (void) memcpy(audit, address._S6_un._S6_u32, + (4 * sizeof (uint32_t))); + } +} static ilb_status_t i_ilbd_action_switch(ilbd_rule_t *irl, ilbd_cmd_t cmd, diff -r 5f6c3c121560 -r 88e527ca878f usr/src/cmd/cmd-inet/usr.lib/ilbd/ilbd_sg.c --- a/usr/src/cmd/cmd-inet/usr.lib/ilbd/ilbd_sg.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/cmd/cmd-inet/usr.lib/ilbd/ilbd_sg.c Thu Sep 09 11:46:43 2010 -0400 @@ -205,16 +205,22 @@ NET_ILB_ENABLE_AUTH; event->adt_ilb_enable_server.server_id = data->ed_serverid; - event->adt_ilb_enable_server.server_ipaddress = - data->ed_server_address; + event->adt_ilb_enable_server.server_ipaddress_type = + data->ed_ipaddr_type; + (void) memcpy(event->adt_ilb_enable_server.server_ipaddress, + data->ed_server_address, + (sizeof (data->ed_server_address))); break; case ILBD_DISABLE_SERVER: event->adt_ilb_disable_server.auth_used = NET_ILB_ENABLE_AUTH; event->adt_ilb_disable_server.server_id = data->ed_serverid; - event->adt_ilb_disable_server.server_ipaddress = - data->ed_server_address; + event->adt_ilb_disable_server.server_ipaddress_type = + data->ed_ipaddr_type; + (void) memcpy(event->adt_ilb_disable_server.server_ipaddress, + data->ed_server_address, + (sizeof (data->ed_server_address))); break; case ILBD_REM_SERVER_FROM_GROUP: event->adt_ilb_remove_server.auth_used = @@ -222,8 +228,11 @@ event->adt_ilb_remove_server.server_id = data->ed_serverid; event->adt_ilb_remove_server.server_group = data->ed_sgroup; - event->adt_ilb_remove_server.server_ipaddress = - data->ed_server_address; + event->adt_ilb_remove_server.server_ipaddress_type = + data->ed_ipaddr_type; + (void) memcpy(event->adt_ilb_remove_server.server_ipaddress, + data->ed_server_address, + (sizeof (data->ed_server_address))); break; case ILBD_CREATE_SERVERGROUP: event->adt_ilb_create_servergroup.auth_used = @@ -234,8 +243,11 @@ case ILBD_ADD_SERVER_TO_GROUP: event->adt_ilb_add_server.auth_used = NET_ILB_CONFIG_AUTH; - event->adt_ilb_add_server.server_ipaddress = - data->ed_server_address; + event->adt_ilb_add_server.server_ipaddress_type = + data->ed_ipaddr_type; + (void) memcpy(event->adt_ilb_add_server.server_ipaddress, + data->ed_server_address, + (sizeof (data->ed_server_address))); event->adt_ilb_add_server.server_id = data->ed_serverid; event->adt_ilb_add_server.server_group = @@ -547,19 +559,24 @@ for (i = 0; i < sg->sg_srvcount; i++) { tsrv = &sg->sg_servers[i]; if (cmd == ILBD_ADD_SERVER_TO_GROUP) { - char addrstr_buf[INET6_ADDRSTRLEN]; audit_sg_data->ed_serverid = NULL; - ilbd_addr2str(&tsrv->sgs_addr, addrstr_buf, - sizeof (addrstr_buf)); - audit_sg_data->ed_server_address = addrstr_buf; + if (IN6_IS_ADDR_V4MAPPED(&tsrv->sgs_addr)) { + audit_sg_data->ed_ipaddr_type = ADT_IPv4; + cvt_addr(audit_sg_data->ed_server_address, + ADT_IPv4, tsrv->sgs_addr); + } else { + audit_sg_data->ed_ipaddr_type = ADT_IPv6; + cvt_addr(audit_sg_data->ed_server_address, + ADT_IPv6, tsrv->sgs_addr); + } audit_sg_data->ed_minport = tsrv->sgs_minport; audit_sg_data->ed_maxport = tsrv->sgs_maxport; audit_sg_data->ed_sgroup = sg->sg_name; } else if (cmd == ILBD_REM_SERVER_FROM_GROUP) { audit_sg_data->ed_serverid = tsrv->sgs_srvID; audit_sg_data->ed_sgroup = sg->sg_name; - audit_sg_data->ed_server_address = NULL; + audit_sg_data->ed_minport = 0; audit_sg_data->ed_maxport = 0; } @@ -582,7 +599,6 @@ ilbd_srv_t *nsrv; ilb_sg_srv_t *srv; audit_sg_event_data_t audit_sg_data; - char addrstr_buf[INET6_ADDRSTRLEN]; if (ps != NULL) { rc = ilbd_check_client_config_auth(ps); @@ -624,9 +640,15 @@ srv = &sg_info->sg_servers[i]; (void) memset(&audit_sg_data, 0, sizeof (audit_sg_data)); - ilbd_addr2str(&srv->sgs_addr, addrstr_buf, - sizeof (addrstr_buf)); - audit_sg_data.ed_server_address = addrstr_buf; + if (IN6_IS_ADDR_V4MAPPED(&srv->sgs_addr)) { + audit_sg_data.ed_ipaddr_type = ADT_IPv4; + cvt_addr(audit_sg_data.ed_server_address, ADT_IPv4, + srv->sgs_addr); + } else { + audit_sg_data.ed_ipaddr_type = ADT_IPv6; + cvt_addr(audit_sg_data.ed_server_address, ADT_IPv6, + srv->sgs_addr); + } audit_sg_data.ed_minport = srv->sgs_minport; audit_sg_data.ed_maxport = srv->sgs_maxport; audit_sg_data.ed_sgroup = sg_info->sg_name; @@ -938,7 +960,6 @@ ilbd_srv_t *srv, tmp_srv; ilb_sg_srv_t *tsrv; audit_sg_event_data_t audit_sg_data; - char addrstr_buf[INET6_ADDRSTRLEN]; rc = ilbd_check_client_config_auth(ps); if (rc != ILB_STATUS_OK) { @@ -958,7 +979,6 @@ tsrv = &sg_info->sg_servers[0]; audit_sg_data.ed_serverid = tsrv->sgs_srvID; audit_sg_data.ed_sgroup = sg_info->sg_name; - audit_sg_data.ed_server_address = NULL; assert(sg_info->sg_srvcount == 1); srv = i_find_srv(&tmp_sg->isg_srvlist, &sg_info->sg_servers[0], @@ -971,9 +991,15 @@ return (ILB_STATUS_SRVUNAVAIL); } tsrv = &srv->isv_srv; - ilbd_addr2str(&tsrv->sgs_addr, addrstr_buf, - sizeof (addrstr_buf)); - audit_sg_data.ed_server_address = addrstr_buf; + if (IN6_IS_ADDR_V4MAPPED(&tsrv->sgs_addr)) { + audit_sg_data.ed_ipaddr_type = ADT_IPv4; + cvt_addr(audit_sg_data.ed_server_address, ADT_IPv4, + tsrv->sgs_addr); + } else { + audit_sg_data.ed_ipaddr_type = ADT_IPv6; + cvt_addr(audit_sg_data.ed_server_address, ADT_IPv6, + tsrv->sgs_addr); + } /* * i_delete_srv frees srv, therefore we need to save * this information for ilbd_scf_del_srv @@ -1184,7 +1210,6 @@ uint32_t nflags; ilbd_srv_status_ind_t u_cmd; audit_sg_event_data_t audit_sg_data; - char addrstr_buf[INET6_ADDRSTRLEN]; (void) memset(&audit_sg_data, 0, sizeof (audit_sg_data)); @@ -1193,7 +1218,6 @@ srv = &sg->sg_servers[0]; audit_sg_data.ed_serverid = srv->sgs_srvID; - audit_sg_data.ed_server_address = NULL; rc = ilbd_check_client_enable_auth(ps); if (rc != ILB_STATUS_OK) { @@ -1298,9 +1322,15 @@ return (ILB_STATUS_INVAL_ENBSRVR); } /* Fill in the server IP address for audit record */ - ilbd_addr2str(&tmp_srv->isv_addr, addrstr_buf, - sizeof (addrstr_buf)); - audit_sg_data.ed_server_address = addrstr_buf; + if (IN6_IS_ADDR_V4MAPPED(&tmp_srv->isv_addr)) { + audit_sg_data.ed_ipaddr_type = ADT_IPv4; + cvt_addr(audit_sg_data.ed_server_address, ADT_IPv4, + tmp_srv->isv_addr); + } else { + audit_sg_data.ed_ipaddr_type = ADT_IPv6; + cvt_addr(audit_sg_data.ed_server_address, ADT_IPv6, + tmp_srv->isv_addr); + } /* * We have found the server in memory, perform the following @@ -1540,38 +1570,6 @@ return (ILB_STATUS_OK); } -void -ilbd_addr2str(struct in6_addr *ipaddr, char *addrstr_buf, size_t sz) -{ - ilb_ip_addr_t ilb_ip; - - IP_COPY_IMPL_2_CLI(ipaddr, &ilb_ip); - addr2str(ilb_ip, addrstr_buf, sz); -} - -/* Convert ip address to a address string */ -void -addr2str(ilb_ip_addr_t ip, char *buf, size_t sz) -{ - - switch (ip.ia_af) { - case AF_INET: - if ((uint32_t *)&(ip).ia_v4 == 0) - buf[0] = '\0'; - else - (void) inet_ntop(AF_INET, (void *)&(ip).ia_v4, buf, sz); - break; - case AF_INET6: - if (IN6_IS_ADDR_UNSPECIFIED(&(ip).ia_v6)) { - buf[0] = '\0'; - break; - } - (void) inet_ntop(ip.ia_af, (void *)&(ip).ia_v6, buf, sz); - break; - default: buf[0] = '\0'; - } -} - /* * Map ilb_status errors to similar errno values from errno.h or * adt_event.h to be used for audit record diff -r 5f6c3c121560 -r 88e527ca878f usr/src/cmd/man/src/man.c --- a/usr/src/cmd/man/src/man.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/cmd/man/src/man.c Thu Sep 09 11:46:43 2010 -0400 @@ -91,7 +91,7 @@ #define SOLIMIT 10 /* maximum allowed .so chain length */ #define MAXDIRS 128 /* max # of subdirs per manpath */ -#define MAXPAGES 32 /* max # for multiple pages */ +#define MAXPAGES 128 /* max # for multiple pages */ #define PLEN 3 /* prefix length {man, cat, fmt} */ #define TMPLEN 7 /* length of tmpfile prefix */ #define MAXTOKENS 64 @@ -1755,7 +1755,7 @@ if (**secv == '\\') { if (!eq(*secv + 1, *dv+plen)) continue; - } else if (!match(*secv, *dv+plen, len)) { + } else if (strncasecmp(*secv, *dv+plen, len) != 0) { /* check to see if directory name changed */ if (!all && (newsection = map_section(*secv, path)) @@ -1945,7 +1945,7 @@ FILE *fp; struct stat sbuf; struct suffix *sp; - struct suffix psecs[MAXPAGES]; + struct suffix psecs[MAXPAGES+1]; char whatfile[MAXPATHLEN+1]; char page[MAXPATHLEN+1]; char *matches[MAXPAGES]; @@ -1982,8 +1982,20 @@ * Save and split sections * section() allocates memory for sp->ds */ - for (sp = psecs, vp = matches; *vp; vp++, sp++) - section(sp, *vp); + for (sp = psecs, vp = matches; *vp; vp++, sp++) { + if ((sp - psecs) < MAXPAGES) { + section(sp, *vp); + } else { + if (debug) + (void) fprintf(stderr, gettext( + "too many sections in %s windex entry\n"), + name); + + /* Setting sp->ds to NULL signifies end-of-data. */ + sp->ds = 0; + goto finish; + } + } sp->ds = 0; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c --- a/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c Thu Sep 09 11:46:43 2010 -0400 @@ -584,16 +584,10 @@ static const smb_exp_t smb_server_exp[] = { { SMB_OPT_ALL_OBJ, - offsetof(smb_server_t, sv_nbt_daemon.ld_session_list.se_rdy.lst), + offsetof(smb_server_t, sv_nbt_daemon.ld_session_list.ll_list), "smbsess", "smb_session"}, { SMB_OPT_ALL_OBJ, - offsetof(smb_server_t, sv_nbt_daemon.ld_session_list.se_act.lst), - "smbsess", "smb_session"}, - { SMB_OPT_ALL_OBJ, - offsetof(smb_server_t, sv_tcp_daemon.ld_session_list.se_rdy.lst), - "smbsess", "smb_session"}, - { SMB_OPT_ALL_OBJ, - offsetof(smb_server_t, sv_tcp_daemon.ld_session_list.se_act.lst), + offsetof(smb_server_t, sv_tcp_daemon.ld_session_list.ll_list), "smbsess", "smb_session"}, { 0, 0, NULL, NULL } }; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/cmd/smbsrv/smbd/server.xml --- a/usr/src/cmd/smbsrv/smbd/server.xml Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/cmd/smbsrv/smbd/server.xml Thu Sep 09 11:46:43 2010 -0400 @@ -169,7 +169,7 @@ + value='100000' override='true'/> #include @@ -159,6 +167,11 @@ %% +/* + * NOTE: Each commands reduction rule must invoke assert_no_unclaimed_tokens() + * before it completes if it isn't processing an error. This ensures that + * reduction rules properly consume TOKENs. + */ commands: command terminator { if ($1 != NULL) { @@ -168,6 +181,7 @@ bzero(list, sizeof (list_property_t)); num_prop_vals = 0; } + assert_no_unclaimed_tokens(); return (0); } | command error terminator @@ -191,6 +205,7 @@ } | terminator { + assert_no_unclaimed_tokens(); return (0); } @@ -228,7 +243,7 @@ cmd = $$; $$->cmd_handler = &add_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } | ADD resource_type @@ -269,7 +284,7 @@ cmd = $$; $$->cmd_handler = &cancel_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } @@ -289,7 +304,7 @@ cmd = $$; $$->cmd_handler = &create_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } | CREATE TOKEN TOKEN @@ -299,8 +314,8 @@ cmd = $$; $$->cmd_handler = &create_func; $$->cmd_argc = 2; - $$->cmd_argv[0] = $2; - $$->cmd_argv[1] = $3; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = claim_token($3); $$->cmd_argv[2] = NULL; } | CREATE TOKEN TOKEN TOKEN @@ -310,9 +325,9 @@ cmd = $$; $$->cmd_handler = &create_func; $$->cmd_argc = 3; - $$->cmd_argv[0] = $2; - $$->cmd_argv[1] = $3; - $$->cmd_argv[2] = $4; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = claim_token($3); + $$->cmd_argv[2] = claim_token($4); $$->cmd_argv[3] = NULL; } @@ -332,7 +347,7 @@ cmd = $$; $$->cmd_handler = &commit_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } @@ -352,7 +367,7 @@ cmd = $$; $$->cmd_handler = &delete_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } @@ -372,7 +387,7 @@ cmd = $$; $$->cmd_handler = &end_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } @@ -392,7 +407,7 @@ cmd = $$; $$->cmd_handler = &exit_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } @@ -412,7 +427,7 @@ cmd = $$; $$->cmd_handler = &export_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } | EXPORT TOKEN TOKEN @@ -422,8 +437,8 @@ cmd = $$; $$->cmd_handler = &export_func; $$->cmd_argc = 2; - $$->cmd_argv[0] = $2; - $$->cmd_argv[1] = $3; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = claim_token($3); $$->cmd_argv[2] = NULL; } @@ -443,7 +458,7 @@ cmd = $$; $$->cmd_handler = &help_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } @@ -461,7 +476,7 @@ short_usage(CMD_INFO); (void) fputs("\n", stderr); usage(B_FALSE, HELP_RES_PROPS); - free($2); + free(claim_token($2)); YYERROR; } | INFO resource_type @@ -687,6 +702,7 @@ short_usage(CMD_REMOVE); (void) fputs("\n", stderr); usage(B_FALSE, HELP_RES_PROPS); + free(claim_token($2)); YYERROR; } | REMOVE resource_type @@ -705,7 +721,7 @@ $$->cmd_handler = &remove_func; $$->cmd_res_type = $3; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } | REMOVE property_name property_value @@ -774,7 +790,7 @@ cmd = $$; $$->cmd_handler = &revert_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } @@ -889,7 +905,7 @@ YYERROR; cmd = $$; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; $$->cmd_handler = &set_func; $$->cmd_prop_nv_pairs = 1; @@ -929,7 +945,7 @@ cmd = $$; $$->cmd_handler = &verify_func; $$->cmd_argc = 1; - $$->cmd_argv[0] = $2; + $$->cmd_argv[0] = claim_token($2); $$->cmd_argv[1] = NULL; } @@ -1046,7 +1062,7 @@ simple_prop_val: TOKEN { $$ = simple_prop_val_func($1); - free($1); + free(claim_token($1)); if ($$ == NULL) YYERROR; } @@ -1081,7 +1097,7 @@ complex_piece: property_name EQUAL TOKEN { $$ = complex_piece_func($1, $3, NULL); - free($3); + free(claim_token($3)); if ($$ == NULL) YYERROR; } @@ -1098,7 +1114,7 @@ | property_name EQUAL TOKEN COMMA complex_piece { $$ = complex_piece_func($1, $3, complex); - free($3); + free(claim_token($3)); if ($$ == NULL) YYERROR; } diff -r 5f6c3c121560 -r 88e527ca878f usr/src/cmd/zonecfg/zonecfg_lex.l --- a/usr/src/cmd/zonecfg/zonecfg_lex.l Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/cmd/zonecfg/zonecfg_lex.l Thu Sep 09 11:46:43 2010 -0400 @@ -24,17 +24,37 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ +#include #include #include #include "zonecfg.h" #include "zonecfg_grammar.tab.h" +/* + * This constant defines the number of entries added to unclaimed_tokens[] + * when it runs out of space. + */ +#define UNCLAIMED_TOKENS_BUFFER_GROWTH 4 + +/* + * Invariants: + * + * unclaimed_tokens == NULL IFF unclaimed_tokens_size == 0 + * unclaimed_tokens_size == 0 IFF num_unclaimed_tokens == 0 + */ +static char **unclaimed_tokens; /* TOKENs produced by Lex (see below) */ + /* but not claimed by YACC reduction */ + /* rules */ +static unsigned int unclaimed_tokens_size; /* size of unclaimed_tokens */ +static unsigned int num_unclaimed_tokens; /* number of unclaimed TOKENs */ + int lex_lineno = 1; /* line number for error reporting */ static int state = INITIAL; extern boolean_t cmd_file_mode; extern boolean_t saw_error; extern void yyerror(char *s); -char *safe_strdup(char *s); + +static char *create_token(char *s); %} %a 7000 @@ -323,29 +343,29 @@ "," { return COMMA; } [^ \t\n\";=\[\]\(\)]+ { - yylval.strval = safe_strdup(yytext); + yylval.strval = create_token(yytext); return TOKEN; } [^ \t\n\",;=\[\]\(\)]+ { - yylval.strval = safe_strdup(yytext); + yylval.strval = create_token(yytext); return TOKEN; } [^ \t\n\",;=\(\)]+ { - yylval.strval = safe_strdup(yytext); + yylval.strval = create_token(yytext); return TOKEN; } \"[^\"\n]*[\"\n] { - yylval.strval = safe_strdup(yytext + 1); + yylval.strval = create_token(yytext + 1); if (yylval.strval[yyleng - 2] == '"') yylval.strval[yyleng - 2] = 0; return TOKEN; } \"[^\"\n]*[\"\n] { - yylval.strval = safe_strdup(yytext + 1); + yylval.strval = create_token(yytext + 1); if (yylval.strval[yyleng - 2] == '"') yylval.strval[yyleng - 2] = 0; return TOKEN; @@ -370,8 +390,88 @@ %% +/* + * Assert that there are no unclaimed tokens. This function enforces the + * invariants mentioned at the top of this file. + */ +void +assert_no_unclaimed_tokens(void) +{ + assert(num_unclaimed_tokens == 0); + assert(unclaimed_tokens == NULL); + assert(unclaimed_tokens_size == 0); +} + +/* + * Claim the specified unclaimed TOKEN. YACC reduction rules that + * use TOKENs should invoke this function immediately before freeing the TOKENs + * or adding them to data structures that will be cleaned up when the YACC + * parser finishes or encounters errors. Reduction rules should only claim the + * TOKENs that they use. + * + * This function returns its argument but does not free its memory. + */ char * -safe_strdup(char *s) +claim_token(char *token) +{ + unsigned int index; + + /* + * Find the token in the list of unclaimed tokens. + */ + assert(num_unclaimed_tokens > 0); + for (index = 0; index < num_unclaimed_tokens; index++) { + if (unclaimed_tokens[index] == token) + break; + } + + /* + * Abort if we didn't find the token. + */ + assert(index != num_unclaimed_tokens); + + /* + * Replace the token with the last unclaimed token. + */ + num_unclaimed_tokens--; + unclaimed_tokens[index] = unclaimed_tokens[num_unclaimed_tokens]; + + /* + * Delete the list of unclaimed tokens if it's empty. + */ + if (num_unclaimed_tokens == 0) { + free(unclaimed_tokens); + unclaimed_tokens = NULL; + unclaimed_tokens_size = 0; + } + + return (token); +} + +/* + * Free all unclaimed TOKENs. This should only be invoked when the YACC + * parser encounters errors. + */ +static void +free_tokens(void) +{ + if (unclaimed_tokens != NULL) { + while (num_unclaimed_tokens > 0) + free(unclaimed_tokens[--num_unclaimed_tokens]); + free(unclaimed_tokens); + unclaimed_tokens = NULL; + unclaimed_tokens_size = 0; + } + assert_no_unclaimed_tokens(); +} + +/* + * Create a TOKEN from the specified string. The TOKEN is merely a duplicate + * of the specified string. TOKENs must be claimed by the YACC reduction rules + * that use them; see claim_token() above. + */ +char * +create_token(char *s) { char *result; @@ -379,12 +479,39 @@ yyerror("Out of memory"); exit(Z_ERR); } + + /* + * Add the new TOKEN to the list of unclaimed TOKENs. The list might + * have to be resized. + * + * Reduction rules should claim TOKENs via claim_token() (see above). + */ + if (num_unclaimed_tokens == unclaimed_tokens_size) { + char **new_unclaimed_tokens; + + unclaimed_tokens_size += UNCLAIMED_TOKENS_BUFFER_GROWTH; + new_unclaimed_tokens = (char **)realloc(unclaimed_tokens, + unclaimed_tokens_size * sizeof (char *)); + if (new_unclaimed_tokens == NULL) { + yyerror("Out of memory"); + free(result); + exit(Z_ERR); + } + unclaimed_tokens = new_unclaimed_tokens; + } + unclaimed_tokens[num_unclaimed_tokens] = result; + num_unclaimed_tokens++; return (result); } void yyerror(char *s) { + /* + * Ensure that we won't leak unclaimed tokens. + */ + free_tokens(); + /* feof(yyin) is not an error; anything else is, so we set saw_error */ if (yytext[0] == '\0') { if (!feof(yyin)) { diff -r 5f6c3c121560 -r 88e527ca878f usr/src/lib/libbsm/common/adt.xml --- a/usr/src/lib/libbsm/common/adt.xml Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/lib/libbsm/common/adt.xml Thu Sep 09 11:46:43 2010 -0400 @@ -20,8 +20,7 @@ CDDL HEADER END -Copyright 2010 Sun Microsystems, Inc. All rights reserved. -Use is subject to license terms. +Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. --> @@ -2064,7 +2063,7 @@ - Integrated Loadbalancer + Create Integrated Loadbalancer healthcheck object /usr/sbin/ilbadm ilbadm(1m) @@ -2115,7 +2114,7 @@ - Integrated Loadbalancer + Delete Integrated Loadbalancer healthcheck object /usr/sbin/ilbadm ilbadm(1m) @@ -2138,12 +2137,8 @@ - - Integrated Loadbalancer + Create Integrated Loadbalancer rule /usr/sbin/ilbadm ilbadm(1m) @@ -2155,19 +2150,19 @@ authorization used - - - + + + LB virtual IP address - - + + minimum value in port range - - + + maximum value in port range - max=min means single port is specified @@ -2182,11 +2177,16 @@ [rr,hip,hipp,hipv],[dsr,nat,half-nat] - - - - proxy source address for NAT - may be single - address or a address range + + + + min value for proxy source address for NAT + + + + + max value in proxy source address range for NAT + - max=min means single address is specified @@ -2269,31 +2269,27 @@ - Integrated Loadbalancer + Delete Integrated Loadbalancer rule /usr/sbin/ilbadm ilbadm(1m) - Integrated Loadbalancer + Disable Integrated Loadbalancer rule /usr/sbin/ilbadm ilbadm(1m) - Integrated Loadbalancer + Enable Integrated Loadbalancer rule /usr/sbin/ilbadm ilbadm(1m) - - Integrated Loadbalancer + Add server to Integrated Loadbalancer /usr/sbin/ilbadm ilbadm(1m) @@ -2305,9 +2301,9 @@ authorization used - - - + + + IP address @@ -2325,15 +2321,15 @@ server group name - - + + server's minimum value in port range - empty means default value (see man page) - - + + server's maximum value in port range - empty means default value(see man page) @@ -2344,12 +2340,8 @@ - - Integrated Loadbalancer + Disable server to Integrated Loadbalancer /usr/sbin/ilbadm ilbadm(1m) @@ -2366,10 +2358,10 @@ serverid - - - - IPaddr corresponding to the serverid - empty + + + + IPaddr corresponding to the serverid - empty if authorization fails, or user specified serverid is nonexistent @@ -2380,12 +2372,8 @@ - - Integrated Loadbalancer + Enable server to Integrated Loadbalancer /usr/sbin/ilbadm ilbadm(1m) @@ -2402,10 +2390,10 @@ serverid - - - - IPaddr corresponding to the serverid - empty + + + + IPaddr corresponding to the serverid - empty if authorization fails, or user specified serverid is nonexistent @@ -2416,12 +2404,8 @@ - - Integrated Loadbalancer + Remove server from Integrated Loadbalancer /usr/sbin/ilbadm ilbadm(1m) @@ -2443,10 +2427,10 @@ server group name - - - - IPaddr corresponding to serverid - empty + + + + IPaddr corresponding to serverid - empty if authorization fails or user specified serverid serverid is nonexistent @@ -2458,7 +2442,7 @@ - Integrated Loadbalancer + Create server group for Integrated Loadbalancer /usr/sbin/ilbadm ilbadm(1m) @@ -2482,7 +2466,7 @@ - Integrated Loadbalancer + Delete server group from Integrated Loadbalancer /usr/sbin/ilbadm ilbadm(1m) diff -r 5f6c3c121560 -r 88e527ca878f usr/src/lib/libnisdb/yptol/dit_access.c --- a/usr/src/lib/libnisdb/yptol/dit_access.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/lib/libnisdb/yptol/dit_access.c Thu Sep 09 11:46:43 2010 -0400 @@ -19,12 +19,9 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * DESCRIPTION: Contains top level functions to read/write to the DIT. These * are the API between the shim and the mapping system. @@ -615,6 +612,16 @@ int next_print = PRINT_FREQ; int search_flag = SUCCESS; + int m; + + /* list of maps whose keys will be transliterated to lowercase */ + char *xlate_to_lcase_maps[] = { + "hosts.byname", + "ipnodes.byname", + NULL + }; + bool_t xlate_to_lcase = FALSE; + if (!map || !map->map_name || !map->domain) { return (FAILURE); } @@ -692,6 +699,20 @@ return (FAILURE); } + /* + * set xlate_to_lcase to TRUE if map_name is found in + * xlate_to_lcase_maps[] + */ + m = 0; + while (xlate_to_lcase_maps[m] != NULL) { + if (strncmp(map->map_name, xlate_to_lcase_maps[m], + strlen(xlate_to_lcase_maps[m])) == 0) { + xlate_to_lcase = TRUE; + break; + } + ++m; + } + /* Try each mapping for the map */ for (flag = 0; t != 0 && search_flag != FAILURE; t = t->next) { @@ -802,7 +823,7 @@ /* Obtain the datum for key */ datkey = getKeyFromRuleValue(t, &rv[i], - &nv, &statP); + &nv, &statP, xlate_to_lcase); if (datkey == 0) { logmsg(MSG_NOTIMECHECK, LOG_WARNING, "%s: Unable to obtain NIS " diff -r 5f6c3c121560 -r 88e527ca878f usr/src/lib/libnisdb/yptol/dit_access_utils.c --- a/usr/src/lib/libnisdb/yptol/dit_access_utils.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/lib/libnisdb/yptol/dit_access_utils.c Thu Sep 09 11:46:43 2010 -0400 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,12 +19,9 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * DESCRIPTION: Contains dit_access interface support functions. */ @@ -55,6 +51,9 @@ #include "yptol.h" #include "dit_access_utils.h" +#define YPMULTI "YP_MULTI_" +#define YPMULTISZ 9 /* == strlen(YPMULTI) */ + /* * Returns 'map,domain.' */ @@ -852,8 +851,9 @@ datum * getKeyFromRuleValue(__nis_table_mapping_t *t, __nis_rule_value_t *rv, int *nv, - int *statP) { - int i, j; + int *statP, bool_t xlate_to_lcase) +{ + int i, j, k; datum *key = 0; char *str; char *myself = "getKeyFromRuleValue"; @@ -868,7 +868,7 @@ if (rv->colName[i] == 0) continue; if (strcasecmp(N2LKEY, rv->colName[i]) == 0 || - strcasecmp(N2LIPKEY, rv->colName[i]) == 0) { + strcasecmp(N2LIPKEY, rv->colName[i]) == 0) { if ((*nv = rv->colVal[i].numVals) == 0) return (0); if ((key = am(myself, sizeof (key[0]) * *nv)) == 0) { @@ -881,15 +881,15 @@ key[j].dptr = 0; } else { if (verifyIndexMatch(t, 0, 0, - rv->colName[i], - str) == 0) { + rv->colName[i], str) == 0) { key[j].dsize = 0; key[j].dptr = 0; continue; } + key[j].dsize = strlen(str); key[j].dptr = am(myself, - key[j].dsize + 1); + key[j].dsize + 1); if (key[j].dptr == 0) { *statP = MAP_NO_MEMORY; for (--j; j >= 0; j--) @@ -897,7 +897,33 @@ sfree(key); return (0); } - bcopy(str, key[j].dptr, key[j].dsize); + + /* transliterate key to lowercase */ + if (xlate_to_lcase == TRUE) { + + /* + * For multi-homed + * entries, skip over + * "YP_MULTI_" prefix. + */ + k = 0; + if (strncmp(YPMULTI, str, + YPMULTISZ) == 0) { + k = YPMULTISZ; + bcopy(str, key[j].dptr, + YPMULTISZ); + } + while (k < key[j].dsize) { + key[j].dptr[k] = + (char)tolower( + (int)(uchar_t) + str[k]); + k++; + } + } else { + bcopy(str, key[j].dptr, + key[j].dsize); + } } } return (key); diff -r 5f6c3c121560 -r 88e527ca878f usr/src/lib/libnisdb/yptol/dit_access_utils.h --- a/usr/src/lib/libnisdb/yptol/dit_access_utils.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/lib/libnisdb/yptol/dit_access_utils.h Thu Sep 09 11:46:43 2010 -0400 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,15 +19,12 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _DIT_ACCESS_UTILS_H #define _DIT_ACCESS_UTILS_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif @@ -73,7 +69,8 @@ extern datum *ruleValueToDatum(__nis_table_mapping_t *t, __nis_rule_value_t *rv, int *statP); extern datum *getKeyFromRuleValue(__nis_table_mapping_t *t, - __nis_rule_value_t *rv, int *nv, int *statP); + __nis_rule_value_t *rv, int *nv, int *statP, + bool_t xlate_to_lcase); extern const char *getObjectClass(char *rdn); extern suc_code makeNISObject(char *domain, char *dn); extern suc_code addNISObject(char *domain, char *dn, diff -r 5f6c3c121560 -r 88e527ca878f usr/src/lib/libzpool/common/sys/zfs_context.h --- a/usr/src/lib/libzpool/common/sys/zfs_context.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/lib/libzpool/common/sys/zfs_context.h Thu Sep 09 11:46:43 2010 -0400 @@ -315,6 +315,7 @@ #define KM_PUSHPAGE KM_SLEEP #define KM_NOSLEEP UMEM_DEFAULT #define KMC_NODEBUG UMC_NODEBUG +#define KMC_NOTOUCH 0 /* not needed for userland caches */ #define kmem_alloc(_s, _f) umem_alloc(_s, _f) #define kmem_zalloc(_s, _f) umem_zalloc(_s, _f) #define kmem_free(_b, _s) umem_free(_b, _s) diff -r 5f6c3c121560 -r 88e527ca878f usr/src/lib/smbsrv/libsmb/common/libsmb.h --- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h Thu Sep 09 11:46:43 2010 -0400 @@ -884,10 +884,6 @@ int smb_kmod_start(int, int, int); void smb_kmod_stop(void); int smb_kmod_event_notify(uint32_t); -int smb_kmod_tcplisten(int); -int smb_kmod_nbtlisten(int); -int smb_kmod_tcpreceive(void); -int smb_kmod_nbtreceive(void); void smb_kmod_unbind(void); int smb_kmod_share(nvlist_t *); int smb_kmod_unshare(nvlist_t *); diff -r 5f6c3c121560 -r 88e527ca878f usr/src/lib/smbsrv/libsmb/common/mapfile-vers --- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers Thu Sep 09 11:46:43 2010 -0400 @@ -222,8 +222,6 @@ smb_kmod_get_open_num; smb_kmod_get_spool_doc; smb_kmod_isbound; - smb_kmod_nbtlisten; - smb_kmod_nbtreceive; smb_kmod_session_close; smb_kmod_setcfg; smb_kmod_setgmtoff; @@ -231,8 +229,6 @@ smb_kmod_shareinfo; smb_kmod_start; smb_kmod_stop; - smb_kmod_tcplisten; - smb_kmod_tcpreceive; smb_kmod_unbind; smb_kmod_unshare; smb_join; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/lib/smbsrv/libsmb/common/smb_kmod.c --- a/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c Thu Sep 09 11:46:43 2010 -0400 @@ -136,40 +136,6 @@ } int -smb_kmod_tcplisten(int error) -{ - smb_ioc_listen_t ioc; - - ioc.error = error; - return (smb_kmod_ioctl(SMB_IOC_TCP_LISTEN, &ioc.hdr, sizeof (ioc))); -} - -int -smb_kmod_nbtlisten(int error) -{ - smb_ioc_listen_t ioc; - - ioc.error = error; - return (smb_kmod_ioctl(SMB_IOC_NBT_LISTEN, &ioc.hdr, sizeof (ioc))); -} - -int -smb_kmod_tcpreceive(void) -{ - smb_ioc_header_t ioc; - - return (smb_kmod_ioctl(SMB_IOC_TCP_RECEIVE, &ioc, sizeof (ioc))); -} - -int -smb_kmod_nbtreceive(void) -{ - smb_ioc_header_t ioc; - - return (smb_kmod_ioctl(SMB_IOC_NBT_RECEIVE, &ioc, sizeof (ioc))); -} - -int smb_kmod_share(nvlist_t *shrlist) { smb_ioc_share_t *ioc; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/smbsrv/smb_init.c --- a/usr/src/uts/common/fs/smbsrv/smb_init.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/smbsrv/smb_init.c Thu Sep 09 11:46:43 2010 -0400 @@ -261,18 +261,6 @@ case SMB_IOC_EVENT: rc = smb_server_notify_event(&ioc->ioc_event); break; - case SMB_IOC_NBT_LISTEN: - rc = smb_server_nbt_listen(&ioc->ioc_listen); - break; - case SMB_IOC_TCP_LISTEN: - rc = smb_server_tcp_listen(&ioc->ioc_listen); - break; - case SMB_IOC_NBT_RECEIVE: - rc = smb_server_nbt_receive(); - break; - case SMB_IOC_TCP_RECEIVE: - rc = smb_server_tcp_receive(); - break; case SMB_IOC_GMTOFF: rc = smb_server_set_gmtoff(&ioc->ioc_gmt); break; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/smbsrv/smb_kshare.c --- a/usr/src/uts/common/fs/smbsrv/smb_kshare.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/smbsrv/smb_kshare.c Thu Sep 09 11:46:43 2010 -0400 @@ -307,7 +307,7 @@ sizeof (smb_unshare_t), offsetof(smb_unshare_t, us_lnd)); smb_thread_init(&smb_export.e_unexport_thread, "smb_thread_unexport", - smb_kshare_unexport_thread, NULL, NULL, NULL); + smb_kshare_unexport_thread, NULL); if ((rc = smb_thread_start(&smb_export.e_unexport_thread)) != 0) return (rc); diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/smbsrv/smb_kutil.c --- a/usr/src/uts/common/fs/smbsrv/smb_kutil.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/smbsrv/smb_kutil.c Thu Sep 09 11:46:43 2010 -0400 @@ -889,9 +889,7 @@ smb_thread_t *thread, char *name, smb_thread_ep_t ep, - void *ep_arg, - smb_thread_aw_t aw, - void *aw_arg) + void *ep_arg) { ASSERT(thread->sth_magic != SMB_THREAD_MAGIC); @@ -900,8 +898,6 @@ (void) strlcpy(thread->sth_name, name, sizeof (thread->sth_name)); thread->sth_ep = ep; thread->sth_ep_arg = ep_arg; - thread->sth_aw = aw; - thread->sth_aw_arg = aw_arg; thread->sth_state = SMB_THREAD_STATE_EXITED; mutex_init(&thread->sth_mtx, NULL, MUTEX_DEFAULT, NULL); cv_init(&thread->sth_cv, NULL, CV_DEFAULT, NULL); @@ -968,8 +964,7 @@ * state has been reached. */ void -smb_thread_stop( - smb_thread_t *thread) +smb_thread_stop(smb_thread_t *thread) { ASSERT(thread->sth_magic == SMB_THREAD_MAGIC); @@ -979,8 +974,6 @@ case SMB_THREAD_STATE_STARTING: if (!thread->sth_kill) { thread->sth_kill = B_TRUE; - if (thread->sth_aw) - thread->sth_aw(thread, thread->sth_aw_arg); cv_broadcast(&thread->sth_cv); while (thread->sth_state != SMB_THREAD_STATE_EXITING) cv_wait(&thread->sth_cv, &thread->sth_mtx); @@ -1021,16 +1014,13 @@ * This function signals a thread. */ void -smb_thread_signal( - smb_thread_t *thread) +smb_thread_signal(smb_thread_t *thread) { ASSERT(thread->sth_magic == SMB_THREAD_MAGIC); mutex_enter(&thread->sth_mtx); switch (thread->sth_state) { case SMB_THREAD_STATE_RUNNING: - if (thread->sth_aw) - thread->sth_aw(thread, thread->sth_aw_arg); cv_signal(&thread->sth_cv); break; @@ -1112,18 +1102,6 @@ return (result); } -void -smb_thread_set_awaken(smb_thread_t *thread, smb_thread_aw_t new_aw_fn, - void *new_aw_arg) -{ - ASSERT(thread->sth_magic == SMB_THREAD_MAGIC); - - mutex_enter(&thread->sth_mtx); - thread->sth_aw = new_aw_fn; - thread->sth_aw_arg = new_aw_arg; - mutex_exit(&thread->sth_mtx); -} - /* * smb_rwx_init */ diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c --- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c Thu Sep 09 11:46:43 2010 -0400 @@ -140,8 +140,7 @@ offsetof(smb_request_t, sr_ncr.nc_lnd)); smb_thread_init(&smb_thread_notify_daemon, - "smb_notify_change_daemon", smb_notify_change_daemon, NULL, - NULL, NULL); + "smb_notify_change_daemon", smb_notify_change_daemon, NULL); rc = smb_thread_start(&smb_thread_notify_daemon); if (rc) { diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/smbsrv/smb_oplock.c --- a/usr/src/uts/common/fs/smbsrv/smb_oplock.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/smbsrv/smb_oplock.c Thu Sep 09 11:46:43 2010 -0400 @@ -98,7 +98,7 @@ offsetof(smb_oplock_break_t, ob_lnd)); smb_thread_init(&smb_oplock_thread, "smb_thread_oplock_break", - smb_oplock_break_thread, NULL, NULL, NULL); + smb_oplock_break_thread, NULL); rc = smb_thread_start(&smb_oplock_thread); if (rc != 0) { diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/smbsrv/smb_server.c --- a/usr/src/uts/common/fs/smbsrv/smb_server.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/smbsrv/smb_server.c Thu Sep 09 11:46:43 2010 -0400 @@ -148,21 +148,11 @@ * SMB_SERVER_STATE_RUNNING * * The server has been started. While in this state the threads listening on - * the sockets car be started. The smbd daemon does so through an Ioctl: - * - * smb_drv_ioctl(SMB_IOC_NBT_LISTEN) --> smb_server_nbt_listen() - * smb_drv_ioctl(SMB_IOC_TCP_LISTEN) --> smb_server_nbt_listen() + * the sockets are started. * - * When a client establishes a connection the thread listening leaves - * temporarily the kernel. While in user space it creates a thread for the - * new session. It then returns to kernel with the result of the thread - * creation. If the creation failed the new session context is destroyed - * before returning listening. - * - * The new created thread enters the kernel though an Ioctl: - * - * smb_drv_ioctl(SMB_IOC_NBT_RECEIVE) --> smb_server_nbt_receive() - * smb_drv_ioctl(SMB_IOC_TCP_RECEIVE) --> smb_server_tcp_receive() + * When a client establishes a connection the thread listening dispatches + * a task with the new session as an argument. If the dispatch fails the new + * session context is destroyed. * * SMB_SERVER_STATE_STOPPING * @@ -231,30 +221,40 @@ extern void smb_reply_notify_change_request(smb_request_t *); +typedef struct { + smb_listener_daemon_t *ra_listener; + smb_session_t *ra_session; +} smb_receiver_arg_t; + static void smb_server_kstat_init(smb_server_t *); static void smb_server_kstat_fini(smb_server_t *); static void smb_server_timers(smb_thread_t *, void *); -static int smb_server_listen(smb_server_t *, smb_listener_daemon_t *, - in_port_t, int, int); -static void smb_server_listen_fini(smb_listener_daemon_t *); -static kt_did_t smb_server_listener_tid(smb_listener_daemon_t *); static int smb_server_lookup(smb_server_t **); static void smb_server_release(smb_server_t *); static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *); static void smb_server_shutdown(smb_server_t *); static int smb_server_fsop_start(smb_server_t *); static void smb_server_fsop_stop(smb_server_t *); -static void smb_server_signal_listeners(smb_server_t *); static void smb_event_cancel(smb_server_t *, uint32_t); static uint32_t smb_event_alloc_txid(void); -static void smb_server_disconnect_share(smb_session_list_t *, const char *); -static void smb_server_enum_private(smb_session_list_t *, smb_svcenum_t *); -static int smb_server_sesion_disconnect(smb_session_list_t *, const char *, +static void smb_server_disconnect_share(smb_llist_t *, const char *); +static void smb_server_enum_private(smb_llist_t *, smb_svcenum_t *); +static int smb_server_session_disconnect(smb_llist_t *, const char *, const char *); -static int smb_server_fclose(smb_session_list_t *, uint32_t); +static int smb_server_fclose(smb_llist_t *, uint32_t); static int smb_server_kstat_update(kstat_t *, int); static int smb_server_legacy_kstat_update(kstat_t *, int); +static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *, + char *, in_port_t, int); +static void smb_server_listener_destroy(smb_listener_daemon_t *); +static int smb_server_listener_start(smb_listener_daemon_t *); +static void smb_server_listener_stop(smb_listener_daemon_t *); +static void smb_server_listener(smb_thread_t *, void *); +static void smb_server_receiver(void *); +static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t); +static void smb_server_destroy_session(smb_listener_daemon_t *, + smb_session_t *); int smb_event_debug = 0; @@ -379,9 +379,6 @@ smb_llist_constructor(&sv->sp_info.sp_fidlist, sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd)); - smb_session_list_constructor(&sv->sv_nbt_daemon.ld_session_list); - smb_session_list_constructor(&sv->sv_tcp_daemon.ld_session_list); - sv->si_cache_request = kmem_cache_create("smb_request_cache", sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0); sv->si_cache_session = kmem_cache_create("smb_session_cache", @@ -400,8 +397,7 @@ sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0); smb_thread_init(&sv->si_thread_timers, - "smb_timers", smb_server_timers, sv, - NULL, NULL); + "smb_timers", smb_server_timers, sv); sv->sv_pid = curproc->p_pid; smb_srqueue_init(&sv->sv_srqueue); @@ -442,8 +438,6 @@ smb_server_delete(void) { smb_server_t *sv; - kt_did_t nbt_tid; - kt_did_t tcp_tid; int rc; rc = smb_server_lookup(&sv); @@ -457,24 +451,15 @@ mutex_enter(&sv->sv_mutex); switch (sv->sv_state) { case SMB_SERVER_STATE_RUNNING: - case SMB_SERVER_STATE_STOPPING: sv->sv_state = SMB_SERVER_STATE_STOPPING; - smb_server_signal_listeners(sv); - nbt_tid = smb_server_listener_tid(&sv->sv_nbt_daemon); - tcp_tid = smb_server_listener_tid(&sv->sv_tcp_daemon); - cv_broadcast(&sv->sp_info.sp_cv); - - sv->sv_state = SMB_SERVER_STATE_DELETING; mutex_exit(&sv->sv_mutex); - - if (nbt_tid != 0) - thread_join(nbt_tid); - if (tcp_tid != 0) - thread_join(tcp_tid); - - smb_server_listen_fini(&sv->sv_nbt_daemon); - smb_server_listen_fini(&sv->sv_tcp_daemon); + smb_server_shutdown(sv); mutex_enter(&sv->sv_mutex); + cv_broadcast(&sv->sp_info.sp_cv); + sv->sv_state = SMB_SERVER_STATE_DELETING; + break; + case SMB_SERVER_STATE_STOPPING: + sv->sv_state = SMB_SERVER_STATE_DELETING; break; case SMB_SERVER_STATE_CONFIGURED: case SMB_SERVER_STATE_CREATED: @@ -499,7 +484,8 @@ smb_llist_remove(&smb_servers, sv); smb_llist_exit(&smb_servers); - smb_server_shutdown(sv); + smb_server_listener_destroy(&sv->sv_nbt_daemon); + smb_server_listener_destroy(&sv->sv_tcp_daemon); rw_destroy(&sv->sv_cfg_lock); smb_opipe_door_fini(); smb_kdoor_fini(); @@ -577,6 +563,7 @@ smb_server_start(smb_ioc_start_t *ioc) { int rc = 0; + int family; smb_server_t *sv; rc = smb_server_lookup(&sv); @@ -588,14 +575,19 @@ case SMB_SERVER_STATE_CONFIGURED: smb_codepage_init(); - sv->sv_thread_pool = taskq_create("smb_workers", + sv->sv_worker_pool = taskq_create("smb_workers", sv->sv_cfg.skc_maxworkers, SMB_WORKER_PRIORITY, sv->sv_cfg.skc_maxworkers, INT_MAX, TASKQ_DYNAMIC|TASKQ_PREPOPULATE); + sv->sv_receiver_pool = taskq_create("smb_receivers", + sv->sv_cfg.skc_maxconnections, SMB_WORKER_PRIORITY, + sv->sv_cfg.skc_maxconnections, INT_MAX, + TASKQ_DYNAMIC); + sv->sv_session = smb_session_create(NULL, 0, sv, 0); - if (sv->sv_thread_pool == NULL || sv->sv_session == NULL) { + if (sv->sv_worker_pool == NULL || sv->sv_session == NULL) { rc = ENOMEM; break; } @@ -616,11 +608,25 @@ } if (rc = smb_thread_start(&sv->si_thread_timers)) break; + + family = AF_INET; + smb_server_listener_init(sv, &sv->sv_nbt_daemon, + "smb_nbt_listener", IPPORT_NETBIOS_SSN, family); + if (sv->sv_cfg.skc_ipv6_enable) + family = AF_INET6; + smb_server_listener_init(sv, &sv->sv_tcp_daemon, + "smb_tcp_listener", IPPORT_SMB, family); + rc = smb_server_listener_start(&sv->sv_nbt_daemon); + if (rc != 0) + break; + rc = smb_server_listener_start(&sv->sv_tcp_daemon); + if (rc != 0) + break; + sv->sv_state = SMB_SERVER_STATE_RUNNING; sv->sv_start_time = gethrtime(); mutex_exit(&sv->sv_mutex); smb_server_release(sv); - smb_export_start(); return (0); default: @@ -630,8 +636,8 @@ return (ENOTTY); } + mutex_exit(&sv->sv_mutex); smb_server_shutdown(sv); - mutex_exit(&sv->sv_mutex); smb_server_release(sv); return (rc); } @@ -652,7 +658,9 @@ switch (sv->sv_state) { case SMB_SERVER_STATE_RUNNING: sv->sv_state = SMB_SERVER_STATE_STOPPING; - smb_server_signal_listeners(sv); + mutex_exit(&sv->sv_mutex); + smb_server_shutdown(sv); + mutex_enter(&sv->sv_mutex); cv_broadcast(&sv->sp_info.sp_cv); break; default: @@ -722,148 +730,6 @@ } /* - * SMB-over-NetBIOS (port 139) - * - * Traditional SMB service over NetBIOS, which requires that a NetBIOS - * session be established. - */ -int -smb_server_nbt_listen(smb_ioc_listen_t *ioc) -{ - smb_server_t *sv; - int rc; - - rc = smb_server_lookup(&sv); - if (rc) - return (rc); - - mutex_enter(&sv->sv_mutex); - switch (sv->sv_state) { - case SMB_SERVER_STATE_RUNNING: - if ((sv->sv_nbt_daemon.ld_kth != NULL) && - (sv->sv_nbt_daemon.ld_kth != curthread)) { - mutex_exit(&sv->sv_mutex); - smb_server_release(sv); - return (EACCES); - } else { - sv->sv_nbt_daemon.ld_kth = curthread; - sv->sv_nbt_daemon.ld_ktdid = curthread->t_did; - } - break; - case SMB_SERVER_STATE_STOPPING: - mutex_exit(&sv->sv_mutex); - smb_server_release(sv); - return (ECANCELED); - default: - SMB_SERVER_STATE_VALID(sv->sv_state); - mutex_exit(&sv->sv_mutex); - smb_server_release(sv); - return (EFAULT); - } - mutex_exit(&sv->sv_mutex); - - /* - * netbios must be ipv4 - */ - rc = smb_server_listen(sv, &sv->sv_nbt_daemon, IPPORT_NETBIOS_SSN, - AF_INET, ioc->error); - - mutex_enter(&sv->sv_mutex); - sv->sv_nbt_daemon.ld_kth = NULL; - mutex_exit(&sv->sv_mutex); - - smb_server_release(sv); - return (rc); -} - -/* - * SMB-over-TCP (port 445) - */ -int -smb_server_tcp_listen(smb_ioc_listen_t *ioc) -{ - smb_server_t *sv; - int rc; - - rc = smb_server_lookup(&sv); - if (rc) - return (rc); - - mutex_enter(&sv->sv_mutex); - switch (sv->sv_state) { - case SMB_SERVER_STATE_RUNNING: - if ((sv->sv_tcp_daemon.ld_kth != NULL) && - (sv->sv_tcp_daemon.ld_kth != curthread)) { - mutex_exit(&sv->sv_mutex); - smb_server_release(sv); - return (EACCES); - } else { - sv->sv_tcp_daemon.ld_kth = curthread; - sv->sv_tcp_daemon.ld_ktdid = curthread->t_did; - } - break; - case SMB_SERVER_STATE_STOPPING: - mutex_exit(&sv->sv_mutex); - smb_server_release(sv); - return (ECANCELED); - default: - SMB_SERVER_STATE_VALID(sv->sv_state); - mutex_exit(&sv->sv_mutex); - smb_server_release(sv); - return (EFAULT); - } - mutex_exit(&sv->sv_mutex); - - if (sv->sv_cfg.skc_ipv6_enable) - rc = smb_server_listen(sv, &sv->sv_tcp_daemon, - IPPORT_SMB, AF_INET6, ioc->error); - else - rc = smb_server_listen(sv, &sv->sv_tcp_daemon, - IPPORT_SMB, AF_INET, ioc->error); - - mutex_enter(&sv->sv_mutex); - sv->sv_tcp_daemon.ld_kth = NULL; - mutex_exit(&sv->sv_mutex); - - smb_server_release(sv); - return (rc); -} - -/* - * smb_server_nbt_receive - */ -int -smb_server_nbt_receive(void) -{ - int rc; - smb_server_t *sv; - - if ((rc = smb_server_lookup(&sv)) == 0) { - rc = smb_session_daemon(&sv->sv_nbt_daemon.ld_session_list); - smb_server_release(sv); - } - - return (rc); -} - -/* - * smb_server_tcp_receive - */ -int -smb_server_tcp_receive(void) -{ - int rc; - smb_server_t *sv; - - if ((rc = smb_server_lookup(&sv)) == 0) { - rc = smb_session_daemon(&sv->sv_tcp_daemon.ld_session_list); - smb_server_release(sv); - } - - return (rc); -} - -/* * smb_server_spooldoc * * Waits for print file close broadcast. @@ -947,10 +813,9 @@ int smb_server_enum(smb_ioc_svcenum_t *ioc) { - smb_svcenum_t *svcenum = &ioc->svcenum; - smb_server_t *sv; - smb_session_list_t *se; - int rc; + smb_svcenum_t *svcenum = &ioc->svcenum; + smb_server_t *sv; + int rc; switch (svcenum->se_type) { case SMB_SVCENUM_TYPE_USER: @@ -968,11 +833,8 @@ svcenum->se_bused = 0; svcenum->se_nitems = 0; - se = &sv->sv_nbt_daemon.ld_session_list; - smb_server_enum_private(se, svcenum); - - se = &sv->sv_tcp_daemon.ld_session_list; - smb_server_enum_private(se, svcenum); + smb_server_enum_private(&sv->sv_nbt_daemon.ld_session_list, svcenum); + smb_server_enum_private(&sv->sv_tcp_daemon.ld_session_list, svcenum); smb_server_release(sv); return (0); @@ -984,20 +846,20 @@ int smb_server_session_close(smb_ioc_session_t *ioc) { - smb_session_list_t *se; - smb_server_t *sv; - int nbt_cnt; - int tcp_cnt; - int rc; + smb_llist_t *ll; + smb_server_t *sv; + int nbt_cnt; + int tcp_cnt; + int rc; if ((rc = smb_server_lookup(&sv)) != 0) return (rc); - se = &sv->sv_nbt_daemon.ld_session_list; - nbt_cnt = smb_server_sesion_disconnect(se, ioc->client, ioc->username); + ll = &sv->sv_nbt_daemon.ld_session_list; + nbt_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username); - se = &sv->sv_tcp_daemon.ld_session_list; - tcp_cnt = smb_server_sesion_disconnect(se, ioc->client, ioc->username); + ll = &sv->sv_tcp_daemon.ld_session_list; + tcp_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username); smb_server_release(sv); @@ -1012,20 +874,20 @@ int smb_server_file_close(smb_ioc_fileid_t *ioc) { - uint32_t uniqid = ioc->uniqid; - smb_session_list_t *se; - smb_server_t *sv; - int rc; + uint32_t uniqid = ioc->uniqid; + smb_llist_t *ll; + smb_server_t *sv; + int rc; if ((rc = smb_server_lookup(&sv)) != 0) return (rc); - se = &sv->sv_nbt_daemon.ld_session_list; - rc = smb_server_fclose(se, uniqid); + ll = &sv->sv_nbt_daemon.ld_session_list; + rc = smb_server_fclose(ll, uniqid); if (rc == ENOENT) { - se = &sv->sv_tcp_daemon.ld_session_list; - rc = smb_server_fclose(se, uniqid); + ll = &sv->sv_tcp_daemon.ld_session_list; + rc = smb_server_fclose(ll, uniqid); } smb_server_release(sv); @@ -1045,12 +907,8 @@ if (smb_server_lookup(&sv)) return (0); - rw_enter(&sv->sv_nbt_daemon.ld_session_list.se_lock, RW_READER); - counter = sv->sv_nbt_daemon.ld_session_list.se_act.count; - rw_exit(&sv->sv_nbt_daemon.ld_session_list.se_lock); - rw_enter(&sv->sv_tcp_daemon.ld_session_list.se_lock, RW_READER); - counter += sv->sv_tcp_daemon.ld_session_list.se_act.count; - rw_exit(&sv->sv_tcp_daemon.ld_session_list.se_lock); + counter = smb_llist_get_count(&sv->sv_nbt_daemon.ld_session_list); + counter += smb_llist_get_count(&sv->sv_tcp_daemon.ld_session_list); smb_server_release(sv); @@ -1155,9 +1013,9 @@ int smb_server_unshare(const char *sharename) { - smb_server_t *sv; - smb_session_list_t *slist; - int rc; + smb_server_t *sv; + smb_llist_t *ll; + int rc; if ((rc = smb_server_lookup(&sv))) return (rc); @@ -1174,11 +1032,11 @@ } mutex_exit(&sv->sv_mutex); - slist = &sv->sv_nbt_daemon.ld_session_list; - smb_server_disconnect_share(slist, sharename); + ll = &sv->sv_nbt_daemon.ld_session_list; + smb_server_disconnect_share(ll, sharename); - slist = &sv->sv_tcp_daemon.ld_session_list; - smb_server_disconnect_share(slist, sharename); + ll = &sv->sv_tcp_daemon.ld_session_list; + smb_server_disconnect_share(ll, sharename); smb_server_release(sv); return (0); @@ -1189,15 +1047,15 @@ * Typically called when a share has been removed. */ static void -smb_server_disconnect_share(smb_session_list_t *slist, const char *sharename) +smb_server_disconnect_share(smb_llist_t *ll, const char *sharename) { - smb_session_t *session; + smb_session_t *session; - rw_enter(&slist->se_lock, RW_READER); + smb_llist_enter(ll, RW_READER); - session = list_head(&slist->se_act.lst); + session = smb_llist_head(ll); while (session) { - ASSERT(session->s_magic == SMB_SESSION_MAGIC); + SMB_SESSION_VALID(session); smb_rwx_rwenter(&session->s_lock, RW_READER); switch (session->s_state) { case SMB_SESSION_STATE_NEGOTIATED: @@ -1209,10 +1067,10 @@ break; } smb_rwx_rwexit(&session->s_lock); - session = list_next(&slist->se_act.lst, session); + session = smb_llist_next(ll, session); } - rw_exit(&slist->se_lock); + smb_llist_exit(ll); } /* @@ -1522,7 +1380,7 @@ } /* - * The mutex of the server must have been entered before calling this function. + * smb_server_shutdown */ static void smb_server_shutdown(smb_server_t *sv) @@ -1537,110 +1395,185 @@ smb_export_stop(); smb_server_fsop_stop(sv); - if (sv->sv_session) { + smb_server_listener_stop(&sv->sv_nbt_daemon); + smb_server_listener_stop(&sv->sv_tcp_daemon); + + if (sv->sv_session != NULL) { smb_session_delete(sv->sv_session); sv->sv_session = NULL; } - if (sv->sv_thread_pool) { - taskq_destroy(sv->sv_thread_pool); - sv->sv_thread_pool = NULL; + if (sv->sv_receiver_pool != NULL) { + taskq_destroy(sv->sv_receiver_pool); + sv->sv_receiver_pool = NULL; + } + + if (sv->sv_worker_pool != NULL) { + taskq_destroy(sv->sv_worker_pool); + sv->sv_worker_pool = NULL; } } -static int -smb_server_listen( +/* + * smb_server_listener_init + * + * Initializes listener contexts. + */ +static void +smb_server_listener_init( smb_server_t *sv, smb_listener_daemon_t *ld, + char *name, in_port_t port, - int family, - int pthread_create_error) + int family) { - int rc = 0; - ksocket_t s_so; - uint32_t on; - uint32_t off; - uint32_t txbuf_size; - smb_session_t *session; + ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC); + + bzero(ld, sizeof (*ld)); + + ld->ld_sv = sv; + ld->ld_family = family; + ld->ld_port = port; - if (pthread_create_error) { - /* - * Delete the last session created. The user space thread - * creation failed. - */ - smb_session_list_delete_tail(&ld->ld_session_list); + if (family == AF_INET) { + ld->ld_sin.sin_family = (uint32_t)family; + ld->ld_sin.sin_port = htons(port); + ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY); + } else { + ld->ld_sin6.sin6_family = (uint32_t)family; + ld->ld_sin6.sin6_port = htons(port); + (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0, + sizeof (ld->ld_sin6.sin6_addr.s6_addr)); } + smb_llist_constructor(&ld->ld_session_list, sizeof (smb_session_t), + offsetof(smb_session_t, s_lnd)); + smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld); + ld->ld_magic = SMB_LISTENER_MAGIC; +} + +/* + * smb_server_listener_destroy + * + * Destroyes listener contexts. + */ +static void +smb_server_listener_destroy(smb_listener_daemon_t *ld) +{ + SMB_LISTENER_VALID(ld); + ASSERT(ld->ld_so == NULL); + smb_thread_destroy(&ld->ld_thread); + smb_llist_destructor(&ld->ld_session_list); + ld->ld_magic = 0; +} + +/* + * smb_server_listener_start + * + * Starts the listener associated with the context passed in. + * + * Return: 0 Success + * not 0 Failure + */ +static int +smb_server_listener_start(smb_listener_daemon_t *ld) +{ + int rc; + uint32_t on; + uint32_t off; + + SMB_LISTENER_VALID(ld); + + if (ld->ld_so != NULL) + return (EINVAL); + + ld->ld_so = smb_socreate(ld->ld_family, SOCK_STREAM, 0); if (ld->ld_so == NULL) { - /* First time listener */ - if (family == AF_INET) { - ld->ld_sin.sin_family = (uint32_t)family; - ld->ld_sin.sin_port = htons(port); - ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY); - } else { - ld->ld_sin6.sin6_family = (uint32_t)family; - ld->ld_sin6.sin6_port = htons(port); - (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0, - sizeof (ld->ld_sin6.sin6_addr.s6_addr)); - } + cmn_err(CE_WARN, "port %d: socket create failed", ld->ld_port); + return (ENOMEM); + } - ld->ld_so = smb_socreate(family, SOCK_STREAM, 0); - if (ld->ld_so == NULL) { - cmn_err(CE_WARN, "port %d: socket create failed", port); - return (ENOMEM); - } + off = 0; + (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, + SO_MAC_EXEMPT, &off, sizeof (off), CRED()); - off = 0; - (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, - SO_MAC_EXEMPT, &off, sizeof (off), CRED()); + on = 1; + (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, + SO_REUSEADDR, &on, sizeof (on), CRED()); - on = 1; - (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, - SO_REUSEADDR, &on, sizeof (on), CRED()); + if (ld->ld_family == AF_INET) { + rc = ksocket_bind(ld->ld_so, + (struct sockaddr *)&ld->ld_sin, + sizeof (ld->ld_sin), CRED()); + } else { + rc = ksocket_bind(ld->ld_so, + (struct sockaddr *)&ld->ld_sin6, + sizeof (ld->ld_sin6), CRED()); + } + + if (rc != 0) { + cmn_err(CE_WARN, "port %d: bind failed", ld->ld_port); + return (rc); + } - if (family == AF_INET) { - rc = ksocket_bind(ld->ld_so, - (struct sockaddr *)&ld->ld_sin, - sizeof (ld->ld_sin), CRED()); - } else { - rc = ksocket_bind(ld->ld_so, - (struct sockaddr *)&ld->ld_sin6, - sizeof (ld->ld_sin6), CRED()); - } + rc = ksocket_listen(ld->ld_so, 20, CRED()); + if (rc < 0) { + cmn_err(CE_WARN, "port %d: listen failed", ld->ld_port); + return (rc); + } + + ksocket_hold(ld->ld_so); + rc = smb_thread_start(&ld->ld_thread); + if (rc != 0) { + ksocket_rele(ld->ld_so); + cmn_err(CE_WARN, "port %d: listener failed to start", + ld->ld_port); + return (rc); + } + return (0); +} - if (rc != 0) { - cmn_err(CE_WARN, "port %d: bind failed (%d)", port, rc); - smb_server_listen_fini(ld); - return (rc); - } +/* + * smb_server_listener_stop + * + * Stops the listener associated with the context passed in. + */ +static void +smb_server_listener_stop(smb_listener_daemon_t *ld) +{ + SMB_LISTENER_VALID(ld); + + if (ld->ld_so != NULL) { + smb_soshutdown(ld->ld_so); + smb_sodestroy(ld->ld_so); + smb_thread_stop(&ld->ld_thread); + ld->ld_so = NULL; + } +} - rc = ksocket_listen(ld->ld_so, 20, CRED()); - if (rc < 0) { - cmn_err(CE_WARN, "port %d: listen failed", port); - smb_server_listen_fini(ld); - return (rc); - } - } +/* + * smb_server_listener + * + * Entry point of the listeners. + */ +static void +smb_server_listener(smb_thread_t *thread, void *arg) +{ + _NOTE(ARGUNUSED(thread)) + smb_listener_daemon_t *ld; + smb_session_t *session; + ksocket_t s_so; + int on; + int txbuf_size; + + ld = (smb_listener_daemon_t *)arg; + + SMB_LISTENER_VALID(ld); DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so); - for (;;) { - if (smb_server_is_stopping()) { - rc = ECANCELED; - break; - } - - rc = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED()); - if (rc != 0) - break; - - if (smb_server_is_stopping()) { - smb_soshutdown(s_so); - smb_sodestroy(s_so); - rc = ECANCELED; - break; - } - + while (ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED()) + == 0) { DTRACE_PROBE1(so__accept, struct sonode *, s_so); on = 1; @@ -1658,45 +1591,35 @@ /* * Create a session for this connection. */ - session = smb_session_create(s_so, port, sv, family); - if (session) { - smb_session_list_append(&ld->ld_session_list, session); - rc = 0; - break; - } else { - smb_soshutdown(s_so); - smb_sodestroy(s_so); - } + smb_server_create_session(ld, s_so); } - - if (rc != 0) - smb_server_listen_fini(ld); - - return (rc); + /* Disconnect all the sessions this listener created. */ + smb_llist_enter(&ld->ld_session_list, RW_READER); + session = smb_llist_head(&ld->ld_session_list); + while (session != NULL) { + smb_session_disconnect(session); + session = smb_llist_next(&ld->ld_session_list, session); + } + smb_llist_exit(&ld->ld_session_list); + ksocket_rele(ld->ld_so); } +/* + * smb_server_receiver + * + * Entry point of the receiver threads. + */ static void -smb_server_listen_fini(smb_listener_daemon_t *ld) +smb_server_receiver(void *arg) { - if (ld->ld_so != NULL) { - smb_session_list_signal(&ld->ld_session_list); - smb_soshutdown(ld->ld_so); - smb_sodestroy(ld->ld_so); - ld->ld_so = NULL; - } -} + smb_listener_daemon_t *ld; + smb_session_t *session; -static kt_did_t -smb_server_listener_tid(smb_listener_daemon_t *ld) -{ - kt_did_t tid = 0; - - if (ld->ld_ktdid != 0) { - tid = ld->ld_ktdid; - ld->ld_ktdid = 0; - } - - return (tid); + ld = ((smb_receiver_arg_t *)arg)->ra_listener; + session = ((smb_receiver_arg_t *)arg)->ra_session; + smb_mem_free(arg); + smb_session_receiver(session); + smb_server_destroy_session(ld, session); } /* @@ -1758,18 +1681,18 @@ * Enumerate the users associated with a session list. */ static void -smb_server_enum_private(smb_session_list_t *se, smb_svcenum_t *svcenum) +smb_server_enum_private(smb_llist_t *ll, smb_svcenum_t *svcenum) { smb_session_t *sn; smb_llist_t *ulist; smb_user_t *user; int rc = 0; - rw_enter(&se->se_lock, RW_READER); - sn = list_head(&se->se_act.lst); + smb_llist_enter(ll, RW_READER); + sn = smb_llist_head(ll); while (sn != NULL) { - ASSERT(sn->s_magic == SMB_SESSION_MAGIC); + SMB_SESSION_VALID(sn); ulist = &sn->s_user_list; smb_llist_enter(ulist, RW_READER); user = smb_llist_head(ulist); @@ -1788,10 +1711,10 @@ if (rc != 0) break; - sn = list_next(&se->se_act.lst, sn); + sn = smb_llist_next(ll, sn); } - rw_exit(&se->se_lock); + smb_llist_exit(ll); } /* @@ -1799,7 +1722,7 @@ * Empty strings are treated as wildcards. */ static int -smb_server_sesion_disconnect(smb_session_list_t *se, +smb_server_session_disconnect(smb_llist_t *ll, const char *client, const char *name) { smb_session_t *sn; @@ -1808,14 +1731,14 @@ boolean_t match; int count = 0; - rw_enter(&se->se_lock, RW_READER); - sn = list_head(&se->se_act.lst); + smb_llist_enter(ll, RW_READER); + sn = smb_llist_head(ll); while (sn != NULL) { - ASSERT(sn->s_magic == SMB_SESSION_MAGIC); + SMB_SESSION_VALID(sn); if ((*client != '\0') && (!smb_session_isclient(sn, client))) { - sn = list_next(&se->se_act.lst, sn); + sn = smb_llist_next(ll, sn); continue; } @@ -1846,10 +1769,10 @@ } smb_llist_exit(ulist); - sn = list_next(&se->se_act.lst, sn); + sn = smb_llist_next(ll, sn); } - rw_exit(&se->se_lock); + smb_llist_exit(ll); return (count); } @@ -1857,18 +1780,18 @@ * Close a file by its unique id. */ static int -smb_server_fclose(smb_session_list_t *se, uint32_t uniqid) +smb_server_fclose(smb_llist_t *ll, uint32_t uniqid) { smb_session_t *sn; smb_llist_t *ulist; smb_user_t *user; int rc = ENOENT; - rw_enter(&se->se_lock, RW_READER); - sn = list_head(&se->se_act.lst); + smb_llist_enter(ll, RW_READER); + sn = smb_llist_head(ll); while ((sn != NULL) && (rc == ENOENT)) { - ASSERT(sn->s_magic == SMB_SESSION_MAGIC); + SMB_SESSION_VALID(sn); ulist = &sn->s_user_list; smb_llist_enter(ulist, RW_READER); user = smb_llist_head(ulist); @@ -1883,10 +1806,10 @@ } smb_llist_exit(ulist); - sn = list_next(&se->se_act.lst, sn); + sn = smb_llist_next(ll, sn); } - rw_exit(&se->se_lock); + smb_llist_exit(ll); return (rc); } @@ -1945,26 +1868,6 @@ } } -static void -smb_server_signal_listeners(smb_server_t *sv) -{ - SMB_SERVER_VALID(sv); - ASSERT(sv->sv_state == SMB_SERVER_STATE_STOPPING); - ASSERT(MUTEX_HELD(&sv->sv_mutex)); - - smb_event_cancel(sv, 0); - - if (sv->sv_nbt_daemon.ld_kth != NULL) { - tsignal(sv->sv_nbt_daemon.ld_kth, SIGINT); - sv->sv_nbt_daemon.ld_kth = NULL; - } - - if (sv->sv_tcp_daemon.ld_kth != NULL) { - tsignal(sv->sv_tcp_daemon.ld_kth, SIGINT); - sv->sv_tcp_daemon.ld_kth = NULL; - } -} - smb_event_t * smb_event_create(int timeout) { @@ -2323,3 +2226,48 @@ smb_server_release(sv); return (rc); } + +/* + * smb_server_create_session + */ +static void +smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so) +{ + smb_session_t *session; + smb_receiver_arg_t *rarg; + + session = smb_session_create(s_so, ld->ld_port, ld->ld_sv, + ld->ld_family); + + if (session != NULL) { + smb_llist_enter(&ld->ld_session_list, RW_WRITER); + smb_llist_insert_tail(&ld->ld_session_list, session); + smb_llist_exit(&ld->ld_session_list); + + rarg = (smb_receiver_arg_t *)smb_mem_alloc( + sizeof (smb_receiver_arg_t)); + rarg->ra_listener = ld; + rarg->ra_session = session; + + if (taskq_dispatch(ld->ld_sv->sv_receiver_pool, + smb_server_receiver, rarg, TQ_NOQUEUE) != 0) + return; + + smb_mem_free(rarg); + smb_session_disconnect(session); + smb_server_destroy_session(ld, session); + } else { + smb_soshutdown(s_so); + smb_sodestroy(s_so); + } + cmn_err(CE_WARN, "SMB Session: creation failed"); +} + +static void +smb_server_destroy_session(smb_listener_daemon_t *ld, smb_session_t *session) +{ + smb_llist_enter(&ld->ld_session_list, RW_WRITER); + smb_llist_remove(&ld->ld_session_list, session); + smb_llist_exit(&ld->ld_session_list); + smb_session_delete(session); +} diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/smbsrv/smb_session.c --- a/usr/src/uts/common/fs/smbsrv/smb_session.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/smbsrv/smb_session.c Thu Sep 09 11:46:43 2010 -0400 @@ -46,30 +46,28 @@ void dump_smb_inaddr(smb_inaddr_t *ipaddr); void -smb_session_timers(smb_session_list_t *se) +smb_session_timers(smb_llist_t *ll) { smb_session_t *session; - rw_enter(&se->se_lock, RW_READER); - session = list_head(&se->se_act.lst); - while (session) { + smb_llist_enter(ll, RW_READER); + session = smb_llist_head(ll); + while (session != NULL) { /* * Walk through the table and decrement each keep_alive * timer that has not timed out yet. (keepalive > 0) */ - ASSERT(session->s_magic == SMB_SESSION_MAGIC); + SMB_SESSION_VALID(session); if (session->keep_alive && (session->keep_alive != (uint32_t)-1)) session->keep_alive--; - session = list_next(&se->se_act.lst, session); + session = smb_llist_next(ll, session); } - rw_exit(&se->se_lock); + smb_llist_exit(ll); } void -smb_session_correct_keep_alive_values( - smb_session_list_t *se, - uint32_t new_keep_alive) +smb_session_correct_keep_alive_values(smb_llist_t *ll, uint32_t new_keep_alive) { smb_session_t *sn; @@ -84,21 +82,15 @@ * Walk through the table and set each session to the new keep_alive * value if they have not already timed out. Block clock interrupts. */ - rw_enter(&se->se_lock, RW_READER); - sn = list_head(&se->se_rdy.lst); - while (sn) { - ASSERT(sn->s_magic == SMB_SESSION_MAGIC); - sn->keep_alive = new_keep_alive; - sn = list_next(&se->se_rdy.lst, sn); + smb_llist_enter(ll, RW_READER); + sn = smb_llist_head(ll); + while (sn != NULL) { + SMB_SESSION_VALID(sn); + if (sn->keep_alive != 0) + sn->keep_alive = new_keep_alive; + sn = smb_llist_next(ll, sn); } - sn = list_head(&se->se_act.lst); - while (sn) { - ASSERT(sn->s_magic == SMB_SESSION_MAGIC); - if (sn->keep_alive) - sn->keep_alive = new_keep_alive; - sn = list_next(&se->se_act.lst, sn); - } - rw_exit(&se->se_lock); + smb_llist_exit(ll); } /* @@ -121,25 +113,25 @@ * there is no NetBIOS name. See also Knowledge Base article Q301673. */ void -smb_session_reconnection_check(smb_session_list_t *se, smb_session_t *sess) +smb_session_reconnection_check(smb_llist_t *ll, smb_session_t *sess) { smb_session_t *sn; - rw_enter(&se->se_lock, RW_READER); - sn = list_head(&se->se_act.lst); - while (sn) { - ASSERT(sn->s_magic == SMB_SESSION_MAGIC); + smb_llist_enter(ll, RW_READER); + sn = smb_llist_head(ll); + while (sn != NULL) { + SMB_SESSION_VALID(sn); if ((sn != sess) && smb_inet_equal(&sn->ipaddr, &sess->ipaddr) && smb_inet_equal(&sn->local_ipaddr, &sess->local_ipaddr) && (strcasecmp(sn->workstation, sess->workstation) == 0) && (sn->opentime <= sess->opentime) && (sn->s_kid < sess->s_kid)) { - tsignal(sn->s_thread, SIGUSR1); + smb_session_disconnect(sn); } - sn = list_next(&se->se_act.lst, sn); + sn = smb_llist_next(ll, sn); } - rw_exit(&se->se_lock); + smb_llist_exit(ll); } /* @@ -465,34 +457,26 @@ } /* - * This is the entry point for processing SMB messages over NetBIOS or - * SMB-over-TCP. + * smb_session_receiver * - * NetBIOS connections require a session request to establish a session - * on which to send session messages. - * - * Session requests are not valid on SMB-over-TCP. We don't need to do - * anything here as session requests will be treated as an error when - * handling session messages. + * Receives request from the network and dispatches them to a worker. */ -int -smb_session_daemon(smb_session_list_t *se) +void +smb_session_receiver(smb_session_t *session) { - int rc = 0; - smb_session_t *session; + int rc; - session = smb_session_list_activate_head(se); - if (session == NULL) - return (EINVAL); + SMB_SESSION_VALID(session); + + session->s_thread = curthread; if (session->s_local_port == IPPORT_NETBIOS_SSN) { rc = smb_session_request(session); - if (rc) { + if (rc != 0) { smb_rwx_rwenter(&session->s_lock, RW_WRITER); session->s_state = SMB_SESSION_STATE_DISCONNECTED; smb_rwx_rwexit(&session->s_lock); - smb_session_list_terminate(se, session); - return (rc); + return; } } @@ -500,7 +484,7 @@ session->s_state = SMB_SESSION_STATE_ESTABLISHED; smb_rwx_rwexit(&session->s_lock); - rc = smb_session_message(session); + (void) smb_session_message(session); smb_rwx_rwenter(&session->s_lock, RW_WRITER); session->s_state = SMB_SESSION_STATE_DISCONNECTED; @@ -511,15 +495,40 @@ DTRACE_PROBE2(session__drop, struct session *, session, int, rc); smb_session_cancel(session); - /* * At this point everything related to the session should have been * cleaned up and we expect that nothing will attempt to use the * socket. */ - smb_session_list_terminate(se, session); +} + +/* + * smb_session_disconnect + * + * Disconnects the session passed in. + */ +void +smb_session_disconnect(smb_session_t *session) +{ + SMB_SESSION_VALID(session); - return (rc); + smb_rwx_rwenter(&session->s_lock, RW_WRITER); + switch (session->s_state) { + case SMB_SESSION_STATE_INITIALIZED: + case SMB_SESSION_STATE_CONNECTED: + case SMB_SESSION_STATE_ESTABLISHED: + case SMB_SESSION_STATE_NEGOTIATED: + case SMB_SESSION_STATE_OPLOCK_BREAKING: + case SMB_SESSION_STATE_WRITE_RAW_ACTIVE: + case SMB_SESSION_STATE_READ_RAW_ACTIVE: + smb_soshutdown(session->sock); + session->s_state = SMB_SESSION_STATE_DISCONNECTED; + _NOTE(FALLTHRU) + case SMB_SESSION_STATE_DISCONNECTED: + case SMB_SESSION_STATE_TERMINATED: + break; + } + smb_rwx_rwexit(&session->s_lock); } /* @@ -640,7 +649,7 @@ sr->sr_time_submitted = gethrtime(); sr->sr_state = SMB_REQ_STATE_SUBMITTED; smb_srqueue_waitq_enter(session->s_srqueue); - (void) taskq_dispatch(session->s_server->sv_thread_pool, + (void) taskq_dispatch(session->s_server->sv_worker_pool, smb_session_worker, sr, TQ_SLEEP); } } @@ -747,11 +756,6 @@ session->s_magic = 0; - if (session->s_local_port == IPPORT_NETBIOS_SSN) - smb_server_dec_nbt_sess(session->s_server); - else - smb_server_dec_tcp_sess(session->s_server); - smb_rwx_destroy(&session->s_lock); smb_net_txl_destructor(&session->s_txlst); @@ -771,6 +775,13 @@ ASSERT(session->s_dir_cnt == 0); smb_idpool_destructor(&session->s_uid_pool); + if (session->sock != NULL) { + if (session->s_local_port == IPPORT_NETBIOS_SSN) + smb_server_dec_nbt_sess(session->s_server); + else + smb_server_dec_tcp_sess(session->s_server); + smb_sodestroy(session->sock); + } kmem_cache_free(session->s_cache, session); } @@ -868,154 +879,6 @@ smb_srqueue_runq_exit(srq); } -void -smb_session_list_constructor(smb_session_list_t *se) -{ - bzero(se, sizeof (*se)); - rw_init(&se->se_lock, NULL, RW_DEFAULT, NULL); - list_create(&se->se_rdy.lst, sizeof (smb_session_t), - offsetof(smb_session_t, s_lnd)); - list_create(&se->se_act.lst, sizeof (smb_session_t), - offsetof(smb_session_t, s_lnd)); -} - -void -smb_session_list_destructor(smb_session_list_t *se) -{ - list_destroy(&se->se_rdy.lst); - list_destroy(&se->se_act.lst); - rw_destroy(&se->se_lock); -} - -void -smb_session_list_append(smb_session_list_t *se, smb_session_t *session) -{ - ASSERT(session->s_magic == SMB_SESSION_MAGIC); - ASSERT(session->s_state == SMB_SESSION_STATE_INITIALIZED); - - rw_enter(&se->se_lock, RW_WRITER); - list_insert_tail(&se->se_rdy.lst, session); - se->se_rdy.count++; - se->se_wrop++; - rw_exit(&se->se_lock); -} - -void -smb_session_list_delete_tail(smb_session_list_t *se) -{ - smb_session_t *session; - - rw_enter(&se->se_lock, RW_WRITER); - session = list_tail(&se->se_rdy.lst); - if (session) { - ASSERT(session->s_magic == SMB_SESSION_MAGIC); - ASSERT(session->s_state == SMB_SESSION_STATE_INITIALIZED); - list_remove(&se->se_rdy.lst, session); - ASSERT(se->se_rdy.count); - se->se_rdy.count--; - rw_exit(&se->se_lock); - smb_session_delete(session); - return; - } - rw_exit(&se->se_lock); -} - -smb_session_t * -smb_session_list_activate_head(smb_session_list_t *se) -{ - smb_session_t *session; - - rw_enter(&se->se_lock, RW_WRITER); - session = list_head(&se->se_rdy.lst); - if (session) { - ASSERT(session->s_magic == SMB_SESSION_MAGIC); - smb_rwx_rwenter(&session->s_lock, RW_WRITER); - ASSERT(session->s_state == SMB_SESSION_STATE_INITIALIZED); - session->s_thread = curthread; - session->s_ktdid = session->s_thread->t_did; - smb_rwx_rwexit(&session->s_lock); - list_remove(&se->se_rdy.lst, session); - se->se_rdy.count--; - list_insert_tail(&se->se_act.lst, session); - se->se_act.count++; - se->se_wrop++; - } - rw_exit(&se->se_lock); - return (session); -} - -void -smb_session_list_terminate(smb_session_list_t *se, smb_session_t *session) -{ - ASSERT(session->s_magic == SMB_SESSION_MAGIC); - - rw_enter(&se->se_lock, RW_WRITER); - - smb_rwx_rwenter(&session->s_lock, RW_WRITER); - ASSERT(session->s_state == SMB_SESSION_STATE_DISCONNECTED); - session->s_state = SMB_SESSION_STATE_TERMINATED; - smb_sodestroy(session->sock); - session->sock = NULL; - smb_rwx_rwexit(&session->s_lock); - - list_remove(&se->se_act.lst, session); - se->se_act.count--; - se->se_wrop++; - - ASSERT(session->s_thread == curthread); - - rw_exit(&se->se_lock); - - smb_session_delete(session); -} - -/* - * smb_session_list_signal - * - * This function signals all the session threads. The intent is to terminate - * them. The sessions still in the SMB_SESSION_STATE_INITIALIZED are delete - * immediately. - * - * This function must only be called by the threads listening and accepting - * connections. They must pass in their respective session list. - */ -void -smb_session_list_signal(smb_session_list_t *se) -{ - smb_session_t *session; - - rw_enter(&se->se_lock, RW_WRITER); - while (session = list_head(&se->se_rdy.lst)) { - - ASSERT(session->s_magic == SMB_SESSION_MAGIC); - - smb_rwx_rwenter(&session->s_lock, RW_WRITER); - ASSERT(session->s_state == SMB_SESSION_STATE_INITIALIZED); - session->s_state = SMB_SESSION_STATE_TERMINATED; - smb_sodestroy(session->sock); - session->sock = NULL; - smb_rwx_rwexit(&session->s_lock); - - list_remove(&se->se_rdy.lst, session); - se->se_rdy.count--; - se->se_wrop++; - - rw_exit(&se->se_lock); - smb_session_delete(session); - rw_enter(&se->se_lock, RW_WRITER); - } - rw_downgrade(&se->se_lock); - - session = list_head(&se->se_act.lst); - while (session) { - - ASSERT(session->s_magic == SMB_SESSION_MAGIC); - tsignal(session->s_thread, SIGUSR1); - session = list_next(&se->se_act.lst, session); - } - rw_exit(&se->se_lock); -} - /* * smb_session_lookup_user */ diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/smbsrv/smb_write_raw.c --- a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/smbsrv/smb_write_raw.c Thu Sep 09 11:46:43 2010 -0400 @@ -428,7 +428,7 @@ smb_rwx_rwexit(&session->s_lock); smb_srqueue_waitq_enter(session->s_srqueue); sr->sr_state = SMB_REQ_STATE_SUBMITTED; - (void) taskq_dispatch(session->s_server->sv_thread_pool, + (void) taskq_dispatch(session->s_server->sv_worker_pool, smb_session_worker, sr, TQ_SLEEP); smb_rwx_rwenter(&session->s_lock, RW_READER); while (session->s_state == SMB_SESSION_STATE_WRITE_RAW_ACTIVE) { diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/vfs.c --- a/usr/src/uts/common/fs/vfs.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/vfs.c Thu Sep 09 11:46:43 2010 -0400 @@ -4718,6 +4718,15 @@ vfsp->vfs_featureset[VFTINDEX(feature)] |= VFTBITS(feature); } +void +vfs_clear_feature(vfs_t *vfsp, vfs_feature_t feature) +{ + /* Note that vfs_featureset[] is found in *vfsp->vfs_implp */ + if (vfsp->vfs_implp == NULL) + return; + vfsp->vfs_featureset[VFTINDEX(feature)] &= VFTBITS(~feature); +} + /* * Query a vfs for a feature. * Returns 1 if feature is present, 0 if not diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/zfs/zfs_vfsops.c --- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c Thu Sep 09 11:46:43 2010 -0400 @@ -1086,13 +1086,22 @@ zfs_set_fuid_feature(zfsvfs_t *zfsvfs) { zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os); - if (zfsvfs->z_use_fuids && zfsvfs->z_vfs) { - vfs_set_feature(zfsvfs->z_vfs, VFSFT_XVATTR); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_REPARSE); + if (zfsvfs->z_vfs) { + if (zfsvfs->z_use_fuids) { + vfs_set_feature(zfsvfs->z_vfs, VFSFT_XVATTR); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_REPARSE); + } else { + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_XVATTR); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_REPARSE); + } } zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os); } @@ -2010,7 +2019,7 @@ int zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname) { - int err, err2; + int err; ASSERT(RRW_WRITE_HELD(&zfsvfs->z_teardown_lock)); ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock)); @@ -2023,19 +2032,34 @@ znode_t *zp; uint64_t sa_obj = 0; - err2 = zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ, + /* + * Make sure version hasn't changed + */ + + err = zfs_get_zplprop(zfsvfs->z_os, ZFS_PROP_VERSION, + &zfsvfs->z_version); + + if (err) + goto bail; + + err = zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1, &sa_obj); - if ((err || err2) && zfsvfs->z_version >= ZPL_VERSION_SA) + if (err && zfsvfs->z_version >= ZPL_VERSION_SA) goto bail; - if ((err = sa_setup(zfsvfs->z_os, sa_obj, zfs_attr_table, ZPL_END, &zfsvfs->z_attr_table)) != 0) goto bail; + if (zfsvfs->z_version >= ZPL_VERSION_SA) + sa_register_update_callback(zfsvfs->z_os, + zfs_sa_upgrade); + VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0); + zfs_set_fuid_feature(zfsvfs); + /* * Attempt to re-establish all the active znodes with * their dbufs. If a zfs_rezget() fails, then we'll let @@ -2048,7 +2072,6 @@ (void) zfs_rezget(zp); } mutex_exit(&zfsvfs->z_znodes_lock); - } bail: @@ -2058,8 +2081,8 @@ if (err) { /* - * Since we couldn't reopen zfsvfs::z_os, force - * unmount this file system. + * Since we couldn't reopen zfsvfs::z_os, or + * setup the sa framework force unmount this file system. */ if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0) (void) dounmount(zfsvfs->z_vfs, MS_FORCE, CRED()); @@ -2219,8 +2242,7 @@ zfsvfs->z_version = newvers; - if (zfsvfs->z_version >= ZPL_VERSION_FUID) - zfs_set_fuid_feature(zfsvfs); + zfs_set_fuid_feature(zfsvfs); return (0); } diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/zfs/zfs_znode.c --- a/usr/src/uts/common/fs/zfs/zfs_znode.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/zfs/zfs_znode.c Thu Sep 09 11:46:43 2010 -0400 @@ -1908,12 +1908,12 @@ static int zfs_grab_sa_handle(objset_t *osp, uint64_t obj, sa_handle_t **hdlp, - dmu_buf_t **db) + dmu_buf_t **db, void *tag) { dmu_object_info_t doi; int error; - if ((error = sa_buf_hold(osp, obj, FTAG, db)) != 0) + if ((error = sa_buf_hold(osp, obj, tag, db)) != 0) return (error); dmu_object_info_from_db(*db, &doi); @@ -1921,13 +1921,13 @@ doi.doi_bonus_type != DMU_OT_ZNODE) || doi.doi_bonus_type == DMU_OT_ZNODE && doi.doi_bonus_size < sizeof (znode_phys_t)) { - sa_buf_rele(*db, FTAG); + sa_buf_rele(*db, tag); return (ENOTSUP); } error = sa_handle_get(osp, obj, NULL, SA_HDL_PRIVATE, hdlp); if (error != 0) { - sa_buf_rele(*db, FTAG); + sa_buf_rele(*db, tag); return (error); } @@ -1935,10 +1935,10 @@ } void -zfs_release_sa_handle(sa_handle_t *hdl, dmu_buf_t *db) +zfs_release_sa_handle(sa_handle_t *hdl, dmu_buf_t *db, void *tag) { sa_handle_destroy(hdl); - sa_buf_rele(db, FTAG); + sa_buf_rele(db, tag); } /* @@ -2015,7 +2015,7 @@ int is_xattrdir; if (prevdb) - zfs_release_sa_handle(prevhdl, prevdb); + zfs_release_sa_handle(prevhdl, prevdb, FTAG); if ((error = zfs_obj_to_pobj(sa_hdl, sa_table, &pobj, &is_xattrdir)) != 0) @@ -2047,7 +2047,7 @@ prevhdl = sa_hdl; prevdb = sa_db; } - error = zfs_grab_sa_handle(osp, obj, &sa_hdl, &sa_db); + error = zfs_grab_sa_handle(osp, obj, &sa_hdl, &sa_db, FTAG); if (error != 0) { sa_hdl = prevhdl; sa_db = prevdb; @@ -2057,7 +2057,7 @@ if (sa_hdl != NULL && sa_hdl != hdl) { ASSERT(sa_db != NULL); - zfs_release_sa_handle(sa_hdl, sa_db); + zfs_release_sa_handle(sa_hdl, sa_db, FTAG); } if (error == 0) @@ -2078,13 +2078,13 @@ if (error != 0) return (error); - error = zfs_grab_sa_handle(osp, obj, &hdl, &db); + error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG); if (error != 0) return (error); error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len); - zfs_release_sa_handle(hdl, db); + zfs_release_sa_handle(hdl, db, FTAG); return (error); } @@ -2104,18 +2104,18 @@ if (error != 0) return (error); - error = zfs_grab_sa_handle(osp, obj, &hdl, &db); + error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG); if (error != 0) return (error); error = zfs_obj_to_stats_impl(hdl, sa_table, sb); if (error != 0) { - zfs_release_sa_handle(hdl, db); + zfs_release_sa_handle(hdl, db, FTAG); return (error); } error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len); - zfs_release_sa_handle(hdl, db); + zfs_release_sa_handle(hdl, db, FTAG); return (error); } diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/fs/zfs/zio.c --- a/usr/src/uts/common/fs/zfs/zio.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/fs/zfs/zio.c Thu Sep 09 11:46:43 2010 -0400 @@ -117,6 +117,7 @@ size_t size = (c + 1) << SPA_MINBLOCKSHIFT; size_t p2 = size; size_t align = 0; + size_t cflags = (size > zio_buf_debug_limit) ? KMC_NODEBUG : 0; while (p2 & (p2 - 1)) p2 &= p2 - 1; @@ -133,13 +134,17 @@ char name[36]; (void) sprintf(name, "zio_buf_%lu", (ulong_t)size); zio_buf_cache[c] = kmem_cache_create(name, size, - align, NULL, NULL, NULL, NULL, NULL, - size > zio_buf_debug_limit ? KMC_NODEBUG : 0); - + align, NULL, NULL, NULL, NULL, NULL, cflags); + + /* + * Since zio_data bufs do not appear in crash dumps, we + * pass KMC_NOTOUCH so that no allocator metadata is + * stored with the buffers. + */ (void) sprintf(name, "zio_data_buf_%lu", (ulong_t)size); zio_data_buf_cache[c] = kmem_cache_create(name, size, align, NULL, NULL, NULL, NULL, data_alloc_arena, - size > zio_buf_debug_limit ? KMC_NODEBUG : 0); + cflags | KMC_NOTOUCH); } } diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_clock.c --- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_clock.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_clock.c Thu Sep 09 11:46:43 2010 -0400 @@ -42,6 +42,7 @@ #endif /* DHCHAP_SUPPORT */ static void emlxs_timer(void *arg); +static void emlxs_timer_check_fw_update(emlxs_hba_t *hba); static void emlxs_timer_check_heartbeat(emlxs_hba_t *hba); static uint32_t emlxs_timer_check_pkts(emlxs_hba_t *hba, uint8_t *flag); static void emlxs_timer_check_nodes(emlxs_port_t *port, uint8_t *flag); @@ -157,6 +158,9 @@ /* Check heartbeat timer */ emlxs_timer_check_heartbeat(hba); + /* Check fw update timer */ + emlxs_timer_check_fw_update(hba); + #ifdef IDLE_TIMER emlxs_pm_idle_timer(hba); #endif /* IDLE_TIMER */ @@ -811,6 +815,32 @@ static void +emlxs_timer_check_fw_update(emlxs_hba_t *hba) +{ + emlxs_port_t *port = &PPORT; + + if (!(hba->fw_flag & FW_UPDATE_NEEDED)) { + hba->fw_timer = 0; + return; + } + + if (hba->timer_tics < hba->fw_timer) { + return; + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_update_msg, + "A manual HBA reset or link reset (using luxadm or fcadm) " + "is required."); + + /* Set timer for 24 hours */ + hba->fw_timer = hba->timer_tics + (60 * 60 * 24); + + return; + +} /* emlxs_timer_check_fw_update() */ + + +static void emlxs_timer_check_discovery(emlxs_port_t *port) { emlxs_hba_t *hba = HBA; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c --- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c Thu Sep 09 11:46:43 2010 -0400 @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Emulex. All rights reserved. + * Copyright 2010 Emulex. All rights reserved. * Use is subject to license terms. */ @@ -38,33 +38,27 @@ PIMAGE_HDR ImageHdr, caddr_t Buffer); static int32_t emlxs_build_parms(caddr_t Buffer, PWAKE_UP_PARMS AbsWakeUpParms, - uint32_t BufferSize, PAIF_HDR AifHeader, - int32_t DwcFile); + uint32_t BufferSize, PAIF_HDR AifHeader); static uint32_t emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, uint32_t Size, emlxs_fw_image_t *fw_image); static void emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t Type, uint32_t RegionId, uint32_t WordCnt, uint32_t BaseAddr); static uint32_t emlxs_start_abs_download(emlxs_hba_t *hba, PAIF_HDR AifHdr, - caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, - uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize, - PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile); + caddr_t Buffer, uint32_t len, + PWAKE_UP_PARMS WakeUpParms); static uint32_t emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, uint32_t offline, emlxs_fw_image_t *fw_image); -static uint32_t emlxs_proc_abs_2mb(emlxs_hba_t *hba, PAIF_HDR AifHdr, +static uint32_t emlxs_proc_abs_2mb(emlxs_hba_t *hba, caddr_t EntireBuffer, uint32_t FileType, - uint32_t BWCflag, uint32_t extType); + uint32_t extType); static void emlxs_format_load_area_cmd(MAILBOXQ *mbq, uint32_t Base, uint32_t DlByteCount, uint32_t Function, uint32_t Complete, uint32_t DataOffset, uint32_t AreaId, uint8_t MbxCmd, uint32_t StepCmd); static uint32_t emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, PAIF_HDR AifHdr, uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms); -static uint32_t emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba, caddr_t Buffer, - uint32_t BufferSize, PAIF_HDR AifHeader, - PWAKE_UP_PARMS AbsWakeUpParms, uint32_t BWCflag, - uint32_t extType, uint32_t *numBootImage); static uint32_t emlxs_update_exp_rom(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms); extern uint32_t emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, @@ -72,7 +66,7 @@ static void emlxs_format_prog_flash(MAILBOXQ *mbq, uint32_t Base, uint32_t DlByteCount, uint32_t Function, uint32_t Complete, uint32_t BdeAddress, - uint32_t BdeSize, PROG_ID *ProgId); + uint32_t BdeSize, PROG_ID *ProgId, uint32_t keep); static void emlxs_format_update_parms(MAILBOXQ *mbq, PWAKE_UP_PARMS WakeUpParms); static void emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq, @@ -95,7 +89,7 @@ PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); static uint32_t emlxs_start_rel_download(emlxs_hba_t *hba, PIMAGE_HDR ImageHdr, caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, - uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize); + uint32_t dwc_flag); static uint32_t emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList); static uint32_t emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr); @@ -104,10 +98,6 @@ static void emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image); -static uint32_t emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize); - -static uint32_t emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer, - uint32_t BufferSize, PAIF_HDR AifHeader); static uint32_t emlxs_type_check(uint32_t type); static uint32_t emlxs_kern_check(emlxs_hba_t *hba, uint32_t version); @@ -142,6 +132,16 @@ static int32_t emlxs_sli4_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, uint32_t offline); +static uint32_t emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer, + emlxs_fw_image_t *fw_image); +static uint32_t emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId); + +static void emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *image); + +static uint32_t emlxs_clean_flash(emlxs_hba_t *hba, + PWAKE_UP_PARMS OldWakeUpParms, + PWAKE_UP_PARMS NewWakeUpParms); + /* ************************************************************************* */ extern int32_t @@ -154,11 +154,6 @@ AIF_HDR AifHdr; uint32_t ImageType; WAKE_UP_PARMS WakeUpParms; - WAKE_UP_PARMS AbsWakeUpParms; - uint32_t MaxRbusSramSize; - uint32_t MaxIbusSramSize; - int32_t AbsChangeParams = 0; - int32_t DwcFile = FALSE; uint32_t rval = 0; emlxs_fw_image_t fw_image; uint32_t i; @@ -209,6 +204,9 @@ goto done; } + /* Verify image */ + emlxs_verify_image(hba, &fw_image); + /* Get image type */ Uptr = (uint32_t *)buffer; ImageType = *Uptr; @@ -239,26 +237,16 @@ /* Pre-pegasus adapters only */ - /* Check for absolute image */ - else if (ImageType == NOP_IMAGE_TYPE) { + /* Initialize headers */ + if (ImageType == NOP_IMAGE_TYPE) { bcopy(buffer, &AifHdr, sizeof (AIF_HDR)); bzero((void *)&ImageHdr, sizeof (IMAGE_HDR)); - - if (AifHdr.ImageBase && (AifHdr.ImageBase == 0x20000)) { - DwcFile = TRUE; - } - - AbsChangeParams = emlxs_build_parms(buffer, - &AbsWakeUpParms, len, &AifHdr, DwcFile); - } else { /* (ImageType != NOP_IMAGE_TYPE) Relative image */ - + } else { /* PRG file */ bzero((void *)&AifHdr, sizeof (AIF_HDR)); bcopy(buffer, &ImageHdr, sizeof (IMAGE_HDR)); } - /* - * Everything checks out, now to just do it - */ + /* Everything checks out, now to just do it */ if (offline) { if (emlxs_offline(hba) != FC_SUCCESS) { @@ -268,7 +256,6 @@ "Unable to take adapter offline."); rval = EMLXS_OFFLINE_FAILED; - goto SLI_DOWNLOAD_EXIT; } @@ -279,11 +266,12 @@ "Unable to restart adapter."); rval = EMLXS_OFFLINE_FAILED; - goto SLI_DOWNLOAD_EXIT; } } + /* Pre-pegasus adapters */ + if (ImageHdr.Id.Type == SBUS_FCODE) { /* Erase Flash */ if (emlxs_erase_fcode_flash(hba)) { @@ -291,7 +279,6 @@ "Unable to erase flash."); rval = EMLXS_IMAGE_FAILED; - goto SLI_DOWNLOAD_EXIT; } @@ -301,62 +288,47 @@ "Unable to write flash."); rval = EMLXS_IMAGE_FAILED; - goto SLI_DOWNLOAD_EXIT; } - } else { /* !SBUS_FCODE */ - - - if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, - "Unable to get parameters."); - - rval = EMLXS_IMAGE_FAILED; - - goto SLI_DOWNLOAD_EXIT; - } - - if (emlxs_get_max_sram(hba, &MaxRbusSramSize, - &MaxIbusSramSize)) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, - "Unable to get RAM size."); + goto SLI_DOWNLOAD_EXIT; + } + + /* Pre-pegasus PCI adapters */ + + if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, + "Unable to get parameters."); + + rval = EMLXS_IMAGE_FAILED; + + goto SLI_DOWNLOAD_EXIT; + } + + if (ImageType == NOP_IMAGE_TYPE) { + if (emlxs_start_abs_download(hba, &AifHdr, + buffer, len, &WakeUpParms)) { + EMLXS_MSGF(EMLXS_CONTEXT, + &emlxs_download_failed_msg, + "Failed to program flash."); rval = EMLXS_IMAGE_FAILED; goto SLI_DOWNLOAD_EXIT; } - if (ImageType == NOP_IMAGE_TYPE) { - if (emlxs_start_abs_download(hba, &AifHdr, buffer, - &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize, - (AbsChangeParams) ? &AbsWakeUpParms : NULL, - DwcFile)) { - EMLXS_MSGF(EMLXS_CONTEXT, - &emlxs_download_failed_msg, - "Failed to program flash."); - - rval = EMLXS_IMAGE_FAILED; - - goto SLI_DOWNLOAD_EXIT; - } - - } else { - - if (emlxs_start_rel_download(hba, &ImageHdr, buffer, - &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize)) { - EMLXS_MSGF(EMLXS_CONTEXT, - &emlxs_download_failed_msg, - "Failed to program flash."); - - rval = EMLXS_IMAGE_FAILED; - - goto SLI_DOWNLOAD_EXIT; - } + } else { /* Relative PRG file */ + if (emlxs_start_rel_download(hba, &ImageHdr, buffer, + &WakeUpParms, 0)) { + EMLXS_MSGF(EMLXS_CONTEXT, + &emlxs_download_failed_msg, + "Failed to program flash."); + + rval = EMLXS_IMAGE_FAILED; + + goto SLI_DOWNLOAD_EXIT; } - - } /* !SBUS_FCODE */ - + } SLI_DOWNLOAD_EXIT: @@ -461,12 +433,13 @@ image_ptr += count; } - /* Set last two words of last payload with */ - /* image size and block crc */ + /* Set last three words of last payload with */ + /* load address, image size and block crc */ if (flashrom->params.opcode == MGMT_FLASHROM_OPCODE_FLASH) { - wptr = (uint32_t *)&payload[(xfer_size - 8)]; - wptr[0] = file->image_size; - wptr[1] = file->block_crc; + wptr = (uint32_t *)&payload[(xfer_size - 12)]; + wptr[0] = file->load_address; + wptr[1] = file->image_size; + wptr[2] = file->block_crc; } /* Send write request */ @@ -1082,6 +1055,7 @@ file->image_offset = entry->offset; file->block_size = entry->pad_size; file->block_crc = entry->checksum; + file->load_address = entry->entry_point; } else { file->image_offset = entry->offset + sizeof (emlxs_sli4_ufi_header_t); @@ -1097,6 +1071,10 @@ file->block_size = (k + 8) - file->image_offset; + /* Read load_address */ + value = *(wptr - 2); + file->load_address = BE_SWAP32(value); + /* Read block_crc */ value = *wptr; file->block_crc = BE_SWAP32(value); @@ -1116,7 +1094,7 @@ } /* Make sure image will fit in block specified */ - if (file->image_size + 8 > file->block_size) { + if (file->image_size + 12 > file->block_size) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, "%s: Image too large for block. image=%x block=%x", file->label, file->image_size, file->block_size); @@ -1134,6 +1112,7 @@ file2->image_size = file->image_size; file2->block_size = file->block_size; file2->block_crc = file->block_crc; + file2->load_address = file->load_address; /* Save FCOE version info */ bptr = (uint8_t *)buffer + file->image_offset + 0x30; @@ -1150,6 +1129,7 @@ file2->image_size = file->image_size; file2->block_size = file->block_size; file2->block_crc = file->block_crc; + file2->load_address = file->load_address; } } @@ -1173,9 +1153,10 @@ } EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, - "%s: type=%x block=%x image=%x offset=%x crc=%x", + "%s: type=%x block=%x image=%x offset=%x crc=%x load=%x", file->label, file->type, file->block_size, - file->image_size, file->image_offset, file->block_crc); + file->image_size, file->image_offset, file->block_crc, + file->load_address); } return (0); @@ -1660,13 +1641,11 @@ emlxs_start_abs_download(emlxs_hba_t *hba, PAIF_HDR AifHdr, caddr_t Buffer, - PWAKE_UP_PARMS WakeUpParms, - uint32_t MaxRbusSramSize, - uint32_t MaxIbusSramSize, PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile) + uint32_t len, + PWAKE_UP_PARMS WakeUpParms) { emlxs_port_t *port = &PPORT; uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; - IMAGE_HDR ImageHdr; uint32_t *Src; uint32_t *Dst; caddr_t DataBuffer = NULL; @@ -1677,8 +1656,10 @@ uint32_t DlToAddr = AifHdr->ImageBase; uint32_t DlCount; uint32_t i; - - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + WAKE_UP_PARMS AbsWakeUpParms; + int32_t AbsChangeParams; + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Performing absolute download..."); if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, @@ -1701,16 +1682,20 @@ mb = (MAILBOX *)mbox; + AbsChangeParams = emlxs_build_parms(Buffer, + &AbsWakeUpParms, len, AifHdr); + Buffer += sizeof (AIF_HDR); - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash..."); - - if (DwcFile) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Erasing flash..."); + + if (AifHdr->ImageBase == 0x20000) { + /* DWC File */ emlxs_format_prog_flash(mbox, 0x20000, 0x50000, ERASE_FLASH, 0, - 0, 0, NULL); + 0, 0, NULL, 0); } else { emlxs_format_prog_flash(mbox, DlToAddr, DlByteCount, - ERASE_FLASH, 0, 0, 0, NULL); + ERASE_FLASH, 0, 0, 0, NULL, 0); } if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { @@ -1723,7 +1708,7 @@ goto EXIT_ABS_DOWNLOAD; } - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Programming flash..."); while (DlByteCount) { @@ -1750,7 +1735,7 @@ sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); emlxs_format_prog_flash(mbox, DlToAddr, DlCount, - PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL); + PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL, 0); if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { @@ -1779,31 +1764,12 @@ } #endif /* FMA_SUPPORT */ - bzero((caddr_t)&ImageHdr, sizeof (IMAGE_HDR)); - ImageHdr.Id.Type = FUNC_FIRMWARE; - - switch (MaxRbusSramSize) { - case REDUCED_RBUS_SRAM_CFG: - ImageHdr.Id.Id = REDUCED_SRAM_CFG_PROG_ID; - break; - case FULL_RBUS_SRAM_CFG: - ImageHdr.Id.Id = FULL_SRAM_CFG_PROG_ID; - break; - default: - ImageHdr.Id.Id = OTHER_SRAM_CFG_PROG_ID; - break; - } - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Updating params..."); - if (AbsWakeUpParms) { + if (AbsChangeParams) { rval = - emlxs_update_wakeup_parms(hba, AbsWakeUpParms, + emlxs_update_wakeup_parms(hba, &AbsWakeUpParms, WakeUpParms); - } else { - rval = - emlxs_update_boot_wakeup_parms(hba, WakeUpParms, - &ImageHdr.Id, 1); } EXIT_ABS_DOWNLOAD: @@ -1827,16 +1793,20 @@ uint32_t DlByteCount, uint32_t Function, uint32_t Complete, - uint32_t BdeAddress, uint32_t BdeSize, PROG_ID *ProgId) + uint32_t BdeAddress, + uint32_t BdeSize, + PROG_ID *ProgId, + uint32_t keep) { MAILBOX *mb = (MAILBOX *)mbq; bzero((void *)mb, MAILBOX_CMD_BSIZE); - if (ProgId) + if (ProgId) { mb->mbxCommand = MBX_DOWN_LOAD; - else + } else { mb->mbxCommand = MBX_LOAD_SM; + } mb->un.varLdSM.load_cmplt = Complete; mb->un.varLdSM.method = DL_FROM_SLIM; @@ -1844,6 +1814,7 @@ mb->un.varLdSM.erase_or_prog = Function; mb->un.varLdSM.dl_to_adr = Base; mb->un.varLdSM.dl_len = DlByteCount; + mb->un.varLdSM.keep = keep; if (BdeSize) { mb->un.varLdSM.un.dl_from_slim_offset = DL_FROM_SLIM_OFFSET; @@ -1911,6 +1882,7 @@ MAILBOX *mb; MAILBOXQ *mbox; uint32_t rval = 0; + PROG_ID old_prog_id; if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_NOSLEEP)) == NULL) { @@ -1928,6 +1900,7 @@ (void) emlxs_update_exp_rom(hba, WakeUpParms); } + old_prog_id = WakeUpParms->u0.boot_bios_id; WakeUpParms->u0.boot_bios_id = *prog_id; emlxs_format_update_parms(mbox, WakeUpParms); @@ -1937,6 +1910,7 @@ "Unable to update boot wakeup parms: Mailbox cmd=%x " "status=%x", mb->mbxCommand, mb->mbxStatus); + WakeUpParms->u0.boot_bios_id = old_prog_id; rval = 1; } @@ -1958,6 +1932,7 @@ uint32_t rval = 0; MAILBOXQ *mbox; MAILBOX *mb; + PROG_ID old_prog_id; if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_NOSLEEP)) == NULL) { @@ -1967,8 +1942,12 @@ return (1); } + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "FF: Updating parms..."); + mb = (MAILBOX *)mbox; + old_prog_id = WakeUpParms->prog_id; WakeUpParms->prog_id = *prog_id; emlxs_format_update_parms(mbox, WakeUpParms); @@ -1978,6 +1957,7 @@ "Unable to update wakeup parameters: Mailbox cmd=%x " "status=%x", mb->mbxCommand, mb->mbxStatus); + WakeUpParms->prog_id = old_prog_id; rval = 1; } @@ -1998,6 +1978,7 @@ uint32_t rval = 0; MAILBOXQ *mbox; MAILBOX *mb; + PROG_ID old_prog_id; if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_NOSLEEP)) == NULL) { @@ -2007,8 +1988,12 @@ return (1); } + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "SLI1: Updating parms..."); + mb = (MAILBOX *)mbox; + old_prog_id = WakeUpParms->sli1_prog_id; WakeUpParms->sli1_prog_id = *prog_id; emlxs_format_update_parms(mbox, WakeUpParms); @@ -2018,6 +2003,7 @@ "Unable to update wakeup parameters. Mailbox cmd=%x " "status=%x", mb->mbxCommand, mb->mbxStatus); + WakeUpParms->sli1_prog_id = old_prog_id; rval = 1; } @@ -2038,6 +2024,7 @@ uint32_t rval = 0; MAILBOXQ *mbox; MAILBOX *mb; + PROG_ID old_prog_id; if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_NOSLEEP)) == NULL) { @@ -2047,8 +2034,12 @@ return (1); } + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "SLI2: Updating parms..."); + mb = (MAILBOX *)mbox; + old_prog_id = WakeUpParms->sli2_prog_id; WakeUpParms->sli2_prog_id = *prog_id; emlxs_format_update_parms(mbox, WakeUpParms); @@ -2058,6 +2049,7 @@ "Unable to update wakeup parameters. Mailbox cmd=%x " "status=%x", mb->mbxCommand, mb->mbxStatus); + WakeUpParms->sli2_prog_id = old_prog_id; rval = 1; } @@ -2078,6 +2070,7 @@ uint32_t rval = 0; MAILBOXQ *mbox; MAILBOX *mb; + PROG_ID old_prog_id; if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_NOSLEEP)) == NULL) { @@ -2087,8 +2080,12 @@ return (1); } + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "SLI3: Updating parms..."); + mb = (MAILBOX *)mbox; + old_prog_id = WakeUpParms->sli3_prog_id; WakeUpParms->sli3_prog_id = *prog_id; emlxs_format_update_parms(mbox, WakeUpParms); @@ -2098,6 +2095,7 @@ "Unable to update wakeup parameters. Mailbox cmd=%x " "status=%x", mb->mbxCommand, mb->mbxStatus); + WakeUpParms->sli3_prog_id = old_prog_id; rval = 1; } @@ -2118,6 +2116,7 @@ uint32_t rval = 0; MAILBOXQ *mbox; MAILBOX *mb; + PROG_ID old_prog_id; if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_NOSLEEP)) == NULL) { @@ -2127,8 +2126,12 @@ return (1); } + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "SLI4: Updating parms..."); + mb = (MAILBOX *)mbox; + old_prog_id = WakeUpParms->sli4_prog_id; WakeUpParms->sli4_prog_id = *prog_id; emlxs_format_update_parms(mbox, WakeUpParms); @@ -2138,6 +2141,7 @@ "Unable to update wakeup parameters. Mailbox cmd=%x " "status=%x", mb->mbxCommand, mb->mbxStatus); + WakeUpParms->sli4_prog_id = old_prog_id; rval = 1; } @@ -2150,13 +2154,184 @@ } /* emlxs_update_sli4_wakeup_parms() */ +static uint32_t +emlxs_clean_flash(emlxs_hba_t *hba, + PWAKE_UP_PARMS OldWakeUpParms, PWAKE_UP_PARMS NewWakeUpParms) +{ + emlxs_port_t *port = &PPORT; + PROG_ID load_list[MAX_LOAD_ENTRY]; + PROG_ID *wakeup_list[MAX_LOAD_ENTRY]; + uint32_t count; + uint32_t i; + uint32_t j; + uint32_t k = 0; + uint32_t *wptr; + + if (!NewWakeUpParms) { + return (1); + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "Cleaning flash..."); + + /* If old wakeup parameter list is available, */ + /* then cleanup old entries */ + if (OldWakeUpParms) { + if (bcmp(&OldWakeUpParms->prog_id, &NewWakeUpParms->prog_id, + sizeof (PROG_ID))) { + + wptr = (uint32_t *)&OldWakeUpParms->prog_id; + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "OLD: prog_id: 0x%08x 0x%08x Removing.", + wptr[0], wptr[1]); + + (void) emlxs_delete_load_entry(hba, + &OldWakeUpParms->prog_id); + } + + if (bcmp(&OldWakeUpParms->u0.boot_bios_id, + &NewWakeUpParms->u0.boot_bios_id, sizeof (PROG_ID))) { + + wptr = (uint32_t *)&OldWakeUpParms->u0.boot_bios_id; + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "OLD: boot_bios_id: 0x%08x 0x%08x Removing.", + wptr[0], wptr[1]); + + (void) emlxs_delete_load_entry(hba, + &OldWakeUpParms->u0.boot_bios_id); + } + + if (bcmp(&OldWakeUpParms->sli1_prog_id, + &NewWakeUpParms->sli1_prog_id, sizeof (PROG_ID))) { + + wptr = (uint32_t *)&OldWakeUpParms->sli1_prog_id; + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "OLD: sli1_prog_id: 0x%08x 0x%08x Removing.", + wptr[0], wptr[1]); + + (void) emlxs_delete_load_entry(hba, + &OldWakeUpParms->sli1_prog_id); + } + + if (bcmp(&OldWakeUpParms->sli2_prog_id, + &NewWakeUpParms->sli2_prog_id, sizeof (PROG_ID))) { + + wptr = (uint32_t *)&OldWakeUpParms->sli2_prog_id; + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "OLD: sli2_prog_id: 0x%08x 0x%08x Removing.", + wptr[0], wptr[1]); + + (void) emlxs_delete_load_entry(hba, + &OldWakeUpParms->sli2_prog_id); + } + + if (bcmp(&OldWakeUpParms->sli3_prog_id, + &NewWakeUpParms->sli3_prog_id, sizeof (PROG_ID))) { + + wptr = (uint32_t *)&OldWakeUpParms->sli3_prog_id; + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "OLD: sli3_prog_id: 0x%08x 0x%08x Removing.", + wptr[0], wptr[1]); + + (void) emlxs_delete_load_entry(hba, + &OldWakeUpParms->sli3_prog_id); + } + + if (bcmp(&OldWakeUpParms->sli4_prog_id, + &NewWakeUpParms->sli4_prog_id, sizeof (PROG_ID))) { + + wptr = (uint32_t *)&OldWakeUpParms->sli4_prog_id; + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "OLD: sli4_prog_id: 0x%08x 0x%08x Removing.", + wptr[0], wptr[1]); + + (void) emlxs_delete_load_entry(hba, + &OldWakeUpParms->sli4_prog_id); + } + + return (0); + } + + /* Otherwise use the current load list */ + count = emlxs_get_load_list(hba, load_list); + + if (!count) { + return (1); + } + + /* Init the wakeup list */ + wptr = (uint32_t *)&NewWakeUpParms->prog_id; + if (*wptr) { + wakeup_list[k++] = &NewWakeUpParms->prog_id; + } + + wptr = (uint32_t *)&NewWakeUpParms->u0.boot_bios_id; + if (*wptr) { + wakeup_list[k++] = &NewWakeUpParms->u0.boot_bios_id; + } + + wptr = (uint32_t *)&NewWakeUpParms->sli1_prog_id; + if (*wptr) { + wakeup_list[k++] = &NewWakeUpParms->sli1_prog_id; + } + + wptr = (uint32_t *)&NewWakeUpParms->sli2_prog_id; + if (*wptr) { + wakeup_list[k++] = &NewWakeUpParms->sli2_prog_id; + } + + wptr = (uint32_t *)&NewWakeUpParms->sli3_prog_id; + if (*wptr) { + wakeup_list[k++] = &NewWakeUpParms->sli3_prog_id; + } + + wptr = (uint32_t *)&NewWakeUpParms->sli4_prog_id; + if (*wptr) { + wakeup_list[k++] = &NewWakeUpParms->sli4_prog_id; + } + + if (k == 0) { + return (0); + } + + /* Match load list to wakeup list */ + for (i = 0; i < count; i++) { + + wptr = (uint32_t *)&load_list[i]; + + for (j = 0; j < k; j++) { + if (bcmp((uint8_t *)wakeup_list[j], + (uint8_t *)&load_list[i], sizeof (PROG_ID)) == 0) { + break; + } + } + + /* No match */ + if (j == k) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "Load List[%d]: %08x %08x Removing.", + i, wptr[0], wptr[1]); + + (void) emlxs_delete_load_entry(hba, &load_list[i]); + } else { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "Load List[%d]: %08x %08x Preserving.", + i, wptr[0], wptr[1]); + } + } + + return (0); + +} /* emlxs_clean_flash() */ + + /* ARGSUSED */ static uint32_t emlxs_start_rel_download(emlxs_hba_t *hba, PIMAGE_HDR ImageHdr, caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, - uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize) + uint32_t dwc_flag) { emlxs_port_t *port = &PPORT; MAILBOXQ *mbox; @@ -2164,21 +2339,23 @@ uint32_t *Src; uint32_t *Dst; caddr_t DataBuffer = NULL; - uint32_t rval = 1; - uint32_t DlByteCount = ImageHdr->BlockSize; + uint32_t rval = 0; + uint32_t DlByteCount; uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; uint32_t DlCount; uint32_t i; - - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "Performing relative download..."); + uint32_t *wptr; + + wptr = (uint32_t *)&ImageHdr->Id; + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, + "Relative download: %08x %08x", wptr[0], wptr[1]); if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, KM_NOSLEEP)) == NULL) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, "Unable to allocate data buffer."); - return (rval); + return (1); } if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), @@ -2188,60 +2365,31 @@ kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); - return (rval); - } - - if (ImageHdr->Id.Type == FUNC_FIRMWARE) { - switch (MaxRbusSramSize) { - case REDUCED_RBUS_SRAM_CFG: - if (ImageHdr->Id.Id != REDUCED_SRAM_CFG_PROG_ID) { - EMLXS_MSGF(EMLXS_CONTEXT, - &emlxs_image_bad_msg, - "Invalid header id."); - - return (1); - } - break; - case FULL_RBUS_SRAM_CFG: - if (ImageHdr->Id.Id != FULL_SRAM_CFG_PROG_ID) { - EMLXS_MSGF(EMLXS_CONTEXT, - &emlxs_image_bad_msg, - "Invalid header id."); - - return (1); - } - break; - default: - if (ImageHdr->Id.Id != OTHER_SRAM_CFG_PROG_ID) { - EMLXS_MSGF(EMLXS_CONTEXT, - &emlxs_image_bad_msg, - "Invalid header id."); - - return (1); - } - break; - } + return (1); } mb = (MAILBOX *)mbox; + DlByteCount = ImageHdr->BlockSize; + emlxs_format_prog_flash(mbox, 0, DlByteCount, ERASE_FLASH, 0, 0, 0, - &ImageHdr->Id); - - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash..."); - - if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { + &ImageHdr->Id, 0); + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, + " Erasing flash..."); + + rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0); + + if (rval) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, "Unable to erase flash. Mailbox cmd=%x status=%x", mb->mbxCommand, mb->mbxStatus); - rval = 1; - goto EXIT_REL_DOWNLOAD; } - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "Programming flash..."); + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, + " Programming flash..."); while (DlByteCount) { if (DlByteCount > SegSize) { @@ -2269,16 +2417,16 @@ 0, DlCount, PROGRAM_FLASH, - (DlByteCount) ? 0 : 1, 0, DlCount, &ImageHdr->Id); - - if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != - MBX_SUCCESS) { + (DlByteCount) ? 0 : 1, + 0, DlCount, &ImageHdr->Id, dwc_flag); + + rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0); + + if (rval) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, "Unable to program flash. Mailbox cmd=%x status=%x", mb->mbxCommand, mb->mbxStatus); - rval = 1; - goto EXIT_REL_DOWNLOAD; } @@ -2297,57 +2445,73 @@ } #endif /* FMA_SUPPORT */ + /* Update wakeup parameters */ switch (ImageHdr->Id.Type) { case TEST_PROGRAM: - rval = 0; break; case FUNC_FIRMWARE: - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "FF: Updating parms..."); - rval = - emlxs_update_ff_wakeup_parms(hba, WakeUpParms, - &ImageHdr->Id); + if (!dwc_flag) { + rval = emlxs_update_ff_wakeup_parms(hba, WakeUpParms, + &ImageHdr->Id); + } else { + WakeUpParms->prog_id = ImageHdr->Id; + } break; case BOOT_BIOS: - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "BOOT: Updating parms..."); - rval = - emlxs_update_boot_wakeup_parms(hba, WakeUpParms, - &ImageHdr->Id, 1); + if (!dwc_flag) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "BOOT: Updating parms..."); + + rval = emlxs_update_boot_wakeup_parms(hba, WakeUpParms, + &ImageHdr->Id, 1); + } else { + if (hba->wakeup_parms.u0.boot_bios_wd[0]) { + WakeUpParms->u0.boot_bios_id = ImageHdr->Id; + } + + if (!(hba->model_info.chip & + (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { + WakeUpParms->u1.EROM_prog_id = ImageHdr->Id; + } + } break; case SLI1_OVERLAY: - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "SLI1: Updating parms..."); - rval = - emlxs_update_sli1_wakeup_parms(hba, WakeUpParms, - &ImageHdr->Id); + if (!dwc_flag) { + rval = emlxs_update_sli1_wakeup_parms(hba, WakeUpParms, + &ImageHdr->Id); + } else { + WakeUpParms->sli1_prog_id = ImageHdr->Id; + } break; case SLI2_OVERLAY: - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "SLI2: Updating parms..."); - rval = - emlxs_update_sli2_wakeup_parms(hba, WakeUpParms, - &ImageHdr->Id); + if (!dwc_flag) { + rval = emlxs_update_sli2_wakeup_parms(hba, WakeUpParms, + &ImageHdr->Id); + } else { + WakeUpParms->sli2_prog_id = ImageHdr->Id; + } break; case SLI3_OVERLAY: - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "SLI3: Updating parms..."); - rval = - emlxs_update_sli3_wakeup_parms(hba, WakeUpParms, - &ImageHdr->Id); + if (!dwc_flag) { + rval = emlxs_update_sli3_wakeup_parms(hba, WakeUpParms, + &ImageHdr->Id); + } else { + WakeUpParms->sli3_prog_id = ImageHdr->Id; + } break; case SLI4_OVERLAY: - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "SLI4: Updating parms..."); - rval = - emlxs_update_sli4_wakeup_parms(hba, WakeUpParms, - &ImageHdr->Id); + if (!dwc_flag) { + rval = emlxs_update_sli4_wakeup_parms(hba, WakeUpParms, + &ImageHdr->Id); + } else { + WakeUpParms->sli4_prog_id = ImageHdr->Id; + } break; default: @@ -2371,6 +2535,74 @@ } /* emlxs_start_rel_download() */ +static uint32_t +emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer, emlxs_fw_image_t *fw_image) +{ + emlxs_port_t *port = &PPORT; + uint32_t rval = 0; + WAKE_UP_PARMS RelWakeUpParms; + WAKE_UP_PARMS WakeUpParms; + uint32_t i; + IMAGE_HDR ImageHdr; + caddr_t bptr; + uint32_t flash_cleaned = 0; + + if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 0)) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, + "Unable to get wakeup parameters."); + + return (EMLXS_IMAGE_FAILED); + } + +download: + + bcopy(&WakeUpParms, &RelWakeUpParms, sizeof (WAKE_UP_PARMS)); + + for (i = 0; i < MAX_PROG_TYPES; i++) { + if (!fw_image->prog[i].version) { + continue; + } + + bptr = buffer + fw_image->prog[i].offset; + + bcopy(bptr, &ImageHdr, sizeof (IMAGE_HDR)); + + rval = emlxs_start_rel_download(hba, &ImageHdr, bptr, + &RelWakeUpParms, 1); + + if (rval) { + EMLXS_MSGF(EMLXS_CONTEXT, + &emlxs_download_failed_msg, + "Failed to program flash."); + + if ((rval == NO_FLASH_MEM_AVAIL) && !flash_cleaned) { + /* Cleanup using current load list */ + (void) emlxs_clean_flash(hba, 0, &WakeUpParms); + + flash_cleaned = 1; + goto download; + } + + return (EMLXS_IMAGE_FAILED); + } + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, + "Updating wakeup parameters."); + + if (emlxs_update_wakeup_parms(hba, &RelWakeUpParms, + &RelWakeUpParms)) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, + "Unable to update parameters."); + + return (EMLXS_IMAGE_FAILED); + } + + return (0); + +} /* emlxs_proc_rel_2mb() */ + + #define FLASH_POLLING_BIT 0x80 #define FLASH_ERROR_BIT 0x20 @@ -2639,6 +2871,46 @@ } /* emlxs_erase_fcode_flash() */ +static uint32_t +emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId) +{ + emlxs_port_t *port = &PPORT; + MAILBOXQ *mbox = NULL; + MAILBOX *mb; + uint32_t rval = 0; + + if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), + KM_NOSLEEP)) == NULL) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "Unable to allocate mailbox buffer."); + + return (1); + } + + mb = (MAILBOX *)mbox; + mb->mbxCommand = MBX_DEL_LD_ENTRY; + mb->un.varDelLdEntry.list_req = FLASH_LOAD_LIST; + mb->un.varDelLdEntry.prog_id = *progId; + + if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, + "Unable to delete load entry: Mailbox cmd=%x status=%x", + mb->mbxCommand, mb->mbxStatus); + + rval = 1; + } + +done: + + if (mbox) { + kmem_free(mbox, sizeof (MAILBOXQ)); + } + + return (rval); + +} /* emlxs_delete_load_entry() */ + + extern uint32_t emlxs_get_load_list(emlxs_hba_t *hba, PROG_ID *load_list) { @@ -2646,7 +2918,7 @@ LOAD_ENTRY *LoadEntry; LOAD_LIST *LoadList = NULL; uint32_t i; - uint32_t rval = 0; + uint32_t count = 0; bzero(load_list, (sizeof (PROG_ID) * MAX_LOAD_ENTRY)); @@ -2655,12 +2927,10 @@ EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, "Unable to allocate LOADLIST buffer."); - rval = 1; goto done; } if (emlxs_read_load_list(hba, LoadList)) { - rval = 1; goto done; } @@ -2668,10 +2938,11 @@ LoadEntry = &LoadList->load_entry[i]; if ((LoadEntry->un.wd[0] != 0) && (LoadEntry->un.wd[0] != 0xffffffff)) { - load_list[i] = LoadEntry->un.id; EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, - "Load List[%d]: %08x %08x", i, + "Load List[%d]: %08x %08x", count, LoadEntry->un.wd[0], LoadEntry->un.wd[1]); + + load_list[count++] = LoadEntry->un.id; } } @@ -2681,7 +2952,7 @@ kmem_free(LoadList, sizeof (LOAD_LIST)); } - return (rval); + return (count); } /* emlxs_get_load_list() */ @@ -2920,74 +3191,11 @@ } /* emlxs_read_load_list() */ -static uint32_t -emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize) -{ - uint32_t Version; - - if (BufferSize < (SLI_VERSION_LOC + 4)) - return (0xffffffff); - - Buffer += SLI_VERSION_LOC; - Version = *((uint32_t *)Buffer); - - return (Version); - -} /* emlxs_get_abs_image_type() */ - - -static uint32_t -emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer, - uint32_t BufferSize, PAIF_HDR AifHeader) -{ - emlxs_port_t *port = &PPORT; - IMAGE_HDR ImageHdr; - uint32_t NextImage; - uint32_t i; - uint8_t *Sptr; - uint8_t *Dptr; - uint32_t HwId = 0xffffffff; - - NextImage = SLI_IMAGE_START - AifHeader->ImageBase; - - while (BufferSize > NextImage) { - Sptr = (uint8_t *)&Buffer[NextImage]; - Dptr = (uint8_t *)&ImageHdr; - for (i = 0; i < sizeof (IMAGE_HDR); i++) { - Dptr[i] = Sptr[i]; - } - - if (ImageHdr.BlockSize == 0xffffffff) - break; - - switch (ImageHdr.Id.Type) { - case 6: - case 7: - if (HwId == 0xffffffff) { - HwId = ImageHdr.Id.Id; - } - - if (HwId != ImageHdr.Id.Id) { - EMLXS_MSGF(EMLXS_CONTEXT, - &emlxs_image_bad_msg, - "Invalid hardware id. %x %x", HwId, - ImageHdr.Id.Id); - } - break; - } - - NextImage += ImageHdr.BlockSize; - } - - return (HwId); - -} /* emlxs_get_dwc_image_type() */ - static int emlxs_build_parms(caddr_t Buffer, PWAKE_UP_PARMS AbsWakeUpParms, - uint32_t BufferSize, PAIF_HDR AifHeader, int32_t DwcFile) + uint32_t BufferSize, PAIF_HDR AifHeader) { IMAGE_HDR ImageHdr; uint32_t NextImage; @@ -2998,7 +3206,8 @@ bzero((caddr_t)AbsWakeUpParms, sizeof (WAKE_UP_PARMS)); - if (!DwcFile && ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) { + if ((AifHeader->ImageBase != 0x20000) && + ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) { return (FALSE); } @@ -3257,6 +3466,164 @@ } /* emlxs_validate_version() */ +static void +emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *fw_image) +{ + emlxs_port_t *port = &PPORT; + emlxs_vpd_t *vpd = &VPD; + uint32_t i; + uint32_t count; + + /* Check for AWC file */ + if (fw_image->awc.version) { + if (fw_image->awc.version == vpd->postKernRev) { + fw_image->awc.version = 0; + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "AWC file: KERN: old=%s new=%s %s.", + vpd->postKernName, + fw_image->awc.label, + (fw_image->awc.version)? "Update":"Skip"); + } + + /* Check for BWC file */ + if (fw_image->bwc.version) { + if (strcmp(vpd->fcode_version, fw_image->bwc.label) == 0) { + fw_image->bwc.version = 0; + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "BWC file: BOOT: old=%s new=%s %s.", + vpd->fcode_version, + fw_image->bwc.label, + (fw_image->bwc.version)? "Update":"Skip"); + } + + /* Check for DWC file */ + if (fw_image->dwc.version) { + /* Check for program files */ + count = 0; + for (i = 0; i < MAX_PROG_TYPES; i++) { + if (!fw_image->prog[i].version) { + continue; + } + + /* Skip components that don't need updating */ + switch (i) { + case TEST_PROGRAM: + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "DWC file: TEST: new=%s " + "Update.", + fw_image->prog[i].label); + break; + + case BOOT_BIOS: + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "DWC file: BOOT: new=%s " + "Update.", + fw_image->prog[i].label); + break; + + case FUNC_FIRMWARE: + if (vpd->opFwRev && + (fw_image->prog[i].version == + vpd->opFwRev)) { + fw_image->prog[i].version = 0; + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "DWC file: STUB: old=%s new=%s %s.", + vpd->opFwName, + fw_image->prog[i].label, + (fw_image->prog[i].version)? + "Update":"Skip"); + break; + + case SLI1_OVERLAY: + if (vpd->sli1FwRev && + (fw_image->prog[i].version == + vpd->sli1FwRev)) { + fw_image->prog[i].version = 0; + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "DWC file: SLI1: old=%s new=%s %s.", + vpd->sli1FwName, + fw_image->prog[i].label, + (fw_image->prog[i].version)? + "Update":"Skip"); + break; + + case SLI2_OVERLAY: + if (vpd->sli2FwRev && + (fw_image->prog[i].version == + vpd->sli2FwRev)) { + fw_image->prog[i].version = 0; + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "DWC file: SLI2: old=%s new=%s %s.", + vpd->sli2FwName, + fw_image->prog[i].label, + (fw_image->prog[i].version)? + "Update":"Skip"); + break; + + case SLI3_OVERLAY: + if (vpd->sli3FwRev && + (fw_image->prog[i].version == + vpd->sli3FwRev)) { + fw_image->prog[i].version = 0; + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "DWC file: SLI3: old=%s new=%s %s.", + vpd->sli3FwName, + fw_image->prog[i].label, + (fw_image->prog[i].version)? + "Update":"Skip"); + break; + + case SLI4_OVERLAY: + if (vpd->sli4FwRev && + (fw_image->prog[i].version == + vpd->sli4FwRev)) { + fw_image->prog[i].version = 0; + } + + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "DWC file: SLI4: old=%s new=%s %s.", + vpd->sli4FwRev, + fw_image->prog[i].label, + (fw_image->prog[i].version)? + "Update":"Skip"); + break; + + default: + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "DWC file: type=%x version=%x label=%s " + "Update.", + i, + fw_image->prog[i].version, + fw_image->prog[i].label); + } + + if (fw_image->prog[i].version) { + count++; + } + } + + if (!count) { + fw_image->dwc.version = 0; + } + } + + return; + +} /* emlxs_verify_image() */ + + static uint32_t emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, uint32_t Size, emlxs_fw_image_t *image) @@ -3266,6 +3633,7 @@ AIF_HDR AifHdr; IMAGE_HDR ImageHdr; uint32_t NextImage; + uint32_t count; uint32_t FileType; uint32_t FileLen = 0; uint32_t TotalLen = 0; @@ -3379,6 +3747,7 @@ NextImage = sizeof (AIF_HDR) + 4; BufferSize = AifHdr.RoSize + AifHdr.RwSize; + count = 0; while (BufferSize > NextImage) { bcopy(&bptr[NextImage], &ImageHdr, sizeof (IMAGE_HDR)); @@ -3416,10 +3785,19 @@ return (rval); } + count++; NextImage += ImageHdr.BlockSize; } /* while () */ + if (count == 0) { + EMLXS_MSGF(EMLXS_CONTEXT, + &emlxs_image_bad_msg, + "DWC file has no PRG images."); + + return (EMLXS_IMAGE_BAD); + } + break; } @@ -3520,7 +3898,9 @@ NextImage += ImageHdr.BlockSize; } - } else { + + } else { /* PRG File */ + /* Precheck image size */ if (Size < sizeof (IMAGE_HDR)) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, @@ -3570,8 +3950,10 @@ /* Acquire the versions */ image->prog[type].version = - (ImageHdr.Id.Type << 24) | (ImageHdr.Id. - Id << 16) | (ImageHdr.Id.Ver << 8) | ImageHdr.Id.Rev; + (ImageHdr.Id.Type << 24) | + (ImageHdr.Id.Id << 16) | + (ImageHdr.Id.Ver << 8) | + ImageHdr.Id.Rev; image->prog[type].revcomp = ImageHdr.Id.un.revcomp; @@ -3584,23 +3966,19 @@ /* * This checks if a DragonFly (pre-V2 ASIC) SLI2 - * image file is greater than version 3.8 + * image file is < version 3.8 */ if (FC_JEDEC_ID(vpd->biuRev) == DRAGONFLY_JEDEC_ID) { - if (image->prog[SLI2_OVERLAY].version != 0) { - ver = (image->prog[SLI2_OVERLAY].version & - 0x0000ff00) >> 8; - - if ((((ver & 0xf0) == 0x30) && - ((ver & 0x0f) >= 0x08)) || - ((ver & 0xf0) > 0x30)) { - EMLXS_MSGF(EMLXS_CONTEXT, - &emlxs_image_incompat_msg, - "ASIC Check: Image requires DragonFly " - "V2 ASIC"); - - return (EMLXS_IMAGE_INCOMPATIBLE); - } + ver = (image->prog[SLI2_OVERLAY].version & + 0x0000ff00) >> 8; + + if (ver >= 0x38) { + EMLXS_MSGF(EMLXS_CONTEXT, + &emlxs_image_incompat_msg, + "ASIC Check: Image requires DragonFly " + "V2 ASIC"); + + return (EMLXS_IMAGE_INCOMPATIBLE); } } @@ -3752,63 +4130,14 @@ uint32_t offline, emlxs_fw_image_t *fw_image) { emlxs_port_t *port = &PPORT; - caddr_t AwcBuffer = NULL; - caddr_t BwcBuffer = NULL; - caddr_t DwcBuffer = NULL; - AIF_HDR *AwcAifHdr; - AIF_HDR *BwcAifHdr; - AIF_HDR *DwcAifHdr; - uint32_t BWCflag; - emlxs_vpd_t *vpd; - uint32_t i; - uint32_t count; - uint32_t extType = 0; uint32_t rval = 0; - vpd = &VPD; - - /* Check for AWC file */ - if (fw_image->awc.version) { - AwcBuffer = buffer + fw_image->awc.offset; - AwcAifHdr = (AIF_HDR *)AwcBuffer; - } - - /* Check for BWC file */ - if (fw_image->bwc.version) { - extType = BWCext; - BwcBuffer = buffer + fw_image->bwc.offset; - BwcAifHdr = (AIF_HDR *)BwcBuffer; - } - - /* Check for DWC file */ - if (fw_image->dwc.version) { - extType = DWCext; - DwcBuffer = buffer + fw_image->dwc.offset; - DwcAifHdr = (AIF_HDR *)DwcBuffer; - } - - /* Check for program files */ - count = 0; - for (i = 0; i < MAX_PROG_TYPES; i++) { - if (fw_image->prog[i].version) { - count++; - } - } - - if (count > 1) { - extType = ALLext; - - if (fw_image->bwc.version) { - BWCflag = ALL_WITH_BWC; - } else { - BWCflag = ALL_WITHOUT_BWC; - } - } else { - BWCflag = NO_ALL; - } - /* If nothing to download then quit now */ - if (!AwcBuffer && !DwcBuffer && !BwcBuffer) { + if (!fw_image->awc.version && + !fw_image->dwc.version && + !fw_image->bwc.version) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, + "Nothing new to update. Exiting."); return (0); } @@ -3825,65 +4154,33 @@ } } - if (AwcBuffer) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "AWC file: KERN: old=%s new=%s ", vpd->postKernName, - fw_image->awc.label); - + if (fw_image->awc.version) { rval = emlxs_proc_abs_2mb(hba, - AwcAifHdr, AwcBuffer, FILE_TYPE_AWC, BWCflag, extType); + (buffer + fw_image->awc.offset), + FILE_TYPE_AWC, 0); if (rval) { goto SLI_DOWNLOAD_2MB_EXIT; } } - if (DwcBuffer) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "DWC file: TEST: new=%s ", - fw_image->prog[TEST_PROGRAM].label); - - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "DWC file: STUB: old=%s new=%s ", vpd->opFwName, - fw_image->prog[FUNC_FIRMWARE].label); - - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "DWC file: SLI1: old=%s new=%s ", vpd->sli1FwName, - fw_image->prog[SLI1_OVERLAY].label); - - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "DWC file: SLI2: old=%s new=%s ", vpd->sli2FwName, - fw_image->prog[SLI2_OVERLAY].label); - - if (vpd->sli3FwRev || fw_image->prog[SLI3_OVERLAY].version) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "DWC file: SLI3: old=%s new=%s ", - vpd->sli3FwName, - fw_image->prog[SLI3_OVERLAY].label); - } - - if (vpd->sli4FwRev || fw_image->prog[SLI4_OVERLAY].version) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "DWC file: SLI4: old=%s new=%s ", - vpd->sli4FwName, - fw_image->prog[SLI4_OVERLAY].label); - } - + if (fw_image->bwc.version) { rval = emlxs_proc_abs_2mb(hba, - DwcAifHdr, DwcBuffer, FILE_TYPE_DWC, BWCflag, extType); + (buffer + fw_image->bwc.offset), + FILE_TYPE_BWC, + (fw_image->dwc.version)? ALLext:BWCext); if (rval) { goto SLI_DOWNLOAD_2MB_EXIT; } } - if (BwcBuffer) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, - "BWC file: BOOT: old=%s new=%s ", vpd->fcode_version, - fw_image->bwc.label); - - rval = emlxs_proc_abs_2mb(hba, - BwcAifHdr, BwcBuffer, FILE_TYPE_BWC, BWCflag, extType); + if (fw_image->dwc.version) { + rval = emlxs_proc_rel_2mb(hba, buffer, fw_image); + + if (rval) { + goto SLI_DOWNLOAD_2MB_EXIT; + } } SLI_DOWNLOAD_2MB_EXIT: @@ -3912,22 +4209,21 @@ * */ static uint32_t -emlxs_proc_abs_2mb(emlxs_hba_t *hba, - PAIF_HDR AifHdr, - caddr_t EntireBuffer, - uint32_t FileType, uint32_t BWCflag, uint32_t extType) +emlxs_proc_abs_2mb(emlxs_hba_t *hba, caddr_t EntireBuffer, + uint32_t FileType, uint32_t extType) { emlxs_port_t *port = &PPORT; + PAIF_HDR AifHdr; caddr_t Buffer = NULL; caddr_t DataBuffer = NULL; uint32_t *Src; uint32_t *Dst; MAILBOXQ *mbox; MAILBOX *mb; - uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; + uint32_t DlByteCount; uint32_t rval = 0; uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; - uint32_t DlToAddr = AifHdr->ImageBase; + uint32_t DlToAddr; uint32_t DlCount; WAKE_UP_PARMS AbsWakeUpParms; uint32_t i; @@ -3935,9 +4231,11 @@ uint32_t EraseByteCount; uint32_t AreaId; uint32_t RspProgress = 0; - uint32_t numBootImage = 0; - uint32_t ParamsChg = 0; - uint32_t BufferSize; + uint32_t ParamsChg; + + AifHdr = (PAIF_HDR)EntireBuffer; + DlByteCount = AifHdr->RoSize + AifHdr->RwSize; + DlToAddr = AifHdr->ImageBase; if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, KM_NOSLEEP)) == NULL) { @@ -3947,8 +4245,6 @@ return (EMLXS_IMAGE_FAILED); } - bzero(DataBuffer, sizeof (DL_SLIM_SEG_BYTE_COUNT)); - if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_NOSLEEP)) == NULL) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, @@ -3961,18 +4257,18 @@ mb = (MAILBOX *)mbox; - BufferSize = DlByteCount + sizeof (AIF_HDR) + sizeof (uint32_t); Buffer = EntireBuffer + sizeof (AIF_HDR); switch (FileType) { case FILE_TYPE_AWC: + ParamsChg = 0; break; case FILE_TYPE_BWC: - ParamsChg = emlxs_build_parms_2mb_bwc(hba, + rval = emlxs_build_parms_2mb_bwc(hba, AifHdr, extType, &AbsWakeUpParms); - if (ParamsChg == FALSE) { + if (rval == FALSE) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, "BWC build parms failed."); @@ -3980,22 +4276,7 @@ goto EXIT_ABS_DOWNLOAD; } - break; - - case FILE_TYPE_DWC: - ParamsChg = emlxs_build_parms_2mb_dwc(hba, - Buffer, - BufferSize, - AifHdr, &AbsWakeUpParms, BWCflag, extType, &numBootImage); - - if (ParamsChg == FALSE) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, - "DWC build parms failed."); - - rval = EMLXS_IMAGE_FAILED; - - goto EXIT_ABS_DOWNLOAD; - } + ParamsChg = 1; break; default: @@ -4190,7 +4471,7 @@ /* Read wakeup paramters */ if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == - CFG_DATA_NO_REGION) { + (uint32_t)CFG_DATA_NO_REGION) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, "Unable to get BWC parameters."); return (FALSE); @@ -4242,148 +4523,6 @@ } /* emlxs_build_parms_2mb_bwc() */ -/* ARGSUSED */ -static uint32_t -emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba, - caddr_t Buffer, - uint32_t BufferSize, - PAIF_HDR AifHeader, - PWAKE_UP_PARMS AbsWakeUpParms, - uint32_t BWCflag, uint32_t extType, uint32_t *numBootImage) -{ - emlxs_port_t *port = &PPORT; - uint32_t NextImage; - uint32_t i; - IMAGE_HDR ImageHdr; - uint32_t *ptr1; - uint32_t *ptr2; - PROG_ID BootId[MAX_BOOTID]; - uint32_t ChangeParams = FALSE; - WAKE_UP_PARMS WakeUpParms; - caddr_t Sptr; - caddr_t Dptr; - - bzero(&BootId, (sizeof (PROG_ID)) * MAX_BOOTID); - - /* Read wakeup paramters */ - if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == - CFG_DATA_NO_REGION) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, - "Unable to get DWC parameters."); - return (FALSE); - } - - bcopy((caddr_t)AbsWakeUpParms, (caddr_t)&WakeUpParms, - sizeof (WAKE_UP_PARMS)); - - if (((BWCflag == ALL_WITHOUT_BWC) || (extType == DWCext)) && - (WakeUpParms.u0.boot_bios_wd[0])) { - *numBootImage = 0; - } - - /* incoming buffer is without aif header */ - NextImage = 0x84 - sizeof (AIF_HDR); - BufferSize -= (sizeof (AIF_HDR) + sizeof (uint32_t)); - - while (BufferSize > NextImage) { - Sptr = &Buffer[NextImage]; - Dptr = (caddr_t)&ImageHdr; - for (i = 0; i < sizeof (IMAGE_HDR); i++) { - Dptr[i] = Sptr[i]; - } - - if (ImageHdr.BlockSize == 0xffffffff) { - break; - } - - switch (ImageHdr.Id.Type) { - case TEST_PROGRAM: - break; - - case FUNC_FIRMWARE: - AbsWakeUpParms->prog_id = ImageHdr.Id; - ChangeParams = TRUE; - break; - - case BOOT_BIOS: - if (!WakeUpParms.u0.boot_bios_wd[0]) { - if (extType == DWCext) { - break; - } else if (BWCflag == ALL_WITHOUT_BWC) { - /* for possible future changes */ - break; - } - } - ChangeParams = TRUE; - - if (*numBootImage < MAX_BOOTID) { - BootId[*numBootImage] = ImageHdr.Id; - (*numBootImage)++; - } - break; - - case SLI1_OVERLAY: - AbsWakeUpParms->sli1_prog_id = ImageHdr.Id; - ChangeParams = TRUE; - break; - - case SLI2_OVERLAY: - AbsWakeUpParms->sli2_prog_id = ImageHdr.Id; - ChangeParams = TRUE; - break; - - case SLI3_OVERLAY: - AbsWakeUpParms->sli3_prog_id = ImageHdr.Id; - ChangeParams = TRUE; - break; - - case SLI4_OVERLAY: - AbsWakeUpParms->sli4_prog_id = ImageHdr.Id; - ChangeParams = TRUE; - break; - } - - NextImage += ImageHdr.BlockSize; - } - - if ((ChangeParams) && ((BWCflag == ALL_WITHOUT_BWC) || - (extType == DWCext))) { - - if (*numBootImage > 1) { - for (i = 0; i < *numBootImage; i++) { - ptr1 = - (uint32_t *)&WakeUpParms.u0. - boot_bios_id; - ptr2 = (uint32_t *)&BootId[i]; - - if (ptr1[0] == ptr2[0]) { - AbsWakeUpParms->u1.EROM_prog_id = - BootId[i]; - (void) emlxs_update_exp_rom(hba, - AbsWakeUpParms); - break; - } - } - } else { - if (*numBootImage == 1) { - ptr2 = (uint32_t *)&BootId[0]; - - if (WakeUpParms.u0.boot_bios_wd[0] == ptr2[0]) { - AbsWakeUpParms->u1.EROM_prog_id = - BootId[0]; - (void) emlxs_update_exp_rom(hba, - AbsWakeUpParms); - } - } - } - } - - return (ChangeParams); - - -} /* emlxs_build_parms_2mb_dwc() */ - - extern uint32_t emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, uint32_t *MaxIbusSize) @@ -4394,6 +4533,14 @@ uint32_t *Uptr; uint32_t rval = 0; + if (MaxRbusSize) { + *MaxRbusSize = 0; + } + + if (MaxIbusSize) { + *MaxIbusSize = 0; + } + if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_NOSLEEP)) == NULL) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, @@ -4425,8 +4572,13 @@ Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; } - *MaxRbusSize = Uptr[0]; - *MaxIbusSize = Uptr[1]; + if (MaxRbusSize) { + *MaxRbusSize = Uptr[0]; + } + + if (MaxIbusSize) { + *MaxIbusSize = Uptr[1]; + } Exit_Function: @@ -4684,6 +4836,7 @@ emlxs_vpd_t *vpd; PROG_ID load_list[MAX_LOAD_ENTRY]; uint32_t i; + uint32_t count; vpd = &VPD; @@ -4716,12 +4869,14 @@ &hba->wakeup_parms.u1.EROM_prog_id, 0); } else { /* (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP) */ - if (emlxs_get_load_list(hba, load_list)) { + count = emlxs_get_load_list(hba, load_list); + + if (!count) { return (FC_FAILURE); } /* Scan load list for a boot image */ - for (i = 0; i < MAX_LOAD_ENTRY; i++) { + for (i = 0; i < count; i++) { if (load_list[i].Type == BOOT_BIOS) { /* Update the parms with the boot image id */ /* Don't load the EROM this time */ @@ -4732,7 +4887,7 @@ } } - if (i == MAX_LOAD_ENTRY) { + if (i == count) { return (EMLXS_NO_BOOT_CODE); } } diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c --- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c Thu Sep 09 11:46:43 2010 -0400 @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Emulex. All rights reserved. + * Copyright 2010 Emulex. All rights reserved. * Use is subject to license terms. */ @@ -1353,6 +1353,7 @@ if (vport->vpi == 0) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg, "%s%s%s", linkspeed, topology, mode); + } else if (npiv_linkup) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_npiv_link_up_msg, "%s%s%s", @@ -1372,6 +1373,7 @@ if (vport->vpi == 0) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg, "%s%s%s *", linkspeed, topology, mode); + } else if (npiv_linkup) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_npiv_link_up_msg, "%s%s%s *", diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c --- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c Thu Sep 09 11:46:43 2010 -0400 @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Emulex. All rights reserved. + * Copyright 2010 Emulex. All rights reserved. * Use is subject to license terms. */ @@ -196,6 +196,7 @@ uint32_t read_rev_reset; uint32_t key = 0; uint32_t fw_check; + uint32_t kern_update = 0; uint32_t rval = 0; uint32_t offset; uint8_t vpd_data[DMP_VPD_SIZE]; @@ -215,6 +216,29 @@ (void) READ_SBUS_CSR_REG(hba, FC_SHS_REG(hba)); } + /* + * Get a buffer which will be used repeatedly for mailbox commands + */ + mbq = (MAILBOXQ *) kmem_zalloc((sizeof (MAILBOXQ)), KM_SLEEP); + + mb = (MAILBOX *)mbq; + + hba->mbox_queue_flag = 0; + hba->sli.sli3.hc_copy = 0; + hba->fc_edtov = FF_DEF_EDTOV; + hba->fc_ratov = FF_DEF_RATOV; + hba->fc_altov = FF_DEF_ALTOV; + hba->fc_arbtov = FF_DEF_ARBTOV; + + /* Set the fw_check flag */ + fw_check = cfg[CFG_FW_CHECK].current; + + if ((fw_check & 0x04) || + (hba->fw_flag & FW_UPDATE_KERNEL)) { + kern_update = 1; + } + +reset: /* Initialize sli mode based on configuration parameter */ switch (cfg[CFG_SLI_MODE].current) { case 2: /* SLI2 mode */ @@ -244,24 +268,6 @@ sli_mode_mask = EMLXS_SLI2_MASK; } - /* Set the fw_check flag */ - fw_check = cfg[CFG_FW_CHECK].current; - - hba->mbox_queue_flag = 0; - hba->sli.sli3.hc_copy = 0; - hba->fc_edtov = FF_DEF_EDTOV; - hba->fc_ratov = FF_DEF_RATOV; - hba->fc_altov = FF_DEF_ALTOV; - hba->fc_arbtov = FF_DEF_ARBTOV; - - /* - * Get a buffer which will be used repeatedly for mailbox commands - */ - mbq = (MAILBOXQ *) kmem_zalloc((sizeof (MAILBOXQ)), KM_SLEEP); - - mb = (MAILBOX *)mbq; -reset: - /* Reset & Initialize the adapter */ if (emlxs_sli3_hba_init(hba)) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, @@ -682,8 +688,11 @@ * If firmware checking is enabled and the adapter model indicates * a firmware image, then perform firmware version check */ - if (((fw_check == 1) && (hba->model_info.flags & EMLXS_SUN_BRANDED) && - hba->model_info.fwid) || ((fw_check == 2) && + hba->fw_flag = 0; + hba->fw_timer = 0; + + if (((fw_check & 0x1) && (hba->model_info.flags & EMLXS_SUN_BRANDED) && + hba->model_info.fwid) || ((fw_check & 0x2) && hba->model_info.fwid)) { emlxs_firmware_t *fw; @@ -701,7 +710,14 @@ * versions of adapter */ if (fw) { - if ((fw->kern && (vpd->postKernRev != fw->kern)) || + if (!kern_update && + ((fw->kern && (vpd->postKernRev != fw->kern)) || + (fw->stub && (vpd->opFwRev != fw->stub)))) { + + hba->fw_flag |= FW_UPDATE_NEEDED; + + } else if ((fw->kern && (vpd->postKernRev != + fw->kern)) || (fw->stub && (vpd->opFwRev != fw->stub)) || (fw->sli1 && (vpd->sli1FwRev != fw->sli1)) || (fw->sli2 && (vpd->sli2FwRev != fw->sli2)) || @@ -728,6 +744,9 @@ EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, "Firmware update failed."); + + hba->fw_flag |= + FW_UPDATE_NEEDED; } #ifdef MODFW_SUPPORT /* @@ -3569,8 +3588,9 @@ iocb->ULPCOMMAND = CMD_FCP_TSEND64_CX; - if (dbuf->db_data_size == - fct_task->task_expected_xfer_length) + if ((hba->sli_mode == EMLXS_HBA_SLI3_MODE) && + (dbuf->db_data_size == + fct_task->task_expected_xfer_length)) iocb->ULPCT = 0x1; /* enable auto-rsp AP feature */ } diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c --- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c Thu Sep 09 11:46:43 2010 -0400 @@ -180,6 +180,7 @@ uint8_t *outptr; uint32_t status; uint32_t fw_check; + uint32_t kern_update = 0; emlxs_firmware_t hba_fw; emlxs_firmware_t *fw; @@ -192,6 +193,11 @@ /* Set the fw_check flag */ fw_check = cfg[CFG_FW_CHECK].current; + if ((fw_check & 0x04) || + (hba->fw_flag & FW_UPDATE_KERNEL)) { + kern_update = 1; + } + hba->mbox_queue_flag = 0; hba->fc_edtov = FF_DEF_EDTOV; hba->fc_ratov = FF_DEF_RATOV; @@ -532,8 +538,11 @@ * If firmware checking is enabled and the adapter model indicates * a firmware image, then perform firmware version check */ - if (((fw_check == 1) && (hba->model_info.flags & EMLXS_SUN_BRANDED) && - hba->model_info.fwid) || ((fw_check == 2) && + hba->fw_flag = 0; + hba->fw_timer = 0; + + if (((fw_check & 0x1) && (hba->model_info.flags & EMLXS_SUN_BRANDED) && + hba->model_info.fwid) || ((fw_check & 0x2) && hba->model_info.fwid)) { /* Find firmware image indicated by adapter model */ @@ -563,7 +572,13 @@ hba_fw.sli4 = vpd->sli4FwRev; } - if ((fw->kern && (hba_fw.kern != fw->kern)) || + if (!kern_update && + ((fw->kern && (hba_fw.kern != fw->kern)) || + (fw->stub && (hba_fw.stub != fw->stub)))) { + + hba->fw_flag |= FW_UPDATE_NEEDED; + + } else if ((fw->kern && (hba_fw.kern != fw->kern)) || (fw->stub && (hba_fw.stub != fw->stub)) || (fw->sli1 && (hba_fw.sli1 != fw->sli1)) || (fw->sli2 && (hba_fw.sli2 != fw->sli2)) || @@ -591,6 +606,9 @@ EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, "Firmware update failed."); + + hba->fw_flag |= + FW_UPDATE_NEEDED; } #ifdef MODFW_SUPPORT /* @@ -6689,6 +6707,7 @@ emlxs_sli4_check_fcf_config(emlxs_hba_t *hba, FCF_RECORD_t *fcfrec) { int i; + uint32_t rval = 1; if (!(hba->flag & FC_FIP_SUPPORTED)) { if (!hba->sli.sli4.cfgFCOE.length) { @@ -6718,12 +6737,15 @@ /* Just check FabricName for now */ for (i = 0; i < MAX_FCFCONNECTLIST_ENTRIES; i++) { if ((hba->sli.sli4.cfgFCF.entry[i].FabricNameValid) && - (bcmp((char *)fcfrec->fabric_name_identifier, - hba->sli.sli4.cfgFCF.entry[i].FabricName, 8) == 0)) { - return (1); /* success */ - } - } - return (0); + (hba->sli.sli4.cfgFCF.entry[i].Valid)) { + rval = 0; + if (bcmp((char *)fcfrec->fabric_name_identifier, + hba->sli.sli4.cfgFCF.entry[i].FabricName, 8) == 0) { + return (1); /* success */ + } + } + } + return (rval); } diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c --- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c Thu Sep 09 11:46:43 2010 -0400 @@ -46,6 +46,7 @@ static void emlxs_fca_attach(emlxs_hba_t *hba); static void emlxs_fca_detach(emlxs_hba_t *hba); static void emlxs_drv_banner(emlxs_hba_t *hba); +static int32_t emlxs_fca_reset(opaque_t fca_port_handle, uint32_t cmd); static int32_t emlxs_get_props(emlxs_hba_t *hba); static int32_t emlxs_send_fcp_cmd(emlxs_port_t *port, emlxs_buf_t *sbp); @@ -268,7 +269,7 @@ emlxs_ub_free, emlxs_ub_release, emlxs_pkt_abort, - emlxs_reset, + emlxs_fca_reset, emlxs_port_manage, emlxs_get_device, emlxs_notify @@ -306,7 +307,7 @@ emlxs_ub_free, emlxs_ub_release, emlxs_pkt_abort, - emlxs_reset, + emlxs_fca_reset, emlxs_port_manage, emlxs_get_device, emlxs_notify @@ -344,7 +345,7 @@ emlxs_ub_free, emlxs_ub_release, emlxs_pkt_abort, - emlxs_reset, + emlxs_fca_reset, emlxs_port_manage, emlxs_get_device, emlxs_notify @@ -375,7 +376,7 @@ emlxs_ub_free, emlxs_ub_release, emlxs_pkt_abort, - emlxs_reset, + emlxs_fca_reset, emlxs_port_manage, emlxs_get_device, emlxs_notify @@ -3851,21 +3852,13 @@ extern int32_t -emlxs_reset(opaque_t fca_port_handle, uint32_t cmd) -{ - emlxs_port_t *port = (emlxs_port_t *)fca_port_handle; +emlxs_reset(emlxs_port_t *port, uint32_t cmd) +{ emlxs_hba_t *hba = HBA; int rval; int ret; clock_t timeout; - if (!(port->flag & EMLXS_PORT_BOUND)) { - EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, - "fca_reset failed. Port not bound."); - - return (FC_UNBOUND); - } - switch (cmd) { case FC_FCA_LINK_RESET: @@ -3875,7 +3868,7 @@ } EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, - "fca_reset: Resetting Link."); + "Resetting Link."); mutex_enter(&EMLXS_LINKUP_LOCK); hba->linkup_wait_flag = TRUE; @@ -3910,7 +3903,7 @@ case FC_FCA_CORE: #ifdef DUMP_SUPPORT EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, - "fca_reset: Core dump."); + "Dumping Core."); /* Schedule a USER dump */ emlxs_dump(hba, EMLXS_USER_DUMP, 0, 0); @@ -3925,7 +3918,7 @@ case FC_FCA_RESET_CORE: EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, - "fca_reset: Resetting Adapter."); + "Resetting Adapter."); rval = FC_SUCCESS; @@ -3933,7 +3926,7 @@ (void) emlxs_online(hba); } else { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, - "fca_reset: Adapter reset failed. Device busy."); + "Adapter reset failed. Device busy."); rval = FC_DEVICE_BUSY; } @@ -3942,7 +3935,7 @@ default: EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, - "fca_reset: Unknown command. cmd=%x", cmd); + "emlxs_reset: Unknown command. cmd=%x", cmd); break; } @@ -3952,6 +3945,64 @@ } /* emlxs_reset() */ +static int32_t +emlxs_fca_reset(opaque_t fca_port_handle, uint32_t cmd) +{ + emlxs_port_t *port = (emlxs_port_t *)fca_port_handle; + emlxs_hba_t *hba = HBA; + int32_t rval; + + if (!(port->flag & EMLXS_PORT_BOUND)) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, + "fca_reset: Port not bound."); + + return (FC_UNBOUND); + } + + switch (cmd) { + case FC_FCA_LINK_RESET: + if (hba->fw_flag & FW_UPDATE_NEEDED) { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, + "fca_reset: FC_FCA_LINK_RESET -> FC_FCA_RESET"); + cmd = FC_FCA_RESET; + } else { + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, + "fca_reset: FC_FCA_LINK_RESET"); + } + break; + + case FC_FCA_CORE: + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, + "fca_reset: FC_FCA_CORE"); + break; + + case FC_FCA_RESET: + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, + "fca_reset: FC_FCA_RESET"); + break; + + case FC_FCA_RESET_CORE: + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, + "fca_reset: FC_FCA_RESET_CORE"); + break; + + default: + EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, + "fca_reset: Unknown command. cmd=%x", cmd); + return (FC_FAILURE); + } + + if (hba->fw_flag & FW_UPDATE_NEEDED) { + hba->fw_flag |= FW_UPDATE_KERNEL; + } + + rval = emlxs_reset(port, cmd); + + return (rval); + +} /* emlxs_fca_reset() */ + + extern int emlxs_port_manage(opaque_t fca_port_handle, fc_fca_pm_t *pm) { @@ -6862,6 +6913,18 @@ } break; + case CFG_FW_CHECK: + /* The 0x2 bit implies the 0x1 bit will also be set */ + if (new_value & 0x2) { + new_value |= 0x1; + } + + /* The 0x4 bit should not be set if 0x1 or 0x2 is not set */ + if (!(new_value & 0x3) && (new_value & 0x4)) { + new_value &= ~0x4; + } + break; + case CFG_LINK_SPEED: if (vpd->link_speed) { switch (new_value) { diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c --- a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c Thu Sep 09 11:46:43 2010 -0400 @@ -58,7 +58,6 @@ size_t, size_t, caddr_t *, ddi_dma_cookie_t *); static void ql_free_phys(ddi_dma_handle_t *, ddi_acc_handle_t *); static int ql_set_routing_reg(qlge_t *, uint32_t, uint32_t, int); -static int ql_route_initialize(qlge_t *); static int ql_attach(dev_info_t *, ddi_attach_cmd_t); static int ql_detach(dev_info_t *, ddi_detach_cmd_t); static int ql_bringdown_adapter(qlge_t *); @@ -1446,13 +1445,18 @@ int i; ddi_dma_cookie_t dma_cookie; + rx_ring->sbq_use_head = 0; + rx_ring->sbq_use_tail = 0; + rx_ring->sbuf_in_use_count = 0; + rx_ring->sbq_free_head = 0; + rx_ring->sbq_free_tail = 0; + rx_ring->sbuf_free_count = 0; rx_ring->sbuf_free = kmem_zalloc(rx_ring->sbq_len * sizeof (struct bq_desc *), KM_NOSLEEP); if (rx_ring->sbuf_free == NULL) { cmn_err(CE_WARN, "!%s: sbuf_free_list alloc: failed", __func__); - rx_ring->sbuf_free_count = 0; goto alloc_sbuf_err; } @@ -1462,13 +1466,9 @@ cmn_err(CE_WARN, "!%s: sbuf_inuse_list alloc: failed", __func__); - rx_ring->sbuf_in_use_count = 0; goto alloc_sbuf_err; } - rx_ring->sbq_use_head = 0; - rx_ring->sbq_use_tail = 0; - rx_ring->sbq_free_head = 0; - rx_ring->sbq_free_tail = 0; + sbq_desc = &rx_ring->sbq_desc[0]; for (i = 0; i < rx_ring->sbq_len; i++, sbq_desc++) { @@ -1591,13 +1591,18 @@ int i; uint32_t lbq_buf_size; + rx_ring->lbq_use_head = 0; + rx_ring->lbq_use_tail = 0; + rx_ring->lbuf_in_use_count = 0; + rx_ring->lbq_free_head = 0; + rx_ring->lbq_free_tail = 0; + rx_ring->lbuf_free_count = 0; rx_ring->lbuf_free = kmem_zalloc(rx_ring->lbq_len * sizeof (struct bq_desc *), KM_NOSLEEP); if (rx_ring->lbuf_free == NULL) { cmn_err(CE_WARN, "!%s: lbuf_free_list alloc: failed", __func__); - rx_ring->lbuf_free_count = 0; goto alloc_lbuf_err; } @@ -1608,13 +1613,8 @@ cmn_err(CE_WARN, "!%s: lbuf_inuse_list alloc: failed", __func__); - rx_ring->lbuf_in_use_count = 0; goto alloc_lbuf_err; } - rx_ring->lbq_use_head = 0; - rx_ring->lbq_use_tail = 0; - rx_ring->lbq_free_head = 0; - rx_ring->lbq_free_tail = 0; lbq_buf_size = (qlge->mtu == ETHERMTU) ? LRG_BUF_NORMAL_SIZE : LRG_BUF_JUMBO_SIZE; @@ -1710,7 +1710,7 @@ return (DDI_SUCCESS); alloc_err: - + ql_free_rx_buffers(qlge); return (DDI_FAILURE); } @@ -3189,11 +3189,13 @@ static void ql_free_phys(ddi_dma_handle_t *dma_handle, ddi_acc_handle_t *acc_handle) { - if (dma_handle != NULL) { + if (*dma_handle != NULL) { (void) ddi_dma_unbind_handle(*dma_handle); - if (acc_handle != NULL) + if (*acc_handle != NULL) ddi_dma_mem_free(acc_handle); ddi_dma_free_handle(dma_handle); + *acc_handle = NULL; + *dma_handle = NULL; } } @@ -3319,9 +3321,11 @@ struct tx_ring_desc *tx_ring_desc; int i, j; - ql_free_phys(&tx_ring->wq_dma.dma_handle, &tx_ring->wq_dma.acc_handle); - bzero(&tx_ring->wq_dma, sizeof (tx_ring->wq_dma)); - + if (tx_ring->wq_dma.dma_handle != NULL) { + ql_free_phys(&tx_ring->wq_dma.dma_handle, + &tx_ring->wq_dma.acc_handle); + bzero(&tx_ring->wq_dma, sizeof (tx_ring->wq_dma)); + } if (tx_ring->wq_desc != NULL) { tx_ring_desc = tx_ring->wq_desc; for (i = 0; i < tx_ring->wq_len; i++, tx_ring_desc++) { @@ -3417,7 +3421,7 @@ cmn_err(CE_WARN, "%s(%d): reqQ tx buf &" "oal alloc failed.", __func__, qlge->instance); - return (DDI_FAILURE); + goto err; } tx_ring_desc->oal = tx_ring_desc->oal_dma.vaddr; @@ -3436,10 +3440,14 @@ DDI_DMA_DONTWAIT, 0, &tx_ring_desc->tx_dma_handle[j]) != DDI_SUCCESS) { + tx_ring_desc->tx_dma_handle[j] = NULL; cmn_err(CE_WARN, "!%s: ddi_dma_alloc_handle: " "tx_dma_handle " "alloc failed", __func__); + ql_free_phys( + &tx_ring_desc->oal_dma.dma_handle, + &tx_ring_desc->oal_dma.acc_handle); goto err; } } @@ -3457,7 +3465,7 @@ bzero(&tx_ring->wqicb_dma, sizeof (tx_ring->wqicb_dma)); cmn_err(CE_WARN, "%s(%d): wqicb allocation failed.", __func__, qlge->instance); - return (DDI_FAILURE); + goto err; } tx_ring->wqicb_dma.dma_addr = dma_cookie.dmac_laddress; @@ -3482,9 +3490,11 @@ } /* Free the small buffer queue control blocks. */ - kmem_free(rx_ring->sbq_desc, rx_ring->sbq_len * - sizeof (struct bq_desc)); - rx_ring->sbq_desc = NULL; + if (rx_ring->sbq_desc != NULL) { + kmem_free(rx_ring->sbq_desc, rx_ring->sbq_len * + sizeof (struct bq_desc)); + rx_ring->sbq_desc = NULL; + } /* Free the large buffer queue. */ if (rx_ring->lbq_dma.dma_handle) { @@ -3494,9 +3504,11 @@ } /* Free the large buffer queue control blocks. */ - kmem_free(rx_ring->lbq_desc, rx_ring->lbq_len * - sizeof (struct bq_desc)); - rx_ring->lbq_desc = NULL; + if (rx_ring->lbq_desc != NULL) { + kmem_free(rx_ring->lbq_desc, rx_ring->lbq_len * + sizeof (struct bq_desc)); + rx_ring->lbq_desc = NULL; + } /* Free cqicb struct */ if (rx_ring->cqicb_dma.dma_handle) { @@ -3616,7 +3628,7 @@ bzero(&rx_ring->cqicb_dma, sizeof (rx_ring->cqicb_dma)); cmn_err(CE_WARN, "%s(%d): cqicb allocation failed.", __func__, qlge->instance); - return (DDI_FAILURE); + goto err_mem; } rx_ring->cqicb_dma.dma_addr = dma_cookie.dmac_laddress; @@ -3709,13 +3721,14 @@ bzero(&qlge->ricb_dma, sizeof (qlge->ricb_dma)); cmn_err(CE_WARN, "%s(%d): ricb allocation failed.", __func__, qlge->instance); - return (DDI_FAILURE); + goto err_mem; } qlge->ricb_dma.dma_addr = dma_cookie.dmac_laddress; return (DDI_SUCCESS); err_mem: + ql_free_mem_resources(qlge); return (DDI_FAILURE); } @@ -3758,6 +3771,7 @@ dma_handle) != DDI_SUCCESS) { cmn_err(CE_WARN, QL_BANG "%s: ddi_dma_alloc_handle FAILED", __func__); + *dma_handle = NULL; return (QL_ERROR); } /* @@ -3769,6 +3783,8 @@ NULL, vaddr, &rlen, acc_handle) != DDI_SUCCESS) { cmn_err(CE_WARN, "alloc_phys: DMA Memory alloc Failed"); ddi_dma_free_handle(dma_handle); + *acc_handle = NULL; + *dma_handle = NULL; return (QL_ERROR); } @@ -3780,6 +3796,8 @@ ddi_dma_free_handle(dma_handle); cmn_err(CE_WARN, "%s ddi_dma_addr_bind_handle FAILED", __func__); + *acc_handle = NULL; + *dma_handle = NULL; return (QL_ERROR); } @@ -3834,6 +3852,7 @@ dma_handle) != DDI_SUCCESS) { cmn_err(CE_WARN, QL_BANG "%s: ddi_dma_alloc_handle FAILED", __func__); + *dma_handle = NULL; return (QL_ERROR); } /* @@ -3845,6 +3864,8 @@ NULL, vaddr, &rlen, acc_handle) != DDI_SUCCESS) { cmn_err(CE_WARN, "alloc_phys: DMA Memory alloc Failed"); ddi_dma_free_handle(dma_handle); + *acc_handle = NULL; + *dma_handle = NULL; return (QL_ERROR); } @@ -3852,10 +3873,11 @@ dma_flags, DDI_DMA_DONTWAIT, NULL, dma_cookie, &cnt) != DDI_DMA_MAPPED) { ddi_dma_mem_free(acc_handle); - ddi_dma_free_handle(dma_handle); cmn_err(CE_WARN, "%s ddi_dma_addr_bind_handle FAILED", __func__); + *acc_handle = NULL; + *dma_handle = NULL; return (QL_ERROR); } @@ -4462,7 +4484,7 @@ qlge->sequence &= ~INIT_PCI_CONFIG_SETUP; } - if (qlge->sequence & INIT_ADD_INTERRUPT) { + if (qlge->sequence & INIT_INTR_ALLOC) { ql_free_irq_vectors(qlge); qlge->sequence &= ~INIT_ADD_INTERRUPT; } @@ -6862,7 +6884,7 @@ } /* Initialize the frame-to-queue routing. */ -static int +int ql_route_initialize(qlge_t *qlge) { int status = 0; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c --- a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c Thu Sep 09 11:46:43 2010 -0400 @@ -1478,6 +1478,7 @@ { normal, "normal", QLGE_LOOP_NONE }, { internal, "parallel", QLGE_LOOP_INTERNAL_PARALLEL }, { internal, "serial", QLGE_LOOP_INTERNAL_SERIAL }, + { external, "phy", QLGE_LOOP_EXTERNAL_PHY } }; /* @@ -1502,6 +1503,7 @@ case QLGE_LOOP_NONE: case QLGE_LOOP_INTERNAL_PARALLEL: case QLGE_LOOP_INTERNAL_SERIAL: + case QLGE_LOOP_EXTERNAL_PHY: break; } @@ -1512,6 +1514,13 @@ mutex_enter(&qlge->mbx_mutex); (void) ql_set_loop_back_mode(qlge); mutex_exit(&qlge->mbx_mutex); + /* if loopback mode test is done */ + if (mode == QLGE_LOOP_NONE) { + mutex_enter(&qlge->hw_mutex); + (void) ql_route_initialize(qlge); + mutex_exit(&qlge->hw_mutex); + } + return (IOC_REPLY); } /* diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c --- a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c Thu Sep 09 11:46:43 2010 -0400 @@ -981,6 +981,8 @@ qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_PARALLEL; else if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_SERIAL) qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_SERIAL; + else if (qlge->loop_back_mode == QLGE_LOOP_EXTERNAL_PHY) + qlge->port_cfg_info.link_cfg |= LOOP_EXTERNAL_PHY; return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info)); diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/os/dumpsubr.c --- a/usr/src/uts/common/os/dumpsubr.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/os/dumpsubr.c Thu Sep 09 11:46:43 2010 -0400 @@ -412,7 +412,6 @@ char *maxvm; /* reserved VM for spare pages */ lock_t helper_lock; /* protect helper state */ char helpers_wanted; /* flag to enable parallelism */ - char helper_present; /* at least one helper showed up */ } dumpcfg_t; static dumpcfg_t dumpcfg; /* config vars */ @@ -883,15 +882,10 @@ int k; /* - * Fall back to doing a serial dump if no helpers showed - * up. It is possible for other CPUs to be stuck in PROM, or - * DRd out. panic("sync initiated") in sync_handler() is one - * case. A parallel dump will hang (dump time out) unless - * there is at least one helper CPU. At this point dumpsys() - * has done some I/O, which means there has been plenty of - * time for helpers to arrive. + * Setting dump_plat_mincpu to 0 at any time forces a serial + * dump. */ - if (!cfg->helper_present) { + if (dump_plat_mincpu == 0) { cfg->clevel = 0; return; } @@ -2189,8 +2183,6 @@ void dumpsys_helper() { - if (!dumpcfg.helper_present) - dumpcfg.helper_present = 1; dumpsys_spinlock(&dumpcfg.helper_lock); if (dumpcfg.helpers_wanted) { helper_t *hp, *hpend = &dumpcfg.helper[dumpcfg.nhelper]; @@ -2229,8 +2221,6 @@ void dumpsys_helper_nw() { - if (!dumpcfg.helper_present) - dumpcfg.helper_present = 1; if (dumpcfg.helpers_wanted) dumpsys_helper(); } @@ -2295,7 +2285,29 @@ cbuf_t *cp; pgcnt_t baseoff, pfnoff; pfn_t base, pfn; - int sec; + int sec, i, dumpserial; + + /* + * Fall back to serial mode if there are no helpers. + * dump_plat_mincpu can be set to 0 at any time. + * dumpcfg.helpermap must contain at least one member. + */ + dumpserial = 1; + + if (dump_plat_mincpu != 0 && dumpcfg.clevel != 0) { + for (i = 0; i < BT_BITOUL(NCPU); ++i) { + if (dumpcfg.helpermap[i] != 0) { + dumpserial = 0; + break; + } + } + } + + if (dumpserial) { + dumpcfg.clevel = 0; + if (dumpcfg.helper[0].lzbuf == NULL) + dumpcfg.helper[0].lzbuf = dumpcfg.helper[1].page; + } dump_init_memlist_walker(&mlw); @@ -2430,7 +2442,7 @@ * If there are no helpers the main task does * non-streams lzjb compress. */ - if (dumpcfg.clevel == 0) { + if (dumpserial) { dumpsys_lzjb_page(dumpcfg.helper, cp); break; } diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/smbsrv/smb_ioctl.h --- a/usr/src/uts/common/smbsrv/smb_ioctl.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/smbsrv/smb_ioctl.h Thu Sep 09 11:46:43 2010 -0400 @@ -39,21 +39,17 @@ #define SMB_IOC_CONFIG _IOW(SMB_IOC_BASE, 1, int) #define SMB_IOC_START _IOW(SMB_IOC_BASE, 2, int) -#define SMB_IOC_NBT_LISTEN _IOW(SMB_IOC_BASE, 3, int) -#define SMB_IOC_TCP_LISTEN _IOW(SMB_IOC_BASE, 4, int) -#define SMB_IOC_NBT_RECEIVE _IOW(SMB_IOC_BASE, 5, int) -#define SMB_IOC_TCP_RECEIVE _IOW(SMB_IOC_BASE, 6, int) -#define SMB_IOC_GMTOFF _IOW(SMB_IOC_BASE, 7, int) -#define SMB_IOC_SHARE _IOW(SMB_IOC_BASE, 8, int) -#define SMB_IOC_UNSHARE _IOW(SMB_IOC_BASE, 9, int) -#define SMB_IOC_NUMOPEN _IOW(SMB_IOC_BASE, 10, int) -#define SMB_IOC_SVCENUM _IOW(SMB_IOC_BASE, 11, int) -#define SMB_IOC_FILE_CLOSE _IOW(SMB_IOC_BASE, 12, int) -#define SMB_IOC_SESSION_CLOSE _IOW(SMB_IOC_BASE, 13, int) -#define SMB_IOC_STOP _IOW(SMB_IOC_BASE, 14, int) -#define SMB_IOC_EVENT _IOW(SMB_IOC_BASE, 15, int) -#define SMB_IOC_SHAREINFO _IOW(SMB_IOC_BASE, 16, int) -#define SMB_IOC_SPOOLDOC _IOW(SMB_IOC_BASE, 17, int) +#define SMB_IOC_GMTOFF _IOW(SMB_IOC_BASE, 3, int) +#define SMB_IOC_SHARE _IOW(SMB_IOC_BASE, 4, int) +#define SMB_IOC_UNSHARE _IOW(SMB_IOC_BASE, 5, int) +#define SMB_IOC_NUMOPEN _IOW(SMB_IOC_BASE, 6, int) +#define SMB_IOC_SVCENUM _IOW(SMB_IOC_BASE, 7, int) +#define SMB_IOC_FILE_CLOSE _IOW(SMB_IOC_BASE, 8, int) +#define SMB_IOC_SESSION_CLOSE _IOW(SMB_IOC_BASE, 9, int) +#define SMB_IOC_STOP _IOW(SMB_IOC_BASE, 10, int) +#define SMB_IOC_EVENT _IOW(SMB_IOC_BASE, 11, int) +#define SMB_IOC_SHAREINFO _IOW(SMB_IOC_BASE, 12, int) +#define SMB_IOC_SPOOLDOC _IOW(SMB_IOC_BASE, 13, int) typedef struct smb_ioc_header { uint32_t version; @@ -87,11 +83,6 @@ uint32_t shortnames; } smb_ioc_shareinfo_t; -typedef struct smb_ioc_listen { - smb_ioc_header_t hdr; - int error; -} smb_ioc_listen_t; - typedef struct smb_ioc_start { smb_ioc_header_t hdr; int opipe; @@ -181,7 +172,6 @@ smb_ioc_cfg_t ioc_cfg; smb_ioc_start_t ioc_start; smb_ioc_event_t ioc_event; - smb_ioc_listen_t ioc_listen; smb_ioc_opennum_t ioc_opennum; smb_ioc_svcenum_t ioc_svcenum; smb_ioc_session_t ioc_session; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/smbsrv/smb_kproto.h --- a/usr/src/uts/common/smbsrv/smb_kproto.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/smbsrv/smb_kproto.h Thu Sep 09 11:46:43 2010 -0400 @@ -367,10 +367,6 @@ boolean_t smb_server_is_stopping(void); int smb_server_cancel_event(uint32_t); int smb_server_notify_event(smb_ioc_event_t *); -int smb_server_nbt_listen(smb_ioc_listen_t *); -int smb_server_tcp_listen(smb_ioc_listen_t *); -int smb_server_nbt_receive(void); -int smb_server_tcp_receive(void); uint32_t smb_server_get_session_count(void); int smb_server_set_gmtoff(smb_ioc_gmt_t *); int smb_server_numopen(smb_ioc_opennum_t *); @@ -514,28 +510,22 @@ * session functions (file smb_session.c) */ smb_session_t *smb_session_create(ksocket_t, uint16_t, smb_server_t *, int); -int smb_session_daemon(smb_session_list_t *); -void smb_session_reconnection_check(smb_session_list_t *, smb_session_t *); -void smb_session_timers(smb_session_list_t *); +void smb_session_receiver(smb_session_t *); +void smb_session_disconnect(smb_session_t *); +void smb_session_reconnection_check(smb_llist_t *, smb_session_t *); +void smb_session_timers(smb_llist_t *); void smb_session_delete(smb_session_t *session); void smb_session_cancel_requests(smb_session_t *, smb_tree_t *, smb_request_t *); void smb_session_config(smb_session_t *session); -void smb_session_disconnect_from_share(smb_session_list_t *, char *); -void smb_session_list_constructor(smb_session_list_t *); -void smb_session_list_destructor(smb_session_list_t *); -void smb_session_list_append(smb_session_list_t *, smb_session_t *); -void smb_session_list_delete_tail(smb_session_list_t *); -smb_session_t *smb_session_list_activate_head(smb_session_list_t *); -void smb_session_list_terminate(smb_session_list_t *, smb_session_t *); -void smb_session_list_signal(smb_session_list_t *); +void smb_session_disconnect_from_share(smb_llist_t *, char *); smb_user_t *smb_session_dup_user(smb_session_t *, char *, char *); smb_user_t *smb_session_lookup_uid(smb_session_t *, uint16_t); void smb_session_post_user(smb_session_t *, smb_user_t *); void smb_session_disconnect_share(smb_session_t *, const char *); void smb_session_getclient(smb_session_t *, char *, size_t); boolean_t smb_session_isclient(smb_session_t *, const char *); -void smb_session_correct_keep_alive_values(smb_session_list_t *, uint32_t); +void smb_session_correct_keep_alive_values(smb_llist_t *, uint32_t); void smb_session_oplock_break(smb_session_t *, uint16_t, uint16_t, uint8_t); int smb_session_send(smb_session_t *, uint8_t type, mbuf_chain_t *); int smb_session_xprt_gethdr(smb_session_t *, smb_xprt_t *); @@ -745,8 +735,7 @@ krw_t smb_rwx_rwupgrade(smb_rwx_t *rwx); void smb_rwx_rwdowngrade(smb_rwx_t *rwx, krw_t mode); -void smb_thread_init(smb_thread_t *, char *, smb_thread_ep_t, void *, - smb_thread_aw_t, void *); +void smb_thread_init(smb_thread_t *, char *, smb_thread_ep_t, void *); void smb_thread_destroy(smb_thread_t *); int smb_thread_start(smb_thread_t *); void smb_thread_stop(smb_thread_t *); @@ -754,7 +743,6 @@ boolean_t smb_thread_continue(smb_thread_t *); boolean_t smb_thread_continue_nowait(smb_thread_t *); boolean_t smb_thread_continue_timedwait(smb_thread_t *, int /* seconds */); -void smb_thread_set_awaken(smb_thread_t *, smb_thread_aw_t, void *); uint32_t smb_denymode_to_sharemode(uint32_t desired_access, char *fname); uint32_t smb_ofun_to_crdisposition(uint16_t ofun); diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/smbsrv/smb_ktypes.h --- a/usr/src/uts/common/smbsrv/smb_ktypes.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/smbsrv/smb_ktypes.h Thu Sep 09 11:46:43 2010 -0400 @@ -238,13 +238,6 @@ * Transition T5 * * This transition is executed in smb_thread_destroy(). - * - * Comments - * -------- - * - * The field smb_thread_aw_t contains a function pointer that knows how to - * awake the thread. It is a temporary solution to work around the fact that - * kernel threads (not part of a userspace process) cannot be signaled. */ typedef enum smb_thread_state { SMB_THREAD_STATE_STARTING = 0, @@ -256,7 +249,6 @@ struct _smb_thread; typedef void (*smb_thread_ep_t)(struct _smb_thread *, void *ep_arg); -typedef void (*smb_thread_aw_t)(struct _smb_thread *, void *aw_arg); #define SMB_THREAD_MAGIC 0x534D4254 /* SMBT */ @@ -268,8 +260,6 @@ kt_did_t sth_did; smb_thread_ep_t sth_ep; void *sth_ep_arg; - smb_thread_aw_t sth_aw; - void *sth_aw_arg; boolean_t sth_kill; kmutex_t sth_mtx; kcondvar_t sth_cv; @@ -453,19 +443,6 @@ smb_avl_nops_t *avl_nops; } smb_avl_t; -typedef struct smb_session_list { - krwlock_t se_lock; - uint64_t se_wrop; - struct { - list_t lst; - uint32_t count; - } se_rdy; - struct { - list_t lst; - uint32_t count; - } se_act; -} smb_session_list_t; - typedef struct { kcondvar_t rwx_cv; kmutex_t rwx_mutex; @@ -1806,13 +1783,20 @@ #define SMB_SERVER_VALID(s) \ ASSERT(((s) != NULL) && ((s)->sv_magic == SMB_SERVER_MAGIC)) +#define SMB_LISTENER_MAGIC 0x4C53544E /* 'LSTN' */ +#define SMB_LISTENER_VALID(ld) \ + ASSERT(((ld) != NULL) && ((ld)->ld_magic == SMB_LISTENER_MAGIC)) + typedef struct { - kthread_t *ld_kth; - kt_did_t ld_ktdid; + uint32_t ld_magic; + struct smb_server *ld_sv; + smb_thread_t ld_thread; ksocket_t ld_so; + in_port_t ld_port; + int ld_family; struct sockaddr_in ld_sin; struct sockaddr_in6 ld_sin6; - smb_session_list_t ld_session_list; + smb_llist_t ld_session_list; } smb_listener_daemon_t; #define SMB_SSETUP_CMD "authentication" @@ -1881,7 +1865,8 @@ smb_thread_t si_thread_timers; - taskq_t *sv_thread_pool; + taskq_t *sv_worker_pool; + taskq_t *sv_receiver_pool; kmem_cache_t *si_cache_request; kmem_cache_t *si_cache_session; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_config.h --- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_config.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_config.h Thu Sep 09 11:46:43 2010 -0400 @@ -283,10 +283,10 @@ /* CFG_FW_CHECK */ {"fw-check", - 0, 2, 1, 0, - PARM_DYNAMIC_RESET | PARM_BOOLEAN | PARM_HIDDEN, - "Enables firmware revision checking of adapters. " - "[0=Off 1=Sun-only 2=All]"}, + 0, 7, 1, 0, + PARM_DYNAMIC_RESET | PARM_HEX | PARM_HIDDEN, + "Enables firmware revision checking. " + "[0=Off 1=Sun-only 2=All 4=kern-update]"}, /* CFG_TRI_REQUIRED */ {"tri-required", diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h --- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h Thu Sep 09 11:46:43 2010 -0400 @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Emulex. All rights reserved. + * Copyright 2010 Emulex. All rights reserved. * Use is subject to license terms. */ @@ -170,8 +170,7 @@ extern uint32_t emlxs_get_instance(int32_t ddiinst); extern char *emlxs_mscmd_xlate(uint16_t cmd); -extern int32_t emlxs_reset(opaque_t fca_port_handle, - uint32_t cmd); +extern int32_t emlxs_reset(emlxs_port_t *port, uint32_t cmd); extern void emlxs_swap_service_params(SERV_PARM *sp); extern void emlxs_swap_fcp_pkt(emlxs_buf_t *sbp); extern void emlxs_swap_ct_pkt(emlxs_buf_t *sbp); diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h --- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h Thu Sep 09 11:46:43 2010 -0400 @@ -1813,6 +1813,11 @@ #define FC_LINKDOWN_MASK 0xFFF30C1F /* Bits to protect during */ /* a linkdown */ + uint32_t fw_timer; + uint32_t fw_flag; +#define FW_UPDATE_NEEDED 0x00000001 +#define FW_UPDATE_KERNEL 0x00000002 + uint32_t temperature; /* Last reported temperature */ /* SBUS adapter management */ diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_hw.h --- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_hw.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_hw.h Thu Sep 09 11:46:43 2010 -0400 @@ -2261,6 +2261,7 @@ uint32_t image_size; uint32_t block_size; uint32_t block_crc; + uint32_t load_address; char label[BE_VERSION_SIZE]; } emlxs_be_fw_file_t; diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_mbox.h --- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_mbox.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_mbox.h Thu Sep 09 11:46:43 2010 -0400 @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Emulex. All rights reserved. + * Copyright 2010 Emulex. All rights reserved. * Use is subject to license terms. */ @@ -391,7 +391,8 @@ typedef struct { #ifdef EMLXS_BIG_ENDIAN - uint32_t rsvd2:25; + uint32_t rsvd2:24; + uint32_t keep:1; uint32_t acknowledgment:1; uint32_t version:1; uint32_t erase_or_prog:1; @@ -408,7 +409,8 @@ uint32_t erase_or_prog:1; uint32_t version:1; uint32_t acknowledgment:1; - uint32_t rsvd2:25; + uint32_t keep:1; + uint32_t rsvd2:24; #endif #define DL_FROM_BDE 0 /* method */ @@ -3685,7 +3687,7 @@ #define PROG_DESCR_STR_LEN 24 -#define MAX_LOAD_ENTRY 10 +#define MAX_LOAD_ENTRY 32 typedef struct { diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_messages.h --- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_messages.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_messages.h Thu Sep 09 11:46:43 2010 -0400 @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Emulex. All rights reserved. + * Copyright 2010 Emulex. All rights reserved. * Use is subject to license terms. */ @@ -1733,6 +1733,20 @@ NULL, \ 0) + DEFINE_MSG(1540, \ + emlxs_fw_update_msg, \ + "Firmware update required.", \ + EMLXS_WARNING, \ + MSG_FIRMWARE, \ + "This indicates that a firmware update is required on the " \ + "adapter.", \ + "The user must perform a manual adapter reset or link reset" \ + "once the host environment is stable to trigger an automatic" \ + "firmware download. DO NOT POWER CYCLE OR REBOOT THE SYSTEM" \ + "DURING THE DOWNLOAD OPERATION.", \ + NULL, \ + 0) + /* GROUP: CT 1600 - 1699 */ DEFINE_MSG(1600, \ diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h --- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h Thu Sep 09 11:46:43 2010 -0400 @@ -31,11 +31,11 @@ extern "C" { #endif -#define EMLXS_VERSION "2.50o" -#define EMLXS_DATE_MINUTE "45" /* 00-59 */ -#define EMLXS_DATE_HOUR "09" /* 00-23 */ -#define EMLXS_DATE_DAY "08" /* 00-31 */ -#define EMLXS_DATE_MONTH "01" /* 01-12 */ +#define EMLXS_VERSION "2.50q" +#define EMLXS_DATE_MINUTE "00" /* 00-59 */ +#define EMLXS_DATE_HOUR "17" /* 00-23 */ +#define EMLXS_DATE_DAY "30" /* 00-31 */ +#define EMLXS_DATE_MONTH "07" /* 01-12 */ #define EMLXS_DATE_YEAR "2010" /* YYYY */ #define EMLXS_REVISION EMLXS_DATE_YEAR "." EMLXS_DATE_MONTH "." \ diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h --- a/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h Thu Sep 09 11:46:43 2010 -0400 @@ -876,6 +876,7 @@ extern void ql_atomic_set_32(volatile uint32_t *target, uint32_t newval); extern uint32_t ql_atomic_read_32(volatile uint32_t *target); extern void ql_restart_timer(qlge_t *qlge); +extern int ql_route_initialize(qlge_t *); /* * Global Function Prototypes in qlge_flash.c source file. */ diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h --- a/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h Thu Sep 09 11:46:43 2010 -0400 @@ -31,7 +31,7 @@ #endif #ifndef VERSIONSTR -#define VERSIONSTR "100429-v1.05" +#define VERSIONSTR "100721-v1.07" #endif #ifndef QL_DEBUG diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/sys/vfs.h --- a/usr/src/uts/common/sys/vfs.h Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/sys/vfs.h Thu Sep 09 11:46:43 2010 -0400 @@ -494,6 +494,7 @@ /* VFS feature routines */ void vfs_set_feature(vfs_t *, vfs_feature_t); +void vfs_clear_feature(vfs_t *, vfs_feature_t); int vfs_has_feature(vfs_t *, vfs_feature_t); void vfs_propagate_features(vfs_t *, vfs_t *); diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/common/vm/seg_kmem.c --- a/usr/src/uts/common/vm/seg_kmem.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/common/vm/seg_kmem.c Thu Sep 09 11:46:43 2010 -0400 @@ -1519,8 +1519,13 @@ ASSERT(zio_mem_base != NULL); ASSERT(zio_mem_size != 0); + /* + * To reduce VA space fragmentation, we set up quantum caches for the + * smaller sizes; we chose 32k because that translates to 128k VA + * slabs, which matches nicely with the common 128k zio_data bufs. + */ zio_arena = vmem_create("zfs_file_data", zio_mem_base, zio_mem_size, - PAGESIZE, NULL, NULL, NULL, 0, VM_SLEEP); + PAGESIZE, NULL, NULL, NULL, 32 * 1024, VM_SLEEP); zio_alloc_arena = vmem_create("zfs_file_data_buf", NULL, 0, PAGESIZE, segkmem_zio_alloc, segkmem_zio_free, zio_arena, 0, VM_SLEEP); diff -r 5f6c3c121560 -r 88e527ca878f usr/src/uts/sun4/os/startup.c --- a/usr/src/uts/sun4/os/startup.c Fri Sep 03 23:10:16 2010 +0200 +++ b/usr/src/uts/sun4/os/startup.c Thu Sep 09 11:46:43 2010 -0400 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -626,6 +627,11 @@ } /* + * Force a serial dump, since there are no CPUs to help. + */ + dump_plat_mincpu = 0; + + /* * We've managed to get here without going through the * normal panic code path. Try and save some useful * information.