Author: sephe
Date: Thu Oct 13 06:39:06 2016
New Revision: 307185
URL: https://svnweb.freebsd.org/changeset/base/307185

Log:
  MFC 305049,305050
  
  305049
      hyperv/hn: Factor out func to exec RNDIS transaction w/o checking result
  
      It will be used by RNDIS HALT and RESET.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7685
  
  305050
      hyperv/hn: Switch to new RNDIS transaction execution for halt.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7686

Modified:
  stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c
  stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c
  stable/10/sys/dev/hyperv/netvsc/if_hnvar.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c        Thu Oct 13 06:34:18 
2016        (r307184)
+++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c        Thu Oct 13 06:39:06 
2016        (r307185)
@@ -73,8 +73,6 @@ static void hv_nv_on_receive(struct hn_s
 static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
     struct hn_softc *, struct vmbus_channel *chan,
     const void *, int);
-static void hn_nvs_sent_xact(struct hn_send_ctx *, struct hn_softc *sc,
-    struct vmbus_channel *, const void *, int);
 
 struct hn_send_ctx     hn_send_ctx_none =
     HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
@@ -654,7 +652,7 @@ hv_nv_on_device_remove(struct hn_softc *
        return (0);
 }
 
-static void
+void
 hn_nvs_sent_xact(struct hn_send_ctx *sndc,
     struct hn_softc *sc __unused, struct vmbus_channel *chan __unused,
     const void *data, int dlen)

Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c   Thu Oct 13 06:34:18 
2016        (r307184)
+++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c   Thu Oct 13 06:39:06 
2016        (r307185)
@@ -72,8 +72,6 @@ __FBSDID("$FreeBSD$");
 /*
  * Forward declarations
  */
-static int  hv_rf_send_request(rndis_device *device, rndis_request *request,
-                              uint32_t message_type);
 static void hv_rf_receive_response(rndis_device *device,
     const rndis_msg *response);
 static void hv_rf_receive_indicate_status(rndis_device *device,
@@ -84,12 +82,6 @@ static inline int hv_rf_query_device_mac
 static inline int hv_rf_query_device_link_status(rndis_device *device);
 static int  hv_rf_init_device(rndis_device *device);
 
-static void hn_rndis_sent_halt(struct hn_send_ctx *sndc,
-    struct hn_softc *sc, struct vmbus_channel *chan,
-    const void *data, int dlen);
-static void hn_rndis_sent_cb(struct hn_send_ctx *sndc,
-    struct hn_softc *sc, struct vmbus_channel *chan,
-    const void *data, int dlen);
 static int hn_rndis_query(struct hn_softc *sc, uint32_t oid,
     const void *idata, size_t idlen, void *odata, size_t *odlen0);
 static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data,
@@ -198,120 +190,6 @@ hv_put_rndis_device(rndis_device *device
 }
 
 /*
- *
- */
-static inline rndis_request *
-hv_rndis_request(rndis_device *device, uint32_t message_type,
-                uint32_t message_length)
-{
-       rndis_request *request;
-       rndis_msg *rndis_mesg;
-       rndis_set_request *set;
-
-       request = malloc(sizeof(rndis_request), M_NETVSC, M_WAITOK | M_ZERO);
-
-       sema_init(&request->wait_sema, 0, "rndis sema");
-       
-       rndis_mesg = &request->request_msg;
-       rndis_mesg->ndis_msg_type = message_type;
-       rndis_mesg->msg_len = message_length;
-
-       /*
-        * Set the request id. This field is always after the rndis header
-        * for request/response packet types so we just use the set_request
-        * as a template.
-        */
-       set = &rndis_mesg->msg.set_request;
-       set->request_id = atomic_fetchadd_int(&device->new_request_id, 1) &
-           HN_RNDIS_RID_COMPAT_MASK;
-
-       /* Add to the request list */
-       mtx_lock(&device->req_lock);
-       STAILQ_INSERT_TAIL(&device->myrequest_list, request, mylist_entry);
-       mtx_unlock(&device->req_lock);
-
-       return (request);
-}
-
-/*
- *
- */
-static inline void
-hv_put_rndis_request(rndis_device *device, rndis_request *request)
-{
-       mtx_lock(&device->req_lock);
-       /* Fixme:  Has O(n) performance */
-       /*
-        * XXXKYS: Use Doubly linked lists.
-        */
-       STAILQ_REMOVE(&device->myrequest_list, request, rndis_request_,
-           mylist_entry);
-       mtx_unlock(&device->req_lock);
-
-       sema_destroy(&request->wait_sema);
-       free(request, M_NETVSC);
-}
-
-/*
- *
- */
-static int
-hv_rf_send_request(rndis_device *device, rndis_request *request,
-    uint32_t message_type)
-{
-       struct hn_softc *sc = device->sc;
-       uint32_t send_buf_section_idx, tot_data_buf_len;
-       struct vmbus_gpa gpa[2];
-       int gpa_cnt, send_buf_section_size;
-       hn_sent_callback_t cb;
-
-       /* Set up the packet to send it */
-       tot_data_buf_len = request->request_msg.msg_len;
-
-       gpa_cnt = 1;
-       gpa[0].gpa_page = hv_get_phys_addr(&request->request_msg) >> PAGE_SHIFT;
-       gpa[0].gpa_len = request->request_msg.msg_len;
-       gpa[0].gpa_ofs = (unsigned long)&request->request_msg & (PAGE_SIZE - 1);
-
-       if (gpa[0].gpa_ofs + gpa[0].gpa_len > PAGE_SIZE) {
-               gpa_cnt = 2;
-               gpa[0].gpa_len = PAGE_SIZE - gpa[0].gpa_ofs;
-               gpa[1].gpa_page =
-                   hv_get_phys_addr((char*)&request->request_msg +
-                   gpa[0].gpa_len) >> PAGE_SHIFT;
-               gpa[1].gpa_ofs = 0;
-               gpa[1].gpa_len = request->request_msg.msg_len - gpa[0].gpa_len;
-       }
-
-       if (message_type != REMOTE_NDIS_HALT_MSG)
-               cb = hn_rndis_sent_cb;
-       else
-               cb = hn_rndis_sent_halt;
-
-       if (tot_data_buf_len < sc->hn_chim_szmax) {
-               send_buf_section_idx = hn_chim_alloc(sc);
-               if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
-                       uint8_t *dest = sc->hn_chim +
-                               (send_buf_section_idx * sc->hn_chim_szmax);
-
-                       memcpy(dest, &request->request_msg, 
request->request_msg.msg_len);
-                       send_buf_section_size = tot_data_buf_len;
-                       gpa_cnt = 0;
-                       goto sendit;
-               }
-               /* Failed to allocate chimney send buffer; move on */
-       }
-       send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
-       send_buf_section_size = 0;
-
-sendit:
-       hn_send_ctx_init(&request->send_ctx, cb, request,
-           send_buf_section_idx, send_buf_section_size);
-       return hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL,
-           &request->send_ctx, gpa, gpa_cnt);
-}
-
-/*
  * RNDIS filter receive response
  */
 static void 
@@ -603,20 +481,15 @@ static uint8_t netvsc_hash_key[NDIS_HASH
 };
 
 static const void *
-hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t 
rid,
-    size_t reqlen, size_t *comp_len0, uint32_t comp_type)
+hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t 
reqlen,
+    struct hn_send_ctx *sndc, size_t *comp_len)
 {
        struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT];
-       const struct rndis_comp_hdr *comp;
-       bus_addr_t paddr;
-       size_t comp_len, min_complen = *comp_len0;
        int gpa_cnt, error;
+       bus_addr_t paddr;
 
-       KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid));
        KASSERT(reqlen <= HN_XACT_REQ_SIZE && reqlen > 0,
            ("invalid request length %zu", reqlen));
-       KASSERT(min_complen >= sizeof(*comp),
-           ("invalid minimum complete len %zu", min_complen));
 
        /*
         * Setup the SG list.
@@ -645,14 +518,34 @@ hn_rndis_xact_execute(struct hn_softc *s
         * message.
         */
        vmbus_xact_activate(xact);
-       error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL,
-           &hn_send_ctx_none, gpa, gpa_cnt);
+       error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL, sndc,
+           gpa, gpa_cnt);
        if (error) {
                vmbus_xact_deactivate(xact);
                if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error);
                return (NULL);
        }
-       comp = vmbus_xact_wait(xact, &comp_len);
+       return (vmbus_xact_wait(xact, comp_len));
+}
+
+static const void *
+hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t 
rid,
+    size_t reqlen, size_t *comp_len0, uint32_t comp_type)
+{
+       const struct rndis_comp_hdr *comp;
+       size_t comp_len, min_complen = *comp_len0;
+
+       KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid));
+       KASSERT(min_complen >= sizeof(*comp),
+           ("invalid minimum complete len %zu", min_complen));
+
+       /*
+        * Execute the xact setup by the caller.
+        */
+       comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_send_ctx_none,
+           &comp_len);
+       if (comp == NULL)
+               return (NULL);
 
        /*
         * Check this RNDIS complete message.
@@ -1038,51 +931,34 @@ done:
        return (error);
 }
 
-#define HALT_COMPLETION_WAIT_COUNT      25
-
 /*
  * RNDIS filter halt device
  */
 static int
-hv_rf_halt_device(rndis_device *device)
+hv_rf_halt_device(struct hn_softc *sc)
 {
-       rndis_request *request;
-       int i, ret;
-
-       /* Attempt to do a rndis device halt */
-       request = hv_rndis_request(device, REMOTE_NDIS_HALT_MSG,
-           RNDIS_MESSAGE_SIZE(rndis_halt_request));
-       if (request == NULL) {
-               return (-1);
-       }
-
-       /* initialize "poor man's semaphore" */
-       request->halt_complete_flag = 0;
-
-       ret = hv_rf_send_request(device, request, REMOTE_NDIS_HALT_MSG);
-       if (ret != 0) {
-               return (-1);
-       }
+       struct vmbus_xact *xact;
+       struct rndis_halt_req *halt;
+       struct hn_send_ctx sndc;
+       size_t comp_len;
 
-       /*
-        * Wait for halt response from halt callback.  We must wait for
-        * the transaction response before freeing the request and other
-        * resources.
-        */
-       for (i=HALT_COMPLETION_WAIT_COUNT; i > 0; i--) {
-               if (request->halt_complete_flag != 0) {
-                       break;
-               }
-               DELAY(400);
-       }
-       if (i == 0) {
-               return (-1);
+       xact = vmbus_xact_get(sc->hn_xact, sizeof(*halt));
+       if (xact == NULL) {
+               if_printf(sc->hn_ifp, "no xact for RNDIS halt\n");
+               return (ENXIO);
        }
+       halt = vmbus_xact_req_data(xact);
+       halt->rm_type = REMOTE_NDIS_HALT_MSG;
+       halt->rm_len = sizeof(*halt);
+       halt->rm_rid = hn_rndis_rid(sc);
+
+       /* No RNDIS completion; rely on NVS message send completion */
+       hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
+       hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len);
 
-       device->state = RNDIS_DEV_UNINITIALIZED;
-
-       hv_put_rndis_request(device, request);
-
+       vmbus_xact_put(xact);
+       if (bootverbose)
+               if_printf(sc->hn_ifp, "RNDIS halt done\n");
        return (0);
 }
 
@@ -1252,7 +1128,7 @@ hv_rf_on_device_remove(struct hn_softc *
        int ret;
 
        /* Halt and release the rndis device */
-       ret = hv_rf_halt_device(rndis_dev);
+       ret = hv_rf_halt_device(sc);
 
        sc->rndis_dev = NULL;
        hv_put_rndis_device(rndis_dev);
@@ -1292,33 +1168,6 @@ hv_rf_on_close(struct hn_softc *sc)
        return (hn_rndis_set_rxfilter(sc, 0));
 }
 
-static void
-hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct hn_softc *sc,
-    struct vmbus_channel *chan __unused, const void *data __unused,
-    int dlen __unused)
-{
-       if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
-               hn_chim_free(sc, sndc->hn_chim_idx);
-}
-
-static void
-hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct hn_softc *sc,
-    struct vmbus_channel *chan __unused, const void *data __unused,
-    int dlen __unused)
-{
-       rndis_request *request = sndc->hn_cbarg;
-
-       if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
-               hn_chim_free(sc, sndc->hn_chim_idx);
-
-       /*
-        * Notify hv_rf_halt_device() about halt completion.
-        * The halt code must wait for completion before freeing
-        * the transaction resources.
-        */
-       request->halt_complete_flag = 1;
-}
-
 void
 hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr)
 {

Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h  Thu Oct 13 06:34:18 2016        
(r307184)
+++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h  Thu Oct 13 06:39:06 2016        
(r307185)
@@ -112,6 +112,8 @@ struct vmbus_xact;
 const void     *hn_nvs_xact_execute(struct hn_softc *sc,
                    struct vmbus_xact *xact, void *req, int reqlen,
                    size_t *resp_len);
+void           hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc,
+                   struct vmbus_channel *chan, const void *data, int dlen);
 uint32_t       hn_chim_alloc(struct hn_softc *sc);
 void           hn_chim_free(struct hn_softc *sc, uint32_t chim_idx);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to