Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

swim3: support highmem

swim3 only uses the virtual address of a bio to stash it into the data
transfer using virt_to_bus. But the ppc32 virt_to_bus just uses the
physical address with an offset. Replace virt_to_bus with a local hack
that performs the equivalent transformation and stop asking for block
layer bounce buffering.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20210406061839.811588-1-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
b60b270b 3d86739c

+25 -9
+25 -9
drivers/block/swim3.c
··· 234 234 }; 235 235 236 236 static void seek_track(struct floppy_state *fs, int n); 237 - static void init_dma(struct dbdma_cmd *cp, int cmd, void *buf, int count); 238 237 static void act(struct floppy_state *fs); 239 238 static void scan_timeout(struct timer_list *t); 240 239 static void seek_timeout(struct timer_list *t); ··· 403 404 fs->settle_time = 0; 404 405 } 405 406 407 + /* 408 + * XXX: this is a horrible hack, but at least allows ppc32 to get 409 + * out of defining virt_to_bus, and this driver out of using the 410 + * deprecated block layer bounce buffering for highmem addresses 411 + * for no good reason. 412 + */ 413 + static unsigned long swim3_phys_to_bus(phys_addr_t paddr) 414 + { 415 + return paddr + PCI_DRAM_OFFSET; 416 + } 417 + 418 + static phys_addr_t swim3_bio_phys(struct bio *bio) 419 + { 420 + return page_to_phys(bio_page(bio)) + bio_offset(bio); 421 + } 422 + 406 423 static inline void init_dma(struct dbdma_cmd *cp, int cmd, 407 - void *buf, int count) 424 + phys_addr_t paddr, int count) 408 425 { 409 426 cp->req_count = cpu_to_le16(count); 410 427 cp->command = cpu_to_le16(cmd); 411 - cp->phy_addr = cpu_to_le32(virt_to_bus(buf)); 428 + cp->phy_addr = cpu_to_le32(swim3_phys_to_bus(paddr)); 412 429 cp->xfer_status = 0; 413 430 } 414 431 ··· 456 441 out_8(&sw->sector, fs->req_sector); 457 442 out_8(&sw->nsect, n); 458 443 out_8(&sw->gap3, 0); 459 - out_le32(&dr->cmdptr, virt_to_bus(cp)); 444 + out_le32(&dr->cmdptr, swim3_phys_to_bus(virt_to_phys(cp))); 460 445 if (rq_data_dir(req) == WRITE) { 461 446 /* Set up 3 dma commands: write preamble, data, postamble */ 462 - init_dma(cp, OUTPUT_MORE, write_preamble, sizeof(write_preamble)); 447 + init_dma(cp, OUTPUT_MORE, virt_to_phys(write_preamble), 448 + sizeof(write_preamble)); 463 449 ++cp; 464 - init_dma(cp, OUTPUT_MORE, bio_data(req->bio), 512); 450 + init_dma(cp, OUTPUT_MORE, swim3_bio_phys(req->bio), 512); 465 451 ++cp; 466 - init_dma(cp, OUTPUT_LAST, write_postamble, sizeof(write_postamble)); 452 + init_dma(cp, OUTPUT_LAST, virt_to_phys(write_postamble), 453 + sizeof(write_postamble)); 467 454 } else { 468 - init_dma(cp, INPUT_LAST, bio_data(req->bio), n * 512); 455 + init_dma(cp, INPUT_LAST, swim3_bio_phys(req->bio), n * 512); 469 456 } 470 457 ++cp; 471 458 out_le16(&cp->command, DBDMA_STOP); ··· 1218 1201 disk->queue = NULL; 1219 1202 goto out_put_disk; 1220 1203 } 1221 - blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); 1222 1204 disk->queue->queuedata = fs; 1223 1205 1224 1206 rc = swim3_add_device(mdev, floppy_count);