]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/s390/cio/device.c
[S390] cio: introduce subchannel todos
[net-next-2.6.git] / drivers / s390 / cio / device.c
index 6097763f1035bab78af7935d3a18cea3f7b2fb72..0dcfc0ee3d812b3d65363408b4c3a48c212bf9bf 100644 (file)
@@ -1051,23 +1051,6 @@ static void io_subchannel_init_fields(struct subchannel *sch)
        io_subchannel_init_config(sch);
 }
 
-static void io_subchannel_do_unreg(struct work_struct *work)
-{
-       struct subchannel *sch;
-
-       sch = container_of(work, struct subchannel, work);
-       css_sch_device_unregister(sch);
-       put_device(&sch->dev);
-}
-
-/* Schedule unregister if we have no cdev. */
-static void io_subchannel_schedule_removal(struct subchannel *sch)
-{
-       get_device(&sch->dev);
-       INIT_WORK(&sch->work, io_subchannel_do_unreg);
-       queue_work(slow_path_wq, &sch->work);
-}
-
 /*
  * Note: We always return 0 so that we bind to the device even on error.
  * This is needed so that our remove function is called on unregister.
@@ -1124,7 +1107,9 @@ static int io_subchannel_probe(struct subchannel *sch)
        return 0;
 
 out_schedule:
-       io_subchannel_schedule_removal(sch);
+       spin_lock_irq(sch->lock);
+       css_sched_sch_todo(sch, SCH_TODO_UNREG);
+       spin_unlock_irq(sch->lock);
        return 0;
 }
 
@@ -1469,6 +1454,8 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
        spin_lock_irqsave(sch->lock, flags);
        if (!device_is_registered(&sch->dev))
                goto out_unlock;
+       if (work_pending(&sch->todo_work))
+               goto out_unlock;
        action = sch_get_action(sch);
        CIO_MSG_EVENT(2, "event: sch 0.%x.%04x, process=%d, action=%d\n",
                      sch->schid.ssid, sch->schid.sch_no, process,