aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/pktcdvd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/pktcdvd.c')
-rw-r--r--drivers/block/pktcdvd.c59
1 files changed, 25 insertions, 34 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 4e7dbcc425ff..93e44d0292ab 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -645,7 +645,7 @@ static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs, struct pag
645 * b) The data can be used as cache to avoid read requests if we receive a 645 * b) The data can be used as cache to avoid read requests if we receive a
646 * new write request for the same zone. 646 * new write request for the same zone.
647 */ 647 */
648static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, int *offsets) 648static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec)
649{ 649{
650 int f, p, offs; 650 int f, p, offs;
651 651
@@ -653,15 +653,15 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, in
653 p = 0; 653 p = 0;
654 offs = 0; 654 offs = 0;
655 for (f = 0; f < pkt->frames; f++) { 655 for (f = 0; f < pkt->frames; f++) {
656 if (pages[f] != pkt->pages[p]) { 656 if (bvec[f].bv_page != pkt->pages[p]) {
657 void *vfrom = kmap_atomic(pages[f], KM_USER0) + offsets[f]; 657 void *vfrom = kmap_atomic(bvec[f].bv_page, KM_USER0) + bvec[f].bv_offset;
658 void *vto = page_address(pkt->pages[p]) + offs; 658 void *vto = page_address(pkt->pages[p]) + offs;
659 memcpy(vto, vfrom, CD_FRAMESIZE); 659 memcpy(vto, vfrom, CD_FRAMESIZE);
660 kunmap_atomic(vfrom, KM_USER0); 660 kunmap_atomic(vfrom, KM_USER0);
661 pages[f] = pkt->pages[p]; 661 bvec[f].bv_page = pkt->pages[p];
662 offsets[f] = offs; 662 bvec[f].bv_offset = offs;
663 } else { 663 } else {
664 BUG_ON(offsets[f] != offs); 664 BUG_ON(bvec[f].bv_offset != offs);
665 } 665 }
666 offs += CD_FRAMESIZE; 666 offs += CD_FRAMESIZE;
667 if (offs >= PAGE_SIZE) { 667 if (offs >= PAGE_SIZE) {
@@ -991,18 +991,17 @@ try_next_bio:
991static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) 991static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
992{ 992{
993 struct bio *bio; 993 struct bio *bio;
994 struct page *pages[PACKET_MAX_SIZE];
995 int offsets[PACKET_MAX_SIZE];
996 int f; 994 int f;
997 int frames_write; 995 int frames_write;
996 struct bio_vec *bvec = pkt->w_bio->bi_io_vec;
998 997
999 for (f = 0; f < pkt->frames; f++) { 998 for (f = 0; f < pkt->frames; f++) {
1000 pages[f] = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; 999 bvec[f].bv_page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE];
1001 offsets[f] = (f * CD_FRAMESIZE) % PAGE_SIZE; 1000 bvec[f].bv_offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
1002 } 1001 }
1003 1002
1004 /* 1003 /*
1005 * Fill-in pages[] and offsets[] with data from orig_bios. 1004 * Fill-in bvec with data from orig_bios.
1006 */ 1005 */
1007 frames_write = 0; 1006 frames_write = 0;
1008 spin_lock(&pkt->lock); 1007 spin_lock(&pkt->lock);
@@ -1024,11 +1023,11 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1024 } 1023 }
1025 1024
1026 if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) { 1025 if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) {
1027 pages[f] = src_bvl->bv_page; 1026 bvec[f].bv_page = src_bvl->bv_page;
1028 offsets[f] = src_bvl->bv_offset + src_offs; 1027 bvec[f].bv_offset = src_bvl->bv_offset + src_offs;
1029 } else { 1028 } else {
1030 pkt_copy_bio_data(bio, segment, src_offs, 1029 pkt_copy_bio_data(bio, segment, src_offs,
1031 pages[f], offsets[f]); 1030 bvec[f].bv_page, bvec[f].bv_offset);
1032 } 1031 }
1033 src_offs += CD_FRAMESIZE; 1032 src_offs += CD_FRAMESIZE;
1034 frames_write++; 1033 frames_write++;
@@ -1042,7 +1041,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1042 BUG_ON(frames_write != pkt->write_size); 1041 BUG_ON(frames_write != pkt->write_size);
1043 1042
1044 if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) { 1043 if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) {
1045 pkt_make_local_copy(pkt, pages, offsets); 1044 pkt_make_local_copy(pkt, bvec);
1046 pkt->cache_valid = 1; 1045 pkt->cache_valid = 1;
1047 } else { 1046 } else {
1048 pkt->cache_valid = 0; 1047 pkt->cache_valid = 0;
@@ -1055,17 +1054,9 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1055 pkt->w_bio->bi_bdev = pd->bdev; 1054 pkt->w_bio->bi_bdev = pd->bdev;
1056 pkt->w_bio->bi_end_io = pkt_end_io_packet_write; 1055 pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
1057 pkt->w_bio->bi_private = pkt; 1056 pkt->w_bio->bi_private = pkt;
1058 for (f = 0; f < pkt->frames; f++) { 1057 for (f = 0; f < pkt->frames; f++)
1059 if ((f + 1 < pkt->frames) && (pages[f + 1] == pages[f]) && 1058 if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
1060 (offsets[f + 1] = offsets[f] + CD_FRAMESIZE)) { 1059 BUG();
1061 if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE * 2, offsets[f]))
1062 BUG();
1063 f++;
1064 } else {
1065 if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE, offsets[f]))
1066 BUG();
1067 }
1068 }
1069 VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt); 1060 VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt);
1070 1061
1071 atomic_set(&pkt->io_wait, 1); 1062 atomic_set(&pkt->io_wait, 1);
@@ -1548,7 +1539,7 @@ static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di)
1548 case 0x12: /* DVD-RAM */ 1539 case 0x12: /* DVD-RAM */
1549 return 0; 1540 return 0;
1550 default: 1541 default:
1551 printk("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile); 1542 VPRINTK("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile);
1552 return 1; 1543 return 1;
1553 } 1544 }
1554 1545
@@ -1894,8 +1885,8 @@ static int pkt_open_write(struct pktcdvd_device *pd)
1894 unsigned int write_speed, media_write_speed, read_speed; 1885 unsigned int write_speed, media_write_speed, read_speed;
1895 1886
1896 if ((ret = pkt_probe_settings(pd))) { 1887 if ((ret = pkt_probe_settings(pd))) {
1897 DPRINTK("pktcdvd: %s failed probe\n", pd->name); 1888 VPRINTK("pktcdvd: %s failed probe\n", pd->name);
1898 return -EIO; 1889 return -EROFS;
1899 } 1890 }
1900 1891
1901 if ((ret = pkt_set_write_settings(pd))) { 1892 if ((ret = pkt_set_write_settings(pd))) {
@@ -2053,10 +2044,9 @@ static int pkt_open(struct inode *inode, struct file *file)
2053 goto out_dec; 2044 goto out_dec;
2054 } 2045 }
2055 } else { 2046 } else {
2056 if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) { 2047 ret = pkt_open_dev(pd, file->f_mode & FMODE_WRITE);
2057 ret = -EIO; 2048 if (ret)
2058 goto out_dec; 2049 goto out_dec;
2059 }
2060 /* 2050 /*
2061 * needed here as well, since ext2 (among others) may change 2051 * needed here as well, since ext2 (among others) may change
2062 * the blocksize at mount time 2052 * the blocksize at mount time
@@ -2436,11 +2426,12 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
2436 * The door gets locked when the device is opened, so we 2426 * The door gets locked when the device is opened, so we
2437 * have to unlock it or else the eject command fails. 2427 * have to unlock it or else the eject command fails.
2438 */ 2428 */
2439 pkt_lock_door(pd, 0); 2429 if (pd->refcnt == 1)
2430 pkt_lock_door(pd, 0);
2440 return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); 2431 return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
2441 2432
2442 default: 2433 default:
2443 printk("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); 2434 VPRINTK("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd);
2444 return -ENOTTY; 2435 return -ENOTTY;
2445 } 2436 }
2446 2437