usb: dwc_otg_310: support vbus controlled by both gpio and pmic
[firefly-linux-kernel-4.4.55.git] / drivers / block / floppy.c
index 04ceb7e2fadd6ca075d20ecd844c39bf1da07ff3..331363e7de0f1d5682d7ca2756c2e2e59cbabbe4 100644 (file)
@@ -961,17 +961,31 @@ static void empty(void)
 {
 }
 
-static DECLARE_WORK(floppy_work, NULL);
+static void (*floppy_work_fn)(void);
+
+static void floppy_work_workfn(struct work_struct *work)
+{
+       floppy_work_fn();
+}
+
+static DECLARE_WORK(floppy_work, floppy_work_workfn);
 
 static void schedule_bh(void (*handler)(void))
 {
        WARN_ON(work_pending(&floppy_work));
 
-       PREPARE_WORK(&floppy_work, (work_func_t)handler);
+       floppy_work_fn = handler;
        queue_work(floppy_wq, &floppy_work);
 }
 
-static DECLARE_DELAYED_WORK(fd_timer, NULL);
+static void (*fd_timer_fn)(void) = NULL;
+
+static void fd_timer_workfn(struct work_struct *work)
+{
+       fd_timer_fn();
+}
+
+static DECLARE_DELAYED_WORK(fd_timer, fd_timer_workfn);
 
 static void cancel_activity(void)
 {
@@ -982,7 +996,7 @@ static void cancel_activity(void)
 
 /* this function makes sure that the disk stays in the drive during the
  * transfer */
-static void fd_watchdog(struct work_struct *arg)
+static void fd_watchdog(void)
 {
        debug_dcl(DP->flags, "calling disk change from watchdog\n");
 
@@ -993,7 +1007,7 @@ static void fd_watchdog(struct work_struct *arg)
                reset_fdc();
        } else {
                cancel_delayed_work(&fd_timer);
-               PREPARE_DELAYED_WORK(&fd_timer, fd_watchdog);
+               fd_timer_fn = fd_watchdog;
                queue_delayed_work(floppy_wq, &fd_timer, HZ / 10);
        }
 }
@@ -1005,7 +1019,8 @@ static void main_command_interrupt(void)
 }
 
 /* waits for a delay (spinup or select) to pass */
-static int fd_wait_for_completion(unsigned long expires, work_func_t function)
+static int fd_wait_for_completion(unsigned long expires,
+                                 void (*function)(void))
 {
        if (FDCS->reset) {
                reset_fdc();    /* do the reset during sleep to win time
@@ -1016,7 +1031,7 @@ static int fd_wait_for_completion(unsigned long expires, work_func_t function)
 
        if (time_before(jiffies, expires)) {
                cancel_delayed_work(&fd_timer);
-               PREPARE_DELAYED_WORK(&fd_timer, function);
+               fd_timer_fn = function;
                queue_delayed_work(floppy_wq, &fd_timer, expires - jiffies);
                return 1;
        }
@@ -1334,8 +1349,7 @@ static int fdc_dtr(void)
         * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
         */
        FDCS->dtr = raw_cmd->rate & 3;
-       return fd_wait_for_completion(jiffies + 2UL * HZ / 100,
-                                     (work_func_t)floppy_ready);
+       return fd_wait_for_completion(jiffies + 2UL * HZ / 100, floppy_ready);
 }                              /* fdc_dtr */
 
 static void tell_sector(void)
@@ -1440,7 +1454,7 @@ static void setup_rw_floppy(void)
        int flags;
        int dflags;
        unsigned long ready_date;
-       work_func_t function;
+       void (*function)(void);
 
        flags = raw_cmd->flags;
        if (flags & (FD_RAW_READ | FD_RAW_WRITE))
@@ -1454,9 +1468,9 @@ static void setup_rw_floppy(void)
                 */
                if (time_after(ready_date, jiffies + DP->select_delay)) {
                        ready_date -= DP->select_delay;
-                       function = (work_func_t)floppy_start;
+                       function = floppy_start;
                } else
-                       function = (work_func_t)setup_rw_floppy;
+                       function = setup_rw_floppy;
 
                /* wait until the floppy is spinning fast enough */
                if (fd_wait_for_completion(ready_date, function))
@@ -1486,7 +1500,7 @@ static void setup_rw_floppy(void)
                inr = result();
                cont->interrupt();
        } else if (flags & FD_RAW_NEED_DISK)
-               fd_watchdog(NULL);
+               fd_watchdog();
 }
 
 static int blind_seek;
@@ -1863,7 +1877,7 @@ static int start_motor(void (*function)(void))
 
        /* wait_for_completion also schedules reset if needed. */
        return fd_wait_for_completion(DRS->select_date + DP->select_delay,
-                                     (work_func_t)function);
+                                     function);
 }
 
 static void floppy_ready(void)
@@ -2337,7 +2351,7 @@ static void rw_interrupt(void)
        }
 
        if (CT(COMMAND) != FD_READ ||
-           raw_cmd->kernel_data == current_req->buffer) {
+           raw_cmd->kernel_data == bio_data(current_req->bio)) {
                /* transfer directly from buffer */
                cont->done(1);
        } else if (CT(COMMAND) == FD_READ) {
@@ -2351,7 +2365,7 @@ static void rw_interrupt(void)
 /* Compute maximal contiguous buffer size. */
 static int buffer_chain_size(void)
 {
-       struct bio_vec *bv;
+       struct bio_vec bv;
        int size;
        struct req_iterator iter;
        char *base;
@@ -2360,10 +2374,10 @@ static int buffer_chain_size(void)
        size = 0;
 
        rq_for_each_segment(bv, current_req, iter) {
-               if (page_address(bv->bv_page) + bv->bv_offset != base + size)
+               if (page_address(bv.bv_page) + bv.bv_offset != base + size)
                        break;
 
-               size += bv->bv_len;
+               size += bv.bv_len;
        }
 
        return size >> 9;
@@ -2389,7 +2403,7 @@ static int transfer_size(int ssize, int max_sector, int max_size)
 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
 {
        int remaining;          /* number of transferred 512-byte sectors */
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *buffer;
        char *dma_buffer;
        int size;
@@ -2427,10 +2441,10 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
                if (!remaining)
                        break;
 
-               size = bv->bv_len;
+               size = bv.bv_len;
                SUPBOUND(size, remaining);
 
-               buffer = page_address(bv->bv_page) + bv->bv_offset;
+               buffer = page_address(bv.bv_page) + bv.bv_offset;
                if (dma_buffer + size >
                    floppy_track_buffer + (max_buffer_sectors << 10) ||
                    dma_buffer < floppy_track_buffer) {
@@ -2626,7 +2640,7 @@ static int make_raw_rw_request(void)
                raw_cmd->flags &= ~FD_RAW_WRITE;
                raw_cmd->flags |= FD_RAW_READ;
                COMMAND = FM_MODE(_floppy, FD_READ);
-       } else if ((unsigned long)current_req->buffer < MAX_DMA_ADDRESS) {
+       } else if ((unsigned long)bio_data(current_req->bio) < MAX_DMA_ADDRESS) {
                unsigned long dma_limit;
                int direct, indirect;
 
@@ -2640,13 +2654,13 @@ static int make_raw_rw_request(void)
                 */
                max_size = buffer_chain_size();
                dma_limit = (MAX_DMA_ADDRESS -
-                            ((unsigned long)current_req->buffer)) >> 9;
+                            ((unsigned long)bio_data(current_req->bio))) >> 9;
                if ((unsigned long)max_size > dma_limit)
                        max_size = dma_limit;
                /* 64 kb boundaries */
-               if (CROSS_64KB(current_req->buffer, max_size << 9))
+               if (CROSS_64KB(bio_data(current_req->bio), max_size << 9))
                        max_size = (K_64 -
-                                   ((unsigned long)current_req->buffer) %
+                                   ((unsigned long)bio_data(current_req->bio)) %
                                    K_64) >> 9;
                direct = transfer_size(ssize, max_sector, max_size) - fsector_t;
                /*
@@ -2663,7 +2677,7 @@ static int make_raw_rw_request(void)
                       (DP->read_track & (1 << DRS->probed_format)))))) {
                        max_size = blk_rq_sectors(current_req);
                } else {
-                       raw_cmd->kernel_data = current_req->buffer;
+                       raw_cmd->kernel_data = bio_data(current_req->bio);
                        raw_cmd->length = current_count_sectors << 9;
                        if (raw_cmd->length == 0) {
                                DPRINT("%s: zero dma transfer attempted\n", __func__);
@@ -2717,7 +2731,7 @@ static int make_raw_rw_request(void)
        raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1;
        raw_cmd->length <<= 9;
        if ((raw_cmd->length < current_count_sectors << 9) ||
-           (raw_cmd->kernel_data != current_req->buffer &&
+           (raw_cmd->kernel_data != bio_data(current_req->bio) &&
             CT(COMMAND) == FD_WRITE &&
             (aligned_sector_t + (raw_cmd->length >> 9) > buffer_max ||
              aligned_sector_t < buffer_min)) ||
@@ -2725,7 +2739,7 @@ static int make_raw_rw_request(void)
            raw_cmd->length <= 0 || current_count_sectors <= 0) {
                DPRINT("fractionary current count b=%lx s=%lx\n",
                       raw_cmd->length, current_count_sectors);
-               if (raw_cmd->kernel_data != current_req->buffer)
+               if (raw_cmd->kernel_data != bio_data(current_req->bio))
                        pr_info("addr=%d, length=%ld\n",
                                (int)((raw_cmd->kernel_data -
                                       floppy_track_buffer) >> 9),
@@ -2742,7 +2756,7 @@ static int make_raw_rw_request(void)
                return 0;
        }
 
-       if (raw_cmd->kernel_data != current_req->buffer) {
+       if (raw_cmd->kernel_data != bio_data(current_req->bio)) {
                if (raw_cmd->kernel_data < floppy_track_buffer ||
                    current_count_sectors < 0 ||
                    raw_cmd->length < 0 ||
@@ -2886,9 +2900,9 @@ static void do_fd_request(struct request_queue *q)
                return;
 
        if (WARN(atomic_read(&usage_count) == 0,
-                "warning: usage count=0, current_req=%p sect=%ld type=%x flags=%x\n",
+                "warning: usage count=0, current_req=%p sect=%ld type=%x flags=%llx\n",
                 current_req, (long)blk_rq_pos(current_req), current_req->cmd_type,
-                current_req->cmd_flags))
+                (unsigned long long) current_req->cmd_flags))
                return;
 
        if (test_and_set_bit(0, &fdc_busy)) {
@@ -3053,7 +3067,10 @@ static int raw_cmd_copyout(int cmd, void __user *param,
        int ret;
 
        while (ptr) {
-               ret = copy_to_user(param, ptr, sizeof(*ptr));
+               struct floppy_raw_cmd cmd = *ptr;
+               cmd.next = NULL;
+               cmd.kernel_data = NULL;
+               ret = copy_to_user(param, &cmd, sizeof(cmd));
                if (ret)
                        return -EFAULT;
                param += sizeof(struct floppy_raw_cmd);
@@ -3107,10 +3124,11 @@ loop:
                return -ENOMEM;
        *rcmd = ptr;
        ret = copy_from_user(ptr, param, sizeof(*ptr));
-       if (ret)
-               return -EFAULT;
        ptr->next = NULL;
        ptr->buffer_length = 0;
+       ptr->kernel_data = NULL;
+       if (ret)
+               return -EFAULT;
        param += sizeof(struct floppy_raw_cmd);
        if (ptr->cmd_count > 33)
                        /* the command may now also take up the space
@@ -3126,7 +3144,6 @@ loop:
        for (i = 0; i < 16; i++)
                ptr->reply[i] = 0;
        ptr->resultcode = 0;
-       ptr->kernel_data = NULL;
 
        if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
                if (ptr->length <= 0)
@@ -3691,9 +3708,12 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
        if (!(mode & FMODE_NDELAY)) {
                if (mode & (FMODE_READ|FMODE_WRITE)) {
                        UDRS->last_checked = 0;
+                       clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
                        check_disk_change(bdev);
                        if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags))
                                goto out;
+                       if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags))
+                               goto out;
                }
                res = -EROFS;
                if ((mode & FMODE_WRITE) &&
@@ -3746,17 +3766,30 @@ static unsigned int floppy_check_events(struct gendisk *disk,
  * a disk in the drive, and whether that disk is writable.
  */
 
-static void floppy_rb0_complete(struct bio *bio, int err)
+struct rb0_cbdata {
+       int drive;
+       struct completion complete;
+};
+
+static void floppy_rb0_cb(struct bio *bio)
 {
-       complete((struct completion *)bio->bi_private);
+       struct rb0_cbdata *cbdata = (struct rb0_cbdata *)bio->bi_private;
+       int drive = cbdata->drive;
+
+       if (bio->bi_error) {
+               pr_info("floppy: error %d while reading block 0\n",
+                       bio->bi_error);
+               set_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
+       }
+       complete(&cbdata->complete);
 }
 
-static int __floppy_read_block_0(struct block_device *bdev)
+static int __floppy_read_block_0(struct block_device *bdev, int drive)
 {
        struct bio bio;
        struct bio_vec bio_vec;
-       struct completion complete;
        struct page *page;
+       struct rb0_cbdata cbdata;
        size_t size;
 
        page = alloc_page(GFP_NOIO);
@@ -3769,23 +3802,26 @@ static int __floppy_read_block_0(struct block_device *bdev)
        if (!size)
                size = 1024;
 
+       cbdata.drive = drive;
+
        bio_init(&bio);
        bio.bi_io_vec = &bio_vec;
        bio_vec.bv_page = page;
        bio_vec.bv_len = size;
        bio_vec.bv_offset = 0;
        bio.bi_vcnt = 1;
-       bio.bi_size = size;
+       bio.bi_iter.bi_size = size;
        bio.bi_bdev = bdev;
-       bio.bi_sector = 0;
-       bio.bi_flags = (1 << BIO_QUIET);
-       init_completion(&complete);
-       bio.bi_private = &complete;
-       bio.bi_end_io = floppy_rb0_complete;
+       bio.bi_iter.bi_sector = 0;
+       bio.bi_flags |= (1 << BIO_QUIET);
+       bio.bi_private = &cbdata;
+       bio.bi_end_io = floppy_rb0_cb;
 
        submit_bio(READ, &bio);
        process_fd_request();
-       wait_for_completion(&complete);
+
+       init_completion(&cbdata.complete);
+       wait_for_completion(&cbdata.complete);
 
        __free_page(page);
 
@@ -3827,7 +3863,7 @@ static int floppy_revalidate(struct gendisk *disk)
                        UDRS->generation++;
                if (drive_no_geom(drive)) {
                        /* auto-sensing */
-                       res = __floppy_read_block_0(opened_bdev[drive]);
+                       res = __floppy_read_block_0(opened_bdev[drive], drive);
                } else {
                        if (cf)
                                poll_drive(false, FD_RAW_NEED_DISK);
@@ -4077,6 +4113,13 @@ static ssize_t floppy_cmos_show(struct device *dev,
 
 static DEVICE_ATTR(cmos, S_IRUGO, floppy_cmos_show, NULL);
 
+static struct attribute *floppy_dev_attrs[] = {
+       &dev_attr_cmos.attr,
+       NULL
+};
+
+ATTRIBUTE_GROUPS(floppy_dev);
+
 static void floppy_device_release(struct device *dev)
 {
 }
@@ -4289,16 +4332,12 @@ static int __init do_floppy_init(void)
                floppy_device[drive].name = floppy_device_name;
                floppy_device[drive].id = drive;
                floppy_device[drive].dev.release = floppy_device_release;
+               floppy_device[drive].dev.groups = floppy_dev_groups;
 
                err = platform_device_register(&floppy_device[drive]);
                if (err)
                        goto out_remove_drives;
 
-               err = device_create_file(&floppy_device[drive].dev,
-                                        &dev_attr_cmos);
-               if (err)
-                       goto out_unreg_platform_dev;
-
                /* to be cleaned up... */
                disks[drive]->private_data = (void *)(long)drive;
                disks[drive]->flags |= GENHD_FL_REMOVABLE;
@@ -4308,13 +4347,10 @@ static int __init do_floppy_init(void)
 
        return 0;
 
-out_unreg_platform_dev:
-       platform_device_unregister(&floppy_device[drive]);
 out_remove_drives:
        while (drive--) {
                if (floppy_available(drive)) {
                        del_gendisk(disks[drive]);
-                       device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
                        platform_device_unregister(&floppy_device[drive]);
                }
        }
@@ -4559,7 +4595,6 @@ static void __exit floppy_module_exit(void)
 
                if (floppy_available(drive)) {
                        del_gendisk(disks[drive]);
-                       device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
                        platform_device_unregister(&floppy_device[drive]);
                }
                blk_cleanup_queue(disks[drive]->queue);