📄 cdu31a.c.txt
字号:
1393 final_pos_msf[0] = params[4];
1394 final_pos_msf[1] = params[5];
1395 final_pos_msf[2] = params[6];
1396 sony_audio_status = CDROM_AUDIO_PLAY;
1397 return 0;
1398 break;
1399
1400 case CDROMREADTOCHDR: /* Read the table of contents header */
1401 {
1402 struct cdrom_tochdr *hdr;
1403 struct cdrom_tochdr loc_hdr;
1404
1405 sony_get_toc();
1406 if (!sony_toc_read)
1407 {
1408 return -EIO;
1409 }
1410
1411 hdr = (struct cdrom_tochdr *) arg;
1412 verify_area(VERIFY_WRITE, hdr, sizeof(*hdr));
1413 loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
1414 loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
1415 memcpy_tofs(hdr, &loc_hdr, sizeof(*hdr));
1416 }
1417 return 0;
1418 break;
1419
1420 case CDROMREADTOCENTRY: /* Read a given table of contents entry */
1421 {
1422 struct cdrom_tocentry *entry;
1423 struct cdrom_tocentry loc_entry;
1424 int track_idx;
1425 unsigned char *msf_val = NULL;
1426
1427 sony_get_toc();
1428 if (!sony_toc_read)
1429 {
1430 return -EIO;
1431 }
1432
1433 entry = (struct cdrom_tocentry *) arg;
1434 verify_area(VERIFY_READ, entry, sizeof(*entry));
1435 verify_area(VERIFY_WRITE, entry, sizeof(*entry));
1436
1437 memcpy_fromfs(&loc_entry, entry, sizeof(loc_entry));
1438
1439 /* Lead out is handled separately since it is special. */
1440 if (loc_entry.cdte_track == CDROM_LEADOUT)
1441 {
1442 loc_entry.cdte_adr = sony_toc->address2;
1443 loc_entry.cdte_ctrl = sony_toc->control2;
1444 msf_val = sony_toc->lead_out_start_msf;
1445 }
1446 else
1447 {
1448 track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
1449 if (track_idx < 0)
1450 {
1451 return -EINVAL;
1452 }
1453
1454 loc_entry.cdte_adr = sony_toc->tracks[track_idx].address;
1455 loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
1456 msf_val = sony_toc->tracks[track_idx].track_start_msf;
1457 }
1458
1459 /* Logical buffer address or MSF format requested? */
1460 if (loc_entry.cdte_format == CDROM_LBA)
1461 {
1462 loc_entry.cdte_addr.lba = msf_to_log(msf_val);
1463 }
1464 else if (loc_entry.cdte_format == CDROM_MSF)
1465 {
1466 loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
1467 loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val+1));
1468 loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val+2));
1469 }
1470 memcpy_tofs(entry, &loc_entry, sizeof(*entry));
1471 }
1472 return 0;
1473 break;
1474
1475 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1476 {
1477 struct cdrom_ti ti;
1478 int track_idx;
1479
1480 sony_get_toc();
1481 if (!sony_toc_read)
1482 {
1483 return -EIO;
1484 }
1485
1486 verify_area(VERIFY_READ, (char *) arg, sizeof(ti));
1487
1488 memcpy_fromfs(&ti, (char *) arg, sizeof(ti));
1489 if ( (ti.cdti_trk0 < sony_toc->first_track_num)
1490 || (ti.cdti_trk0 > sony_toc->last_track_num)
1491 || (ti.cdti_trk1 < ti.cdti_trk0))
1492 {
1493 return -EINVAL;
1494 }
1495
1496 track_idx = find_track(int_to_bcd(ti.cdti_trk0));
1497 if (track_idx < 0)
1498 {
1499 return -EINVAL;
1500 }
1501 params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
1502 params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
1503 params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
1504
1505 /*
1506 * If we want to stop after the last track, use the lead-out
1507 * MSF to do that.
1508 */
1509 if (ti.cdti_trk1 >= bcd_to_int(sony_toc->last_track_num))
1510 {
1511 log_to_msf(msf_to_log(sony_toc->lead_out_start_msf)-1,
1512 &(params[4]));
1513 }
1514 else
1515 {
1516 track_idx = find_track(int_to_bcd(ti.cdti_trk1+1));
1517 if (track_idx < 0)
1518 {
1519 return -EINVAL;
1520 }
1521 log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf)-1,
1522 &(params[4]));
1523 }
1524 params[0] = 0x03;
1525
1526 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1527
1528 do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
1529 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1530 {
1531 printk("Params: %x %x %x %x %x %x %x\n", params[0], params[1],
1532 params[2], params[3], params[4], params[5], params[6]);
1533 printk("Sony CDROM error 0x%2.2x (CDROMPLAYTRKIND\n", res_reg[1]);
1534 return -EIO;
1535 }
1536
1537 /* Save the final position for pauses and resumes */
1538 final_pos_msf[0] = params[4];
1539 final_pos_msf[1] = params[5];
1540 final_pos_msf[2] = params[6];
1541 sony_audio_status = CDROM_AUDIO_PLAY;
1542 return 0;
1543 }
1544
1545 case CDROMSUBCHNL: /* Get subchannel info */
1546 return sony_get_subchnl_info(arg);
1547
1548 case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
1549 {
1550 struct cdrom_volctrl volctrl;
1551
1552 verify_area(VERIFY_READ, (char *) arg, sizeof(volctrl));
1553
1554 memcpy_fromfs(&volctrl, (char *) arg, sizeof(volctrl));
1555 params[0] = SONY_SD_AUDIO_VOLUME;
1556 params[1] = volctrl.channel0;
1557 params[2] = volctrl.channel1;
1558 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, params, 3, res_reg, &res_size);
1559 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1560 {
1561 printk("Sony CDROM error 0x%2.2x (CDROMVOLCTRL)\n", res_reg[1]);
1562 return -EIO;
1563 }
1564 }
1565 return 0;
1566
1567 case CDROMEJECT: /* Eject the drive */
1568 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
1569 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1570
1571 sony_audio_status = CDROM_AUDIO_INVALID;
1572 do_sony_cd_cmd(SONY_EJECT_CMD, NULL, 0, res_reg, &res_size);
1573 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1574 {
1575 printk("Sony CDROM error 0x%2.2x (CDROMEJECT)\n", res_reg[1]);
1576 return -EIO;
1577 }
1578 return 0;
1579 break;
1580
1581 default:
1582 return -EINVAL;
1583 }
1584 }
1585
1586
1587 /*
1588 * Open the drive for operations. Spin the drive up and read the table of
1589 * contents if these have not already been done.
1590 */
1591 static int
1592 scd_open(struct inode *inode,
1593 struct file *filp)
1594 {
1595 unsigned char res_reg[2];
1596 unsigned int res_size;
1597 int num_spin_ups;
1598
1599
1600 if (!sony_spun_up)
1601 {
1602 num_spin_ups = 0;
1603
1604 respinup_on_open:
1605 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1606
1607 /* The drive sometimes returns error 0. I don't know why, but ignore
1608 it. It seems to mean the drive has already done the operation. */
1609 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
1610 {
1611 printk("Sony CDROM error 0x%2.2x (scd_open, spin up)\n", res_reg[1]);
1612 return -EIO;
1613 }
1614
1615 do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
1616
1617 /* The drive sometimes returns error 0. I don't know why, but ignore
1618 it. It seems to mean the drive has already done the operation. */
1619 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
1620 {
1621 /* If the drive is already playing, its ok. */
1622 if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
1623 {
1624 goto drive_spinning;
1625 }
1626
1627 /* If the drive says it is not spun up (even though we just did it!)
1628 then retry the operation at least a few times. */
1629 if ( (res_reg[1] == SONY_NOT_SPIN_ERR)
1630 && (num_spin_ups < MAX_CDU31A_RETRIES))
1631 {
1632 num_spin_ups++;
1633 goto respinup_on_open;
1634 }
1635
1636 printk("Sony CDROM error 0x%2.2x (scd_open, read toc)\n", res_reg[1]);
1637 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1638
1639 return -EIO;
1640 }
1641
1642 sony_get_toc();
1643 if (!sony_toc_read)
1644 {
1645 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1646 return -EIO;
1647 }
1648
1649 sony_spun_up = 1;
1650 }
1651
1652 drive_spinning:
1653
1654 if (inode)
1655 {
1656 check_disk_change(inode->i_rdev);
1657 }
1658
1659 sony_usage++;
1660
1661 return 0;
1662 }
1663
1664
1665 /*
1666 * Close the drive. Spin it down if no task is using it. The spin
1667 * down will fail if playing audio, so audio play is OK.
1668 */
1669 static void
1670 scd_release(struct inode *inode,
1671 struct file *filp)
1672 {
1673 unsigned char res_reg[2];
1674 unsigned int res_size;
1675
1676
1677 if (sony_usage > 0)
1678 {
1679 sony_usage--;
1680 }
1681 if (sony_usage == 0)
1682 {
1683 sync_dev(inode->i_rdev);
1684 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1685
1686 sony_spun_up = 0;
1687 }
1688 }
1689
1690
1691 static struct file_operations scd_fops = {
1692 NULL, /* lseek - default */
1693 block_read, /* read - general block-dev read */
1694 block_write, /* write - general block-dev write */
1695 NULL, /* readdir - bad */
1696 NULL, /* select */
1697 scd_ioctl, /* ioctl */
1698 NULL, /* mmap */
1699 scd_open, /* open */
1700 scd_release, /* release */
1701 NULL /* fsync */
1702 };
1703
1704
1705 /* The different types of disc loading mechanisms supported */
1706 static char *load_mech[] = { "caddy", "tray", "pop-up", "unknown" };
1707
1708 /* Read-ahead buffer sizes for different drives. These are just arbitrary
1709 values, I don't know what is really optimum. */
1710 static unsigned int mem_size[] = { 16384, 16384, 16384, 2048 };
1711
1712 void
1713 get_drive_configuration(unsigned short base_io,
1714 unsigned char res_reg[],
1715 unsigned int *res_size)
1716 {
1717 int retry_count;
1718
1719
1720 /* Set the base address */
1721 sony_cd_base_io = base_io;
1722
1723 /* Set up all the register locations */
1724 sony_cd_cmd_reg = sony_cd_base_io + SONY_CMD_REG_OFFSET;
1725 sony_cd_param_reg = sony_cd_base_io + SONY_PARAM_REG_OFFSET;
1726 sony_cd_write_reg = sony_cd_base_io + SONY_WRITE_REG_OFFSET;
1727 sony_cd_control_reg = sony_cd_base_io + SONY_CONTROL_REG_OFFSET;
1728 sony_cd_status_reg = sony_cd_base_io + SONY_STATUS_REG_OFFSET;
1729 sony_cd_result_reg = sony_cd_base_io + SONY_RESULT_REG_OFFSET;
1730 sony_cd_read_reg = sony_cd_base_io + SONY_READ_REG_OFFSET;
1731 sony_cd_fifost_reg = sony_cd_base_io + SONY_FIFOST_REG_OFFSET;
1732
1733 /*
1734 * Check to see if anything exists at the status register location.
1735 * I don't know if this is a good way to check, but it seems to work
1736 * ok for me.
1737 */
1738 if (read_status_register() != 0xff)
1739 {
1740 /*
1741 * Reset the drive and wait for attention from it (to say its reset).
1742 * If you don't wait, the next operation will probably fail.
1743 */
1744 reset_drive();
1745 retry_count = jiffies + SONY_RESET_TIMEOUT;
1746 while ((retry_count > jiffies) && (!is_attention()))
1747 {
1748 sony_sleep();
1749 }
1750
1751 /* If attention is never seen probably not a CDU31a present */
1752 if (!is_attention())
1753 {
1754 res_reg[0] = 0x20;
1755 return;
1756 }
1757
1758 /*
1759 * Get the drive configuration.
1760 */
1761 do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
1762 NULL,
1763 0,
1764 (unsigned char *) res_reg,
1765 res_size);
1766 return;
1767 }
1768
1769 /* Return an error */
1770 res_reg[0] = 0x20;
1771 }
1772
1773
1774 /*
1775 * Initialize the driver.
1776 */
1777 unsigned long
1778 cdu31a_init(unsigned long mem_start, unsigned long mem_end)
1779 {
1780 struct s_sony_drive_config drive_config;
1781 unsigned int res_size;
1782 int i;
1783 int drive_found;
1784
1785
1786 /*
1787 * According to Alex Freed (freed@europa.orion.adobe.com), this is
1788 * required for the Fusion CD-16 package. If the sound driver is
1789 * loaded, it should work fine, but just in case...
1790 *
1791 * The following turn on the CD-ROM interface for a Fusion CD-16.
1792 */
1793 outb(0xbc, 0x9a01);
1794 outb(0xe2, 0x9a01);
1795
1796 i = 0;
1797 drive_found = 0;
1798 while ( (cdu31a_addresses[i] != 0)
1799 && (!drive_found))
1800 {
1801 if (check_region(cdu31a_addresses[i], 4)) {
1802 i++;
1803 continue;
1804 }
1805 get_drive_configuration(cdu31a_addresses[i],
1806 drive_config.exec_status,
1807 &res_size);
1808 if ((res_size > 2) && ((drive_config.exec_status[0] & 0x20) == 0x00))
1809 {
1810 drive_found = 1;
1811 snarf_region(cdu31a_addresses[i], 4);
1812
1813 if (register_blkdev(MAJOR_NR,"cdu31a",&scd_fops))
1814 {
1815 printk("Unable to get major %d for CDU-31a\n", MAJOR_NR);
1816 return mem_start;
1817 }
1818
1819 sony_buffer_size = mem_size[SONY_HWC_GET_BUF_MEM_SIZE(drive_config)];
1820 sony_buffer_sectors = sony_buffer_size / 2048;
1821
1822 printk("Sony I/F CDROM : %8.8s %16.16s %8.8s with %s load mechanism\n",
1823 drive_config.vendor_id,
1824 drive_config.product_id,
1825 drive_config.product_rev_level,
1826 load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
1827 printk(" using %d byte buffer", sony_buffer_size);
1828 if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
1829 {
1830 printk(", capable of audio playback");
1831 }
1832 printk("\n");
1833
1834 set_drive_params();
1835
1836 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1837 read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
1838
1839 sony_toc = (struct s_sony_toc *) mem_start;
1840 mem_start += sizeof(*sony_toc);
1841 last_sony_subcode = (struct s_sony_subcode *) mem_start;
1842 mem_start += sizeof(*last_sony_subcode);
1843 sony_buffer = (unsigned char *) mem_start;
1844 mem_start += sony_buffer_size;
1845 }
1846
1847 i++;
1848 }
1849
1850 return mem_start;
1851 }
1852
1853
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -