return fh;
}
- struct gnttab_free_callback *callback = gnttab_free_callback_list;
+static void do_free_callbacks(void)
+{
- schedule_work(callback->work);
- callback = callback->next;
++ struct gnttab_free_callback *callback = gnttab_free_callback_list, *next;
+ gnttab_free_callback_list = NULL;
+ while (callback) {
++ next = callback->next;
++ callback->next = NULL;
++ callback->fn(callback->arg);
++ callback = next;
+ }
+}
+
static inline void
put_free_entry(
grant_ref_t ref)
*private_head = release;
}
- struct work_struct *work)
+void
+gnttab_request_free_callback(struct gnttab_free_callback *callback,
- callback->work = work;
++ void (*fn)(void *), void *arg)
+{
++ if (callback->next)
++ return;
++ callback->fn = fn;
++ callback->arg = arg;
+ callback->next = gnttab_free_callback_list;
+ gnttab_free_callback_list = callback;
+}
+
/*
* ProcFS operations
*/
module_init(xlblk_init);
-static struct xlbd_disk_info *head_waiting = NULL;
-static void kick_pending_request_queues(void)
+static void kick_pending_request_queues(struct blkfront_info *info)
{
- struct xlbd_disk_info *di;
- while ( ((di = head_waiting) != NULL) && !RING_FULL(&blk_ring) )
- {
- head_waiting = di->next_waiting;
- di->next_waiting = NULL;
- /* Re-enable calldowns. */
- blk_start_queue(di->rq);
- /* Kick things off immediately. */
- do_blkif_request(di->rq);
- }
+ if (!RING_FULL(&info->ring)) {
+ /* Re-enable calldowns. */
+ blk_start_queue(info->rq);
+ /* Kick things off immediately. */
+ do_blkif_request(info->rq);
+ }
+}
+
+static void blkif_restart_queue(void *arg)
+{
+ struct blkfront_info *info = (struct blkfront_info *)arg;
+ spin_lock_irq(&blkif_io_lock);
- info->callback.work = NULL;
+ kick_pending_request_queues(info);
+ spin_unlock_irq(&blkif_io_lock);
+}
+
++static void blkif_restart_queue_callback(void *arg)
++{
++ struct blkfront_info *info = (struct blkfront_info *)arg;
++ schedule_work(&info->work);
+ }
+
int blkif_open(struct inode *inode, struct file *filep)
{
- struct gendisk *gd = inode->i_bdev->bd_disk;
- struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
+ // struct gendisk *gd = inode->i_bdev->bd_disk;
+ // struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
- /* Update of usage count is protected by per-device semaphore. */
- di->mi->usage++;
-
- return 0;
+ /* Update of usage count is protected by per-device semaphore. */
+ // di->mi->usage++;
+
+ return 0;
}
unsigned long id;
unsigned int fsect, lsect;
int ref;
+ grant_ref_t gref_head, gref_terminal;
- if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) )
+ if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
return 1;
- if (info->callback.work)
- return 1;
- INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
- gnttab_request_free_callback(&info->callback, &info->work);
+ if (gnttab_alloc_grant_references(BLKIF_MAX_SEGMENTS_PER_REQUEST,
+ &gref_head, &gref_terminal) < 0) {
++ gnttab_request_free_callback(&info->callback,
++ blkif_restart_queue_callback, info);
+ return 1;
+ }
+
/* Fill out a communications ring structure. */
- ring_req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
+ ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
id = GET_ID_FROM_FREELIST();
blk_shadow[id].request = (unsigned long)req;
xenbus_dev_error(dev, err, "allocating info structure");
return err;
}
- info->dev = dev;
+ info->xbdev = dev;
info->vdevice = vdevice;
- info->connected = 0;
+ info->connected = BLKIF_STATE_DISCONNECTED;
+ info->mi = NULL;
++ INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
/* Front end dir is a number, which is used as the id. */
info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
#define NR_GRANT_FRAMES 4
#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
- struct work_struct *work;
+struct work_struct;
+
+struct gnttab_free_callback {
+ struct gnttab_free_callback *next;
++ void (*fn)(void *);
++ void *arg;
+};
+
int
gnttab_grant_foreign_access(
domid_t domid, unsigned long frame, int readonly);
gnttab_release_grant_reference(
grant_ref_t *private_head, grant_ref_t release );
- struct gnttab_free_callback *callback, struct work_struct *work );
+void
+gnttab_request_free_callback(
++ struct gnttab_free_callback *callback, void (*fn)(void *), void *arg);
+
void
gnttab_grant_foreign_access_ref(
grant_ref_t ref, domid_t domid, unsigned long frame, int readonly);