summaryrefslogtreecommitdiff
path: root/drivers/block/floppy.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-04-28 14:39:37 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-04-28 14:39:37 -0700
commitfc0586062816559defb14c947319ef8c4c326fb3 (patch)
tree5ca73bd1fc9de596a11e6d3549fd8fbf6f87dafc /drivers/block/floppy.c
parent6c0029211382011af508273c4fc98a732f841d95 (diff)
parent8324fbae75ce65fc2eb960a8434799dca48248ac (diff)
Merge tag 'for-5.13/drivers-2021-04-27' of git://git.kernel.dk/linux-block
Pull block driver updates from Jens Axboe: - MD changes via Song: - raid5 POWER fix - raid1 failure fix - UAF fix for md cluster - mddev_find_or_alloc() clean up - Fix NULL pointer deref with external bitmap - Performance improvement for raid10 discard requests - Fix missing information of /proc/mdstat - rsxx const qualifier removal (Arnd) - Expose allocated brd pages (Calvin) - rnbd via Gioh Kim: - Change maintainer - Change domain address of maintainers' email - Add polling IO mode and document update - Fix memory leak and some bug detected by static code analysis tools - Code refactoring - Series of floppy cleanups/fixes (Denis) - s390 dasd fixes (Julian) - kerneldoc fixes (Lee) - null_blk double free (Lv) - null_blk virtual boundary addition (Max) - Remove xsysace driver (Michal) - umem driver removal (Davidlohr) - ataflop fixes (Dan) - Revalidate disk removal (Christoph) - Bounce buffer cleanups (Christoph) - Mark lightnvm as deprecated (Christoph) - mtip32xx init cleanups (Shixin) - Various fixes (Tian, Gustavo, Coly, Yang, Zhang, Zhiqiang) * tag 'for-5.13/drivers-2021-04-27' of git://git.kernel.dk/linux-block: (143 commits) async_xor: increase src_offs when dropping destination page drivers/block/null_blk/main: Fix a double free in null_init. md/raid1: properly indicate failure when ending a failed write request md-cluster: fix use-after-free issue when removing rdev nvme: introduce generic per-namespace chardev nvme: cleanup nvme_configure_apst nvme: do not try to reconfigure APST when the controller is not live nvme: add 'kato' sysfs attribute nvme: sanitize KATO setting nvmet: avoid queuing keep-alive timer if it is disabled brd: expose number of allocated pages in debugfs ataflop: fix off by one in ataflop_probe() ataflop: potential out of bounds in do_format() drbd: Fix fall-through warnings for Clang block/rnbd: Use strscpy instead of strlcpy block/rnbd-clt-sysfs: Remove copy buffer overlap in rnbd_clt_get_path_name block/rnbd-clt: Remove max_segment_size block/rnbd-clt: Generate kobject_uevent when the rnbd device state changes block/rnbd-srv: Remove unused arguments of rnbd_srv_rdma_ev Documentation/ABI/rnbd-clt: Add description for nr_poll_queues ...
Diffstat (limited to 'drivers/block/floppy.c')
-rw-r--r--drivers/block/floppy.c159
1 files changed, 33 insertions, 126 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 4aa9683ee0c1..8a9d22207c59 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -145,8 +145,6 @@
* Better audit of register_blkdev.
*/
-#undef FLOPPY_SILENT_DCL_CLEAR
-
#define REALLY_SLOW_IO
#define DEBUGT 2
@@ -2399,11 +2397,10 @@ static void rw_interrupt(void)
probing = 0;
}
- if (CT(raw_cmd->cmd[COMMAND]) != FD_READ ||
- raw_cmd->kernel_data == bio_data(current_req->bio)) {
+ if (CT(raw_cmd->cmd[COMMAND]) != FD_READ) {
/* transfer directly from buffer */
cont->done(1);
- } else if (CT(raw_cmd->cmd[COMMAND]) == FD_READ) {
+ } else {
buffer_track = raw_cmd->track;
buffer_drive = current_drive;
INFBOUND(buffer_max, nr_sectors + fsector_t);
@@ -2411,27 +2408,6 @@ static void rw_interrupt(void)
cont->redo();
}
-/* Compute maximal contiguous buffer size. */
-static int buffer_chain_size(void)
-{
- struct bio_vec bv;
- int size;
- struct req_iterator iter;
- char *base;
-
- base = bio_data(current_req->bio);
- size = 0;
-
- rq_for_each_segment(bv, current_req, iter) {
- if (page_address(bv.bv_page) + bv.bv_offset != base + size)
- break;
-
- size += bv.bv_len;
- }
-
- return size >> 9;
-}
-
/* Compute the maximal transfer size */
static int transfer_size(int ssize, int max_sector, int max_size)
{
@@ -2453,7 +2429,6 @@ 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;
- char *buffer;
char *dma_buffer;
int size;
struct req_iterator iter;
@@ -2492,8 +2467,6 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
size = bv.bv_len;
SUPBOUND(size, remaining);
-
- 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) {
@@ -2509,13 +2482,13 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
pr_info("write\n");
break;
}
- if (((unsigned long)buffer) % 512)
- DPRINT("%p buffer not aligned\n", buffer);
if (CT(raw_cmd->cmd[COMMAND]) == FD_READ)
- memcpy(buffer, dma_buffer, size);
+ memcpy_to_page(bv.bv_page, bv.bv_offset, dma_buffer,
+ size);
else
- memcpy(dma_buffer, buffer, size);
+ memcpy_from_page(dma_buffer, bv.bv_page, bv.bv_offset,
+ size);
remaining -= size;
dma_buffer += size;
@@ -2690,54 +2663,6 @@ static int make_raw_rw_request(void)
raw_cmd->flags &= ~FD_RAW_WRITE;
raw_cmd->flags |= FD_RAW_READ;
raw_cmd->cmd[COMMAND] = FM_MODE(_floppy, FD_READ);
- } else if ((unsigned long)bio_data(current_req->bio) < MAX_DMA_ADDRESS) {
- unsigned long dma_limit;
- int direct, indirect;
-
- indirect =
- transfer_size(ssize, max_sector,
- max_buffer_sectors * 2) - fsector_t;
-
- /*
- * Do NOT use minimum() here---MAX_DMA_ADDRESS is 64 bits wide
- * on a 64 bit machine!
- */
- max_size = buffer_chain_size();
- dma_limit = (MAX_DMA_ADDRESS -
- ((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(bio_data(current_req->bio), max_size << 9))
- max_size = (K_64 -
- ((unsigned long)bio_data(current_req->bio)) %
- K_64) >> 9;
- direct = transfer_size(ssize, max_sector, max_size) - fsector_t;
- /*
- * We try to read tracks, but if we get too many errors, we
- * go back to reading just one sector at a time.
- *
- * This means we should be able to read a sector even if there
- * are other bad sectors on this track.
- */
- if (!direct ||
- (indirect * 2 > direct * 3 &&
- *errors < drive_params[current_drive].max_errors.read_track &&
- ((!probing ||
- (drive_params[current_drive].read_track & (1 << drive_state[current_drive].probed_format)))))) {
- max_size = blk_rq_sectors(current_req);
- } else {
- 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__);
- DPRINT("indirect=%d direct=%d fsector_t=%d\n",
- indirect, direct, fsector_t);
- return 0;
- }
- virtualdmabug_workaround();
- return 2;
- }
}
if (CT(raw_cmd->cmd[COMMAND]) == FD_READ)
@@ -2781,19 +2706,17 @@ 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 != bio_data(current_req->bio) &&
- CT(raw_cmd->cmd[COMMAND]) == FD_WRITE &&
+ (CT(raw_cmd->cmd[COMMAND]) == FD_WRITE &&
(aligned_sector_t + (raw_cmd->length >> 9) > buffer_max ||
aligned_sector_t < buffer_min)) ||
raw_cmd->length % (128 << raw_cmd->cmd[SIZECODE]) ||
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 != bio_data(current_req->bio))
- pr_info("addr=%d, length=%ld\n",
- (int)((raw_cmd->kernel_data -
- floppy_track_buffer) >> 9),
- current_count_sectors);
+ pr_info("addr=%d, length=%ld\n",
+ (int)((raw_cmd->kernel_data -
+ floppy_track_buffer) >> 9),
+ current_count_sectors);
pr_info("st=%d ast=%d mse=%d msi=%d\n",
fsector_t, aligned_sector_t, max_sector, max_size);
pr_info("ssize=%x SIZECODE=%d\n", ssize, raw_cmd->cmd[SIZECODE]);
@@ -2807,31 +2730,21 @@ static int make_raw_rw_request(void)
return 0;
}
- 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 ||
- raw_cmd->kernel_data + raw_cmd->length >
- floppy_track_buffer + (max_buffer_sectors << 10)) {
- DPRINT("buffer overrun in schedule dma\n");
- pr_info("fsector_t=%d buffer_min=%d current_count=%ld\n",
- fsector_t, buffer_min, raw_cmd->length >> 9);
- pr_info("current_count_sectors=%ld\n",
- current_count_sectors);
- if (CT(raw_cmd->cmd[COMMAND]) == FD_READ)
- pr_info("read\n");
- if (CT(raw_cmd->cmd[COMMAND]) == FD_WRITE)
- pr_info("write\n");
- return 0;
- }
- } else if (raw_cmd->length > blk_rq_bytes(current_req) ||
- current_count_sectors > blk_rq_sectors(current_req)) {
- DPRINT("buffer overrun in direct transfer\n");
+ if (raw_cmd->kernel_data < floppy_track_buffer ||
+ current_count_sectors < 0 ||
+ raw_cmd->length < 0 ||
+ raw_cmd->kernel_data + raw_cmd->length >
+ floppy_track_buffer + (max_buffer_sectors << 10)) {
+ DPRINT("buffer overrun in schedule dma\n");
+ pr_info("fsector_t=%d buffer_min=%d current_count=%ld\n",
+ fsector_t, buffer_min, raw_cmd->length >> 9);
+ pr_info("current_count_sectors=%ld\n",
+ current_count_sectors);
+ if (CT(raw_cmd->cmd[COMMAND]) == FD_READ)
+ pr_info("read\n");
+ if (CT(raw_cmd->cmd[COMMAND]) == FD_WRITE)
+ pr_info("write\n");
return 0;
- } else if (raw_cmd->length < current_count_sectors << 9) {
- DPRINT("more sectors than bytes\n");
- pr_info("bytes=%ld\n", raw_cmd->length >> 9);
- pr_info("sectors=%ld\n", current_count_sectors);
}
if (raw_cmd->length == 0) {
DPRINT("zero dma transfer attempted from make_raw_request\n");
@@ -3073,8 +2986,6 @@ static const char *drive_name(int type, int drive)
/* raw commands */
static void raw_cmd_done(int flag)
{
- int i;
-
if (!flag) {
raw_cmd->flags |= FD_RAW_FAILURE;
raw_cmd->flags |= FD_RAW_HARDFAILURE;
@@ -3082,8 +2993,7 @@ static void raw_cmd_done(int flag)
raw_cmd->reply_count = inr;
if (raw_cmd->reply_count > FD_RAW_REPLY_SIZE)
raw_cmd->reply_count = 0;
- for (i = 0; i < raw_cmd->reply_count; i++)
- raw_cmd->reply[i] = reply_buffer[i];
+ memcpy(raw_cmd->reply, reply_buffer, raw_cmd->reply_count);
if (raw_cmd->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
unsigned long flags;
@@ -3175,7 +3085,6 @@ static int raw_cmd_copyin(int cmd, void __user *param,
{
struct floppy_raw_cmd *ptr;
int ret;
- int i;
*rcmd = NULL;
@@ -3194,8 +3103,7 @@ loop:
if (ptr->cmd_count > FD_RAW_CMD_FULLSIZE)
return -EINVAL;
- for (i = 0; i < FD_RAW_REPLY_SIZE; i++)
- ptr->reply[i] = 0;
+ memset(ptr->reply, 0, FD_RAW_REPLY_SIZE);
ptr->resultcode = 0;
if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
@@ -4317,7 +4225,7 @@ static char __init get_fdc_version(int fdc)
r = result(fdc);
if (r <= 0x00)
return FDC_NONE; /* No FDC present ??? */
- if ((r == 1) && (reply_buffer[0] == 0x80)) {
+ if ((r == 1) && (reply_buffer[ST0] == 0x80)) {
pr_info("FDC %d is an 8272A\n", fdc);
return FDC_8272A; /* 8272a/765 don't know DUMPREGS */
}
@@ -4342,12 +4250,12 @@ static char __init get_fdc_version(int fdc)
output_byte(fdc, FD_UNLOCK);
r = result(fdc);
- if ((r == 1) && (reply_buffer[0] == 0x80)) {
+ if ((r == 1) && (reply_buffer[ST0] == 0x80)) {
pr_info("FDC %d is a pre-1991 82077\n", fdc);
return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know
* LOCK/UNLOCK */
}
- if ((r != 1) || (reply_buffer[0] != 0x00)) {
+ if ((r != 1) || (reply_buffer[ST0] != 0x00)) {
pr_info("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
fdc, r);
return FDC_UNKNOWN;
@@ -4359,11 +4267,11 @@ static char __init get_fdc_version(int fdc)
fdc, r);
return FDC_UNKNOWN;
}
- if (reply_buffer[0] == 0x80) {
+ if (reply_buffer[ST0] == 0x80) {
pr_info("FDC %d is a post-1991 82077\n", fdc);
return FDC_82077; /* Revised 82077AA passes all the tests */
}
- switch (reply_buffer[0] >> 5) {
+ switch (reply_buffer[ST0] >> 5) {
case 0x0:
/* Either a 82078-1 or a 82078SL running at 5Volt */
pr_info("FDC %d is an 82078.\n", fdc);
@@ -4379,7 +4287,7 @@ static char __init get_fdc_version(int fdc)
return FDC_87306;
default:
pr_info("FDC %d init: 82078 variant with unknown PARTID=%d.\n",
- fdc, reply_buffer[0] >> 5);
+ fdc, reply_buffer[ST0] >> 5);
return FDC_82078_UNKN;
}
} /* get_fdc_version */
@@ -4597,7 +4505,6 @@ static int floppy_alloc_disk(unsigned int drive, unsigned int type)
return err;
}
- blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH);
blk_queue_max_hw_sectors(disk->queue, 64);
disk->major = FLOPPY_MAJOR;
disk->first_minor = TOMINOR(drive) | (type << 2);