else
device = channel->device_obj;
- net_device = get_inbound_net_device(device);
- if (!net_device)
- return;
ndev = hv_get_drvdata(device);
- buffer = get_per_channel_state(channel);
+ if (unlikely(!ndev))
+ return;
+
+ net_device = net_device_to_netvsc_device(ndev);
+ if (unlikely(net_device->destroy) &&
+ netvsc_channel_idle(net_device, q_idx))
+ return;
- do {
- desc = get_next_pkt_raw(channel);
- if (desc != NULL) {
- netvsc_process_raw_pkt(device,
- channel,
- net_device,
- ndev,
- desc->trans_id,
- desc);
-
- put_pkt_raw(channel, desc);
- need_to_commit = true;
- continue;
- }
- if (need_to_commit) {
- need_to_commit = false;
- commit_rd_index(channel);
- }
-
- ret = vmbus_recvpacket_raw(channel, buffer, bufferlen,
- &bytes_recvd, &request_id);
- if (ret == 0) {
- if (bytes_recvd > 0) {
- desc = (struct vmpacket_descriptor *)buffer;
- netvsc_process_raw_pkt(device,
- channel,
- net_device,
- ndev,
- request_id,
- desc);
- } else {
- /*
- * We are done for this pass.
- */
- break;
- }
-
- } else if (ret == -ENOBUFS) {
- if (bufferlen > NETVSC_PACKET_SIZE)
- kfree(buffer);
- /* Handle large packet */
- buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
- if (buffer == NULL) {
- /* Try again next time around */
- netdev_err(ndev,
- "unable to allocate buffer of size "
- "(%d)!!\n", bytes_recvd);
- break;
- }
-
- bufferlen = bytes_recvd;
- }
-
- init_cached_read_index(channel);
+ /* commit_rd_index() -> hv_signal_on_read() needs this. */
+ init_cached_read_index(channel);
+
+ while ((desc = get_next_pkt_raw(channel)) != NULL) {
+ netvsc_process_raw_pkt(device, channel, net_device,
+ ndev, desc->trans_id, desc);
- } while (1);
+ put_pkt_raw(channel, desc);
+ need_to_commit = true;
+ }
- if (bufferlen > NETVSC_PACKET_SIZE)
- kfree(buffer);
+ if (need_to_commit)
+ commit_rd_index(channel);
netvsc_chk_recv_comp(net_device, channel, q_idx);
}