diff options
Diffstat (limited to 'drivers/ieee1394/pcilynx.c')
-rw-r--r-- | drivers/ieee1394/pcilynx.c | 391 |
1 files changed, 1 insertions, 390 deletions
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index a261d2b0e5ac..2689d938276e 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c | |||
@@ -834,327 +834,6 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) | |||
834 | * IEEE-1394 functionality section END * | 834 | * IEEE-1394 functionality section END * |
835 | ***************************************/ | 835 | ***************************************/ |
836 | 836 | ||
837 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
838 | /* VFS functions for local bus / aux device access. Access to those | ||
839 | * is implemented as a character device instead of block devices | ||
840 | * because buffers are not wanted for this. Therefore llseek (from | ||
841 | * VFS) can be used for these char devices with obvious effects. | ||
842 | */ | ||
843 | static int mem_open(struct inode*, struct file*); | ||
844 | static int mem_release(struct inode*, struct file*); | ||
845 | static unsigned int aux_poll(struct file*, struct poll_table_struct*); | ||
846 | static loff_t mem_llseek(struct file*, loff_t, int); | ||
847 | static ssize_t mem_read (struct file*, char*, size_t, loff_t*); | ||
848 | static ssize_t mem_write(struct file*, const char*, size_t, loff_t*); | ||
849 | |||
850 | |||
851 | static struct file_operations aux_ops = { | ||
852 | .owner = THIS_MODULE, | ||
853 | .read = mem_read, | ||
854 | .write = mem_write, | ||
855 | .poll = aux_poll, | ||
856 | .llseek = mem_llseek, | ||
857 | .open = mem_open, | ||
858 | .release = mem_release, | ||
859 | }; | ||
860 | |||
861 | |||
862 | static void aux_setup_pcls(struct ti_lynx *lynx) | ||
863 | { | ||
864 | struct ti_pcl pcl; | ||
865 | |||
866 | pcl.next = PCL_NEXT_INVALID; | ||
867 | pcl.user_data = pcl_bus(lynx, lynx->dmem_pcl); | ||
868 | put_pcl(lynx, lynx->dmem_pcl, &pcl); | ||
869 | } | ||
870 | |||
871 | static int mem_open(struct inode *inode, struct file *file) | ||
872 | { | ||
873 | int cid = iminor(inode); | ||
874 | enum { t_rom, t_aux, t_ram } type; | ||
875 | struct memdata *md; | ||
876 | |||
877 | if (cid < PCILYNX_MINOR_AUX_START) { | ||
878 | /* just for completeness */ | ||
879 | return -ENXIO; | ||
880 | } else if (cid < PCILYNX_MINOR_ROM_START) { | ||
881 | cid -= PCILYNX_MINOR_AUX_START; | ||
882 | if (cid >= num_of_cards || !cards[cid].aux_port) | ||
883 | return -ENXIO; | ||
884 | type = t_aux; | ||
885 | } else if (cid < PCILYNX_MINOR_RAM_START) { | ||
886 | cid -= PCILYNX_MINOR_ROM_START; | ||
887 | if (cid >= num_of_cards || !cards[cid].local_rom) | ||
888 | return -ENXIO; | ||
889 | type = t_rom; | ||
890 | } else { | ||
891 | /* WARNING: Know what you are doing when opening RAM. | ||
892 | * It is currently used inside the driver! */ | ||
893 | cid -= PCILYNX_MINOR_RAM_START; | ||
894 | if (cid >= num_of_cards || !cards[cid].local_ram) | ||
895 | return -ENXIO; | ||
896 | type = t_ram; | ||
897 | } | ||
898 | |||
899 | md = (struct memdata *)kmalloc(sizeof(struct memdata), SLAB_KERNEL); | ||
900 | if (md == NULL) | ||
901 | return -ENOMEM; | ||
902 | |||
903 | md->lynx = &cards[cid]; | ||
904 | md->cid = cid; | ||
905 | |||
906 | switch (type) { | ||
907 | case t_rom: | ||
908 | md->type = rom; | ||
909 | break; | ||
910 | case t_ram: | ||
911 | md->type = ram; | ||
912 | break; | ||
913 | case t_aux: | ||
914 | atomic_set(&md->aux_intr_last_seen, | ||
915 | atomic_read(&cards[cid].aux_intr_seen)); | ||
916 | md->type = aux; | ||
917 | break; | ||
918 | } | ||
919 | |||
920 | file->private_data = md; | ||
921 | |||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | static int mem_release(struct inode *inode, struct file *file) | ||
926 | { | ||
927 | kfree(file->private_data); | ||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | static unsigned int aux_poll(struct file *file, poll_table *pt) | ||
932 | { | ||
933 | struct memdata *md = (struct memdata *)file->private_data; | ||
934 | int cid = md->cid; | ||
935 | unsigned int mask; | ||
936 | |||
937 | /* reading and writing is always allowed */ | ||
938 | mask = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM; | ||
939 | |||
940 | if (md->type == aux) { | ||
941 | poll_wait(file, &cards[cid].aux_intr_wait, pt); | ||
942 | |||
943 | if (atomic_read(&md->aux_intr_last_seen) | ||
944 | != atomic_read(&cards[cid].aux_intr_seen)) { | ||
945 | mask |= POLLPRI; | ||
946 | atomic_inc(&md->aux_intr_last_seen); | ||
947 | } | ||
948 | } | ||
949 | |||
950 | return mask; | ||
951 | } | ||
952 | |||
953 | loff_t mem_llseek(struct file *file, loff_t offs, int orig) | ||
954 | { | ||
955 | loff_t newoffs; | ||
956 | |||
957 | switch (orig) { | ||
958 | case 0: | ||
959 | newoffs = offs; | ||
960 | break; | ||
961 | case 1: | ||
962 | newoffs = offs + file->f_pos; | ||
963 | break; | ||
964 | case 2: | ||
965 | newoffs = PCILYNX_MAX_MEMORY + 1 + offs; | ||
966 | break; | ||
967 | default: | ||
968 | return -EINVAL; | ||
969 | } | ||
970 | |||
971 | if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) return -EINVAL; | ||
972 | |||
973 | file->f_pos = newoffs; | ||
974 | return newoffs; | ||
975 | } | ||
976 | |||
977 | /* | ||
978 | * do not DMA if count is too small because this will have a serious impact | ||
979 | * on performance - the value 2400 was found by experiment and may not work | ||
980 | * everywhere as good as here - use mem_mindma option for modules to change | ||
981 | */ | ||
982 | static short mem_mindma = 2400; | ||
983 | module_param(mem_mindma, short, 0444); | ||
984 | MODULE_PARM_DESC(mem_mindma, "Minimum amount of data required to use DMA"); | ||
985 | |||
986 | static ssize_t mem_dmaread(struct memdata *md, u32 physbuf, ssize_t count, | ||
987 | int offset) | ||
988 | { | ||
989 | pcltmp_t pcltmp; | ||
990 | struct ti_pcl *pcl; | ||
991 | size_t retval; | ||
992 | int i; | ||
993 | DECLARE_WAITQUEUE(wait, current); | ||
994 | |||
995 | count &= ~3; | ||
996 | count = min(count, 53196); | ||
997 | retval = count; | ||
998 | |||
999 | if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) | ||
1000 | & DMA_CHAN_CTRL_BUSY) { | ||
1001 | PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!"); | ||
1002 | } | ||
1003 | |||
1004 | reg_write(md->lynx, LBUS_ADDR, md->type | offset); | ||
1005 | |||
1006 | pcl = edit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); | ||
1007 | pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | min(count, 4092); | ||
1008 | pcl->buffer[0].pointer = physbuf; | ||
1009 | count -= 4092; | ||
1010 | |||
1011 | i = 0; | ||
1012 | while (count > 0) { | ||
1013 | i++; | ||
1014 | pcl->buffer[i].control = min(count, 4092); | ||
1015 | pcl->buffer[i].pointer = physbuf + i * 4092; | ||
1016 | count -= 4092; | ||
1017 | } | ||
1018 | pcl->buffer[i].control |= PCL_LAST_BUFF; | ||
1019 | commit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); | ||
1020 | |||
1021 | set_current_state(TASK_INTERRUPTIBLE); | ||
1022 | add_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); | ||
1023 | run_sub_pcl(md->lynx, md->lynx->dmem_pcl, 2, CHANNEL_LOCALBUS); | ||
1024 | |||
1025 | schedule(); | ||
1026 | while (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) | ||
1027 | & DMA_CHAN_CTRL_BUSY) { | ||
1028 | if (signal_pending(current)) { | ||
1029 | retval = -EINTR; | ||
1030 | break; | ||
1031 | } | ||
1032 | schedule(); | ||
1033 | } | ||
1034 | |||
1035 | reg_write(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS), 0); | ||
1036 | remove_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); | ||
1037 | |||
1038 | if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) | ||
1039 | & DMA_CHAN_CTRL_BUSY) { | ||
1040 | PRINT(KERN_ERR, md->lynx->id, "DMA STILL ACTIVE!"); | ||
1041 | } | ||
1042 | |||
1043 | return retval; | ||
1044 | } | ||
1045 | |||
1046 | static ssize_t mem_read(struct file *file, char *buffer, size_t count, | ||
1047 | loff_t *offset) | ||
1048 | { | ||
1049 | struct memdata *md = (struct memdata *)file->private_data; | ||
1050 | ssize_t bcount; | ||
1051 | size_t alignfix; | ||
1052 | loff_t off = *offset; /* avoid useless 64bit-arithmetic */ | ||
1053 | ssize_t retval; | ||
1054 | void *membase; | ||
1055 | |||
1056 | if ((off + count) > PCILYNX_MAX_MEMORY+1) { | ||
1057 | count = PCILYNX_MAX_MEMORY+1 - off; | ||
1058 | } | ||
1059 | if (count == 0 || off > PCILYNX_MAX_MEMORY) { | ||
1060 | return -ENOSPC; | ||
1061 | } | ||
1062 | |||
1063 | switch (md->type) { | ||
1064 | case rom: | ||
1065 | membase = md->lynx->local_rom; | ||
1066 | break; | ||
1067 | case ram: | ||
1068 | membase = md->lynx->local_ram; | ||
1069 | break; | ||
1070 | case aux: | ||
1071 | membase = md->lynx->aux_port; | ||
1072 | break; | ||
1073 | default: | ||
1074 | panic("pcilynx%d: unsupported md->type %d in %s", | ||
1075 | md->lynx->id, md->type, __FUNCTION__); | ||
1076 | } | ||
1077 | |||
1078 | down(&md->lynx->mem_dma_mutex); | ||
1079 | |||
1080 | if (count < mem_mindma) { | ||
1081 | memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, count); | ||
1082 | goto out; | ||
1083 | } | ||
1084 | |||
1085 | bcount = count; | ||
1086 | alignfix = 4 - (off % 4); | ||
1087 | if (alignfix != 4) { | ||
1088 | if (bcount < alignfix) { | ||
1089 | alignfix = bcount; | ||
1090 | } | ||
1091 | memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, | ||
1092 | alignfix); | ||
1093 | if (bcount == alignfix) { | ||
1094 | goto out; | ||
1095 | } | ||
1096 | bcount -= alignfix; | ||
1097 | off += alignfix; | ||
1098 | } | ||
1099 | |||
1100 | while (bcount >= 4) { | ||
1101 | retval = mem_dmaread(md, md->lynx->mem_dma_buffer_dma | ||
1102 | + count - bcount, bcount, off); | ||
1103 | if (retval < 0) return retval; | ||
1104 | |||
1105 | bcount -= retval; | ||
1106 | off += retval; | ||
1107 | } | ||
1108 | |||
1109 | if (bcount) { | ||
1110 | memcpy_fromio(md->lynx->mem_dma_buffer + count - bcount, | ||
1111 | membase+off, bcount); | ||
1112 | } | ||
1113 | |||
1114 | out: | ||
1115 | retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count); | ||
1116 | up(&md->lynx->mem_dma_mutex); | ||
1117 | |||
1118 | if (retval) return -EFAULT; | ||
1119 | *offset += count; | ||
1120 | return count; | ||
1121 | } | ||
1122 | |||
1123 | |||
1124 | static ssize_t mem_write(struct file *file, const char *buffer, size_t count, | ||
1125 | loff_t *offset) | ||
1126 | { | ||
1127 | struct memdata *md = (struct memdata *)file->private_data; | ||
1128 | |||
1129 | if (((*offset) + count) > PCILYNX_MAX_MEMORY+1) { | ||
1130 | count = PCILYNX_MAX_MEMORY+1 - *offset; | ||
1131 | } | ||
1132 | if (count == 0 || *offset > PCILYNX_MAX_MEMORY) { | ||
1133 | return -ENOSPC; | ||
1134 | } | ||
1135 | |||
1136 | /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */ | ||
1137 | switch (md->type) { | ||
1138 | case aux: | ||
1139 | if (copy_from_user(md->lynx->aux_port+(*offset), buffer, count)) | ||
1140 | return -EFAULT; | ||
1141 | break; | ||
1142 | case ram: | ||
1143 | if (copy_from_user(md->lynx->local_ram+(*offset), buffer, count)) | ||
1144 | return -EFAULT; | ||
1145 | break; | ||
1146 | case rom: | ||
1147 | /* the ROM may be writeable */ | ||
1148 | if (copy_from_user(md->lynx->local_rom+(*offset), buffer, count)) | ||
1149 | return -EFAULT; | ||
1150 | break; | ||
1151 | } | ||
1152 | |||
1153 | file->f_pos += count; | ||
1154 | return count; | ||
1155 | } | ||
1156 | #endif /* CONFIG_IEEE1394_PCILYNX_PORTS */ | ||
1157 | |||
1158 | 837 | ||
1159 | /******************************************************** | 838 | /******************************************************** |
1160 | * Global stuff (interrupt handler, init/shutdown code) * | 839 | * Global stuff (interrupt handler, init/shutdown code) * |
@@ -1181,18 +860,6 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id, | |||
1181 | reg_write(lynx, LINK_INT_STATUS, linkint); | 860 | reg_write(lynx, LINK_INT_STATUS, linkint); |
1182 | reg_write(lynx, PCI_INT_STATUS, intmask); | 861 | reg_write(lynx, PCI_INT_STATUS, intmask); |
1183 | 862 | ||
1184 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1185 | if (intmask & PCI_INT_AUX_INT) { | ||
1186 | atomic_inc(&lynx->aux_intr_seen); | ||
1187 | wake_up_interruptible(&lynx->aux_intr_wait); | ||
1188 | } | ||
1189 | |||
1190 | if (intmask & PCI_INT_DMA_HLT(CHANNEL_LOCALBUS)) { | ||
1191 | wake_up_interruptible(&lynx->mem_dma_intr_wait); | ||
1192 | } | ||
1193 | #endif | ||
1194 | |||
1195 | |||
1196 | if (intmask & PCI_INT_1394) { | 863 | if (intmask & PCI_INT_1394) { |
1197 | if (linkint & LINK_INT_PHY_TIMEOUT) { | 864 | if (linkint & LINK_INT_PHY_TIMEOUT) { |
1198 | PRINT(KERN_INFO, lynx->id, "PHY timeout occurred"); | 865 | PRINT(KERN_INFO, lynx->id, "PHY timeout occurred"); |
@@ -1484,15 +1151,9 @@ static void remove_card(struct pci_dev *dev) | |||
1484 | pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page, | 1151 | pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page, |
1485 | lynx->rcv_page_dma); | 1152 | lynx->rcv_page_dma); |
1486 | case have_aux_buf: | 1153 | case have_aux_buf: |
1487 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1488 | pci_free_consistent(lynx->dev, 65536, lynx->mem_dma_buffer, | ||
1489 | lynx->mem_dma_buffer_dma); | ||
1490 | #endif | ||
1491 | case have_pcl_mem: | 1154 | case have_pcl_mem: |
1492 | #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
1493 | pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem, | 1155 | pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem, |
1494 | lynx->pcl_mem_dma); | 1156 | lynx->pcl_mem_dma); |
1495 | #endif | ||
1496 | case clear: | 1157 | case clear: |
1497 | /* do nothing - already freed */ | 1158 | /* do nothing - already freed */ |
1498 | ; | 1159 | ; |
@@ -1546,7 +1207,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1546 | spin_lock_init(&lynx->lock); | 1207 | spin_lock_init(&lynx->lock); |
1547 | spin_lock_init(&lynx->phy_reg_lock); | 1208 | spin_lock_init(&lynx->phy_reg_lock); |
1548 | 1209 | ||
1549 | #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
1550 | lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE, | 1210 | lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE, |
1551 | &lynx->pcl_mem_dma); | 1211 | &lynx->pcl_mem_dma); |
1552 | 1212 | ||
@@ -1558,16 +1218,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1558 | } else { | 1218 | } else { |
1559 | FAIL("failed to allocate PCL memory area"); | 1219 | FAIL("failed to allocate PCL memory area"); |
1560 | } | 1220 | } |
1561 | #endif | ||
1562 | |||
1563 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1564 | lynx->mem_dma_buffer = pci_alloc_consistent(dev, 65536, | ||
1565 | &lynx->mem_dma_buffer_dma); | ||
1566 | if (lynx->mem_dma_buffer == NULL) { | ||
1567 | FAIL("failed to allocate DMA buffer for aux"); | ||
1568 | } | ||
1569 | lynx->state = have_aux_buf; | ||
1570 | #endif | ||
1571 | 1221 | ||
1572 | lynx->rcv_page = pci_alloc_consistent(dev, PAGE_SIZE, | 1222 | lynx->rcv_page = pci_alloc_consistent(dev, PAGE_SIZE, |
1573 | &lynx->rcv_page_dma); | 1223 | &lynx->rcv_page_dma); |
@@ -1597,13 +1247,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1597 | FAIL("failed to remap registers - card not accessible"); | 1247 | FAIL("failed to remap registers - card not accessible"); |
1598 | } | 1248 | } |
1599 | 1249 | ||
1600 | #ifdef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
1601 | if (lynx->local_ram == NULL) { | ||
1602 | FAIL("failed to remap local RAM which is required for " | ||
1603 | "operation"); | ||
1604 | } | ||
1605 | #endif | ||
1606 | |||
1607 | reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); | 1250 | reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); |
1608 | /* Fix buggy cards with autoboot pin not tied low: */ | 1251 | /* Fix buggy cards with autoboot pin not tied low: */ |
1609 | reg_write(lynx, DMA0_CHAN_CTRL, 0); | 1252 | reg_write(lynx, DMA0_CHAN_CTRL, 0); |
@@ -1624,13 +1267,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1624 | 1267 | ||
1625 | /* alloc_pcl return values are not checked, it is expected that the | 1268 | /* alloc_pcl return values are not checked, it is expected that the |
1626 | * provided PCL space is sufficient for the initial allocations */ | 1269 | * provided PCL space is sufficient for the initial allocations */ |
1627 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1628 | if (lynx->aux_port != NULL) { | ||
1629 | lynx->dmem_pcl = alloc_pcl(lynx); | ||
1630 | aux_setup_pcls(lynx); | ||
1631 | sema_init(&lynx->mem_dma_mutex, 1); | ||
1632 | } | ||
1633 | #endif | ||
1634 | lynx->rcv_pcl = alloc_pcl(lynx); | 1270 | lynx->rcv_pcl = alloc_pcl(lynx); |
1635 | lynx->rcv_pcl_start = alloc_pcl(lynx); | 1271 | lynx->rcv_pcl_start = alloc_pcl(lynx); |
1636 | lynx->async.pcl = alloc_pcl(lynx); | 1272 | lynx->async.pcl = alloc_pcl(lynx); |
@@ -1647,12 +1283,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1647 | 1283 | ||
1648 | reg_write(lynx, PCI_INT_ENABLE, PCI_INT_DMA_ALL); | 1284 | reg_write(lynx, PCI_INT_ENABLE, PCI_INT_DMA_ALL); |
1649 | 1285 | ||
1650 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1651 | reg_set_bits(lynx, PCI_INT_ENABLE, PCI_INT_AUX_INT); | ||
1652 | init_waitqueue_head(&lynx->mem_dma_intr_wait); | ||
1653 | init_waitqueue_head(&lynx->aux_intr_wait); | ||
1654 | #endif | ||
1655 | |||
1656 | tasklet_init(&lynx->iso_rcv.tq, (void (*)(unsigned long))iso_rcv_bh, | 1286 | tasklet_init(&lynx->iso_rcv.tq, (void (*)(unsigned long))iso_rcv_bh, |
1657 | (unsigned long)lynx); | 1287 | (unsigned long)lynx); |
1658 | 1288 | ||
@@ -1944,37 +1574,18 @@ static int __init pcilynx_init(void) | |||
1944 | { | 1574 | { |
1945 | int ret; | 1575 | int ret; |
1946 | 1576 | ||
1947 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1948 | if (register_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME, &aux_ops)) { | ||
1949 | PRINT_G(KERN_ERR, "allocation of char major number %d failed", | ||
1950 | PCILYNX_MAJOR); | ||
1951 | return -EBUSY; | ||
1952 | } | ||
1953 | #endif | ||
1954 | |||
1955 | ret = pci_register_driver(&lynx_pci_driver); | 1577 | ret = pci_register_driver(&lynx_pci_driver); |
1956 | if (ret < 0) { | 1578 | if (ret < 0) { |
1957 | PRINT_G(KERN_ERR, "PCI module init failed"); | 1579 | PRINT_G(KERN_ERR, "PCI module init failed"); |
1958 | goto free_char_dev; | 1580 | return ret; |
1959 | } | 1581 | } |
1960 | 1582 | ||
1961 | return 0; | 1583 | return 0; |
1962 | |||
1963 | free_char_dev: | ||
1964 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1965 | unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME); | ||
1966 | #endif | ||
1967 | |||
1968 | return ret; | ||
1969 | } | 1584 | } |
1970 | 1585 | ||
1971 | static void __exit pcilynx_cleanup(void) | 1586 | static void __exit pcilynx_cleanup(void) |
1972 | { | 1587 | { |
1973 | pci_unregister_driver(&lynx_pci_driver); | 1588 | pci_unregister_driver(&lynx_pci_driver); |
1974 | |||
1975 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1976 | unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME); | ||
1977 | #endif | ||
1978 | } | 1589 | } |
1979 | 1590 | ||
1980 | 1591 | ||