diff options
Diffstat (limited to 'usr/src/uts/common/io/strplumb.c')
| -rw-r--r-- | usr/src/uts/common/io/strplumb.c | 275 |
1 files changed, 14 insertions, 261 deletions
diff --git a/usr/src/uts/common/io/strplumb.c b/usr/src/uts/common/io/strplumb.c index 644d83c352..6f20d98a5a 100644 --- a/usr/src/uts/common/io/strplumb.c +++ b/usr/src/uts/common/io/strplumb.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -626,12 +626,8 @@ done: static uchar_t boot_macaddr[16]; static int boot_maclen; -static uchar_t *getmacaddr(dev_info_t *dip, int *maclen); +static uchar_t *getmacaddr(dev_info_t *dip, size_t *maclenp); static int matchmac(dev_info_t *dip, void *arg); -int dl_attach(ldi_handle_t lh, int unit); -int dl_bind(ldi_handle_t lh, uint_t sap, uint_t max_conn, - uint_t service, uint_t conn_mgmt); -int dl_phys_addr(ldi_handle_t lh, struct ether_addr *eaddr); #endif /* !_OBP */ @@ -705,7 +701,7 @@ matchmac(dev_info_t *dip, void *arg) char **devpathp = (char **)arg; char *model_str; uchar_t *macaddr; - int maclen; + size_t maclen; /* XXX Should use "device-type" per IEEE 1275 */ if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, @@ -750,40 +746,15 @@ matchmac(dev_info_t *dip, void *arg) } static uchar_t * -getmacaddr_gldv3(char *drv, int inst, int *maclenp) -{ - char ifname[16]; - mac_handle_t mh; - uchar_t *macaddr; - - (void) snprintf(ifname, sizeof (ifname), "%s%d", drv, inst); - if (mac_open(ifname, &mh) < 0) { - return (NULL); - } - *maclenp = sizeof (struct ether_addr); - macaddr = kmem_alloc(*maclenp, KM_SLEEP); - mac_unicst_get(mh, macaddr); - mac_close(mh); - - return (macaddr); -} - -static uchar_t * -getmacaddr(dev_info_t *dip, int *maclenp) +getmacaddr(dev_info_t *dip, size_t *maclenp) { int rc, ppa; ldi_ident_t li; ldi_handle_t lh; - char *drv_name = (char *)ddi_driver_name(dip); + const char *drv_name = ddi_driver_name(dip); char *clonepath; uchar_t *macaddr = NULL; - /* a simpler way to get mac address for GLDv3 drivers */ - if (GLDV3_DRV(ddi_name_to_major(drv_name))) { - return (getmacaddr_gldv3(drv_name, ddi_get_instance(dip), - maclenp)); - } - if (rc = ldi_ident_from_mod(&modlinkage, &li)) { cmn_err(CE_WARN, "getmacaddr: ldi_ident_from_mod failed: %d\n", rc); @@ -806,245 +777,27 @@ getmacaddr(dev_info_t *dip, int *maclenp) kmem_free(clonepath, MAXPATHLEN); ppa = i_ddi_devi_get_ppa(dip); - if ((dl_attach(lh, ppa) != 0) || - (dl_bind(lh, ETHERTYPE_IP, 0, DL_CLDLS, 0) != 0)) { + if ((dl_attach(lh, ppa, NULL) != 0) || + (dl_bind(lh, ETHERTYPE_IP, NULL) != 0)) { (void) ldi_close(lh, FREAD|FWRITE, CRED()); cmn_err(CE_WARN, "getmacaddr: dl_attach/bind(%s%d) failed: %d\n", drv_name, ppa, rc); return (NULL); } - *maclenp = sizeof (struct ether_addr); - macaddr = kmem_alloc(*maclenp, KM_SLEEP); - if (dl_phys_addr(lh, (struct ether_addr *)macaddr) != 0) { - kmem_free(macaddr, *maclenp); + + *maclenp = ETHERADDRL; + macaddr = kmem_alloc(ETHERADDRL, KM_SLEEP); + if (dl_phys_addr(lh, macaddr, maclenp, NULL) != 0 || + *maclenp != ETHERADDRL) { + kmem_free(macaddr, ETHERADDRL); macaddr = NULL; *maclenp = 0; cmn_err(CE_WARN, - "getmacaddr: dl_macaddr(%s%d) failed: %d\n", + "getmacaddr: dl_phys_addr(%s%d) failed: %d\n", drv_name, ppa, rc); } (void) ldi_close(lh, FREAD|FWRITE, CRED()); return (macaddr); } - #endif /* !_OBP */ - -int -dl_attach(ldi_handle_t lh, int unit) -{ - dl_attach_req_t *attach_req; - union DL_primitives *dl_prim; - mblk_t *mp; - int error; - - if ((mp = allocb(sizeof (dl_attach_req_t), BPRI_MED)) == NULL) { - cmn_err(CE_WARN, "dl_attach: allocb failed"); - return (ENOSR); - } - mp->b_datap->db_type = M_PROTO; - mp->b_wptr += sizeof (dl_attach_req_t); - - attach_req = (dl_attach_req_t *)mp->b_rptr; - attach_req->dl_primitive = DL_ATTACH_REQ; - attach_req->dl_ppa = unit; - - (void) ldi_putmsg(lh, mp); - if ((error = ldi_getmsg(lh, &mp, (timestruc_t *)NULL)) != 0) { - cmn_err(CE_NOTE, "!dl_attach: ldi_getmsg failed: %d", error); - return (error); - } - - dl_prim = (union DL_primitives *)mp->b_rptr; - switch (dl_prim->dl_primitive) { - case DL_OK_ACK: - if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_ok_ack_t)) { - cmn_err(CE_NOTE, - "!dl_attach: DL_OK_ACK protocol error"); - break; - } - if (((dl_ok_ack_t *)dl_prim)->dl_correct_primitive != - DL_ATTACH_REQ) { - cmn_err(CE_NOTE, "!dl_attach: DL_OK_ACK rtnd prim %u", - ((dl_ok_ack_t *)dl_prim)->dl_correct_primitive); - break; - } - freemsg(mp); - return (0); - - case DL_ERROR_ACK: - if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_error_ack_t)) { - cmn_err(CE_NOTE, - "!dl_attach: DL_ERROR_ACK protocol error"); - break; - } - break; - - default: - cmn_err(CE_NOTE, "!dl_attach: bad ACK header %u", - dl_prim->dl_primitive); - break; - } - - /* - * Error return only. - */ - freemsg(mp); - return (-1); -} - -int -dl_bind(ldi_handle_t lh, uint_t sap, uint_t max_conn, uint_t service, - uint_t conn_mgmt) -{ - dl_bind_req_t *bind_req; - union DL_primitives *dl_prim; - mblk_t *mp; - int error; - - if ((mp = allocb(sizeof (dl_bind_req_t), BPRI_MED)) == NULL) { - cmn_err(CE_WARN, "dl_bind: allocb failed"); - return (ENOSR); - } - mp->b_datap->db_type = M_PROTO; - - bind_req = (dl_bind_req_t *)mp->b_wptr; - mp->b_wptr += sizeof (dl_bind_req_t); - bind_req->dl_primitive = DL_BIND_REQ; - bind_req->dl_sap = sap; - bind_req->dl_max_conind = max_conn; - bind_req->dl_service_mode = service; - bind_req->dl_conn_mgmt = conn_mgmt; - bind_req->dl_xidtest_flg = 0; - - (void) ldi_putmsg(lh, mp); - if ((error = ldi_getmsg(lh, &mp, (timestruc_t *)NULL)) != 0) { - cmn_err(CE_NOTE, "!dl_bind: ldi_getmsg failed: %d", error); - return (error); - } - - dl_prim = (union DL_primitives *)mp->b_rptr; - switch (dl_prim->dl_primitive) { - case DL_BIND_ACK: - if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_bind_ack_t)) { - cmn_err(CE_NOTE, - "!dl_bind: DL_BIND_ACK protocol error"); - break; - } - if (((dl_bind_ack_t *)dl_prim)->dl_sap != sap) { - cmn_err(CE_NOTE, "!dl_bind: DL_BIND_ACK bad sap %u", - ((dl_bind_ack_t *)dl_prim)->dl_sap); - break; - } - freemsg(mp); - return (0); - - case DL_ERROR_ACK: - if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_error_ack_t)) { - cmn_err(CE_NOTE, - "!dl_bind: DL_ERROR_ACK protocol error"); - break; - } - break; - - default: - cmn_err(CE_NOTE, "!dl_bind: bad ACK header %u", - dl_prim->dl_primitive); - break; - } - - /* - * Error return only. - */ - freemsg(mp); - return (-1); -} - -int -dl_phys_addr(ldi_handle_t lh, struct ether_addr *eaddr) -{ - dl_phys_addr_req_t *phys_addr_req; - dl_phys_addr_ack_t *phys_addr_ack; - union DL_primitives *dl_prim; - mblk_t *mp; - int error; - uchar_t *addrp; - timestruc_t tv; - - if ((mp = allocb(sizeof (dl_phys_addr_req_t), BPRI_MED)) == - (mblk_t *)NULL) { - cmn_err(CE_WARN, "dl_phys_addr: allocb failed"); - return (ENOSR); - } - mp->b_datap->db_type = M_PROTO; - mp->b_wptr += sizeof (dl_phys_addr_req_t); - - phys_addr_req = (dl_phys_addr_req_t *)mp->b_rptr; - phys_addr_req->dl_primitive = DL_PHYS_ADDR_REQ; - phys_addr_req->dl_addr_type = DL_CURR_PHYS_ADDR; - - /* - * In case some provider doesn't implement or nack the - * request just wait for 15 seconds. - */ - tv.tv_sec = 15; - tv.tv_nsec = 0; - - (void) ldi_putmsg(lh, mp); - error = ldi_getmsg(lh, &mp, &tv); - if (error == ETIME) { - cmn_err(CE_NOTE, "!dl_phys_addr: timed out"); - return (-1); - } else if (error != 0) { - cmn_err(CE_NOTE, "!dl_phys_addr: ldi_getmsg failed: %d", error); - return (error); - } - - dl_prim = (union DL_primitives *)mp->b_rptr; - switch (dl_prim->dl_primitive) { - case DL_PHYS_ADDR_ACK: - if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_phys_addr_ack_t)) { - cmn_err(CE_NOTE, "!dl_phys_addr: " - "DL_PHYS_ADDR_ACK protocol error"); - break; - } - phys_addr_ack = &dl_prim->physaddr_ack; - if (phys_addr_ack->dl_addr_length != sizeof (*eaddr)) { - cmn_err(CE_NOTE, - "!dl_phys_addr: DL_PHYS_ADDR_ACK bad len %u", - phys_addr_ack->dl_addr_length); - break; - } - if (phys_addr_ack->dl_addr_length + - phys_addr_ack->dl_addr_offset > (mp->b_wptr-mp->b_rptr)) { - cmn_err(CE_NOTE, - "!dl_phys_addr: DL_PHYS_ADDR_ACK bad len %u", - phys_addr_ack->dl_addr_length); - break; - } - addrp = mp->b_rptr + phys_addr_ack->dl_addr_offset; - bcopy(addrp, eaddr, sizeof (*eaddr)); - freemsg(mp); - return (0); - - case DL_ERROR_ACK: - if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_error_ack_t)) { - cmn_err(CE_NOTE, - "!dl_phys_addr: DL_ERROR_ACK protocol error"); - break; - } - - break; - - default: - cmn_err(CE_NOTE, "!dl_phys_addr: bad ACK header %u", - dl_prim->dl_primitive); - break; - } - - /* - * Error return only. - */ - freemsg(mp); - return (-1); -} |
