diff options
Diffstat (limited to 'drivers/ieee1394/iso.c')
-rw-r--r-- | drivers/ieee1394/iso.c | 102 |
1 files changed, 60 insertions, 42 deletions
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c index 615541b8b90f..f26680ebef7c 100644 --- a/drivers/ieee1394/iso.c +++ b/drivers/ieee1394/iso.c | |||
@@ -36,20 +36,22 @@ void hpsb_iso_shutdown(struct hpsb_iso *iso) | |||
36 | kfree(iso); | 36 | kfree(iso); |
37 | } | 37 | } |
38 | 38 | ||
39 | static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_iso_type type, | 39 | static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host, |
40 | enum hpsb_iso_type type, | ||
40 | unsigned int data_buf_size, | 41 | unsigned int data_buf_size, |
41 | unsigned int buf_packets, | 42 | unsigned int buf_packets, |
42 | int channel, | 43 | int channel, int dma_mode, |
43 | int dma_mode, | ||
44 | int irq_interval, | 44 | int irq_interval, |
45 | void (*callback)(struct hpsb_iso*)) | 45 | void (*callback) (struct hpsb_iso |
46 | *)) | ||
46 | { | 47 | { |
47 | struct hpsb_iso *iso; | 48 | struct hpsb_iso *iso; |
48 | int dma_direction; | 49 | int dma_direction; |
49 | 50 | ||
50 | /* make sure driver supports the ISO API */ | 51 | /* make sure driver supports the ISO API */ |
51 | if (!host->driver->isoctl) { | 52 | if (!host->driver->isoctl) { |
52 | printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n", | 53 | printk(KERN_INFO |
54 | "ieee1394: host driver '%s' does not support the rawiso API\n", | ||
53 | host->driver->name); | 55 | host->driver->name); |
54 | return NULL; | 56 | return NULL; |
55 | } | 57 | } |
@@ -59,12 +61,13 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i | |||
59 | if (buf_packets < 2) | 61 | if (buf_packets < 2) |
60 | buf_packets = 2; | 62 | buf_packets = 2; |
61 | 63 | ||
62 | if ((dma_mode < HPSB_ISO_DMA_DEFAULT) || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER)) | 64 | if ((dma_mode < HPSB_ISO_DMA_DEFAULT) |
63 | dma_mode=HPSB_ISO_DMA_DEFAULT; | 65 | || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER)) |
66 | dma_mode = HPSB_ISO_DMA_DEFAULT; | ||
64 | 67 | ||
65 | if ((irq_interval < 0) || (irq_interval > buf_packets / 4)) | 68 | if ((irq_interval < 0) || (irq_interval > buf_packets / 4)) |
66 | irq_interval = buf_packets / 4; | 69 | irq_interval = buf_packets / 4; |
67 | if (irq_interval == 0) /* really interrupt for each packet*/ | 70 | if (irq_interval == 0) /* really interrupt for each packet */ |
68 | irq_interval = 1; | 71 | irq_interval = 1; |
69 | 72 | ||
70 | if (channel < -1 || channel >= 64) | 73 | if (channel < -1 || channel >= 64) |
@@ -76,7 +79,10 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i | |||
76 | 79 | ||
77 | /* allocate and write the struct hpsb_iso */ | 80 | /* allocate and write the struct hpsb_iso */ |
78 | 81 | ||
79 | iso = kmalloc(sizeof(*iso) + buf_packets * sizeof(struct hpsb_iso_packet_info), GFP_KERNEL); | 82 | iso = |
83 | kmalloc(sizeof(*iso) + | ||
84 | buf_packets * sizeof(struct hpsb_iso_packet_info), | ||
85 | GFP_KERNEL); | ||
80 | if (!iso) | 86 | if (!iso) |
81 | return NULL; | 87 | return NULL; |
82 | 88 | ||
@@ -111,17 +117,18 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i | |||
111 | iso->prebuffer = 0; | 117 | iso->prebuffer = 0; |
112 | 118 | ||
113 | /* allocate the packet buffer */ | 119 | /* allocate the packet buffer */ |
114 | if (dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction)) | 120 | if (dma_region_alloc |
121 | (&iso->data_buf, iso->buf_size, host->pdev, dma_direction)) | ||
115 | goto err; | 122 | goto err; |
116 | 123 | ||
117 | return iso; | 124 | return iso; |
118 | 125 | ||
119 | err: | 126 | err: |
120 | hpsb_iso_shutdown(iso); | 127 | hpsb_iso_shutdown(iso); |
121 | return NULL; | 128 | return NULL; |
122 | } | 129 | } |
123 | 130 | ||
124 | int hpsb_iso_n_ready(struct hpsb_iso* iso) | 131 | int hpsb_iso_n_ready(struct hpsb_iso *iso) |
125 | { | 132 | { |
126 | unsigned long flags; | 133 | unsigned long flags; |
127 | int val; | 134 | int val; |
@@ -133,18 +140,19 @@ int hpsb_iso_n_ready(struct hpsb_iso* iso) | |||
133 | return val; | 140 | return val; |
134 | } | 141 | } |
135 | 142 | ||
136 | 143 | struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host, | |
137 | struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host, | ||
138 | unsigned int data_buf_size, | 144 | unsigned int data_buf_size, |
139 | unsigned int buf_packets, | 145 | unsigned int buf_packets, |
140 | int channel, | 146 | int channel, |
141 | int speed, | 147 | int speed, |
142 | int irq_interval, | 148 | int irq_interval, |
143 | void (*callback)(struct hpsb_iso*)) | 149 | void (*callback) (struct hpsb_iso *)) |
144 | { | 150 | { |
145 | struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT, | 151 | struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT, |
146 | data_buf_size, buf_packets, | 152 | data_buf_size, buf_packets, |
147 | channel, HPSB_ISO_DMA_DEFAULT, irq_interval, callback); | 153 | channel, |
154 | HPSB_ISO_DMA_DEFAULT, | ||
155 | irq_interval, callback); | ||
148 | if (!iso) | 156 | if (!iso) |
149 | return NULL; | 157 | return NULL; |
150 | 158 | ||
@@ -157,22 +165,23 @@ struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host, | |||
157 | iso->flags |= HPSB_ISO_DRIVER_INIT; | 165 | iso->flags |= HPSB_ISO_DRIVER_INIT; |
158 | return iso; | 166 | return iso; |
159 | 167 | ||
160 | err: | 168 | err: |
161 | hpsb_iso_shutdown(iso); | 169 | hpsb_iso_shutdown(iso); |
162 | return NULL; | 170 | return NULL; |
163 | } | 171 | } |
164 | 172 | ||
165 | struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host, | 173 | struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host, |
166 | unsigned int data_buf_size, | 174 | unsigned int data_buf_size, |
167 | unsigned int buf_packets, | 175 | unsigned int buf_packets, |
168 | int channel, | 176 | int channel, |
169 | int dma_mode, | 177 | int dma_mode, |
170 | int irq_interval, | 178 | int irq_interval, |
171 | void (*callback)(struct hpsb_iso*)) | 179 | void (*callback) (struct hpsb_iso *)) |
172 | { | 180 | { |
173 | struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV, | 181 | struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV, |
174 | data_buf_size, buf_packets, | 182 | data_buf_size, buf_packets, |
175 | channel, dma_mode, irq_interval, callback); | 183 | channel, dma_mode, |
184 | irq_interval, callback); | ||
176 | if (!iso) | 185 | if (!iso) |
177 | return NULL; | 186 | return NULL; |
178 | 187 | ||
@@ -183,7 +192,7 @@ struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host, | |||
183 | iso->flags |= HPSB_ISO_DRIVER_INIT; | 192 | iso->flags |= HPSB_ISO_DRIVER_INIT; |
184 | return iso; | 193 | return iso; |
185 | 194 | ||
186 | err: | 195 | err: |
187 | hpsb_iso_shutdown(iso); | 196 | hpsb_iso_shutdown(iso); |
188 | return NULL; | 197 | return NULL; |
189 | } | 198 | } |
@@ -197,16 +206,17 @@ int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel) | |||
197 | 206 | ||
198 | int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel) | 207 | int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel) |
199 | { | 208 | { |
200 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) | 209 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) |
201 | return -EINVAL; | 210 | return -EINVAL; |
202 | return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel); | 211 | return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel); |
203 | } | 212 | } |
204 | 213 | ||
205 | int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) | 214 | int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) |
206 | { | 215 | { |
207 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1) | 216 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1) |
208 | return -EINVAL; | 217 | return -EINVAL; |
209 | return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask); | 218 | return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, |
219 | (unsigned long)&mask); | ||
210 | } | 220 | } |
211 | 221 | ||
212 | int hpsb_iso_recv_flush(struct hpsb_iso *iso) | 222 | int hpsb_iso_recv_flush(struct hpsb_iso *iso) |
@@ -283,7 +293,9 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync) | |||
283 | 293 | ||
284 | isoctl_args[2] = sync; | 294 | isoctl_args[2] = sync; |
285 | 295 | ||
286 | retval = iso->host->driver->isoctl(iso, RECV_START, (unsigned long) &isoctl_args[0]); | 296 | retval = |
297 | iso->host->driver->isoctl(iso, RECV_START, | ||
298 | (unsigned long)&isoctl_args[0]); | ||
287 | if (retval) | 299 | if (retval) |
288 | return retval; | 300 | return retval; |
289 | 301 | ||
@@ -296,7 +308,8 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync) | |||
296 | 308 | ||
297 | static int hpsb_iso_check_offset_len(struct hpsb_iso *iso, | 309 | static int hpsb_iso_check_offset_len(struct hpsb_iso *iso, |
298 | unsigned int offset, unsigned short len, | 310 | unsigned int offset, unsigned short len, |
299 | unsigned int *out_offset, unsigned short *out_len) | 311 | unsigned int *out_offset, |
312 | unsigned short *out_len) | ||
300 | { | 313 | { |
301 | if (offset >= iso->buf_size) | 314 | if (offset >= iso->buf_size) |
302 | return -EFAULT; | 315 | return -EFAULT; |
@@ -316,8 +329,8 @@ static int hpsb_iso_check_offset_len(struct hpsb_iso *iso, | |||
316 | return 0; | 329 | return 0; |
317 | } | 330 | } |
318 | 331 | ||
319 | 332 | int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, | |
320 | int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy) | 333 | u8 tag, u8 sy) |
321 | { | 334 | { |
322 | struct hpsb_iso_packet_info *info; | 335 | struct hpsb_iso_packet_info *info; |
323 | unsigned long flags; | 336 | unsigned long flags; |
@@ -334,7 +347,8 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag | |||
334 | info = &iso->infos[iso->first_packet]; | 347 | info = &iso->infos[iso->first_packet]; |
335 | 348 | ||
336 | /* check for bogus offset/length */ | 349 | /* check for bogus offset/length */ |
337 | if (hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len)) | 350 | if (hpsb_iso_check_offset_len |
351 | (iso, offset, len, &info->offset, &info->len)) | ||
338 | return -EFAULT; | 352 | return -EFAULT; |
339 | 353 | ||
340 | info->tag = tag; | 354 | info->tag = tag; |
@@ -342,13 +356,13 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag | |||
342 | 356 | ||
343 | spin_lock_irqsave(&iso->lock, flags); | 357 | spin_lock_irqsave(&iso->lock, flags); |
344 | 358 | ||
345 | rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long) info); | 359 | rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long)info); |
346 | if (rv) | 360 | if (rv) |
347 | goto out; | 361 | goto out; |
348 | 362 | ||
349 | /* increment cursors */ | 363 | /* increment cursors */ |
350 | iso->first_packet = (iso->first_packet+1) % iso->buf_packets; | 364 | iso->first_packet = (iso->first_packet + 1) % iso->buf_packets; |
351 | iso->xmit_cycle = (iso->xmit_cycle+1) % 8000; | 365 | iso->xmit_cycle = (iso->xmit_cycle + 1) % 8000; |
352 | iso->n_ready_packets--; | 366 | iso->n_ready_packets--; |
353 | 367 | ||
354 | if (iso->prebuffer != 0) { | 368 | if (iso->prebuffer != 0) { |
@@ -359,7 +373,7 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag | |||
359 | } | 373 | } |
360 | } | 374 | } |
361 | 375 | ||
362 | out: | 376 | out: |
363 | spin_unlock_irqrestore(&iso->lock, flags); | 377 | spin_unlock_irqrestore(&iso->lock, flags); |
364 | return rv; | 378 | return rv; |
365 | } | 379 | } |
@@ -369,7 +383,9 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso) | |||
369 | if (iso->type != HPSB_ISO_XMIT) | 383 | if (iso->type != HPSB_ISO_XMIT) |
370 | return -EINVAL; | 384 | return -EINVAL; |
371 | 385 | ||
372 | return wait_event_interruptible(iso->waitq, hpsb_iso_n_ready(iso) == iso->buf_packets); | 386 | return wait_event_interruptible(iso->waitq, |
387 | hpsb_iso_n_ready(iso) == | ||
388 | iso->buf_packets); | ||
373 | } | 389 | } |
374 | 390 | ||
375 | void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error) | 391 | void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error) |
@@ -396,7 +412,8 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error) | |||
396 | } | 412 | } |
397 | 413 | ||
398 | void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, | 414 | void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, |
399 | u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy) | 415 | u16 total_len, u16 cycle, u8 channel, u8 tag, |
416 | u8 sy) | ||
400 | { | 417 | { |
401 | unsigned long flags; | 418 | unsigned long flags; |
402 | spin_lock_irqsave(&iso->lock, flags); | 419 | spin_lock_irqsave(&iso->lock, flags); |
@@ -416,7 +433,7 @@ void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, | |||
416 | info->tag = tag; | 433 | info->tag = tag; |
417 | info->sy = sy; | 434 | info->sy = sy; |
418 | 435 | ||
419 | iso->pkt_dma = (iso->pkt_dma+1) % iso->buf_packets; | 436 | iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets; |
420 | iso->n_ready_packets++; | 437 | iso->n_ready_packets++; |
421 | } | 438 | } |
422 | 439 | ||
@@ -435,20 +452,21 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets) | |||
435 | spin_lock_irqsave(&iso->lock, flags); | 452 | spin_lock_irqsave(&iso->lock, flags); |
436 | for (i = 0; i < n_packets; i++) { | 453 | for (i = 0; i < n_packets; i++) { |
437 | rv = iso->host->driver->isoctl(iso, RECV_RELEASE, | 454 | rv = iso->host->driver->isoctl(iso, RECV_RELEASE, |
438 | (unsigned long) &iso->infos[iso->first_packet]); | 455 | (unsigned long)&iso->infos[iso-> |
456 | first_packet]); | ||
439 | if (rv) | 457 | if (rv) |
440 | break; | 458 | break; |
441 | 459 | ||
442 | iso->first_packet = (iso->first_packet+1) % iso->buf_packets; | 460 | iso->first_packet = (iso->first_packet + 1) % iso->buf_packets; |
443 | iso->n_ready_packets--; | 461 | iso->n_ready_packets--; |
444 | 462 | ||
445 | /* release memory from packets discarded when queue was full */ | 463 | /* release memory from packets discarded when queue was full */ |
446 | if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */ | 464 | if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */ |
447 | if (iso->bytes_discarded != 0) { | 465 | if (iso->bytes_discarded != 0) { |
448 | struct hpsb_iso_packet_info inf; | 466 | struct hpsb_iso_packet_info inf; |
449 | inf.total_len = iso->bytes_discarded; | 467 | inf.total_len = iso->bytes_discarded; |
450 | iso->host->driver->isoctl(iso, RECV_RELEASE, | 468 | iso->host->driver->isoctl(iso, RECV_RELEASE, |
451 | (unsigned long) &inf); | 469 | (unsigned long)&inf); |
452 | iso->bytes_discarded = 0; | 470 | iso->bytes_discarded = 0; |
453 | } | 471 | } |
454 | } | 472 | } |