#include <xen/interface/grant_table.h>
#include <xen/gnttab.h>
#include <asm/hypervisor.h>
+#include <asm/maddr.h>
#define BLKIF_STATE_DISCONNECTED 0
#define BLKIF_STATE_CONNECTED 1
static void kick_pending_request_queues(struct blkfront_info *);
-static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs);
-static void blkif_restart_queue(void *arg);
+static irqreturn_t blkif_int(int irq, void *dev_id);
+static void blkif_restart_queue(struct work_struct *work);
static void blkif_recover(struct blkfront_info *);
static void blkif_completion(struct blk_shadow *);
static void blkif_free(struct blkfront_info *, int);
info->xbdev = dev;
info->vdevice = vdevice;
info->connected = BLKIF_STATE_DISCONNECTED;
- INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
+ INIT_WORK(&info->work, blkif_restart_queue);
for (i = 0; i < BLK_RING_SIZE; i++)
info->shadow[i].req.id = i+1;
DPRINTK("blkfront:backend_changed.\n");
switch (backend_state) {
- case XenbusStateUnknown:
case XenbusStateInitialising:
case XenbusStateInitWait:
case XenbusStateInitialised:
+ case XenbusStateUnknown:
case XenbusStateClosed:
break;
*/
static void connect(struct blkfront_info *info)
{
- unsigned long sectors, sector_size;
+ unsigned long long sectors;
+ unsigned long sector_size;
unsigned int binfo;
int err;
DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
- "sectors", "%lu", §ors,
+ "sectors", "%llu", §ors,
"info", "%u", &binfo,
"sector-size", "%lu", §or_size,
NULL);
DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
if (info->rq == NULL)
- return;
+ goto out;
spin_lock_irqsave(&blkif_io_lock, flags);
/* No more blkif_request(). */
blk_stop_queue(info->rq);
/* No more gnttab callback work. */
gnttab_cancel_free_callback(&info->callback);
- flush_scheduled_work();
spin_unlock_irqrestore(&blkif_io_lock, flags);
+ /* Flush gnttab callback work. Must be done with no locks held. */
+ flush_scheduled_work();
+
xlvbd_del(info);
- xenbus_switch_state(dev, XenbusStateClosed);
+out:
+ xenbus_frontend_closed(dev);
}
}
}
-static void blkif_restart_queue(void *arg)
+static void blkif_restart_queue(struct work_struct *work)
{
- struct blkfront_info *info = (struct blkfront_info *)arg;
+ struct blkfront_info *info = container_of(work, struct blkfront_info, work);
+
spin_lock_irq(&blkif_io_lock);
if (info->connected == BLKIF_STATE_CONNECTED)
kick_pending_request_queues(info);
if (RING_FULL(&info->ring))
goto wait;
- DPRINTK("do_blk_req %p: cmd %p, sec %lx, "
+ DPRINTK("do_blk_req %p: cmd %p, sec %llx, "
"(%u/%li) buffer:%p [%s]\n",
- req, req->cmd, req->sector, req->current_nr_sectors,
+ req, req->cmd, (u64)req->sector, req->current_nr_sectors,
req->nr_sectors, req->buffer,
rq_data_dir(req) ? "write" : "read");
}
-static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
+static irqreturn_t blkif_int(int irq, void *dev_id)
{
struct request *req;
blkif_response_t *bret;
blk_stop_queue(info->rq);
/* No more gnttab callback work. */
gnttab_cancel_free_callback(&info->callback);
- flush_scheduled_work();
spin_unlock_irq(&blkif_io_lock);
+ /* Flush gnttab callback work. Must be done with no locks held. */
+ flush_scheduled_work();
+
/* Free resources associated with old device channel. */
if (info->ring_ref != GRANT_INVALID_REF) {
gnttab_end_foreign_access(info->ring_ref, 0,