diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-03-17 07:44:08 (GMT) |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-03-17 07:44:08 (GMT) |
commit | 1d2a1959fe534279cf37aba20b08c24c20840e52 (patch) | |
tree | 67c0b9aa7fe22a44bf0b4af88947799203eb8f67 /drivers/staging/hv/storvsc.c | |
parent | 5a79ce76e9bb8f4b2cd8106ee36d15ee05013bcf (diff) | |
parent | 054cfaacf88865bff1dd58d305443d5d6c068a08 (diff) | |
download | linux-1d2a1959fe534279cf37aba20b08c24c20840e52.tar.xz |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into sh-latest
Diffstat (limited to 'drivers/staging/hv/storvsc.c')
-rw-r--r-- | drivers/staging/hv/storvsc.c | 152 |
1 files changed, 84 insertions, 68 deletions
diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 9295113..e2ad729 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -19,11 +19,13 @@ * Hank Janssen <hjanssen@microsoft.com> */ #include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/wait.h> #include <linux/string.h> #include <linux/slab.h> #include <linux/mm.h> #include <linux/delay.h> -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "storvsc_api.h" #include "vmbus_packet_format.h" @@ -38,7 +40,8 @@ struct storvsc_request_extension { struct hv_device *device; /* Synchronize the request/response if needed */ - struct osd_waitevent *wait_event; + int wait_condition; + wait_queue_head_t wait_event; struct vstor_packet vstor_packet; }; @@ -94,7 +97,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) atomic_cmpxchg(&stor_device->ref_count, 0, 2); stor_device->device = device; - device->Extension = stor_device; + device->ext = stor_device; return stor_device; } @@ -110,7 +113,7 @@ static inline struct storvsc_device *get_stor_device(struct hv_device *device) { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; if (stor_device && atomic_read(&stor_device->ref_count) > 1) atomic_inc(&stor_device->ref_count); else @@ -125,7 +128,7 @@ static inline struct storvsc_device *must_get_stor_device( { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; if (stor_device && atomic_read(&stor_device->ref_count)) atomic_inc(&stor_device->ref_count); else @@ -138,7 +141,7 @@ static inline void put_stor_device(struct hv_device *device) { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; /* ASSERT(stor_device); */ atomic_dec(&stor_device->ref_count); @@ -151,7 +154,7 @@ static inline struct storvsc_device *release_stor_device( { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; /* ASSERT(stor_device); */ /* Busy wait until the ref drop to 2, then set it to 1 */ @@ -167,14 +170,14 @@ static inline struct storvsc_device *final_release_stor_device( { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; /* ASSERT(stor_device); */ /* Busy wait until the ref drop to 1, then set it to 0 */ while (atomic_cmpxchg(&stor_device->ref_count, 1, 0) != 1) udelay(100); - device->Extension = NULL; + device->ext = NULL; return stor_device; } @@ -200,40 +203,38 @@ static int stor_vsc_channel_init(struct hv_device *device) * channel */ memset(request, 0, sizeof(struct storvsc_request_extension)); - request->wait_event = osd_waitevent_create(); - if (!request->wait_event) { - ret = -ENOMEM; - goto nomem; - } - + init_waitqueue_head(&request->wait_event); vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; - /*SpinlockAcquire(gDriverExt.packetListLock); - INSERT_TAIL_LIST(&gDriverExt.packetList, &packet->listEntry.entry); - SpinlockRelease(gDriverExt.packetListLock);*/ - DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION..."); + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(STORVSC, "unable to send BEGIN_INITIALIZATION_OPERATION"); - goto Cleanup; + goto cleanup; + } + + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; } - osd_waitevent_wait(request->wait_event); if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) { DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed " "(op %d status 0x%x)", vstor_packet->operation, vstor_packet->status); - goto Cleanup; + goto cleanup; } DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION..."); @@ -246,18 +247,24 @@ static int stor_vsc_channel_init(struct hv_device *device) vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; FILL_VMSTOR_REVISION(vstor_packet->version.revision); + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(STORVSC, "unable to send BEGIN_INITIALIZATION_OPERATION"); - goto Cleanup; + goto cleanup; } - osd_waitevent_wait(request->wait_event); + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } /* TODO: Check returned version */ if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || @@ -265,7 +272,7 @@ static int stor_vsc_channel_init(struct hv_device *device) DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed " "(op %d status 0x%x)", vstor_packet->operation, vstor_packet->status); - goto Cleanup; + goto cleanup; } /* Query channel properties */ @@ -277,19 +284,25 @@ static int stor_vsc_channel_init(struct hv_device *device) vstor_packet->storage_channel_properties.port_number = stor_device->port_number; + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(STORVSC, "unable to send QUERY_PROPERTIES_OPERATION"); - goto Cleanup; + goto cleanup; } - osd_waitevent_wait(request->wait_event); + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } /* TODO: Check returned version */ if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || @@ -297,7 +310,7 @@ static int stor_vsc_channel_init(struct hv_device *device) DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed " "(op %d status 0x%x)", vstor_packet->operation, vstor_packet->status); - goto Cleanup; + goto cleanup; } stor_device->path_id = vstor_packet->storage_channel_properties.path_id; @@ -314,34 +327,37 @@ static int stor_vsc_channel_init(struct hv_device *device) vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(STORVSC, "unable to send END_INITIALIZATION_OPERATION"); - goto Cleanup; + goto cleanup; } - osd_waitevent_wait(request->wait_event); + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) { DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed " "(op %d status 0x%x)", vstor_packet->operation, vstor_packet->status); - goto Cleanup; + goto cleanup; } DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****"); -Cleanup: - kfree(request->wait_event); - request->wait_event = NULL; -nomem: +cleanup: put_stor_device(device); return ret; } @@ -437,7 +453,7 @@ static void stor_vsc_on_channel_callback(void *context) struct storvsc_device *stor_device; u32 bytes_recvd; u64 request_id; - unsigned char packet[ALIGN_UP(sizeof(struct vstor_packet), 8)]; + unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)]; struct storvsc_request_extension *request; int ret; @@ -452,7 +468,7 @@ static void stor_vsc_on_channel_callback(void *context) do { ret = vmbus_recvpacket(device->channel, packet, - ALIGN_UP(sizeof(struct vstor_packet), 8), + ALIGN(sizeof(struct vstor_packet), 8), &bytes_recvd, &request_id); if (ret == 0 && bytes_recvd > 0) { DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx", @@ -476,8 +492,8 @@ static void stor_vsc_on_channel_callback(void *context) memcpy(&request->vstor_packet, packet, sizeof(struct vstor_packet)); - - osd_waitevent_set(request->wait_event); + request->wait_condition = 1; + wake_up(&request->wait_event); } else { stor_vsc_on_receive(device, (struct vstor_packet *)packet, @@ -499,7 +515,7 @@ static int stor_vsc_connect_to_vsp(struct hv_device *device) struct storvsc_driver_object *stor_driver; int ret; - stor_driver = (struct storvsc_driver_object *)device->Driver; + stor_driver = (struct storvsc_driver_object *)device->drv; memset(&props, 0, sizeof(struct vmstorage_channel_properties)); /* Open the channel */ @@ -539,7 +555,7 @@ static int stor_vsc_on_device_add(struct hv_device *device, stor_device = alloc_stor_device(device); if (!stor_device) { ret = -1; - goto Cleanup; + goto cleanup; } /* Save the channel properties to our storvsc channel */ @@ -569,7 +585,7 @@ static int stor_vsc_on_device_add(struct hv_device *device, stor_device->port_number, stor_device->path_id, stor_device->target_id); -Cleanup: +cleanup: return ret; } @@ -581,7 +597,7 @@ static int stor_vsc_on_device_remove(struct hv_device *device) struct storvsc_device *stor_device; DPRINT_INFO(STORVSC, "disabling storage device (%p)...", - device->Extension); + device->ext); stor_device = release_stor_device(device); @@ -597,7 +613,7 @@ static int stor_vsc_on_device_remove(struct hv_device *device) } DPRINT_INFO(STORVSC, "removing storage device (%p)...", - device->Extension); + device->ext); stor_device = final_release_stor_device(device); @@ -629,31 +645,31 @@ int stor_vsc_on_host_reset(struct hv_device *device) request = &stor_device->reset_request; vstor_packet = &request->vstor_packet; - request->wait_event = osd_waitevent_create(); - if (!request->wait_event) { - ret = -ENOMEM; - goto Cleanup; - } + init_waitqueue_head(&request->wait_event); vstor_packet->operation = VSTOR_OPERATION_RESET_BUS; vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->vm_srb.path_id = stor_device->path_id; + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)&stor_device->reset_request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", vstor_packet, ret); - goto Cleanup; + goto cleanup; } - /* FIXME: Add a timeout */ - osd_waitevent_wait(request->wait_event); + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } - kfree(request->wait_event); DPRINT_INFO(STORVSC, "host adapter reset completed"); /* @@ -661,7 +677,7 @@ int stor_vsc_on_host_reset(struct hv_device *device) * should have been flushed out and return to us */ -Cleanup: +cleanup: put_stor_device(device); return ret; } @@ -687,7 +703,7 @@ static int stor_vsc_on_io_request(struct hv_device *device, request_extension); DPRINT_DBG(STORVSC, "req %p len %d bus %d, target %d, lun %d cdblen %d", - request, request->data_buffer.Length, request->bus, + request, request->data_buffer.len, request->bus, request->target_id, request->lun_id, request->cdb_len); if (!stor_device) { @@ -720,7 +736,7 @@ static int stor_vsc_on_io_request(struct hv_device *device, memcpy(&vstor_packet->vm_srb.cdb, request->cdb, request->cdb_len); vstor_packet->vm_srb.data_in = request->type; - vstor_packet->vm_srb.data_transfer_length = request->data_buffer.Length; + vstor_packet->vm_srb.data_transfer_length = request->data_buffer.len; vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB; @@ -734,7 +750,7 @@ static int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.sense_info_length, vstor_packet->vm_srb.cdb_length); - if (request_extension->request->data_buffer.Length) { + if (request_extension->request->data_buffer.len) { ret = vmbus_sendpacket_multipagebuffer(device->channel, &request_extension->request->data_buffer, vstor_packet, @@ -744,7 +760,7 @@ static int stor_vsc_on_io_request(struct hv_device *device, ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request_extension, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); } @@ -788,7 +804,7 @@ int stor_vsc_initialize(struct hv_driver *driver) /* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */ driver->name = g_driver_name; - memcpy(&driver->deviceType, &gStorVscDeviceType, + memcpy(&driver->dev_type, &gStorVscDeviceType, sizeof(struct hv_guid)); stor_driver->request_ext_size = @@ -802,7 +818,7 @@ int stor_vsc_initialize(struct hv_driver *driver) */ stor_driver->max_outstanding_req_per_channel = ((stor_driver->ring_buffer_size - PAGE_SIZE) / - ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + + ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + sizeof(struct vstor_packet) + sizeof(u64), sizeof(u64))); @@ -811,9 +827,9 @@ int stor_vsc_initialize(struct hv_driver *driver) STORVSC_MAX_IO_REQUESTS); /* Setup the dispatch table */ - stor_driver->base.OnDeviceAdd = stor_vsc_on_device_add; - stor_driver->base.OnDeviceRemove = stor_vsc_on_device_remove; - stor_driver->base.OnCleanup = stor_vsc_on_cleanup; + stor_driver->base.dev_add = stor_vsc_on_device_add; + stor_driver->base.dev_rm = stor_vsc_on_device_remove; + stor_driver->base.cleanup = stor_vsc_on_cleanup; stor_driver->on_io_request = stor_vsc_on_io_request; |