54 */ |
54 */ |
55 static int ccat_bar_init(struct ccat_bar *bar, size_t index, |
55 static int ccat_bar_init(struct ccat_bar *bar, size_t index, |
56 struct pci_dev *pdev) |
56 struct pci_dev *pdev) |
57 { |
57 { |
58 struct resource *res; |
58 struct resource *res; |
|
59 |
59 bar->start = pci_resource_start(pdev, index); |
60 bar->start = pci_resource_start(pdev, index); |
60 bar->end = pci_resource_end(pdev, index); |
61 bar->end = pci_resource_end(pdev, index); |
61 bar->len = pci_resource_len(pdev, index); |
62 bar->len = pci_resource_len(pdev, index); |
62 bar->flags = pci_resource_flags(pdev, index); |
63 bar->flags = pci_resource_flags(pdev, index); |
63 if (!(IORESOURCE_MEM & bar->flags)) { |
64 if (!(IORESOURCE_MEM & bar->flags)) { |
64 pr_info("bar%llu is no mem_region -> abort.\n", |
65 pr_info("bar%llu is no mem_region -> abort.\n", (u64) index); |
65 (uint64_t) index); |
|
66 return -EIO; |
66 return -EIO; |
67 } |
67 } |
68 |
68 |
69 res = request_mem_region(bar->start, bar->len, KBUILD_MODNAME); |
69 res = request_mem_region(bar->start, bar->len, KBUILD_MODNAME); |
70 if (!res) { |
70 if (!res) { |
71 pr_info("allocate mem_region failed.\n"); |
71 pr_info("allocate mem_region failed.\n"); |
72 return -EIO; |
72 return -EIO; |
73 } |
73 } |
74 pr_debug("bar%llu at [%lx,%lx] len=%lu res: %p.\n", (uint64_t) index, |
74 pr_debug("bar%llu at [%lx,%lx] len=%lu res: %p.\n", (u64) index, |
75 bar->start, bar->end, bar->len, res); |
75 bar->start, bar->end, bar->len, res); |
76 |
76 |
77 bar->ioaddr = ioremap(bar->start, bar->len); |
77 bar->ioaddr = ioremap(bar->start, bar->len); |
78 if (!bar->ioaddr) { |
78 if (!bar->ioaddr) { |
79 pr_info("bar%llu ioremap failed.\n", (uint64_t) index); |
79 pr_info("bar%llu ioremap failed.\n", (u64) index); |
80 release_mem_region(bar->start, bar->len); |
80 release_mem_region(bar->start, bar->len); |
81 return -EIO; |
81 return -EIO; |
82 } |
82 } |
83 pr_debug("bar%llu I/O mem mapped to %p.\n", (uint64_t) index, |
83 pr_debug("bar%llu I/O mem mapped to %p.\n", (u64) index, bar->ioaddr); |
84 bar->ioaddr); |
|
85 return 0; |
84 return 0; |
86 } |
85 } |
87 |
86 |
88 void ccat_dma_free(struct ccat_dma *const dma) |
87 void ccat_dma_free(struct ccat_dma *const dma) |
89 { |
88 { |
90 const struct ccat_dma tmp = *dma; |
89 const struct ccat_dma tmp = *dma; |
|
90 |
91 free_dma(dma->channel); |
91 free_dma(dma->channel); |
92 memset(dma, 0, sizeof(*dma)); |
92 memset(dma, 0, sizeof(*dma)); |
93 dma_free_coherent(tmp.dev, tmp.size, tmp.virt, tmp.phys); |
93 dma_free_coherent(tmp.dev, tmp.size, tmp.virt, tmp.phys); |
94 } |
94 } |
95 |
95 |
102 */ |
102 */ |
103 int ccat_dma_init(struct ccat_dma *const dma, size_t channel, |
103 int ccat_dma_init(struct ccat_dma *const dma, size_t channel, |
104 void __iomem * const ioaddr, struct device *const dev) |
104 void __iomem * const ioaddr, struct device *const dev) |
105 { |
105 { |
106 void *frame; |
106 void *frame; |
107 uint64_t addr; |
107 u64 addr; |
108 uint32_t translateAddr; |
108 u32 translateAddr; |
109 uint32_t memTranslate; |
109 u32 memTranslate; |
110 uint32_t memSize; |
110 u32 memSize; |
111 uint32_t data = 0xffffffff; |
111 u32 data = 0xffffffff; |
112 uint32_t offset = (sizeof(uint64_t) * channel) + 0x1000; |
112 u32 offset = (sizeof(u64) * channel) + 0x1000; |
113 |
113 |
114 dma->channel = channel; |
114 dma->channel = channel; |
115 dma->dev = dev; |
115 dma->dev = dev; |
116 |
116 |
117 /* calculate size and alignments */ |
117 /* calculate size and alignments */ |
121 memTranslate = data & 0xfffffffc; |
121 memTranslate = data & 0xfffffffc; |
122 memSize = (~memTranslate) + 1; |
122 memSize = (~memTranslate) + 1; |
123 dma->size = 2 * memSize - PAGE_SIZE; |
123 dma->size = 2 * memSize - PAGE_SIZE; |
124 dma->virt = dma_zalloc_coherent(dev, dma->size, &dma->phys, GFP_KERNEL); |
124 dma->virt = dma_zalloc_coherent(dev, dma->size, &dma->phys, GFP_KERNEL); |
125 if (!dma->virt || !dma->phys) { |
125 if (!dma->virt || !dma->phys) { |
126 pr_info("init DMA%llu memory failed.\n", (uint64_t) channel); |
126 pr_info("init DMA%llu memory failed.\n", (u64) channel); |
127 return -1; |
127 return -1; |
128 } |
128 } |
129 |
129 |
130 if (request_dma(channel, KBUILD_MODNAME)) { |
130 if (request_dma(channel, KBUILD_MODNAME)) { |
131 pr_info("request dma channel %llu failed\n", |
131 pr_info("request dma channel %llu failed\n", (u64) channel); |
132 (uint64_t) channel); |
|
133 ccat_dma_free(dma); |
132 ccat_dma_free(dma); |
134 return -1; |
133 return -1; |
135 } |
134 } |
136 |
135 |
137 translateAddr = (dma->phys + memSize - PAGE_SIZE) & memTranslate; |
136 translateAddr = (dma->phys + memSize - PAGE_SIZE) & memTranslate; |
138 addr = translateAddr; |
137 addr = translateAddr; |
139 memcpy_toio(ioaddr + offset, &addr, sizeof(addr)); |
138 memcpy_toio(ioaddr + offset, &addr, sizeof(addr)); |
140 frame = dma->virt + translateAddr - dma->phys; |
139 frame = dma->virt + translateAddr - dma->phys; |
141 pr_debug |
140 pr_debug |
142 ("DMA%llu mem initialized\n virt: 0x%p\n phys: 0x%llx\n translated: 0x%llx\n pci addr: 0x%08x%x\n memTranslate: 0x%x\n size: %llu bytes.\n", |
141 ("DMA%llu mem initialized\n virt: 0x%p\n phys: 0x%llx\n translated: 0x%llx\n pci addr: 0x%08x%x\n memTranslate: 0x%x\n size: %llu bytes.\n", |
143 (uint64_t) channel, dma->virt, (uint64_t) (dma->phys), addr, |
142 (u64) channel, dma->virt, (u64) (dma->phys), addr, |
144 ioread32(ioaddr + offset + 4), ioread32(ioaddr + offset), |
143 ioread32(ioaddr + offset + 4), ioread32(ioaddr + offset), |
145 memTranslate, (uint64_t) dma->size); |
144 memTranslate, (u64) dma->size); |
146 return 0; |
145 return 0; |
147 } |
146 } |
148 |
147 |
149 /** |
148 /** |
150 * Initialize all available CCAT functions. |
149 * Initialize all available CCAT functions. |
152 * Return: count of failed functions |
151 * Return: count of failed functions |
153 */ |
152 */ |
154 static int ccat_functions_init(struct ccat_device *const ccatdev) |
153 static int ccat_functions_init(struct ccat_device *const ccatdev) |
155 { |
154 { |
156 /* read CCatInfoBlock.nMaxEntries from ccat */ |
155 /* read CCatInfoBlock.nMaxEntries from ccat */ |
157 const uint8_t num_func = ioread8(ccatdev->bar[0].ioaddr + 4); |
156 const u8 num_func = ioread8(ccatdev->bar[0].ioaddr + 4); |
158 void __iomem *addr = ccatdev->bar[0].ioaddr; |
157 void __iomem *addr = ccatdev->bar[0].ioaddr; |
159 const void __iomem *end = addr + (sizeof(CCatInfoBlock) * num_func); |
158 const void __iomem *end = addr + (sizeof(CCatInfoBlock) * num_func); |
160 int status = 0; //count init function failures |
159 int status = 0; /* count init function failures */ |
161 |
160 |
162 while (addr < end) { |
161 while (addr < end) { |
163 const uint8_t type = ioread16(addr); |
162 const u8 type = ioread16(addr); |
164 switch (type) { |
163 switch (type) { |
165 case CCATINFO_NOTUSED: |
164 case CCATINFO_NOTUSED: |
166 break; |
165 break; |
167 case CCATINFO_EPCS_PROM: |
166 case CCATINFO_EPCS_PROM: |
168 pr_info("Found: CCAT update(EPCS_PROM) -> init()\n"); |
167 pr_info("Found: CCAT update(EPCS_PROM) -> init()\n"); |
207 static int ccat_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
206 static int ccat_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
208 { |
207 { |
209 int status; |
208 int status; |
210 u8 revision; |
209 u8 revision; |
211 struct ccat_device *ccatdev = kmalloc(sizeof(*ccatdev), GFP_KERNEL); |
210 struct ccat_device *ccatdev = kmalloc(sizeof(*ccatdev), GFP_KERNEL); |
|
211 |
212 if (!ccatdev) { |
212 if (!ccatdev) { |
213 pr_err("%s() out of memory.\n", __FUNCTION__); |
213 pr_err("%s() out of memory.\n", __FUNCTION__); |
214 return -ENOMEM; |
214 return -ENOMEM; |
215 } |
215 } |
216 memset(ccatdev, 0, sizeof(*ccatdev)); |
216 memset(ccatdev, 0, sizeof(*ccatdev)); |