hv_connection.c (300105) | hv_connection.c (300107) |
---|---|
1/*- 2 * Copyright (c) 2009-2012,2016 Microsoft Corp. 3 * Copyright (c) 2012 NetApp Inc. 4 * Copyright (c) 2012 Citrix Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 275 unchanged lines hidden (view full) --- 284 mtx_destroy(&hv_vmbus_g_connection.channel_msg_lock); 285 286 free(hv_vmbus_g_connection.channels, M_DEVBUF); 287 hv_vmbus_g_connection.connect_state = HV_DISCONNECTED; 288 289 return (ret); 290} 291 | 1/*- 2 * Copyright (c) 2009-2012,2016 Microsoft Corp. 3 * Copyright (c) 2012 NetApp Inc. 4 * Copyright (c) 2012 Citrix Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 275 unchanged lines hidden (view full) --- 284 mtx_destroy(&hv_vmbus_g_connection.channel_msg_lock); 285 286 free(hv_vmbus_g_connection.channels, M_DEVBUF); 287 hv_vmbus_g_connection.connect_state = HV_DISCONNECTED; 288 289 return (ret); 290} 291 |
292/** 293 * Handler for events 294 */ 295void 296hv_vmbus_on_events(int cpu) | 292static __inline void 293vmbus_event_flags_proc(unsigned long *event_flags, int flag_cnt) |
297{ | 294{ |
298 unsigned long *intr_flags; 299 hv_vmbus_synic_event_flags *event; 300 void *page_addr; 301 int flag_cnt, f; | 295 int f; |
302 | 296 |
303 KASSERT(cpu <= mp_maxid, ("VMBUS: hv_vmbus_on_events: " 304 "cpu out of range!")); 305 306 page_addr = hv_vmbus_g_context.syn_ic_event_page[cpu]; 307 event = (hv_vmbus_synic_event_flags *) 308 page_addr + HV_VMBUS_MESSAGE_SINT; 309 if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) || 310 (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) { 311 flag_cnt = HV_MAX_NUM_CHANNELS_SUPPORTED >> 312 HV_CHANNEL_ULONG_SHIFT; 313 /* 314 * receive size is 1/2 page and divide that by 4 bytes 315 */ 316 if (atomic_testandclear_int(&event->flags32[0], 0)) 317 intr_flags = hv_vmbus_g_connection.recv_interrupt_page; 318 else 319 return; 320 } else { 321 /* 322 * On Host with Win8 or above, the event page can be 323 * checked directly to get the id of the channel 324 * that has the pending interrupt. 325 */ 326 flag_cnt = VMBUS_PCPU_GET(event_flag_cnt, cpu); 327 intr_flags = event->flagsul; 328 } 329 330 /* 331 * Check events 332 */ 333 for (f = 0; f < flag_cnt; f++) { | 297 for (f = 0; f < flag_cnt; ++f) { |
334 uint32_t rel_id_base; 335 unsigned long flags; 336 int bit; 337 | 298 uint32_t rel_id_base; 299 unsigned long flags; 300 int bit; 301 |
338 if (intr_flags[f] == 0) | 302 if (event_flags[f] == 0) |
339 continue; 340 | 303 continue; 304 |
341 flags = atomic_swap_long(&intr_flags[f], 0); | 305 flags = atomic_swap_long(&event_flags[f], 0); |
342 rel_id_base = f << HV_CHANNEL_ULONG_SHIFT; 343 344 while ((bit = ffsl(flags)) != 0) { 345 struct hv_vmbus_channel *channel; 346 uint32_t rel_id; 347 348 --bit; /* NOTE: ffsl is 1-based */ 349 flags &= ~(1UL << bit); --- 7 unchanged lines hidden (view full) --- 357 358 if (channel->batched_reading) 359 hv_ring_buffer_read_begin(&channel->inbound); 360 taskqueue_enqueue(channel->rxq, &channel->channel_task); 361 } 362 } 363} 364 | 306 rel_id_base = f << HV_CHANNEL_ULONG_SHIFT; 307 308 while ((bit = ffsl(flags)) != 0) { 309 struct hv_vmbus_channel *channel; 310 uint32_t rel_id; 311 312 --bit; /* NOTE: ffsl is 1-based */ 313 flags &= ~(1UL << bit); --- 7 unchanged lines hidden (view full) --- 321 322 if (channel->batched_reading) 323 hv_ring_buffer_read_begin(&channel->inbound); 324 taskqueue_enqueue(channel->rxq, &channel->channel_task); 325 } 326 } 327} 328 |
329void 330vmbus_event_proc(struct vmbus_softc *sc, int cpu) 331{ 332 hv_vmbus_synic_event_flags *event; 333 334 event = ((hv_vmbus_synic_event_flags *) 335 hv_vmbus_g_context.syn_ic_event_page[cpu]) + HV_VMBUS_MESSAGE_SINT; 336 337 /* 338 * On Host with Win8 or above, the event page can be checked directly 339 * to get the id of the channel that has the pending interrupt. 340 */ 341 vmbus_event_flags_proc(event->flagsul, 342 VMBUS_SC_PCPU_GET(sc, event_flag_cnt, cpu)); 343} 344 345void 346vmbus_event_proc_compat(struct vmbus_softc *sc __unused, int cpu) 347{ 348 hv_vmbus_synic_event_flags *event; 349 350 event = ((hv_vmbus_synic_event_flags *) 351 hv_vmbus_g_context.syn_ic_event_page[cpu]) + HV_VMBUS_MESSAGE_SINT; 352 353 if (atomic_testandclear_int(&event->flags32[0], 0)) { 354 vmbus_event_flags_proc( 355 hv_vmbus_g_connection.recv_interrupt_page, 356 HV_MAX_NUM_CHANNELS_SUPPORTED >> HV_CHANNEL_ULONG_SHIFT); 357 } 358} 359 |
|
365/** 366 * Send a msg on the vmbus's message connection 367 */ 368int hv_vmbus_post_message(void *buffer, size_t bufferLen) 369{ 370 hv_vmbus_connection_id connId; 371 sbintime_t time = SBT_1MS; 372 int retries; --- 70 unchanged lines hidden --- | 360/** 361 * Send a msg on the vmbus's message connection 362 */ 363int hv_vmbus_post_message(void *buffer, size_t bufferLen) 364{ 365 hv_vmbus_connection_id connId; 366 sbintime_t time = SBT_1MS; 367 int retries; --- 70 unchanged lines hidden --- |