diff options
author | David S. Miller <davem@davemloft.net> | 2008-03-18 02:44:31 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-03-18 02:44:31 -0400 |
commit | 2f633928cbba8a5858bb39b11e7219a41b0fbef5 (patch) | |
tree | 9a82f4b7f2c3afe4b0208d8e44ea61bae90a7d22 /drivers/char/nozomi.c | |
parent | 5e226e4d9016daee170699f8a4188a5505021756 (diff) | |
parent | bde4f8fa8db2abd5ac9c542d76012d0fedab050f (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/char/nozomi.c')
-rw-r--r-- | drivers/char/nozomi.c | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index dfaab2322de3..6d0dc5f9b6bb 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -190,6 +190,14 @@ enum card_type { | |||
190 | F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */ | 190 | F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */ |
191 | }; | 191 | }; |
192 | 192 | ||
193 | /* Initialization states a card can be in */ | ||
194 | enum card_state { | ||
195 | NOZOMI_STATE_UKNOWN = 0, | ||
196 | NOZOMI_STATE_ENABLED = 1, /* pci device enabled */ | ||
197 | NOZOMI_STATE_ALLOCATED = 2, /* config setup done */ | ||
198 | NOZOMI_STATE_READY = 3, /* flowcontrols received */ | ||
199 | }; | ||
200 | |||
193 | /* Two different toggle channels exist */ | 201 | /* Two different toggle channels exist */ |
194 | enum channel_type { | 202 | enum channel_type { |
195 | CH_A = 0, | 203 | CH_A = 0, |
@@ -385,6 +393,7 @@ struct nozomi { | |||
385 | spinlock_t spin_mutex; /* secures access to registers and tty */ | 393 | spinlock_t spin_mutex; /* secures access to registers and tty */ |
386 | 394 | ||
387 | unsigned int index_start; | 395 | unsigned int index_start; |
396 | enum card_state state; | ||
388 | u32 open_ttys; | 397 | u32 open_ttys; |
389 | }; | 398 | }; |
390 | 399 | ||
@@ -686,6 +695,7 @@ static int nozomi_read_config_table(struct nozomi *dc) | |||
686 | dc->last_ier = dc->last_ier | CTRL_DL; | 695 | dc->last_ier = dc->last_ier | CTRL_DL; |
687 | writew(dc->last_ier, dc->reg_ier); | 696 | writew(dc->last_ier, dc->reg_ier); |
688 | 697 | ||
698 | dc->state = NOZOMI_STATE_ALLOCATED; | ||
689 | dev_info(&dc->pdev->dev, "Initialization OK!\n"); | 699 | dev_info(&dc->pdev->dev, "Initialization OK!\n"); |
690 | return 1; | 700 | return 1; |
691 | } | 701 | } |
@@ -944,6 +954,14 @@ static int receive_flow_control(struct nozomi *dc) | |||
944 | case CTRL_APP2: | 954 | case CTRL_APP2: |
945 | port = PORT_APP2; | 955 | port = PORT_APP2; |
946 | enable_ier = APP2_DL; | 956 | enable_ier = APP2_DL; |
957 | if (dc->state == NOZOMI_STATE_ALLOCATED) { | ||
958 | /* | ||
959 | * After card initialization the flow control | ||
960 | * received for APP2 is always the last | ||
961 | */ | ||
962 | dc->state = NOZOMI_STATE_READY; | ||
963 | dev_info(&dc->pdev->dev, "Device READY!\n"); | ||
964 | } | ||
947 | break; | 965 | break; |
948 | default: | 966 | default: |
949 | dev_err(&dc->pdev->dev, | 967 | dev_err(&dc->pdev->dev, |
@@ -1366,22 +1384,12 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1366 | 1384 | ||
1367 | dc->pdev = pdev; | 1385 | dc->pdev = pdev; |
1368 | 1386 | ||
1369 | /* Find out what card type it is */ | ||
1370 | nozomi_get_card_type(dc); | ||
1371 | |||
1372 | ret = pci_enable_device(dc->pdev); | 1387 | ret = pci_enable_device(dc->pdev); |
1373 | if (ret) { | 1388 | if (ret) { |
1374 | dev_err(&pdev->dev, "Failed to enable PCI Device\n"); | 1389 | dev_err(&pdev->dev, "Failed to enable PCI Device\n"); |
1375 | goto err_free; | 1390 | goto err_free; |
1376 | } | 1391 | } |
1377 | 1392 | ||
1378 | start = pci_resource_start(dc->pdev, 0); | ||
1379 | if (start == 0) { | ||
1380 | dev_err(&pdev->dev, "No I/O address for card detected\n"); | ||
1381 | ret = -ENODEV; | ||
1382 | goto err_disable_device; | ||
1383 | } | ||
1384 | |||
1385 | ret = pci_request_regions(dc->pdev, NOZOMI_NAME); | 1393 | ret = pci_request_regions(dc->pdev, NOZOMI_NAME); |
1386 | if (ret) { | 1394 | if (ret) { |
1387 | dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", | 1395 | dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", |
@@ -1389,6 +1397,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1389 | goto err_disable_device; | 1397 | goto err_disable_device; |
1390 | } | 1398 | } |
1391 | 1399 | ||
1400 | start = pci_resource_start(dc->pdev, 0); | ||
1401 | if (start == 0) { | ||
1402 | dev_err(&pdev->dev, "No I/O address for card detected\n"); | ||
1403 | ret = -ENODEV; | ||
1404 | goto err_rel_regs; | ||
1405 | } | ||
1406 | |||
1407 | /* Find out what card type it is */ | ||
1408 | nozomi_get_card_type(dc); | ||
1409 | |||
1392 | dc->base_addr = ioremap(start, dc->card_type); | 1410 | dc->base_addr = ioremap(start, dc->card_type); |
1393 | if (!dc->base_addr) { | 1411 | if (!dc->base_addr) { |
1394 | dev_err(&pdev->dev, "Unable to map card MMIO\n"); | 1412 | dev_err(&pdev->dev, "Unable to map card MMIO\n"); |
@@ -1425,6 +1443,14 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1425 | dc->index_start = ndev_idx * MAX_PORT; | 1443 | dc->index_start = ndev_idx * MAX_PORT; |
1426 | ndevs[ndev_idx] = dc; | 1444 | ndevs[ndev_idx] = dc; |
1427 | 1445 | ||
1446 | pci_set_drvdata(pdev, dc); | ||
1447 | |||
1448 | /* Enable RESET interrupt */ | ||
1449 | dc->last_ier = RESET; | ||
1450 | iowrite16(dc->last_ier, dc->reg_ier); | ||
1451 | |||
1452 | dc->state = NOZOMI_STATE_ENABLED; | ||
1453 | |||
1428 | for (i = 0; i < MAX_PORT; i++) { | 1454 | for (i = 0; i < MAX_PORT; i++) { |
1429 | mutex_init(&dc->port[i].tty_sem); | 1455 | mutex_init(&dc->port[i].tty_sem); |
1430 | dc->port[i].tty_open_count = 0; | 1456 | dc->port[i].tty_open_count = 0; |
@@ -1433,12 +1459,6 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1433 | &pdev->dev); | 1459 | &pdev->dev); |
1434 | } | 1460 | } |
1435 | 1461 | ||
1436 | /* Enable RESET interrupt. */ | ||
1437 | dc->last_ier = RESET; | ||
1438 | writew(dc->last_ier, dc->reg_ier); | ||
1439 | |||
1440 | pci_set_drvdata(pdev, dc); | ||
1441 | |||
1442 | return 0; | 1462 | return 0; |
1443 | 1463 | ||
1444 | err_free_sbuf: | 1464 | err_free_sbuf: |
@@ -1553,7 +1573,7 @@ static int ntty_open(struct tty_struct *tty, struct file *file) | |||
1553 | struct nozomi *dc = get_dc_by_tty(tty); | 1573 | struct nozomi *dc = get_dc_by_tty(tty); |
1554 | unsigned long flags; | 1574 | unsigned long flags; |
1555 | 1575 | ||
1556 | if (!port || !dc) | 1576 | if (!port || !dc || dc->state != NOZOMI_STATE_READY) |
1557 | return -ENODEV; | 1577 | return -ENODEV; |
1558 | 1578 | ||
1559 | if (mutex_lock_interruptible(&port->tty_sem)) | 1579 | if (mutex_lock_interruptible(&port->tty_sem)) |
@@ -1716,6 +1736,10 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file) | |||
1716 | static int ntty_tiocmset(struct tty_struct *tty, struct file *file, | 1736 | static int ntty_tiocmset(struct tty_struct *tty, struct file *file, |
1717 | unsigned int set, unsigned int clear) | 1737 | unsigned int set, unsigned int clear) |
1718 | { | 1738 | { |
1739 | struct nozomi *dc = get_dc_by_tty(tty); | ||
1740 | unsigned long flags; | ||
1741 | |||
1742 | spin_lock_irqsave(&dc->spin_mutex, flags); | ||
1719 | if (set & TIOCM_RTS) | 1743 | if (set & TIOCM_RTS) |
1720 | set_rts(tty, 1); | 1744 | set_rts(tty, 1); |
1721 | else if (clear & TIOCM_RTS) | 1745 | else if (clear & TIOCM_RTS) |
@@ -1725,6 +1749,7 @@ static int ntty_tiocmset(struct tty_struct *tty, struct file *file, | |||
1725 | set_dtr(tty, 1); | 1749 | set_dtr(tty, 1); |
1726 | else if (clear & TIOCM_DTR) | 1750 | else if (clear & TIOCM_DTR) |
1727 | set_dtr(tty, 0); | 1751 | set_dtr(tty, 0); |
1752 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | ||
1728 | 1753 | ||
1729 | return 0; | 1754 | return 0; |
1730 | } | 1755 | } |
@@ -1762,7 +1787,7 @@ static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp) | |||
1762 | icount.brk = cnow.brk; | 1787 | icount.brk = cnow.brk; |
1763 | icount.buf_overrun = cnow.buf_overrun; | 1788 | icount.buf_overrun = cnow.buf_overrun; |
1764 | 1789 | ||
1765 | return copy_to_user(argp, &icount, sizeof(icount)); | 1790 | return copy_to_user(argp, &icount, sizeof(icount)) ? -EFAULT : 0; |
1766 | } | 1791 | } |
1767 | 1792 | ||
1768 | static int ntty_ioctl(struct tty_struct *tty, struct file *file, | 1793 | static int ntty_ioctl(struct tty_struct *tty, struct file *file, |