Merge branch 'x86/for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip...
[pandora-kernel.git] / drivers / s390 / char / tape_core.c
index 2fae633..181a544 100644 (file)
@@ -37,7 +37,7 @@ static void tape_long_busy_timeout(unsigned long data);
  * we can assign the devices to minor numbers of the same major
  * The list is protected by the rwlock
  */
-static struct list_head tape_device_list = LIST_HEAD_INIT(tape_device_list);
+static LIST_HEAD(tape_device_list);
 static DEFINE_RWLOCK(tape_device_lock);
 
 /*
@@ -76,32 +76,9 @@ const char *tape_op_verbose[TO_SIZE] =
        [TO_KEKL_QUERY] = "KLQ",[TO_RDC] = "RDC",
 };
 
-static int
-busid_to_int(char *bus_id)
+static int devid_to_int(struct ccw_dev_id *dev_id)
 {
-       int     dec;
-       int     d;
-       char *  s;
-
-       for(s = bus_id, d = 0; *s != '\0' && *s != '.'; s++)
-               d = (d * 10) + (*s - '0');
-       dec = d;
-       for(s++, d = 0; *s != '\0' && *s != '.'; s++)
-               d = (d * 10) + (*s - '0');
-       dec = (dec << 8) + d;
-
-       for(s++; *s != '\0'; s++) {
-               if (*s >= '0' && *s <= '9') {
-                       d = *s - '0';
-               } else if (*s >= 'a' && *s <= 'f') {
-                       d = *s - 'a' + 10;
-               } else {
-                       d = *s - 'A' + 10;
-               }
-               dec = (dec << 4) + d;
-       }
-
-       return dec;
+       return dev_id->devno + (dev_id->ssid << 16);
 }
 
 /*
@@ -472,6 +449,7 @@ tape_alloc_device(void)
        INIT_LIST_HEAD(&device->req_queue);
        INIT_LIST_HEAD(&device->node);
        init_waitqueue_head(&device->state_change_wq);
+       init_waitqueue_head(&device->wait_queue);
        device->tape_state = TS_INIT;
        device->medium_state = MS_UNKNOWN;
        *device->modeset_byte = 0;
@@ -551,6 +529,7 @@ tape_generic_probe(struct ccw_device *cdev)
 {
        struct tape_device *device;
        int ret;
+       struct ccw_dev_id dev_id;
 
        device = tape_alloc_device();
        if (IS_ERR(device))
@@ -565,7 +544,8 @@ tape_generic_probe(struct ccw_device *cdev)
        cdev->dev.driver_data = device;
        cdev->handler = __tape_do_irq;
        device->cdev = cdev;
-       device->cdev_id = busid_to_int(cdev->dev.bus_id);
+       ccw_device_get_id(cdev, &dev_id);
+       device->cdev_id = devid_to_int(&dev_id);
        PRINT_INFO("tape device %s found\n", cdev->dev.bus_id);
        return ret;
 }
@@ -859,7 +839,7 @@ tape_dump_sense(struct tape_device* device, struct tape_request *request,
 
        PRINT_INFO("-------------------------------------------------\n");
        PRINT_INFO("DSTAT : %02x  CSTAT: %02x   CPA: %04x\n",
-                  irb->scsw.dstat, irb->scsw.cstat, irb->scsw.cpa);
+                  irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa);
        PRINT_INFO("DEVICE: %s\n", device->cdev->dev.bus_id);
        if (request != NULL)
                PRINT_INFO("OP    : %s\n", tape_op_verbose[request->op]);
@@ -887,7 +867,7 @@ tape_dump_sense_dbf(struct tape_device *device, struct tape_request *request,
        else
                op = "---";
        DBF_EVENT(3, "DSTAT : %02x   CSTAT: %02x\n",
-                 irb->scsw.dstat,irb->scsw.cstat);
+                 irb->scsw.cmd.dstat, irb->scsw.cmd.cstat);
        DBF_EVENT(3, "DEVICE: %08x OP\t: %s\n", device->cdev_id, op);
        sptr = (unsigned int *) irb->ecw;
        DBF_EVENT(3, "%08x %08x\n", sptr[0], sptr[1]);
@@ -975,21 +955,19 @@ __tape_wake_up(struct tape_request *request, void *data)
 int
 tape_do_io(struct tape_device *device, struct tape_request *request)
 {
-       wait_queue_head_t wq;
        int rc;
 
-       init_waitqueue_head(&wq);
        spin_lock_irq(get_ccwdev_lock(device->cdev));
        /* Setup callback */
        request->callback = __tape_wake_up;
-       request->callback_data = &wq;
+       request->callback_data = &device->wait_queue;
        /* Add request to request queue and try to start it. */
        rc = __tape_start_request(device, request);
        spin_unlock_irq(get_ccwdev_lock(device->cdev));
        if (rc)
                return rc;
        /* Request added to the queue. Wait for its completion. */
-       wait_event(wq, (request->callback == NULL));
+       wait_event(device->wait_queue, (request->callback == NULL));
        /* Get rc from request */
        return request->rc;
 }
@@ -1010,20 +988,19 @@ int
 tape_do_io_interruptible(struct tape_device *device,
                         struct tape_request *request)
 {
-       wait_queue_head_t wq;
        int rc;
 
-       init_waitqueue_head(&wq);
        spin_lock_irq(get_ccwdev_lock(device->cdev));
        /* Setup callback */
        request->callback = __tape_wake_up_interruptible;
-       request->callback_data = &wq;
+       request->callback_data = &device->wait_queue;
        rc = __tape_start_request(device, request);
        spin_unlock_irq(get_ccwdev_lock(device->cdev));
        if (rc)
                return rc;
        /* Request added to the queue. Wait for its completion. */
-       rc = wait_event_interruptible(wq, (request->callback == NULL));
+       rc = wait_event_interruptible(device->wait_queue,
+                                     (request->callback == NULL));
        if (rc != -ERESTARTSYS)
                /* Request finished normally. */
                return request->rc;
@@ -1036,7 +1013,7 @@ tape_do_io_interruptible(struct tape_device *device,
                /* Wait for the interrupt that acknowledges the halt. */
                do {
                        rc = wait_event_interruptible(
-                               wq,
+                               device->wait_queue,
                                (request->callback == NULL)
                        );
                } while (rc == -ERESTARTSYS);
@@ -1106,10 +1083,11 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
         * error might still apply. So we just schedule the request to be
         * started later.
         */
-       if (irb->scsw.cc != 0 && (irb->scsw.fctl & SCSW_FCTL_START_FUNC) &&
+       if (irb->scsw.cmd.cc != 0 &&
+           (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
            (request->status == TAPE_REQUEST_IN_IO)) {
                DBF_EVENT(3,"(%08x): deferred cc=%i, fctl=%i. restarting\n",
-                       device->cdev_id, irb->scsw.cc, irb->scsw.fctl);
+                       device->cdev_id, irb->scsw.cmd.cc, irb->scsw.cmd.fctl);
                request->status = TAPE_REQUEST_QUEUED;
                schedule_delayed_work(&device->tape_dnr, HZ);
                return;
@@ -1117,8 +1095,8 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
 
        /* May be an unsolicited irq */
        if(request != NULL)
-               request->rescnt = irb->scsw.count;
-       else if ((irb->scsw.dstat == 0x85 || irb->scsw.dstat == 0x80) &&
+               request->rescnt = irb->scsw.cmd.count;
+       else if ((irb->scsw.cmd.dstat == 0x85 || irb->scsw.cmd.dstat == 0x80) &&
                 !list_empty(&device->req_queue)) {
                /* Not Ready to Ready after long busy ? */
                struct tape_request *req;
@@ -1134,7 +1112,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                        return;
                }
        }
-       if (irb->scsw.dstat != 0x0c) {
+       if (irb->scsw.cmd.dstat != 0x0c) {
                /* Set the 'ONLINE' flag depending on sense byte 1 */
                if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE)
                        device->tape_generic_status |= GMT_ONLINE(~0);