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.c139
1 files changed, 60 insertions, 79 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 4e7dbcc425ff..bc9b2bcd7dba 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -58,6 +58,7 @@
58#include <linux/suspend.h> 58#include <linux/suspend.h>
59#include <scsi/scsi_cmnd.h> 59#include <scsi/scsi_cmnd.h>
60#include <scsi/scsi_ioctl.h> 60#include <scsi/scsi_ioctl.h>
61#include <scsi/scsi.h>
61 62
62#include <asm/uaccess.h> 63#include <asm/uaccess.h>
63 64
@@ -380,6 +381,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
380 memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE); 381 memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
381 if (sizeof(rq->cmd) > CDROM_PACKET_SIZE) 382 if (sizeof(rq->cmd) > CDROM_PACKET_SIZE)
382 memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE); 383 memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE);
384 rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
383 385
384 rq->ref_count++; 386 rq->ref_count++;
385 rq->flags |= REQ_NOMERGE; 387 rq->flags |= REQ_NOMERGE;
@@ -645,7 +647,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 647 * b) The data can be used as cache to avoid read requests if we receive a
646 * new write request for the same zone. 648 * new write request for the same zone.
647 */ 649 */
648static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, int *offsets) 650static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec)
649{ 651{
650 int f, p, offs; 652 int f, p, offs;
651 653
@@ -653,15 +655,15 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, in
653 p = 0; 655 p = 0;
654 offs = 0; 656 offs = 0;
655 for (f = 0; f < pkt->frames; f++) { 657 for (f = 0; f < pkt->frames; f++) {
656 if (pages[f] != pkt->pages[p]) { 658 if (bvec[f].bv_page != pkt->pages[p]) {
657 void *vfrom = kmap_atomic(pages[f], KM_USER0) + offsets[f]; 659 void *vfrom = kmap_atomic(bvec[f].bv_page, KM_USER0) + bvec[f].bv_offset;
658 void *vto = page_address(pkt->pages[p]) + offs; 660 void *vto = page_address(pkt->pages[p]) + offs;
659 memcpy(vto, vfrom, CD_FRAMESIZE); 661 memcpy(vto, vfrom, CD_FRAMESIZE);
660 kunmap_atomic(vfrom, KM_USER0); 662 kunmap_atomic(vfrom, KM_USER0);
661 pages[f] = pkt->pages[p]; 663 bvec[f].bv_page = pkt->pages[p];
662 offsets[f] = offs; 664 bvec[f].bv_offset = offs;
663 } else { 665 } else {
664 BUG_ON(offsets[f] != offs); 666 BUG_ON(bvec[f].bv_offset != offs);
665 } 667 }
666 offs += CD_FRAMESIZE; 668 offs += CD_FRAMESIZE;
667 if (offs >= PAGE_SIZE) { 669 if (offs >= PAGE_SIZE) {
@@ -991,18 +993,17 @@ try_next_bio:
991static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) 993static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
992{ 994{
993 struct bio *bio; 995 struct bio *bio;
994 struct page *pages[PACKET_MAX_SIZE];
995 int offsets[PACKET_MAX_SIZE];
996 int f; 996 int f;
997 int frames_write; 997 int frames_write;
998 struct bio_vec *bvec = pkt->w_bio->bi_io_vec;
998 999
999 for (f = 0; f < pkt->frames; f++) { 1000 for (f = 0; f < pkt->frames; f++) {
1000 pages[f] = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; 1001 bvec[f].bv_page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE];
1001 offsets[f] = (f * CD_FRAMESIZE) % PAGE_SIZE; 1002 bvec[f].bv_offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
1002 } 1003 }
1003 1004
1004 /* 1005 /*
1005 * Fill-in pages[] and offsets[] with data from orig_bios. 1006 * Fill-in bvec with data from orig_bios.
1006 */ 1007 */
1007 frames_write = 0; 1008 frames_write = 0;
1008 spin_lock(&pkt->lock); 1009 spin_lock(&pkt->lock);
@@ -1024,11 +1025,11 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1024 } 1025 }
1025 1026
1026 if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) { 1027 if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) {
1027 pages[f] = src_bvl->bv_page; 1028 bvec[f].bv_page = src_bvl->bv_page;
1028 offsets[f] = src_bvl->bv_offset + src_offs; 1029 bvec[f].bv_offset = src_bvl->bv_offset + src_offs;
1029 } else { 1030 } else {
1030 pkt_copy_bio_data(bio, segment, src_offs, 1031 pkt_copy_bio_data(bio, segment, src_offs,
1031 pages[f], offsets[f]); 1032 bvec[f].bv_page, bvec[f].bv_offset);
1032 } 1033 }
1033 src_offs += CD_FRAMESIZE; 1034 src_offs += CD_FRAMESIZE;
1034 frames_write++; 1035 frames_write++;
@@ -1042,7 +1043,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1042 BUG_ON(frames_write != pkt->write_size); 1043 BUG_ON(frames_write != pkt->write_size);
1043 1044
1044 if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) { 1045 if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) {
1045 pkt_make_local_copy(pkt, pages, offsets); 1046 pkt_make_local_copy(pkt, bvec);
1046 pkt->cache_valid = 1; 1047 pkt->cache_valid = 1;
1047 } else { 1048 } else {
1048 pkt->cache_valid = 0; 1049 pkt->cache_valid = 0;
@@ -1055,17 +1056,9 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1055 pkt->w_bio->bi_bdev = pd->bdev; 1056 pkt->w_bio->bi_bdev = pd->bdev;
1056 pkt->w_bio->bi_end_io = pkt_end_io_packet_write; 1057 pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
1057 pkt->w_bio->bi_private = pkt; 1058 pkt->w_bio->bi_private = pkt;
1058 for (f = 0; f < pkt->frames; f++) { 1059 for (f = 0; f < pkt->frames; f++)
1059 if ((f + 1 < pkt->frames) && (pages[f + 1] == pages[f]) && 1060 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)) { 1061 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); 1062 VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt);
1070 1063
1071 atomic_set(&pkt->io_wait, 1); 1064 atomic_set(&pkt->io_wait, 1);
@@ -1504,40 +1497,42 @@ static int pkt_set_write_settings(struct pktcdvd_device *pd)
1504} 1497}
1505 1498
1506/* 1499/*
1507 * 0 -- we can write to this track, 1 -- we can't 1500 * 1 -- we can write to this track, 0 -- we can't
1508 */ 1501 */
1509static int pkt_good_track(track_information *ti) 1502static int pkt_writable_track(struct pktcdvd_device *pd, track_information *ti)
1510{ 1503{
1511 /* 1504 switch (pd->mmc3_profile) {
1512 * only good for CD-RW at the moment, not DVD-RW 1505 case 0x1a: /* DVD+RW */
1513 */ 1506 case 0x12: /* DVD-RAM */
1507 /* The track is always writable on DVD+RW/DVD-RAM */
1508 return 1;
1509 default:
1510 break;
1511 }
1514 1512
1515 /* 1513 if (!ti->packet || !ti->fp)
1516 * FIXME: only for FP
1517 */
1518 if (ti->fp == 0)
1519 return 0; 1514 return 0;
1520 1515
1521 /* 1516 /*
1522 * "good" settings as per Mt Fuji. 1517 * "good" settings as per Mt Fuji.
1523 */ 1518 */
1524 if (ti->rt == 0 && ti->blank == 0 && ti->packet == 1) 1519 if (ti->rt == 0 && ti->blank == 0)
1525 return 0; 1520 return 1;
1526 1521
1527 if (ti->rt == 0 && ti->blank == 1 && ti->packet == 1) 1522 if (ti->rt == 0 && ti->blank == 1)
1528 return 0; 1523 return 1;
1529 1524
1530 if (ti->rt == 1 && ti->blank == 0 && ti->packet == 1) 1525 if (ti->rt == 1 && ti->blank == 0)
1531 return 0; 1526 return 1;
1532 1527
1533 printk("pktcdvd: bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet); 1528 printk("pktcdvd: bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet);
1534 return 1; 1529 return 0;
1535} 1530}
1536 1531
1537/* 1532/*
1538 * 0 -- we can write to this disc, 1 -- we can't 1533 * 1 -- we can write to this disc, 0 -- we can't
1539 */ 1534 */
1540static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di) 1535static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di)
1541{ 1536{
1542 switch (pd->mmc3_profile) { 1537 switch (pd->mmc3_profile) {
1543 case 0x0a: /* CD-RW */ 1538 case 0x0a: /* CD-RW */
@@ -1546,10 +1541,10 @@ static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di)
1546 case 0x1a: /* DVD+RW */ 1541 case 0x1a: /* DVD+RW */
1547 case 0x13: /* DVD-RW */ 1542 case 0x13: /* DVD-RW */
1548 case 0x12: /* DVD-RAM */ 1543 case 0x12: /* DVD-RAM */
1549 return 0;
1550 default:
1551 printk("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile);
1552 return 1; 1544 return 1;
1545 default:
1546 VPRINTK("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile);
1547 return 0;
1553 } 1548 }
1554 1549
1555 /* 1550 /*
@@ -1558,25 +1553,25 @@ static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di)
1558 */ 1553 */
1559 if (di->disc_type == 0xff) { 1554 if (di->disc_type == 0xff) {
1560 printk("pktcdvd: Unknown disc. No track?\n"); 1555 printk("pktcdvd: Unknown disc. No track?\n");
1561 return 1; 1556 return 0;
1562 } 1557 }
1563 1558
1564 if (di->disc_type != 0x20 && di->disc_type != 0) { 1559 if (di->disc_type != 0x20 && di->disc_type != 0) {
1565 printk("pktcdvd: Wrong disc type (%x)\n", di->disc_type); 1560 printk("pktcdvd: Wrong disc type (%x)\n", di->disc_type);
1566 return 1; 1561 return 0;
1567 } 1562 }
1568 1563
1569 if (di->erasable == 0) { 1564 if (di->erasable == 0) {
1570 printk("pktcdvd: Disc not erasable\n"); 1565 printk("pktcdvd: Disc not erasable\n");
1571 return 1; 1566 return 0;
1572 } 1567 }
1573 1568
1574 if (di->border_status == PACKET_SESSION_RESERVED) { 1569 if (di->border_status == PACKET_SESSION_RESERVED) {
1575 printk("pktcdvd: Can't write to last track (reserved)\n"); 1570 printk("pktcdvd: Can't write to last track (reserved)\n");
1576 return 1; 1571 return 0;
1577 } 1572 }
1578 1573
1579 return 0; 1574 return 1;
1580} 1575}
1581 1576
1582static int pkt_probe_settings(struct pktcdvd_device *pd) 1577static int pkt_probe_settings(struct pktcdvd_device *pd)
@@ -1601,23 +1596,9 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
1601 return ret; 1596 return ret;
1602 } 1597 }
1603 1598
1604 if (pkt_good_disc(pd, &di)) 1599 if (!pkt_writable_disc(pd, &di))
1605 return -ENXIO; 1600 return -EROFS;
1606 1601
1607 switch (pd->mmc3_profile) {
1608 case 0x1a: /* DVD+RW */
1609 printk("pktcdvd: inserted media is DVD+RW\n");
1610 break;
1611 case 0x13: /* DVD-RW */
1612 printk("pktcdvd: inserted media is DVD-RW\n");
1613 break;
1614 case 0x12: /* DVD-RAM */
1615 printk("pktcdvd: inserted media is DVD-RAM\n");
1616 break;
1617 default:
1618 printk("pktcdvd: inserted media is CD-R%s\n", di.erasable ? "W" : "");
1619 break;
1620 }
1621 pd->type = di.erasable ? PACKET_CDRW : PACKET_CDR; 1602 pd->type = di.erasable ? PACKET_CDRW : PACKET_CDR;
1622 1603
1623 track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */ 1604 track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */
@@ -1626,9 +1607,9 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
1626 return ret; 1607 return ret;
1627 } 1608 }
1628 1609
1629 if (pkt_good_track(&ti)) { 1610 if (!pkt_writable_track(pd, &ti)) {
1630 printk("pktcdvd: can't write to this track\n"); 1611 printk("pktcdvd: can't write to this track\n");
1631 return -ENXIO; 1612 return -EROFS;
1632 } 1613 }
1633 1614
1634 /* 1615 /*
@@ -1642,7 +1623,7 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
1642 } 1623 }
1643 if (pd->settings.size > PACKET_MAX_SECTORS) { 1624 if (pd->settings.size > PACKET_MAX_SECTORS) {
1644 printk("pktcdvd: packet size is too big\n"); 1625 printk("pktcdvd: packet size is too big\n");
1645 return -ENXIO; 1626 return -EROFS;
1646 } 1627 }
1647 pd->settings.fp = ti.fp; 1628 pd->settings.fp = ti.fp;
1648 pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1); 1629 pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1);
@@ -1684,7 +1665,7 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
1684 break; 1665 break;
1685 default: 1666 default:
1686 printk("pktcdvd: unknown data mode\n"); 1667 printk("pktcdvd: unknown data mode\n");
1687 return 1; 1668 return -EROFS;
1688 } 1669 }
1689 return 0; 1670 return 0;
1690} 1671}
@@ -1894,8 +1875,8 @@ static int pkt_open_write(struct pktcdvd_device *pd)
1894 unsigned int write_speed, media_write_speed, read_speed; 1875 unsigned int write_speed, media_write_speed, read_speed;
1895 1876
1896 if ((ret = pkt_probe_settings(pd))) { 1877 if ((ret = pkt_probe_settings(pd))) {
1897 DPRINTK("pktcdvd: %s failed probe\n", pd->name); 1878 VPRINTK("pktcdvd: %s failed probe\n", pd->name);
1898 return -EIO; 1879 return ret;
1899 } 1880 }
1900 1881
1901 if ((ret = pkt_set_write_settings(pd))) { 1882 if ((ret = pkt_set_write_settings(pd))) {
@@ -2053,10 +2034,9 @@ static int pkt_open(struct inode *inode, struct file *file)
2053 goto out_dec; 2034 goto out_dec;
2054 } 2035 }
2055 } else { 2036 } else {
2056 if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) { 2037 ret = pkt_open_dev(pd, file->f_mode & FMODE_WRITE);
2057 ret = -EIO; 2038 if (ret)
2058 goto out_dec; 2039 goto out_dec;
2059 }
2060 /* 2040 /*
2061 * needed here as well, since ext2 (among others) may change 2041 * needed here as well, since ext2 (among others) may change
2062 * the blocksize at mount time 2042 * the blocksize at mount time
@@ -2436,11 +2416,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 2416 * The door gets locked when the device is opened, so we
2437 * have to unlock it or else the eject command fails. 2417 * have to unlock it or else the eject command fails.
2438 */ 2418 */
2439 pkt_lock_door(pd, 0); 2419 if (pd->refcnt == 1)
2420 pkt_lock_door(pd, 0);
2440 return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); 2421 return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
2441 2422
2442 default: 2423 default:
2443 printk("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); 2424 VPRINTK("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd);
2444 return -ENOTTY; 2425 return -ENOTTY;
2445 } 2426 }
2446 2427