diff options
author | David S. Miller <davem@davemloft.net> | 2009-02-28 18:36:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-28 18:36:58 -0500 |
commit | 18963caaf55240d6a0491bdb27b7fef2882ffb15 (patch) | |
tree | d0e4365cae0ce401ba826809f4eef0bd755f4f2d /drivers | |
parent | 98f8948f13b4d27c3695c49ac9a970a77166f9ee (diff) | |
parent | 778ef1e6cbb049c9bcbf405936ee6f2b6e451892 (diff) |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'drivers')
98 files changed, 3803 insertions, 371 deletions
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 63719ab9ea44..115b1cd6dcf5 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/libata.h> | 24 | #include <linux/libata.h> |
25 | 25 | ||
26 | #define DRV_NAME "pata_amd" | 26 | #define DRV_NAME "pata_amd" |
27 | #define DRV_VERSION "0.3.11" | 27 | #define DRV_VERSION "0.4.1" |
28 | 28 | ||
29 | /** | 29 | /** |
30 | * timing_setup - shared timing computation and load | 30 | * timing_setup - shared timing computation and load |
@@ -145,6 +145,13 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline) | |||
145 | return ata_sff_prereset(link, deadline); | 145 | return ata_sff_prereset(link, deadline); |
146 | } | 146 | } |
147 | 147 | ||
148 | /** | ||
149 | * amd_cable_detect - report cable type | ||
150 | * @ap: port | ||
151 | * | ||
152 | * AMD controller/BIOS setups record the cable type in word 0x42 | ||
153 | */ | ||
154 | |||
148 | static int amd_cable_detect(struct ata_port *ap) | 155 | static int amd_cable_detect(struct ata_port *ap) |
149 | { | 156 | { |
150 | static const u32 bitmask[2] = {0x03, 0x0C}; | 157 | static const u32 bitmask[2] = {0x03, 0x0C}; |
@@ -158,6 +165,40 @@ static int amd_cable_detect(struct ata_port *ap) | |||
158 | } | 165 | } |
159 | 166 | ||
160 | /** | 167 | /** |
168 | * amd_fifo_setup - set the PIO FIFO for ATA/ATAPI | ||
169 | * @ap: ATA interface | ||
170 | * @adev: ATA device | ||
171 | * | ||
172 | * Set the PCI fifo for this device according to the devices present | ||
173 | * on the bus at this point in time. We need to turn the post write buffer | ||
174 | * off for ATAPI devices as we may need to issue a word sized write to the | ||
175 | * device as the final I/O | ||
176 | */ | ||
177 | |||
178 | static void amd_fifo_setup(struct ata_port *ap) | ||
179 | { | ||
180 | struct ata_device *adev; | ||
181 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
182 | static const u8 fifobit[2] = { 0xC0, 0x30}; | ||
183 | u8 fifo = fifobit[ap->port_no]; | ||
184 | u8 r; | ||
185 | |||
186 | |||
187 | ata_for_each_dev(adev, &ap->link, ENABLED) { | ||
188 | if (adev->class == ATA_DEV_ATAPI) | ||
189 | fifo = 0; | ||
190 | } | ||
191 | if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) /* FIFO is broken */ | ||
192 | fifo = 0; | ||
193 | |||
194 | /* On the later chips the read prefetch bits become no-op bits */ | ||
195 | pci_read_config_byte(pdev, 0x41, &r); | ||
196 | r &= ~fifobit[ap->port_no]; | ||
197 | r |= fifo; | ||
198 | pci_write_config_byte(pdev, 0x41, r); | ||
199 | } | ||
200 | |||
201 | /** | ||
161 | * amd33_set_piomode - set initial PIO mode data | 202 | * amd33_set_piomode - set initial PIO mode data |
162 | * @ap: ATA interface | 203 | * @ap: ATA interface |
163 | * @adev: ATA device | 204 | * @adev: ATA device |
@@ -167,21 +208,25 @@ static int amd_cable_detect(struct ata_port *ap) | |||
167 | 208 | ||
168 | static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev) | 209 | static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev) |
169 | { | 210 | { |
211 | amd_fifo_setup(ap); | ||
170 | timing_setup(ap, adev, 0x40, adev->pio_mode, 1); | 212 | timing_setup(ap, adev, 0x40, adev->pio_mode, 1); |
171 | } | 213 | } |
172 | 214 | ||
173 | static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev) | 215 | static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev) |
174 | { | 216 | { |
217 | amd_fifo_setup(ap); | ||
175 | timing_setup(ap, adev, 0x40, adev->pio_mode, 2); | 218 | timing_setup(ap, adev, 0x40, adev->pio_mode, 2); |
176 | } | 219 | } |
177 | 220 | ||
178 | static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev) | 221 | static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev) |
179 | { | 222 | { |
223 | amd_fifo_setup(ap); | ||
180 | timing_setup(ap, adev, 0x40, adev->pio_mode, 3); | 224 | timing_setup(ap, adev, 0x40, adev->pio_mode, 3); |
181 | } | 225 | } |
182 | 226 | ||
183 | static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev) | 227 | static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev) |
184 | { | 228 | { |
229 | amd_fifo_setup(ap); | ||
185 | timing_setup(ap, adev, 0x40, adev->pio_mode, 4); | 230 | timing_setup(ap, adev, 0x40, adev->pio_mode, 4); |
186 | } | 231 | } |
187 | 232 | ||
@@ -397,6 +442,16 @@ static struct ata_port_operations nv133_port_ops = { | |||
397 | .set_dmamode = nv133_set_dmamode, | 442 | .set_dmamode = nv133_set_dmamode, |
398 | }; | 443 | }; |
399 | 444 | ||
445 | static void amd_clear_fifo(struct pci_dev *pdev) | ||
446 | { | ||
447 | u8 fifo; | ||
448 | /* Disable the FIFO, the FIFO logic will re-enable it as | ||
449 | appropriate */ | ||
450 | pci_read_config_byte(pdev, 0x41, &fifo); | ||
451 | fifo &= 0x0F; | ||
452 | pci_write_config_byte(pdev, 0x41, fifo); | ||
453 | } | ||
454 | |||
400 | static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 455 | static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
401 | { | 456 | { |
402 | static const struct ata_port_info info[10] = { | 457 | static const struct ata_port_info info[10] = { |
@@ -503,14 +558,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
503 | 558 | ||
504 | if (type < 3) | 559 | if (type < 3) |
505 | ata_pci_bmdma_clear_simplex(pdev); | 560 | ata_pci_bmdma_clear_simplex(pdev); |
506 | 561 | if (pdev->vendor == PCI_VENDOR_ID_AMD) | |
507 | /* Check for AMD7411 */ | 562 | amd_clear_fifo(pdev); |
508 | if (type == 3) | ||
509 | /* FIFO is broken */ | ||
510 | pci_write_config_byte(pdev, 0x41, fifo & 0x0F); | ||
511 | else | ||
512 | pci_write_config_byte(pdev, 0x41, fifo | 0xF0); | ||
513 | |||
514 | /* Cable detection on Nvidia chips doesn't work too well, | 563 | /* Cable detection on Nvidia chips doesn't work too well, |
515 | * cache BIOS programmed UDMA mode. | 564 | * cache BIOS programmed UDMA mode. |
516 | */ | 565 | */ |
@@ -536,18 +585,11 @@ static int amd_reinit_one(struct pci_dev *pdev) | |||
536 | return rc; | 585 | return rc; |
537 | 586 | ||
538 | if (pdev->vendor == PCI_VENDOR_ID_AMD) { | 587 | if (pdev->vendor == PCI_VENDOR_ID_AMD) { |
539 | u8 fifo; | 588 | amd_clear_fifo(pdev); |
540 | pci_read_config_byte(pdev, 0x41, &fifo); | ||
541 | if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) | ||
542 | /* FIFO is broken */ | ||
543 | pci_write_config_byte(pdev, 0x41, fifo & 0x0F); | ||
544 | else | ||
545 | pci_write_config_byte(pdev, 0x41, fifo | 0xF0); | ||
546 | if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 || | 589 | if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 || |
547 | pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401) | 590 | pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401) |
548 | ata_pci_bmdma_clear_simplex(pdev); | 591 | ata_pci_bmdma_clear_simplex(pdev); |
549 | } | 592 | } |
550 | |||
551 | ata_host_resume(host); | 593 | ata_host_resume(host); |
552 | return 0; | 594 | return 0; |
553 | } | 595 | } |
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index f1bb2f9fecbf..b05b86a912c5 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c | |||
@@ -557,6 +557,9 @@ static unsigned int it821x_read_id(struct ata_device *adev, | |||
557 | id[83] |= 0x4400; /* Word 83 is valid and LBA48 */ | 557 | id[83] |= 0x4400; /* Word 83 is valid and LBA48 */ |
558 | id[86] |= 0x0400; /* LBA48 on */ | 558 | id[86] |= 0x0400; /* LBA48 on */ |
559 | id[ATA_ID_MAJOR_VER] |= 0x1F; | 559 | id[ATA_ID_MAJOR_VER] |= 0x1F; |
560 | /* Clear the serial number because it's different each boot | ||
561 | which breaks validation on resume */ | ||
562 | memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN); | ||
560 | } | 563 | } |
561 | return err_mask; | 564 | return err_mask; |
562 | } | 565 | } |
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 6c1d778b63a9..e3bc1b436284 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -283,9 +283,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
283 | static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, | 283 | static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, |
284 | unsigned char *buf, unsigned int buflen, int rw) | 284 | unsigned char *buf, unsigned int buflen, int rw) |
285 | { | 285 | { |
286 | if (ata_id_has_dword_io(dev->id)) { | 286 | int slop = buflen & 3; |
287 | /* 32bit I/O capable *and* we need to write a whole number of dwords */ | ||
288 | if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) { | ||
287 | struct ata_port *ap = dev->link->ap; | 289 | struct ata_port *ap = dev->link->ap; |
288 | int slop = buflen & 3; | ||
289 | unsigned long flags; | 290 | unsigned long flags; |
290 | 291 | ||
291 | local_irq_save(flags); | 292 | local_irq_save(flags); |
@@ -735,7 +736,7 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf, | |||
735 | struct ata_port *ap = adev->link->ap; | 736 | struct ata_port *ap = adev->link->ap; |
736 | int slop = buflen & 3; | 737 | int slop = buflen & 3; |
737 | 738 | ||
738 | if (ata_id_has_dword_io(adev->id)) { | 739 | if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) { |
739 | if (rw == WRITE) | 740 | if (rw == WRITE) |
740 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | 741 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); |
741 | else | 742 | else |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 4ae1a4138b47..7007edd2d451 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -3114,19 +3114,17 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3114 | writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); | 3114 | writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); |
3115 | } | 3115 | } |
3116 | 3116 | ||
3117 | if (!IS_SOC(hpriv)) { | 3117 | /* Clear any currently outstanding host interrupt conditions */ |
3118 | /* Clear any currently outstanding host interrupt conditions */ | 3118 | writelfl(0, mmio + hpriv->irq_cause_ofs); |
3119 | writelfl(0, mmio + hpriv->irq_cause_ofs); | ||
3120 | 3119 | ||
3121 | /* and unmask interrupt generation for host regs */ | 3120 | /* and unmask interrupt generation for host regs */ |
3122 | writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); | 3121 | writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); |
3123 | 3122 | ||
3124 | /* | 3123 | /* |
3125 | * enable only global host interrupts for now. | 3124 | * enable only global host interrupts for now. |
3126 | * The per-port interrupts get done later as ports are set up. | 3125 | * The per-port interrupts get done later as ports are set up. |
3127 | */ | 3126 | */ |
3128 | mv_set_main_irq_mask(host, 0, PCI_ERR); | 3127 | mv_set_main_irq_mask(host, 0, PCI_ERR); |
3129 | } | ||
3130 | done: | 3128 | done: |
3131 | return rc; | 3129 | return rc; |
3132 | } | 3130 | } |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index d2cb67b61176..b5a061114630 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -3611,11 +3611,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3611 | schedule_timeout_uninterruptible(30*HZ); | 3611 | schedule_timeout_uninterruptible(30*HZ); |
3612 | 3612 | ||
3613 | /* Now try to get the controller to respond to a no-op */ | 3613 | /* Now try to get the controller to respond to a no-op */ |
3614 | for (i=0; i<12; i++) { | 3614 | for (i=0; i<30; i++) { |
3615 | if (cciss_noop(pdev) == 0) | 3615 | if (cciss_noop(pdev) == 0) |
3616 | break; | 3616 | break; |
3617 | else | 3617 | |
3618 | printk("cciss: no-op failed%s\n", (i < 11 ? "; re-trying" : "")); | 3618 | schedule_timeout_uninterruptible(HZ); |
3619 | } | ||
3620 | if (i == 30) { | ||
3621 | printk(KERN_ERR "cciss: controller seems dead\n"); | ||
3622 | return -EBUSY; | ||
3619 | } | 3623 | } |
3620 | } | 3624 | } |
3621 | 3625 | ||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 918ef725de41..b6c8ce254359 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/hdreg.h> | 40 | #include <linux/hdreg.h> |
41 | #include <linux/cdrom.h> | 41 | #include <linux/cdrom.h> |
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/scatterlist.h> | ||
43 | 44 | ||
44 | #include <xen/xenbus.h> | 45 | #include <xen/xenbus.h> |
45 | #include <xen/grant_table.h> | 46 | #include <xen/grant_table.h> |
@@ -82,6 +83,7 @@ struct blkfront_info | |||
82 | enum blkif_state connected; | 83 | enum blkif_state connected; |
83 | int ring_ref; | 84 | int ring_ref; |
84 | struct blkif_front_ring ring; | 85 | struct blkif_front_ring ring; |
86 | struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | ||
85 | unsigned int evtchn, irq; | 87 | unsigned int evtchn, irq; |
86 | struct request_queue *rq; | 88 | struct request_queue *rq; |
87 | struct work_struct work; | 89 | struct work_struct work; |
@@ -204,12 +206,11 @@ static int blkif_queue_request(struct request *req) | |||
204 | struct blkfront_info *info = req->rq_disk->private_data; | 206 | struct blkfront_info *info = req->rq_disk->private_data; |
205 | unsigned long buffer_mfn; | 207 | unsigned long buffer_mfn; |
206 | struct blkif_request *ring_req; | 208 | struct blkif_request *ring_req; |
207 | struct req_iterator iter; | ||
208 | struct bio_vec *bvec; | ||
209 | unsigned long id; | 209 | unsigned long id; |
210 | unsigned int fsect, lsect; | 210 | unsigned int fsect, lsect; |
211 | int ref; | 211 | int i, ref; |
212 | grant_ref_t gref_head; | 212 | grant_ref_t gref_head; |
213 | struct scatterlist *sg; | ||
213 | 214 | ||
214 | if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) | 215 | if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) |
215 | return 1; | 216 | return 1; |
@@ -238,12 +239,13 @@ static int blkif_queue_request(struct request *req) | |||
238 | if (blk_barrier_rq(req)) | 239 | if (blk_barrier_rq(req)) |
239 | ring_req->operation = BLKIF_OP_WRITE_BARRIER; | 240 | ring_req->operation = BLKIF_OP_WRITE_BARRIER; |
240 | 241 | ||
241 | ring_req->nr_segments = 0; | 242 | ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); |
242 | rq_for_each_segment(bvec, req, iter) { | 243 | BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); |
243 | BUG_ON(ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST); | 244 | |
244 | buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page)); | 245 | for_each_sg(info->sg, sg, ring_req->nr_segments, i) { |
245 | fsect = bvec->bv_offset >> 9; | 246 | buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg))); |
246 | lsect = fsect + (bvec->bv_len >> 9) - 1; | 247 | fsect = sg->offset >> 9; |
248 | lsect = fsect + (sg->length >> 9) - 1; | ||
247 | /* install a grant reference. */ | 249 | /* install a grant reference. */ |
248 | ref = gnttab_claim_grant_reference(&gref_head); | 250 | ref = gnttab_claim_grant_reference(&gref_head); |
249 | BUG_ON(ref == -ENOSPC); | 251 | BUG_ON(ref == -ENOSPC); |
@@ -254,16 +256,12 @@ static int blkif_queue_request(struct request *req) | |||
254 | buffer_mfn, | 256 | buffer_mfn, |
255 | rq_data_dir(req) ); | 257 | rq_data_dir(req) ); |
256 | 258 | ||
257 | info->shadow[id].frame[ring_req->nr_segments] = | 259 | info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn); |
258 | mfn_to_pfn(buffer_mfn); | 260 | ring_req->seg[i] = |
259 | |||
260 | ring_req->seg[ring_req->nr_segments] = | ||
261 | (struct blkif_request_segment) { | 261 | (struct blkif_request_segment) { |
262 | .gref = ref, | 262 | .gref = ref, |
263 | .first_sect = fsect, | 263 | .first_sect = fsect, |
264 | .last_sect = lsect }; | 264 | .last_sect = lsect }; |
265 | |||
266 | ring_req->nr_segments++; | ||
267 | } | 265 | } |
268 | 266 | ||
269 | info->ring.req_prod_pvt++; | 267 | info->ring.req_prod_pvt++; |
@@ -622,6 +620,8 @@ static int setup_blkring(struct xenbus_device *dev, | |||
622 | SHARED_RING_INIT(sring); | 620 | SHARED_RING_INIT(sring); |
623 | FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); | 621 | FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); |
624 | 622 | ||
623 | sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST); | ||
624 | |||
625 | err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); | 625 | err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); |
626 | if (err < 0) { | 626 | if (err < 0) { |
627 | free_page((unsigned long)sring); | 627 | free_page((unsigned long)sring); |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 733028b4d45e..1c3a8c557140 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -452,6 +452,59 @@ static void drm_setup_crtcs(struct drm_device *dev) | |||
452 | kfree(modes); | 452 | kfree(modes); |
453 | kfree(enabled); | 453 | kfree(enabled); |
454 | } | 454 | } |
455 | |||
456 | /** | ||
457 | * drm_encoder_crtc_ok - can a given crtc drive a given encoder? | ||
458 | * @encoder: encoder to test | ||
459 | * @crtc: crtc to test | ||
460 | * | ||
461 | * Return false if @encoder can't be driven by @crtc, true otherwise. | ||
462 | */ | ||
463 | static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, | ||
464 | struct drm_crtc *crtc) | ||
465 | { | ||
466 | struct drm_device *dev; | ||
467 | struct drm_crtc *tmp; | ||
468 | int crtc_mask = 1; | ||
469 | |||
470 | WARN(!crtc, "checking null crtc?"); | ||
471 | |||
472 | dev = crtc->dev; | ||
473 | |||
474 | list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { | ||
475 | if (tmp == crtc) | ||
476 | break; | ||
477 | crtc_mask <<= 1; | ||
478 | } | ||
479 | |||
480 | if (encoder->possible_crtcs & crtc_mask) | ||
481 | return true; | ||
482 | return false; | ||
483 | } | ||
484 | |||
485 | /* | ||
486 | * Check the CRTC we're going to map each output to vs. its current | ||
487 | * CRTC. If they don't match, we have to disable the output and the CRTC | ||
488 | * since the driver will have to re-route things. | ||
489 | */ | ||
490 | static void | ||
491 | drm_crtc_prepare_encoders(struct drm_device *dev) | ||
492 | { | ||
493 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
494 | struct drm_encoder *encoder; | ||
495 | |||
496 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
497 | encoder_funcs = encoder->helper_private; | ||
498 | /* Disable unused encoders */ | ||
499 | if (encoder->crtc == NULL) | ||
500 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); | ||
501 | /* Disable encoders whose CRTC is about to change */ | ||
502 | if (encoder_funcs->get_crtc && | ||
503 | encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) | ||
504 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); | ||
505 | } | ||
506 | } | ||
507 | |||
455 | /** | 508 | /** |
456 | * drm_crtc_set_mode - set a mode | 509 | * drm_crtc_set_mode - set a mode |
457 | * @crtc: CRTC to program | 510 | * @crtc: CRTC to program |
@@ -547,6 +600,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
547 | encoder_funcs->prepare(encoder); | 600 | encoder_funcs->prepare(encoder); |
548 | } | 601 | } |
549 | 602 | ||
603 | drm_crtc_prepare_encoders(dev); | ||
604 | |||
550 | crtc_funcs->prepare(crtc); | 605 | crtc_funcs->prepare(crtc); |
551 | 606 | ||
552 | /* Set up the DPLL and any encoders state that needs to adjust or depend | 607 | /* Set up the DPLL and any encoders state that needs to adjust or depend |
@@ -617,7 +672,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
617 | struct drm_device *dev; | 672 | struct drm_device *dev; |
618 | struct drm_crtc **save_crtcs, *new_crtc; | 673 | struct drm_crtc **save_crtcs, *new_crtc; |
619 | struct drm_encoder **save_encoders, *new_encoder; | 674 | struct drm_encoder **save_encoders, *new_encoder; |
620 | struct drm_framebuffer *old_fb; | 675 | struct drm_framebuffer *old_fb = NULL; |
621 | bool save_enabled; | 676 | bool save_enabled; |
622 | bool mode_changed = false; | 677 | bool mode_changed = false; |
623 | bool fb_changed = false; | 678 | bool fb_changed = false; |
@@ -668,9 +723,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
668 | * and then just flip_or_move it */ | 723 | * and then just flip_or_move it */ |
669 | if (set->crtc->fb != set->fb) { | 724 | if (set->crtc->fb != set->fb) { |
670 | /* If we have no fb then treat it as a full mode set */ | 725 | /* If we have no fb then treat it as a full mode set */ |
671 | if (set->crtc->fb == NULL) | 726 | if (set->crtc->fb == NULL) { |
727 | DRM_DEBUG("crtc has no fb, full mode set\n"); | ||
672 | mode_changed = true; | 728 | mode_changed = true; |
673 | else if ((set->fb->bits_per_pixel != | 729 | } else if ((set->fb->bits_per_pixel != |
674 | set->crtc->fb->bits_per_pixel) || | 730 | set->crtc->fb->bits_per_pixel) || |
675 | set->fb->depth != set->crtc->fb->depth) | 731 | set->fb->depth != set->crtc->fb->depth) |
676 | fb_changed = true; | 732 | fb_changed = true; |
@@ -682,7 +738,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
682 | fb_changed = true; | 738 | fb_changed = true; |
683 | 739 | ||
684 | if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { | 740 | if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { |
685 | DRM_DEBUG("modes are different\n"); | 741 | DRM_DEBUG("modes are different, full mode set\n"); |
686 | drm_mode_debug_printmodeline(&set->crtc->mode); | 742 | drm_mode_debug_printmodeline(&set->crtc->mode); |
687 | drm_mode_debug_printmodeline(set->mode); | 743 | drm_mode_debug_printmodeline(set->mode); |
688 | mode_changed = true; | 744 | mode_changed = true; |
@@ -708,6 +764,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
708 | } | 764 | } |
709 | 765 | ||
710 | if (new_encoder != connector->encoder) { | 766 | if (new_encoder != connector->encoder) { |
767 | DRM_DEBUG("encoder changed, full mode switch\n"); | ||
711 | mode_changed = true; | 768 | mode_changed = true; |
712 | connector->encoder = new_encoder; | 769 | connector->encoder = new_encoder; |
713 | } | 770 | } |
@@ -734,10 +791,20 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
734 | if (set->connectors[ro] == connector) | 791 | if (set->connectors[ro] == connector) |
735 | new_crtc = set->crtc; | 792 | new_crtc = set->crtc; |
736 | } | 793 | } |
794 | |||
795 | /* Make sure the new CRTC will work with the encoder */ | ||
796 | if (new_crtc && | ||
797 | !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { | ||
798 | ret = -EINVAL; | ||
799 | goto fail_set_mode; | ||
800 | } | ||
737 | if (new_crtc != connector->encoder->crtc) { | 801 | if (new_crtc != connector->encoder->crtc) { |
802 | DRM_DEBUG("crtc changed, full mode switch\n"); | ||
738 | mode_changed = true; | 803 | mode_changed = true; |
739 | connector->encoder->crtc = new_crtc; | 804 | connector->encoder->crtc = new_crtc; |
740 | } | 805 | } |
806 | DRM_DEBUG("setting connector %d crtc to %p\n", | ||
807 | connector->base.id, new_crtc); | ||
741 | } | 808 | } |
742 | 809 | ||
743 | /* mode_set_base is not a required function */ | 810 | /* mode_set_base is not a required function */ |
@@ -781,6 +848,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
781 | 848 | ||
782 | fail_set_mode: | 849 | fail_set_mode: |
783 | set->crtc->enabled = save_enabled; | 850 | set->crtc->enabled = save_enabled; |
851 | set->crtc->fb = old_fb; | ||
784 | count = 0; | 852 | count = 0; |
785 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 853 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
786 | if (!connector->encoder) | 854 | if (!connector->encoder) |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 5a4d3244758a..a839a28d8ee6 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -125,7 +125,7 @@ static bool edid_is_valid(struct edid *edid) | |||
125 | DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); | 125 | DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); |
126 | goto bad; | 126 | goto bad; |
127 | } | 127 | } |
128 | if (edid->revision <= 0 || edid->revision > 3) { | 128 | if (edid->revision > 3) { |
129 | DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision); | 129 | DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision); |
130 | goto bad; | 130 | goto bad; |
131 | } | 131 | } |
@@ -320,10 +320,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
320 | mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo); | 320 | mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo); |
321 | 321 | ||
322 | mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo; | 322 | mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo; |
323 | mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 8) | | 323 | mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) | |
324 | pt->vsync_offset_lo); | 324 | pt->vsync_offset_lo); |
325 | mode->vsync_end = mode->vsync_start + | 325 | mode->vsync_end = mode->vsync_start + |
326 | ((pt->vsync_pulse_width_hi << 8) | | 326 | ((pt->vsync_pulse_width_hi << 4) | |
327 | pt->vsync_pulse_width_lo); | 327 | pt->vsync_pulse_width_lo); |
328 | mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo); | 328 | mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo); |
329 | 329 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 3795dbc0f50c..93e677a481f5 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -435,6 +435,8 @@ EXPORT_SYMBOL(drm_vblank_get); | |||
435 | */ | 435 | */ |
436 | void drm_vblank_put(struct drm_device *dev, int crtc) | 436 | void drm_vblank_put(struct drm_device *dev, int crtc) |
437 | { | 437 | { |
438 | BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0); | ||
439 | |||
438 | /* Last user schedules interrupt disable */ | 440 | /* Last user schedules interrupt disable */ |
439 | if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) | 441 | if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) |
440 | mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); | 442 | mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); |
@@ -460,8 +462,9 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) | |||
460 | * so that interrupts remain enabled in the interim. | 462 | * so that interrupts remain enabled in the interim. |
461 | */ | 463 | */ |
462 | if (!dev->vblank_inmodeset[crtc]) { | 464 | if (!dev->vblank_inmodeset[crtc]) { |
463 | dev->vblank_inmodeset[crtc] = 1; | 465 | dev->vblank_inmodeset[crtc] = 0x1; |
464 | drm_vblank_get(dev, crtc); | 466 | if (drm_vblank_get(dev, crtc) == 0) |
467 | dev->vblank_inmodeset[crtc] |= 0x2; | ||
465 | } | 468 | } |
466 | } | 469 | } |
467 | EXPORT_SYMBOL(drm_vblank_pre_modeset); | 470 | EXPORT_SYMBOL(drm_vblank_pre_modeset); |
@@ -473,9 +476,12 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) | |||
473 | if (dev->vblank_inmodeset[crtc]) { | 476 | if (dev->vblank_inmodeset[crtc]) { |
474 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 477 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
475 | dev->vblank_disable_allowed = 1; | 478 | dev->vblank_disable_allowed = 1; |
476 | dev->vblank_inmodeset[crtc] = 0; | ||
477 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 479 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
478 | drm_vblank_put(dev, crtc); | 480 | |
481 | if (dev->vblank_inmodeset[crtc] & 0x2) | ||
482 | drm_vblank_put(dev, crtc); | ||
483 | |||
484 | dev->vblank_inmodeset[crtc] = 0; | ||
479 | } | 485 | } |
480 | } | 486 | } |
481 | EXPORT_SYMBOL(drm_vblank_post_modeset); | 487 | EXPORT_SYMBOL(drm_vblank_post_modeset); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2d797ffe8137..6dab63bdc4c1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -811,7 +811,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
811 | dev_priv->hws_map.flags = 0; | 811 | dev_priv->hws_map.flags = 0; |
812 | dev_priv->hws_map.mtrr = 0; | 812 | dev_priv->hws_map.mtrr = 0; |
813 | 813 | ||
814 | drm_core_ioremap(&dev_priv->hws_map, dev); | 814 | drm_core_ioremap_wc(&dev_priv->hws_map, dev); |
815 | if (dev_priv->hws_map.handle == NULL) { | 815 | if (dev_priv->hws_map.handle == NULL) { |
816 | i915_dma_cleanup(dev); | 816 | i915_dma_cleanup(dev); |
817 | dev_priv->status_gfx_addr = 0; | 817 | dev_priv->status_gfx_addr = 0; |
@@ -1090,6 +1090,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1090 | dev_priv->mm.gtt_mapping = | 1090 | dev_priv->mm.gtt_mapping = |
1091 | io_mapping_create_wc(dev->agp->base, | 1091 | io_mapping_create_wc(dev->agp->base, |
1092 | dev->agp->agp_info.aper_size * 1024*1024); | 1092 | dev->agp->agp_info.aper_size * 1024*1024); |
1093 | if (dev_priv->mm.gtt_mapping == NULL) { | ||
1094 | ret = -EIO; | ||
1095 | goto out_rmmap; | ||
1096 | } | ||
1097 | |||
1093 | /* Set up a WC MTRR for non-PAT systems. This is more common than | 1098 | /* Set up a WC MTRR for non-PAT systems. This is more common than |
1094 | * one would think, because the kernel disables PAT on first | 1099 | * one would think, because the kernel disables PAT on first |
1095 | * generation Core chips because WC PAT gets overridden by a UC | 1100 | * generation Core chips because WC PAT gets overridden by a UC |
@@ -1122,7 +1127,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1122 | if (!I915_NEED_GFX_HWS(dev)) { | 1127 | if (!I915_NEED_GFX_HWS(dev)) { |
1123 | ret = i915_init_phys_hws(dev); | 1128 | ret = i915_init_phys_hws(dev); |
1124 | if (ret != 0) | 1129 | if (ret != 0) |
1125 | goto out_rmmap; | 1130 | goto out_iomapfree; |
1126 | } | 1131 | } |
1127 | 1132 | ||
1128 | /* On the 945G/GM, the chipset reports the MSI capability on the | 1133 | /* On the 945G/GM, the chipset reports the MSI capability on the |
@@ -1161,6 +1166,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1161 | 1166 | ||
1162 | return 0; | 1167 | return 0; |
1163 | 1168 | ||
1169 | out_iomapfree: | ||
1170 | io_mapping_free(dev_priv->mm.gtt_mapping); | ||
1164 | out_rmmap: | 1171 | out_rmmap: |
1165 | iounmap(dev_priv->regs); | 1172 | iounmap(dev_priv->regs); |
1166 | free_priv: | 1173 | free_priv: |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 28b726d07a0c..85685bfd12da 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3548,7 +3548,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
3548 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 3548 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
3549 | obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; | 3549 | obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; |
3550 | 3550 | ||
3551 | DRM_ERROR("obj_addr %p, %lld\n", obj_addr, args->size); | 3551 | DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size); |
3552 | ret = copy_from_user(obj_addr, user_data, args->size); | 3552 | ret = copy_from_user(obj_addr, user_data, args->size); |
3553 | if (ret) | 3553 | if (ret) |
3554 | return -EFAULT; | 3554 | return -EFAULT; |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 65be30dccc77..fc28e2bbd542 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -111,6 +111,12 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb) | |||
111 | panel_fixed_mode->clock = dvo_timing->clock * 10; | 111 | panel_fixed_mode->clock = dvo_timing->clock * 10; |
112 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; | 112 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; |
113 | 113 | ||
114 | /* Some VBTs have bogus h/vtotal values */ | ||
115 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) | ||
116 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; | ||
117 | if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) | ||
118 | panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; | ||
119 | |||
114 | drm_mode_set_name(panel_fixed_mode); | 120 | drm_mode_set_name(panel_fixed_mode); |
115 | 121 | ||
116 | dev_priv->vbt_mode = panel_fixed_mode; | 122 | dev_priv->vbt_mode = panel_fixed_mode; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 65b635ce28c8..a2834276cb38 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -217,7 +217,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) | |||
217 | return false; | 217 | return false; |
218 | } | 218 | } |
219 | 219 | ||
220 | #define INTELPllInvalid(s) do { DRM_DEBUG(s); return false; } while (0) | 220 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) |
221 | /** | 221 | /** |
222 | * Returns whether the given set of divisors are valid for a given refclk with | 222 | * Returns whether the given set of divisors are valid for a given refclk with |
223 | * the given connectors. | 223 | * the given connectors. |
diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c index 9fee3ca17344..9aefb5e5864d 100644 --- a/drivers/i2c/busses/i2c-acorn.c +++ b/drivers/i2c/busses/i2c-acorn.c | |||
@@ -79,10 +79,11 @@ static struct i2c_algo_bit_data ioc_data = { | |||
79 | .getsda = ioc_getsda, | 79 | .getsda = ioc_getsda, |
80 | .getscl = ioc_getscl, | 80 | .getscl = ioc_getscl, |
81 | .udelay = 80, | 81 | .udelay = 80, |
82 | .timeout = 100 | 82 | .timeout = HZ, |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static struct i2c_adapter ioc_ops = { | 85 | static struct i2c_adapter ioc_ops = { |
86 | .nr = 0, | ||
86 | .algo_data = &ioc_data, | 87 | .algo_data = &ioc_data, |
87 | }; | 88 | }; |
88 | 89 | ||
@@ -90,7 +91,7 @@ static int __init i2c_ioc_init(void) | |||
90 | { | 91 | { |
91 | force_ones = FORCE_ONES | SCL | SDA; | 92 | force_ones = FORCE_ONES | SCL | SDA; |
92 | 93 | ||
93 | return i2c_bit_add_bus(&ioc_ops); | 94 | return i2c_bit_add_numbered_bus(&ioc_ops); |
94 | } | 95 | } |
95 | 96 | ||
96 | module_init(i2c_ioc_init); | 97 | module_init(i2c_ioc_init); |
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index edab51973bf5..a7c59908c457 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c | |||
@@ -72,7 +72,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus) | |||
72 | { | 72 | { |
73 | int timeout = 500; | 73 | int timeout = 500; |
74 | 74 | ||
75 | while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF)) | 75 | while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout) |
76 | udelay(1); | 76 | udelay(1); |
77 | 77 | ||
78 | if (!timeout) { | 78 | if (!timeout) { |
@@ -88,7 +88,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus) | |||
88 | { | 88 | { |
89 | int timeout = 500; | 89 | int timeout = 500; |
90 | 90 | ||
91 | while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF)) | 91 | while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout) |
92 | udelay(1); | 92 | udelay(1); |
93 | 93 | ||
94 | if (!timeout) { | 94 | if (!timeout) { |
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index 8e8467970481..c016f7a2c5fc 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c | |||
@@ -114,7 +114,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev) | |||
114 | drv_data->algo_data.getsda = ixp2000_bit_getsda; | 114 | drv_data->algo_data.getsda = ixp2000_bit_getsda; |
115 | drv_data->algo_data.getscl = ixp2000_bit_getscl; | 115 | drv_data->algo_data.getscl = ixp2000_bit_getscl; |
116 | drv_data->algo_data.udelay = 6; | 116 | drv_data->algo_data.udelay = 6; |
117 | drv_data->algo_data.timeout = 100; | 117 | drv_data->algo_data.timeout = HZ; |
118 | 118 | ||
119 | strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, | 119 | strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, |
120 | sizeof(drv_data->adapter.name)); | 120 | sizeof(drv_data->adapter.name)); |
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 6af68146c342..bdb1f7510e91 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -644,7 +644,7 @@ static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c, | |||
644 | 644 | ||
645 | i2c_pxa_start_message(i2c); | 645 | i2c_pxa_start_message(i2c); |
646 | 646 | ||
647 | while (timeout-- && i2c->msg_num > 0) { | 647 | while (i2c->msg_num > 0 && --timeout) { |
648 | i2c_pxa_handler(0, i2c); | 648 | i2c_pxa_handler(0, i2c); |
649 | udelay(10); | 649 | udelay(10); |
650 | } | 650 | } |
diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c index 162b74a04886..42df0eca43d5 100644 --- a/drivers/i2c/busses/scx200_i2c.c +++ b/drivers/i2c/busses/scx200_i2c.c | |||
@@ -76,7 +76,7 @@ static struct i2c_algo_bit_data scx200_i2c_data = { | |||
76 | .getsda = scx200_i2c_getsda, | 76 | .getsda = scx200_i2c_getsda, |
77 | .getscl = scx200_i2c_getscl, | 77 | .getscl = scx200_i2c_getscl, |
78 | .udelay = 10, | 78 | .udelay = 10, |
79 | .timeout = 100, | 79 | .timeout = HZ, |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static struct i2c_adapter scx200_i2c_ops = { | 82 | static struct i2c_adapter scx200_i2c_ops = { |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b1c9abe24c7b..e7d984866de0 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -1831,7 +1831,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, | |||
1831 | case I2C_SMBUS_QUICK: | 1831 | case I2C_SMBUS_QUICK: |
1832 | msg[0].len = 0; | 1832 | msg[0].len = 0; |
1833 | /* Special case: The read/write field is used as data */ | 1833 | /* Special case: The read/write field is used as data */ |
1834 | msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; | 1834 | msg[0].flags = flags | (read_write == I2C_SMBUS_READ ? |
1835 | I2C_M_RD : 0); | ||
1835 | num = 1; | 1836 | num = 1; |
1836 | break; | 1837 | break; |
1837 | case I2C_SMBUS_BYTE: | 1838 | case I2C_SMBUS_BYTE: |
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index c171988a9f51..7e13d2df9af3 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/i2c.h> | 35 | #include <linux/i2c.h> |
36 | #include <linux/i2c-dev.h> | 36 | #include <linux/i2c-dev.h> |
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
38 | #include <linux/jiffies.h> | ||
38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
39 | 40 | ||
40 | static struct i2c_driver i2cdev_driver; | 41 | static struct i2c_driver i2cdev_driver; |
@@ -422,7 +423,10 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
422 | client->adapter->retries = arg; | 423 | client->adapter->retries = arg; |
423 | break; | 424 | break; |
424 | case I2C_TIMEOUT: | 425 | case I2C_TIMEOUT: |
425 | client->adapter->timeout = arg; | 426 | /* For historical reasons, user-space sets the timeout |
427 | * value in units of 10 ms. | ||
428 | */ | ||
429 | client->adapter->timeout = msecs_to_jiffies(arg * 10); | ||
426 | break; | 430 | break; |
427 | default: | 431 | default: |
428 | /* NOTE: returning a fault code here could cause trouble | 432 | /* NOTE: returning a fault code here could cause trouble |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 3dad2299d9c5..e072903b12f0 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -46,7 +46,7 @@ menuconfig IDE | |||
46 | SMART parameters from disk drives. | 46 | SMART parameters from disk drives. |
47 | 47 | ||
48 | To compile this driver as a module, choose M here: the | 48 | To compile this driver as a module, choose M here: the |
49 | module will be called ide. | 49 | module will be called ide-core.ko. |
50 | 50 | ||
51 | For further information, please read <file:Documentation/ide/ide.txt>. | 51 | For further information, please read <file:Documentation/ide/ide.txt>. |
52 | 52 | ||
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c index 69660a431cd9..77267c859965 100644 --- a/drivers/ide/amd74xx.c +++ b/drivers/ide/amd74xx.c | |||
@@ -166,7 +166,7 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *dev) | |||
166 | * Check for broken FIFO support. | 166 | * Check for broken FIFO support. |
167 | */ | 167 | */ |
168 | if (dev->vendor == PCI_VENDOR_ID_AMD && | 168 | if (dev->vendor == PCI_VENDOR_ID_AMD && |
169 | dev->vendor == PCI_DEVICE_ID_AMD_VIPER_7411) | 169 | dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) |
170 | t &= 0x0f; | 170 | t &= 0x0f; |
171 | else | 171 | else |
172 | t |= 0xf0; | 172 | t |= 0xf0; |
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c index b2735d28f5cc..ecd1e62ca91a 100644 --- a/drivers/ide/atiixp.c +++ b/drivers/ide/atiixp.c | |||
@@ -52,7 +52,7 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
52 | { | 52 | { |
53 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); | 53 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); |
54 | unsigned long flags; | 54 | unsigned long flags; |
55 | int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; | 55 | int timing_shift = (drive->dn ^ 1) * 8; |
56 | u32 pio_timing_data; | 56 | u32 pio_timing_data; |
57 | u16 pio_mode_data; | 57 | u16 pio_mode_data; |
58 | 58 | ||
@@ -85,7 +85,7 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
85 | { | 85 | { |
86 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); | 86 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); |
87 | unsigned long flags; | 87 | unsigned long flags; |
88 | int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; | 88 | int timing_shift = (drive->dn ^ 1) * 8; |
89 | u32 tmp32; | 89 | u32 tmp32; |
90 | u16 tmp16; | 90 | u16 tmp16; |
91 | u16 udma_ctl = 0; | 91 | u16 udma_ctl = 0; |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 0bfeb0c79d6e..ddfbea41d296 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -55,7 +55,7 @@ | |||
55 | 55 | ||
56 | static DEFINE_MUTEX(idecd_ref_mutex); | 56 | static DEFINE_MUTEX(idecd_ref_mutex); |
57 | 57 | ||
58 | static void ide_cd_release(struct kref *); | 58 | static void ide_cd_release(struct device *); |
59 | 59 | ||
60 | static struct cdrom_info *ide_cd_get(struct gendisk *disk) | 60 | static struct cdrom_info *ide_cd_get(struct gendisk *disk) |
61 | { | 61 | { |
@@ -67,7 +67,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk) | |||
67 | if (ide_device_get(cd->drive)) | 67 | if (ide_device_get(cd->drive)) |
68 | cd = NULL; | 68 | cd = NULL; |
69 | else | 69 | else |
70 | kref_get(&cd->kref); | 70 | get_device(&cd->dev); |
71 | 71 | ||
72 | } | 72 | } |
73 | mutex_unlock(&idecd_ref_mutex); | 73 | mutex_unlock(&idecd_ref_mutex); |
@@ -79,7 +79,7 @@ static void ide_cd_put(struct cdrom_info *cd) | |||
79 | ide_drive_t *drive = cd->drive; | 79 | ide_drive_t *drive = cd->drive; |
80 | 80 | ||
81 | mutex_lock(&idecd_ref_mutex); | 81 | mutex_lock(&idecd_ref_mutex); |
82 | kref_put(&cd->kref, ide_cd_release); | 82 | put_device(&cd->dev); |
83 | ide_device_put(drive); | 83 | ide_device_put(drive); |
84 | mutex_unlock(&idecd_ref_mutex); | 84 | mutex_unlock(&idecd_ref_mutex); |
85 | } | 85 | } |
@@ -194,6 +194,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, | |||
194 | bio_sectors = max(bio_sectors(failed_command->bio), 4U); | 194 | bio_sectors = max(bio_sectors(failed_command->bio), 4U); |
195 | sector &= ~(bio_sectors - 1); | 195 | sector &= ~(bio_sectors - 1); |
196 | 196 | ||
197 | /* | ||
198 | * The SCSI specification allows for the value | ||
199 | * returned by READ CAPACITY to be up to 75 2K | ||
200 | * sectors past the last readable block. | ||
201 | * Therefore, if we hit a medium error within the | ||
202 | * last 75 2K sectors, we decrease the saved size | ||
203 | * value. | ||
204 | */ | ||
197 | if (sector < get_capacity(info->disk) && | 205 | if (sector < get_capacity(info->disk) && |
198 | drive->probed_capacity - sector < 4 * 75) | 206 | drive->probed_capacity - sector < 4 * 75) |
199 | set_capacity(info->disk, sector); | 207 | set_capacity(info->disk, sector); |
@@ -1790,15 +1798,17 @@ static void ide_cd_remove(ide_drive_t *drive) | |||
1790 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | 1798 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); |
1791 | 1799 | ||
1792 | ide_proc_unregister_driver(drive, info->driver); | 1800 | ide_proc_unregister_driver(drive, info->driver); |
1793 | 1801 | device_del(&info->dev); | |
1794 | del_gendisk(info->disk); | 1802 | del_gendisk(info->disk); |
1795 | 1803 | ||
1796 | ide_cd_put(info); | 1804 | mutex_lock(&idecd_ref_mutex); |
1805 | put_device(&info->dev); | ||
1806 | mutex_unlock(&idecd_ref_mutex); | ||
1797 | } | 1807 | } |
1798 | 1808 | ||
1799 | static void ide_cd_release(struct kref *kref) | 1809 | static void ide_cd_release(struct device *dev) |
1800 | { | 1810 | { |
1801 | struct cdrom_info *info = to_ide_drv(kref, cdrom_info); | 1811 | struct cdrom_info *info = to_ide_drv(dev, cdrom_info); |
1802 | struct cdrom_device_info *devinfo = &info->devinfo; | 1812 | struct cdrom_device_info *devinfo = &info->devinfo; |
1803 | ide_drive_t *drive = info->drive; | 1813 | ide_drive_t *drive = info->drive; |
1804 | struct gendisk *g = info->disk; | 1814 | struct gendisk *g = info->disk; |
@@ -1997,7 +2007,12 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
1997 | 2007 | ||
1998 | ide_init_disk(g, drive); | 2008 | ide_init_disk(g, drive); |
1999 | 2009 | ||
2000 | kref_init(&info->kref); | 2010 | info->dev.parent = &drive->gendev; |
2011 | info->dev.release = ide_cd_release; | ||
2012 | dev_set_name(&info->dev, dev_name(&drive->gendev)); | ||
2013 | |||
2014 | if (device_register(&info->dev)) | ||
2015 | goto out_free_disk; | ||
2001 | 2016 | ||
2002 | info->drive = drive; | 2017 | info->drive = drive; |
2003 | info->driver = &ide_cdrom_driver; | 2018 | info->driver = &ide_cdrom_driver; |
@@ -2011,7 +2026,7 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
2011 | g->driverfs_dev = &drive->gendev; | 2026 | g->driverfs_dev = &drive->gendev; |
2012 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; | 2027 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; |
2013 | if (ide_cdrom_setup(drive)) { | 2028 | if (ide_cdrom_setup(drive)) { |
2014 | ide_cd_release(&info->kref); | 2029 | put_device(&info->dev); |
2015 | goto failed; | 2030 | goto failed; |
2016 | } | 2031 | } |
2017 | 2032 | ||
@@ -2021,6 +2036,8 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
2021 | add_disk(g); | 2036 | add_disk(g); |
2022 | return 0; | 2037 | return 0; |
2023 | 2038 | ||
2039 | out_free_disk: | ||
2040 | put_disk(g); | ||
2024 | out_free_cd: | 2041 | out_free_cd: |
2025 | kfree(info); | 2042 | kfree(info); |
2026 | failed: | 2043 | failed: |
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index ac40d6cb90a2..c878bfcf1116 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h | |||
@@ -80,7 +80,7 @@ struct cdrom_info { | |||
80 | ide_drive_t *drive; | 80 | ide_drive_t *drive; |
81 | struct ide_driver *driver; | 81 | struct ide_driver *driver; |
82 | struct gendisk *disk; | 82 | struct gendisk *disk; |
83 | struct kref kref; | 83 | struct device dev; |
84 | 84 | ||
85 | /* Buffer for table of contents. NULL if we haven't allocated | 85 | /* Buffer for table of contents. NULL if we haven't allocated |
86 | a TOC buffer for this device yet. */ | 86 | a TOC buffer for this device yet. */ |
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index 7857b209c6df..047109419902 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c | |||
@@ -25,7 +25,7 @@ module_param(debug_mask, ulong, 0644); | |||
25 | 25 | ||
26 | static DEFINE_MUTEX(ide_disk_ref_mutex); | 26 | static DEFINE_MUTEX(ide_disk_ref_mutex); |
27 | 27 | ||
28 | static void ide_disk_release(struct kref *); | 28 | static void ide_disk_release(struct device *); |
29 | 29 | ||
30 | static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) | 30 | static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) |
31 | { | 31 | { |
@@ -37,7 +37,7 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) | |||
37 | if (ide_device_get(idkp->drive)) | 37 | if (ide_device_get(idkp->drive)) |
38 | idkp = NULL; | 38 | idkp = NULL; |
39 | else | 39 | else |
40 | kref_get(&idkp->kref); | 40 | get_device(&idkp->dev); |
41 | } | 41 | } |
42 | mutex_unlock(&ide_disk_ref_mutex); | 42 | mutex_unlock(&ide_disk_ref_mutex); |
43 | return idkp; | 43 | return idkp; |
@@ -48,7 +48,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp) | |||
48 | ide_drive_t *drive = idkp->drive; | 48 | ide_drive_t *drive = idkp->drive; |
49 | 49 | ||
50 | mutex_lock(&ide_disk_ref_mutex); | 50 | mutex_lock(&ide_disk_ref_mutex); |
51 | kref_put(&idkp->kref, ide_disk_release); | 51 | put_device(&idkp->dev); |
52 | ide_device_put(drive); | 52 | ide_device_put(drive); |
53 | mutex_unlock(&ide_disk_ref_mutex); | 53 | mutex_unlock(&ide_disk_ref_mutex); |
54 | } | 54 | } |
@@ -66,17 +66,18 @@ static void ide_gd_remove(ide_drive_t *drive) | |||
66 | struct gendisk *g = idkp->disk; | 66 | struct gendisk *g = idkp->disk; |
67 | 67 | ||
68 | ide_proc_unregister_driver(drive, idkp->driver); | 68 | ide_proc_unregister_driver(drive, idkp->driver); |
69 | 69 | device_del(&idkp->dev); | |
70 | del_gendisk(g); | 70 | del_gendisk(g); |
71 | |||
72 | drive->disk_ops->flush(drive); | 71 | drive->disk_ops->flush(drive); |
73 | 72 | ||
74 | ide_disk_put(idkp); | 73 | mutex_lock(&ide_disk_ref_mutex); |
74 | put_device(&idkp->dev); | ||
75 | mutex_unlock(&ide_disk_ref_mutex); | ||
75 | } | 76 | } |
76 | 77 | ||
77 | static void ide_disk_release(struct kref *kref) | 78 | static void ide_disk_release(struct device *dev) |
78 | { | 79 | { |
79 | struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj); | 80 | struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj); |
80 | ide_drive_t *drive = idkp->drive; | 81 | ide_drive_t *drive = idkp->drive; |
81 | struct gendisk *g = idkp->disk; | 82 | struct gendisk *g = idkp->disk; |
82 | 83 | ||
@@ -348,7 +349,12 @@ static int ide_gd_probe(ide_drive_t *drive) | |||
348 | 349 | ||
349 | ide_init_disk(g, drive); | 350 | ide_init_disk(g, drive); |
350 | 351 | ||
351 | kref_init(&idkp->kref); | 352 | idkp->dev.parent = &drive->gendev; |
353 | idkp->dev.release = ide_disk_release; | ||
354 | dev_set_name(&idkp->dev, dev_name(&drive->gendev)); | ||
355 | |||
356 | if (device_register(&idkp->dev)) | ||
357 | goto out_free_disk; | ||
352 | 358 | ||
353 | idkp->drive = drive; | 359 | idkp->drive = drive; |
354 | idkp->driver = &ide_gd_driver; | 360 | idkp->driver = &ide_gd_driver; |
@@ -373,6 +379,8 @@ static int ide_gd_probe(ide_drive_t *drive) | |||
373 | add_disk(g); | 379 | add_disk(g); |
374 | return 0; | 380 | return 0; |
375 | 381 | ||
382 | out_free_disk: | ||
383 | put_disk(g); | ||
376 | out_free_idkp: | 384 | out_free_idkp: |
377 | kfree(idkp); | 385 | kfree(idkp); |
378 | failed: | 386 | failed: |
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h index a86779f0756b..b604bdd318a1 100644 --- a/drivers/ide/ide-gd.h +++ b/drivers/ide/ide-gd.h | |||
@@ -17,7 +17,7 @@ struct ide_disk_obj { | |||
17 | ide_drive_t *drive; | 17 | ide_drive_t *drive; |
18 | struct ide_driver *driver; | 18 | struct ide_driver *driver; |
19 | struct gendisk *disk; | 19 | struct gendisk *disk; |
20 | struct kref kref; | 20 | struct device dev; |
21 | unsigned int openers; /* protected by BKL for now */ | 21 | unsigned int openers; /* protected by BKL for now */ |
22 | 22 | ||
23 | /* Last failed packet command */ | 23 | /* Last failed packet command */ |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d7ecd3c79757..bb450a7608c2 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -169,7 +169,7 @@ typedef struct ide_tape_obj { | |||
169 | ide_drive_t *drive; | 169 | ide_drive_t *drive; |
170 | struct ide_driver *driver; | 170 | struct ide_driver *driver; |
171 | struct gendisk *disk; | 171 | struct gendisk *disk; |
172 | struct kref kref; | 172 | struct device dev; |
173 | 173 | ||
174 | /* | 174 | /* |
175 | * failed_pc points to the last failed packet command, or contains | 175 | * failed_pc points to the last failed packet command, or contains |
@@ -267,7 +267,7 @@ static DEFINE_MUTEX(idetape_ref_mutex); | |||
267 | 267 | ||
268 | static struct class *idetape_sysfs_class; | 268 | static struct class *idetape_sysfs_class; |
269 | 269 | ||
270 | static void ide_tape_release(struct kref *); | 270 | static void ide_tape_release(struct device *); |
271 | 271 | ||
272 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) | 272 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) |
273 | { | 273 | { |
@@ -279,7 +279,7 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) | |||
279 | if (ide_device_get(tape->drive)) | 279 | if (ide_device_get(tape->drive)) |
280 | tape = NULL; | 280 | tape = NULL; |
281 | else | 281 | else |
282 | kref_get(&tape->kref); | 282 | get_device(&tape->dev); |
283 | } | 283 | } |
284 | mutex_unlock(&idetape_ref_mutex); | 284 | mutex_unlock(&idetape_ref_mutex); |
285 | return tape; | 285 | return tape; |
@@ -290,7 +290,7 @@ static void ide_tape_put(struct ide_tape_obj *tape) | |||
290 | ide_drive_t *drive = tape->drive; | 290 | ide_drive_t *drive = tape->drive; |
291 | 291 | ||
292 | mutex_lock(&idetape_ref_mutex); | 292 | mutex_lock(&idetape_ref_mutex); |
293 | kref_put(&tape->kref, ide_tape_release); | 293 | put_device(&tape->dev); |
294 | ide_device_put(drive); | 294 | ide_device_put(drive); |
295 | mutex_unlock(&idetape_ref_mutex); | 295 | mutex_unlock(&idetape_ref_mutex); |
296 | } | 296 | } |
@@ -308,7 +308,7 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) | |||
308 | mutex_lock(&idetape_ref_mutex); | 308 | mutex_lock(&idetape_ref_mutex); |
309 | tape = idetape_devs[i]; | 309 | tape = idetape_devs[i]; |
310 | if (tape) | 310 | if (tape) |
311 | kref_get(&tape->kref); | 311 | get_device(&tape->dev); |
312 | mutex_unlock(&idetape_ref_mutex); | 312 | mutex_unlock(&idetape_ref_mutex); |
313 | return tape; | 313 | return tape; |
314 | } | 314 | } |
@@ -2256,15 +2256,17 @@ static void ide_tape_remove(ide_drive_t *drive) | |||
2256 | idetape_tape_t *tape = drive->driver_data; | 2256 | idetape_tape_t *tape = drive->driver_data; |
2257 | 2257 | ||
2258 | ide_proc_unregister_driver(drive, tape->driver); | 2258 | ide_proc_unregister_driver(drive, tape->driver); |
2259 | 2259 | device_del(&tape->dev); | |
2260 | ide_unregister_region(tape->disk); | 2260 | ide_unregister_region(tape->disk); |
2261 | 2261 | ||
2262 | ide_tape_put(tape); | 2262 | mutex_lock(&idetape_ref_mutex); |
2263 | put_device(&tape->dev); | ||
2264 | mutex_unlock(&idetape_ref_mutex); | ||
2263 | } | 2265 | } |
2264 | 2266 | ||
2265 | static void ide_tape_release(struct kref *kref) | 2267 | static void ide_tape_release(struct device *dev) |
2266 | { | 2268 | { |
2267 | struct ide_tape_obj *tape = to_ide_drv(kref, ide_tape_obj); | 2269 | struct ide_tape_obj *tape = to_ide_drv(dev, ide_tape_obj); |
2268 | ide_drive_t *drive = tape->drive; | 2270 | ide_drive_t *drive = tape->drive; |
2269 | struct gendisk *g = tape->disk; | 2271 | struct gendisk *g = tape->disk; |
2270 | 2272 | ||
@@ -2407,7 +2409,12 @@ static int ide_tape_probe(ide_drive_t *drive) | |||
2407 | 2409 | ||
2408 | ide_init_disk(g, drive); | 2410 | ide_init_disk(g, drive); |
2409 | 2411 | ||
2410 | kref_init(&tape->kref); | 2412 | tape->dev.parent = &drive->gendev; |
2413 | tape->dev.release = ide_tape_release; | ||
2414 | dev_set_name(&tape->dev, dev_name(&drive->gendev)); | ||
2415 | |||
2416 | if (device_register(&tape->dev)) | ||
2417 | goto out_free_disk; | ||
2411 | 2418 | ||
2412 | tape->drive = drive; | 2419 | tape->drive = drive; |
2413 | tape->driver = &idetape_driver; | 2420 | tape->driver = &idetape_driver; |
@@ -2436,6 +2443,8 @@ static int ide_tape_probe(ide_drive_t *drive) | |||
2436 | 2443 | ||
2437 | return 0; | 2444 | return 0; |
2438 | 2445 | ||
2446 | out_free_disk: | ||
2447 | put_disk(g); | ||
2439 | out_free_tape: | 2448 | out_free_tape: |
2440 | kfree(tape); | 2449 | kfree(tape); |
2441 | failed: | 2450 | failed: |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 258805da15c3..0920e3b0c962 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -337,6 +337,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) | |||
337 | int a, b, i, j = 1; | 337 | int a, b, i, j = 1; |
338 | unsigned int *dev_param_mask = (unsigned int *)kp->arg; | 338 | unsigned int *dev_param_mask = (unsigned int *)kp->arg; |
339 | 339 | ||
340 | /* controller . device (0 or 1) [ : 1 (set) | 0 (clear) ] */ | ||
340 | if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 && | 341 | if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 && |
341 | sscanf(s, "%d.%d", &a, &b) != 2) | 342 | sscanf(s, "%d.%d", &a, &b) != 2) |
342 | return -EINVAL; | 343 | return -EINVAL; |
@@ -349,7 +350,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) | |||
349 | if (j) | 350 | if (j) |
350 | *dev_param_mask |= (1 << i); | 351 | *dev_param_mask |= (1 << i); |
351 | else | 352 | else |
352 | *dev_param_mask &= (1 << i); | 353 | *dev_param_mask &= ~(1 << i); |
353 | 354 | ||
354 | return 0; | 355 | return 0; |
355 | } | 356 | } |
@@ -392,6 +393,8 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp) | |||
392 | { | 393 | { |
393 | int a, b, c = 0, h = 0, s = 0, i, j = 1; | 394 | int a, b, c = 0, h = 0, s = 0, i, j = 1; |
394 | 395 | ||
396 | /* controller . device (0 or 1) : Cylinders , Heads , Sectors */ | ||
397 | /* controller . device (0 or 1) : 1 (use CHS) | 0 (ignore CHS) */ | ||
395 | if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 && | 398 | if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 && |
396 | sscanf(str, "%d.%d:%d", &a, &b, &j) != 3) | 399 | sscanf(str, "%d.%d:%d", &a, &b, &j) != 3) |
397 | return -EINVAL; | 400 | return -EINVAL; |
@@ -407,7 +410,7 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp) | |||
407 | if (j) | 410 | if (j) |
408 | ide_disks |= (1 << i); | 411 | ide_disks |= (1 << i); |
409 | else | 412 | else |
410 | ide_disks &= (1 << i); | 413 | ide_disks &= ~(1 << i); |
411 | 414 | ||
412 | ide_disks_chs[i].cyl = c; | 415 | ide_disks_chs[i].cyl = c; |
413 | ide_disks_chs[i].head = h; | 416 | ide_disks_chs[i].head = h; |
@@ -469,6 +472,8 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp) | |||
469 | { | 472 | { |
470 | int i, j = 1; | 473 | int i, j = 1; |
471 | 474 | ||
475 | /* controller (ignore) */ | ||
476 | /* controller : 1 (ignore) | 0 (use) */ | ||
472 | if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1) | 477 | if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1) |
473 | return -EINVAL; | 478 | return -EINVAL; |
474 | 479 | ||
@@ -478,7 +483,7 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp) | |||
478 | if (j) | 483 | if (j) |
479 | ide_ignore_cable |= (1 << i); | 484 | ide_ignore_cable |= (1 << i); |
480 | else | 485 | else |
481 | ide_ignore_cable &= (1 << i); | 486 | ide_ignore_cable &= ~(1 << i); |
482 | 487 | ||
483 | return 0; | 488 | return 0; |
484 | } | 489 | } |
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index e1c4f5437396..13b8153112ed 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c | |||
@@ -5,9 +5,8 @@ | |||
5 | * May be copied or modified under the terms of the GNU General Public License | 5 | * May be copied or modified under the terms of the GNU General Public License |
6 | * Based in part on the ITE vendor provided SCSI driver. | 6 | * Based in part on the ITE vendor provided SCSI driver. |
7 | * | 7 | * |
8 | * Documentation available from | 8 | * Documentation: |
9 | * http://www.ite.com.tw/pc/IT8212F_V04.pdf | 9 | * Datasheet is freely available, some other documents under NDA. |
10 | * Some other documents are NDA. | ||
11 | * | 10 | * |
12 | * The ITE8212 isn't exactly a standard IDE controller. It has two | 11 | * The ITE8212 isn't exactly a standard IDE controller. It has two |
13 | * modes. In pass through mode then it is an IDE controller. In its smart | 12 | * modes. In pass through mode then it is an IDE controller. In its smart |
diff --git a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h index 2727bcd24194..467373cab8e5 100644 --- a/drivers/ieee1394/dma.h +++ b/drivers/ieee1394/dma.h | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <asm/types.h> | 13 | #include <asm/types.h> |
14 | 14 | ||
15 | struct file; | ||
15 | struct pci_dev; | 16 | struct pci_dev; |
16 | struct scatterlist; | 17 | struct scatterlist; |
17 | struct vm_area_struct; | 18 | struct vm_area_struct; |
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 2beb8d94f7bd..872338003721 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c | |||
@@ -1275,7 +1275,7 @@ static void __exit ieee1394_cleanup(void) | |||
1275 | unregister_chrdev_region(IEEE1394_CORE_DEV, 256); | 1275 | unregister_chrdev_region(IEEE1394_CORE_DEV, 256); |
1276 | } | 1276 | } |
1277 | 1277 | ||
1278 | module_init(ieee1394_init); | 1278 | fs_initcall(ieee1394_init); |
1279 | module_exit(ieee1394_cleanup); | 1279 | module_exit(ieee1394_cleanup); |
1280 | 1280 | ||
1281 | /* Exported symbols */ | 1281 | /* Exported symbols */ |
@@ -1314,6 +1314,7 @@ EXPORT_SYMBOL(hpsb_make_lock64packet); | |||
1314 | EXPORT_SYMBOL(hpsb_make_phypacket); | 1314 | EXPORT_SYMBOL(hpsb_make_phypacket); |
1315 | EXPORT_SYMBOL(hpsb_read); | 1315 | EXPORT_SYMBOL(hpsb_read); |
1316 | EXPORT_SYMBOL(hpsb_write); | 1316 | EXPORT_SYMBOL(hpsb_write); |
1317 | EXPORT_SYMBOL(hpsb_lock); | ||
1317 | EXPORT_SYMBOL(hpsb_packet_success); | 1318 | EXPORT_SYMBOL(hpsb_packet_success); |
1318 | 1319 | ||
1319 | /** highlevel.c **/ | 1320 | /** highlevel.c **/ |
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 10c3d9f8c038..675b3135d5f1 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c | |||
@@ -501,8 +501,6 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation, | |||
501 | if (length == 0) | 501 | if (length == 0) |
502 | return -EINVAL; | 502 | return -EINVAL; |
503 | 503 | ||
504 | BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet | ||
505 | |||
506 | packet = hpsb_make_readpacket(host, node, addr, length); | 504 | packet = hpsb_make_readpacket(host, node, addr, length); |
507 | 505 | ||
508 | if (!packet) { | 506 | if (!packet) { |
@@ -550,8 +548,6 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, | |||
550 | if (length == 0) | 548 | if (length == 0) |
551 | return -EINVAL; | 549 | return -EINVAL; |
552 | 550 | ||
553 | BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet | ||
554 | |||
555 | packet = hpsb_make_writepacket(host, node, addr, buffer, length); | 551 | packet = hpsb_make_writepacket(host, node, addr, buffer, length); |
556 | 552 | ||
557 | if (!packet) | 553 | if (!packet) |
@@ -570,3 +566,30 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, | |||
570 | 566 | ||
571 | return retval; | 567 | return retval; |
572 | } | 568 | } |
569 | |||
570 | int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, | ||
571 | u64 addr, int extcode, quadlet_t *data, quadlet_t arg) | ||
572 | { | ||
573 | struct hpsb_packet *packet; | ||
574 | int retval = 0; | ||
575 | |||
576 | packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); | ||
577 | if (!packet) | ||
578 | return -ENOMEM; | ||
579 | |||
580 | packet->generation = generation; | ||
581 | retval = hpsb_send_packet_and_wait(packet); | ||
582 | if (retval < 0) | ||
583 | goto hpsb_lock_fail; | ||
584 | |||
585 | retval = hpsb_packet_success(packet); | ||
586 | |||
587 | if (retval == 0) | ||
588 | *data = packet->data[0]; | ||
589 | |||
590 | hpsb_lock_fail: | ||
591 | hpsb_free_tlabel(packet); | ||
592 | hpsb_free_packet(packet); | ||
593 | |||
594 | return retval; | ||
595 | } | ||
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h index d2d5bc3546d7..20b693be14b2 100644 --- a/drivers/ieee1394/ieee1394_transactions.h +++ b/drivers/ieee1394/ieee1394_transactions.h | |||
@@ -30,6 +30,8 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation, | |||
30 | u64 addr, quadlet_t *buffer, size_t length); | 30 | u64 addr, quadlet_t *buffer, size_t length); |
31 | int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, | 31 | int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, |
32 | u64 addr, quadlet_t *buffer, size_t length); | 32 | u64 addr, quadlet_t *buffer, size_t length); |
33 | int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, | ||
34 | u64 addr, int extcode, quadlet_t *data, quadlet_t arg); | ||
33 | 35 | ||
34 | #ifdef HPSB_DEBUG_TLABELS | 36 | #ifdef HPSB_DEBUG_TLABELS |
35 | extern spinlock_t hpsb_tlabel_lock; | 37 | extern spinlock_t hpsb_tlabel_lock; |
diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h index b5de5f21ef78..c2089c093aa7 100644 --- a/drivers/ieee1394/iso.h +++ b/drivers/ieee1394/iso.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #define IEEE1394_ISO_H | 13 | #define IEEE1394_ISO_H |
14 | 14 | ||
15 | #include <linux/spinlock_types.h> | 15 | #include <linux/spinlock_types.h> |
16 | #include <linux/wait.h> | ||
16 | #include <asm/atomic.h> | 17 | #include <asm/atomic.h> |
17 | #include <asm/types.h> | 18 | #include <asm/types.h> |
18 | 19 | ||
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 906c5a98d814..53aada5bbe1e 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -971,6 +971,9 @@ static struct unit_directory *nodemgr_process_unit_directory | |||
971 | ud->ud_kv = ud_kv; | 971 | ud->ud_kv = ud_kv; |
972 | ud->id = (*id)++; | 972 | ud->id = (*id)++; |
973 | 973 | ||
974 | /* inherit vendor_id from root directory if none exists in unit dir */ | ||
975 | ud->vendor_id = ne->vendor_id; | ||
976 | |||
974 | csr1212_for_each_dir_entry(ne->csr, kv, ud_kv, dentry) { | 977 | csr1212_for_each_dir_entry(ne->csr, kv, ud_kv, dentry) { |
975 | switch (kv->key.id) { | 978 | switch (kv->key.id) { |
976 | case CSR1212_KV_ID_VENDOR: | 979 | case CSR1212_KV_ID_VENDOR: |
@@ -1265,7 +1268,8 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, | |||
1265 | csr1212_destroy_csr(csr); | 1268 | csr1212_destroy_csr(csr); |
1266 | } | 1269 | } |
1267 | 1270 | ||
1268 | /* Mark the node current */ | 1271 | /* Finally, mark the node current */ |
1272 | smp_wmb(); | ||
1269 | ne->generation = generation; | 1273 | ne->generation = generation; |
1270 | 1274 | ||
1271 | if (ne->in_limbo) { | 1275 | if (ne->in_limbo) { |
@@ -1798,7 +1802,7 @@ void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet) | |||
1798 | { | 1802 | { |
1799 | packet->host = ne->host; | 1803 | packet->host = ne->host; |
1800 | packet->generation = ne->generation; | 1804 | packet->generation = ne->generation; |
1801 | barrier(); | 1805 | smp_rmb(); |
1802 | packet->node_id = ne->nodeid; | 1806 | packet->node_id = ne->nodeid; |
1803 | } | 1807 | } |
1804 | 1808 | ||
@@ -1807,7 +1811,7 @@ int hpsb_node_write(struct node_entry *ne, u64 addr, | |||
1807 | { | 1811 | { |
1808 | unsigned int generation = ne->generation; | 1812 | unsigned int generation = ne->generation; |
1809 | 1813 | ||
1810 | barrier(); | 1814 | smp_rmb(); |
1811 | return hpsb_write(ne->host, ne->nodeid, generation, | 1815 | return hpsb_write(ne->host, ne->nodeid, generation, |
1812 | addr, buffer, length); | 1816 | addr, buffer, length); |
1813 | } | 1817 | } |
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h index 15ea09733e84..ee5acdbd114a 100644 --- a/drivers/ieee1394/nodemgr.h +++ b/drivers/ieee1394/nodemgr.h | |||
@@ -21,9 +21,11 @@ | |||
21 | #define _IEEE1394_NODEMGR_H | 21 | #define _IEEE1394_NODEMGR_H |
22 | 22 | ||
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <asm/system.h> | ||
24 | #include <asm/types.h> | 25 | #include <asm/types.h> |
25 | 26 | ||
26 | #include "ieee1394_core.h" | 27 | #include "ieee1394_core.h" |
28 | #include "ieee1394_transactions.h" | ||
27 | #include "ieee1394_types.h" | 29 | #include "ieee1394_types.h" |
28 | 30 | ||
29 | struct csr1212_csr; | 31 | struct csr1212_csr; |
@@ -154,6 +156,22 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne) | |||
154 | void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet); | 156 | void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet); |
155 | int hpsb_node_write(struct node_entry *ne, u64 addr, | 157 | int hpsb_node_write(struct node_entry *ne, u64 addr, |
156 | quadlet_t *buffer, size_t length); | 158 | quadlet_t *buffer, size_t length); |
159 | static inline int hpsb_node_read(struct node_entry *ne, u64 addr, | ||
160 | quadlet_t *buffer, size_t length) | ||
161 | { | ||
162 | unsigned int g = ne->generation; | ||
163 | |||
164 | smp_rmb(); | ||
165 | return hpsb_read(ne->host, ne->nodeid, g, addr, buffer, length); | ||
166 | } | ||
167 | static inline int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode, | ||
168 | quadlet_t *buffer, quadlet_t arg) | ||
169 | { | ||
170 | unsigned int g = ne->generation; | ||
171 | |||
172 | smp_rmb(); | ||
173 | return hpsb_lock(ne->host, ne->nodeid, g, addr, extcode, buffer, arg); | ||
174 | } | ||
157 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)); | 175 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)); |
158 | 176 | ||
159 | int init_ieee1394_nodemgr(void); | 177 | int init_ieee1394_nodemgr(void); |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 01e3cffd03b8..e2466425d9ca 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1237,8 +1237,9 @@ static void end_sync_write(struct bio *bio, int error) | |||
1237 | update_head_pos(mirror, r1_bio); | 1237 | update_head_pos(mirror, r1_bio); |
1238 | 1238 | ||
1239 | if (atomic_dec_and_test(&r1_bio->remaining)) { | 1239 | if (atomic_dec_and_test(&r1_bio->remaining)) { |
1240 | md_done_sync(mddev, r1_bio->sectors, uptodate); | 1240 | sector_t s = r1_bio->sectors; |
1241 | put_buf(r1_bio); | 1241 | put_buf(r1_bio); |
1242 | md_done_sync(mddev, s, uptodate); | ||
1242 | } | 1243 | } |
1243 | } | 1244 | } |
1244 | 1245 | ||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 6736d6dff981..7301631abe04 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1236,6 +1236,7 @@ static void end_sync_read(struct bio *bio, int error) | |||
1236 | /* for reconstruct, we always reschedule after a read. | 1236 | /* for reconstruct, we always reschedule after a read. |
1237 | * for resync, only after all reads | 1237 | * for resync, only after all reads |
1238 | */ | 1238 | */ |
1239 | rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); | ||
1239 | if (test_bit(R10BIO_IsRecover, &r10_bio->state) || | 1240 | if (test_bit(R10BIO_IsRecover, &r10_bio->state) || |
1240 | atomic_dec_and_test(&r10_bio->remaining)) { | 1241 | atomic_dec_and_test(&r10_bio->remaining)) { |
1241 | /* we have read all the blocks, | 1242 | /* we have read all the blocks, |
@@ -1243,7 +1244,6 @@ static void end_sync_read(struct bio *bio, int error) | |||
1243 | */ | 1244 | */ |
1244 | reschedule_retry(r10_bio); | 1245 | reschedule_retry(r10_bio); |
1245 | } | 1246 | } |
1246 | rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); | ||
1247 | } | 1247 | } |
1248 | 1248 | ||
1249 | static void end_sync_write(struct bio *bio, int error) | 1249 | static void end_sync_write(struct bio *bio, int error) |
@@ -1264,11 +1264,13 @@ static void end_sync_write(struct bio *bio, int error) | |||
1264 | 1264 | ||
1265 | update_head_pos(i, r10_bio); | 1265 | update_head_pos(i, r10_bio); |
1266 | 1266 | ||
1267 | rdev_dec_pending(conf->mirrors[d].rdev, mddev); | ||
1267 | while (atomic_dec_and_test(&r10_bio->remaining)) { | 1268 | while (atomic_dec_and_test(&r10_bio->remaining)) { |
1268 | if (r10_bio->master_bio == NULL) { | 1269 | if (r10_bio->master_bio == NULL) { |
1269 | /* the primary of several recovery bios */ | 1270 | /* the primary of several recovery bios */ |
1270 | md_done_sync(mddev, r10_bio->sectors, 1); | 1271 | sector_t s = r10_bio->sectors; |
1271 | put_buf(r10_bio); | 1272 | put_buf(r10_bio); |
1273 | md_done_sync(mddev, s, 1); | ||
1272 | break; | 1274 | break; |
1273 | } else { | 1275 | } else { |
1274 | r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio; | 1276 | r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio; |
@@ -1276,7 +1278,6 @@ static void end_sync_write(struct bio *bio, int error) | |||
1276 | r10_bio = r10_bio2; | 1278 | r10_bio = r10_bio2; |
1277 | } | 1279 | } |
1278 | } | 1280 | } |
1279 | rdev_dec_pending(conf->mirrors[d].rdev, mddev); | ||
1280 | } | 1281 | } |
1281 | 1282 | ||
1282 | /* | 1283 | /* |
@@ -1749,8 +1750,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1749 | if (!go_faster && conf->nr_waiting) | 1750 | if (!go_faster && conf->nr_waiting) |
1750 | msleep_interruptible(1000); | 1751 | msleep_interruptible(1000); |
1751 | 1752 | ||
1752 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); | ||
1753 | |||
1754 | /* Again, very different code for resync and recovery. | 1753 | /* Again, very different code for resync and recovery. |
1755 | * Both must result in an r10bio with a list of bios that | 1754 | * Both must result in an r10bio with a list of bios that |
1756 | * have bi_end_io, bi_sector, bi_bdev set, | 1755 | * have bi_end_io, bi_sector, bi_bdev set, |
@@ -1886,6 +1885,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1886 | /* resync. Schedule a read for every block at this virt offset */ | 1885 | /* resync. Schedule a read for every block at this virt offset */ |
1887 | int count = 0; | 1886 | int count = 0; |
1888 | 1887 | ||
1888 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); | ||
1889 | |||
1889 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, | 1890 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, |
1890 | &sync_blocks, mddev->degraded) && | 1891 | &sync_blocks, mddev->degraded) && |
1891 | !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { | 1892 | !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { |
@@ -2010,13 +2011,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
2010 | /* There is nowhere to write, so all non-sync | 2011 | /* There is nowhere to write, so all non-sync |
2011 | * drives must be failed, so try the next chunk... | 2012 | * drives must be failed, so try the next chunk... |
2012 | */ | 2013 | */ |
2013 | { | 2014 | if (sector_nr + max_sync < max_sector) |
2014 | sector_t sec = max_sector - sector_nr; | 2015 | max_sector = sector_nr + max_sync; |
2015 | sectors_skipped += sec; | 2016 | |
2017 | sectors_skipped += (max_sector - sector_nr); | ||
2016 | chunks_skipped ++; | 2018 | chunks_skipped ++; |
2017 | sector_nr = max_sector; | 2019 | sector_nr = max_sector; |
2018 | goto skipped; | 2020 | goto skipped; |
2019 | } | ||
2020 | } | 2021 | } |
2021 | 2022 | ||
2022 | static int run(mddev_t *mddev) | 2023 | static int run(mddev_t *mddev) |
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index 40ebde53b3ce..b0198691892a 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig | |||
@@ -51,6 +51,10 @@ comment "Supported SDMC DM1105 Adapters" | |||
51 | depends on DVB_CORE && PCI && I2C | 51 | depends on DVB_CORE && PCI && I2C |
52 | source "drivers/media/dvb/dm1105/Kconfig" | 52 | source "drivers/media/dvb/dm1105/Kconfig" |
53 | 53 | ||
54 | comment "Supported FireWire (IEEE 1394) Adapters" | ||
55 | depends on DVB_CORE && IEEE1394 | ||
56 | source "drivers/media/dvb/firewire/Kconfig" | ||
57 | |||
54 | comment "Supported DVB Frontends" | 58 | comment "Supported DVB Frontends" |
55 | depends on DVB_CORE | 59 | depends on DVB_CORE |
56 | source "drivers/media/dvb/frontends/Kconfig" | 60 | source "drivers/media/dvb/frontends/Kconfig" |
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index f91e9eb15e52..6092a5bb5a7d 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile | |||
@@ -3,3 +3,5 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ | 5 | obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ |
6 | |||
7 | obj-$(CONFIG_DVB_FIREDTV) += firewire/ | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c index b386cc66c6b3..451974ba32f3 100644 --- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c | |||
@@ -192,6 +192,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d | |||
192 | 192 | ||
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
195 | EXPORT_SYMBOL(flexcop_pid_feed_control); | ||
195 | 196 | ||
196 | void flexcop_hw_filter_init(struct flexcop_device *fc) | 197 | void flexcop_hw_filter_init(struct flexcop_device *fc) |
197 | { | 198 | { |
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 5b30dfc7846b..76e37fd96bb6 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
@@ -13,9 +13,9 @@ static int enable_pid_filtering = 1; | |||
13 | module_param(enable_pid_filtering, int, 0444); | 13 | module_param(enable_pid_filtering, int, 0444); |
14 | MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); | 14 | MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); |
15 | 15 | ||
16 | static int irq_chk_intv; | 16 | static int irq_chk_intv = 100; |
17 | module_param(irq_chk_intv, int, 0644); | 17 | module_param(irq_chk_intv, int, 0644); |
18 | MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging)."); | 18 | MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog."); |
19 | 19 | ||
20 | #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG | 20 | #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG |
21 | #define dprintk(level,args...) \ | 21 | #define dprintk(level,args...) \ |
@@ -34,7 +34,9 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently jus | |||
34 | 34 | ||
35 | static int debug; | 35 | static int debug; |
36 | module_param(debug, int, 0644); | 36 | module_param(debug, int, 0644); |
37 | MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS); | 37 | MODULE_PARM_DESC(debug, |
38 | "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))." | ||
39 | DEBSTATUS); | ||
38 | 40 | ||
39 | #define DRIVER_VERSION "0.1" | 41 | #define DRIVER_VERSION "0.1" |
40 | #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" | 42 | #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" |
@@ -58,6 +60,8 @@ struct flexcop_pci { | |||
58 | int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ | 60 | int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ |
59 | u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ | 61 | u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ |
60 | int count; | 62 | int count; |
63 | int count_prev; | ||
64 | int stream_problem; | ||
61 | 65 | ||
62 | spinlock_t irq_lock; | 66 | spinlock_t irq_lock; |
63 | 67 | ||
@@ -103,18 +107,32 @@ static void flexcop_pci_irq_check_work(struct work_struct *work) | |||
103 | container_of(work, struct flexcop_pci, irq_check_work.work); | 107 | container_of(work, struct flexcop_pci, irq_check_work.work); |
104 | struct flexcop_device *fc = fc_pci->fc_dev; | 108 | struct flexcop_device *fc = fc_pci->fc_dev; |
105 | 109 | ||
106 | flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); | 110 | if (fc->feedcount) { |
107 | 111 | ||
108 | flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4); | 112 | if (fc_pci->count == fc_pci->count_prev) { |
109 | 113 | deb_chk("no IRQ since the last check\n"); | |
110 | if (v.sram_dest_reg_714.net_ovflow_error) | 114 | if (fc_pci->stream_problem++ == 3) { |
111 | deb_chk("sram net_ovflow_error\n"); | 115 | struct dvb_demux_feed *feed; |
112 | if (v.sram_dest_reg_714.media_ovflow_error) | 116 | |
113 | deb_chk("sram media_ovflow_error\n"); | 117 | spin_lock_irq(&fc->demux.lock); |
114 | if (v.sram_dest_reg_714.cai_ovflow_error) | 118 | list_for_each_entry(feed, &fc->demux.feed_list, |
115 | deb_chk("sram cai_ovflow_error\n"); | 119 | list_head) { |
116 | if (v.sram_dest_reg_714.cai_ovflow_error) | 120 | flexcop_pid_feed_control(fc, feed, 0); |
117 | deb_chk("sram cai_ovflow_error\n"); | 121 | } |
122 | |||
123 | list_for_each_entry(feed, &fc->demux.feed_list, | ||
124 | list_head) { | ||
125 | flexcop_pid_feed_control(fc, feed, 1); | ||
126 | } | ||
127 | spin_unlock_irq(&fc->demux.lock); | ||
128 | |||
129 | fc_pci->stream_problem = 0; | ||
130 | } | ||
131 | } else { | ||
132 | fc_pci->stream_problem = 0; | ||
133 | fc_pci->count_prev = fc_pci->count; | ||
134 | } | ||
135 | } | ||
118 | 136 | ||
119 | schedule_delayed_work(&fc_pci->irq_check_work, | 137 | schedule_delayed_work(&fc_pci->irq_check_work, |
120 | msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); | 138 | msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); |
@@ -216,16 +234,12 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff) | |||
216 | flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); | 234 | flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); |
217 | deb_irq("IRQ enabled\n"); | 235 | deb_irq("IRQ enabled\n"); |
218 | 236 | ||
237 | fc_pci->count_prev = fc_pci->count; | ||
238 | |||
219 | // fc_pci->active_dma1_addr = 0; | 239 | // fc_pci->active_dma1_addr = 0; |
220 | // flexcop_dma_control_size_irq(fc,FC_DMA_1,1); | 240 | // flexcop_dma_control_size_irq(fc,FC_DMA_1,1); |
221 | 241 | ||
222 | if (irq_chk_intv > 0) | ||
223 | schedule_delayed_work(&fc_pci->irq_check_work, | ||
224 | msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); | ||
225 | } else { | 242 | } else { |
226 | if (irq_chk_intv > 0) | ||
227 | cancel_delayed_work(&fc_pci->irq_check_work); | ||
228 | |||
229 | flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); | 243 | flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); |
230 | deb_irq("IRQ disabled\n"); | 244 | deb_irq("IRQ disabled\n"); |
231 | 245 | ||
@@ -299,8 +313,6 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) | |||
299 | IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) | 313 | IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) |
300 | goto err_pci_iounmap; | 314 | goto err_pci_iounmap; |
301 | 315 | ||
302 | |||
303 | |||
304 | fc_pci->init_state |= FC_PCI_INIT; | 316 | fc_pci->init_state |= FC_PCI_INIT; |
305 | return ret; | 317 | return ret; |
306 | 318 | ||
@@ -375,6 +387,10 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
375 | 387 | ||
376 | INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); | 388 | INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); |
377 | 389 | ||
390 | if (irq_chk_intv > 0) | ||
391 | schedule_delayed_work(&fc_pci->irq_check_work, | ||
392 | msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); | ||
393 | |||
378 | return ret; | 394 | return ret; |
379 | 395 | ||
380 | err_fc_exit: | 396 | err_fc_exit: |
@@ -393,6 +409,9 @@ static void flexcop_pci_remove(struct pci_dev *pdev) | |||
393 | { | 409 | { |
394 | struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); | 410 | struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); |
395 | 411 | ||
412 | if (irq_chk_intv > 0) | ||
413 | cancel_delayed_work(&fc_pci->irq_check_work); | ||
414 | |||
396 | flexcop_pci_dma_exit(fc_pci); | 415 | flexcop_pci_dma_exit(fc_pci); |
397 | flexcop_device_exit(fc_pci->fc_dev); | 416 | flexcop_device_exit(fc_pci->fc_dev); |
398 | flexcop_pci_exit(fc_pci); | 417 | flexcop_pci_exit(fc_pci); |
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c index 676413a915b4..91068952b502 100644 --- a/drivers/media/dvb/b2c2/flexcop.c +++ b/drivers/media/dvb/b2c2/flexcop.c | |||
@@ -212,8 +212,7 @@ void flexcop_reset_block_300(struct flexcop_device *fc) | |||
212 | v210.sw_reset_210.Block_reset_enable = 0xb2; | 212 | v210.sw_reset_210.Block_reset_enable = 0xb2; |
213 | 213 | ||
214 | fc->write_ibi_reg(fc,sw_reset_210,v210); | 214 | fc->write_ibi_reg(fc,sw_reset_210,v210); |
215 | msleep(1); | 215 | udelay(1000); |
216 | |||
217 | fc->write_ibi_reg(fc,ctrl_208,v208_save); | 216 | fc->write_ibi_reg(fc,ctrl_208,v208_save); |
218 | } | 217 | } |
219 | 218 | ||
diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig new file mode 100644 index 000000000000..69028253e984 --- /dev/null +++ b/drivers/media/dvb/firewire/Kconfig | |||
@@ -0,0 +1,22 @@ | |||
1 | config DVB_FIREDTV | ||
2 | tristate "FireDTV and FloppyDTV" | ||
3 | depends on DVB_CORE && IEEE1394 | ||
4 | help | ||
5 | Support for DVB receivers from Digital Everywhere | ||
6 | which are connected via IEEE 1394 (FireWire). | ||
7 | |||
8 | These devices don't have an MPEG decoder built in, | ||
9 | so you need an external software decoder to watch TV. | ||
10 | |||
11 | To compile this driver as a module, say M here: | ||
12 | the module will be called firedtv. | ||
13 | |||
14 | if DVB_FIREDTV | ||
15 | |||
16 | config DVB_FIREDTV_IEEE1394 | ||
17 | def_bool IEEE1394 | ||
18 | |||
19 | config DVB_FIREDTV_INPUT | ||
20 | def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m) | ||
21 | |||
22 | endif # DVB_FIREDTV | ||
diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile new file mode 100644 index 000000000000..2034695ba194 --- /dev/null +++ b/drivers/media/dvb/firewire/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | obj-$(CONFIG_DVB_FIREDTV) += firedtv.o | ||
2 | |||
3 | firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o | ||
4 | firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o | ||
5 | firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o | ||
6 | |||
7 | ccflags-y += -Idrivers/media/dvb/dvb-core | ||
8 | ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394 | ||
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c new file mode 100644 index 000000000000..4e207658c5d9 --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-1394.c | |||
@@ -0,0 +1,285 @@ | |||
1 | /* | ||
2 | * FireDTV driver (formerly known as FireSAT) | ||
3 | * | ||
4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | ||
5 | * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com> | ||
6 | * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of | ||
11 | * the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/device.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/types.h> | ||
20 | |||
21 | #include <dma.h> | ||
22 | #include <csr1212.h> | ||
23 | #include <highlevel.h> | ||
24 | #include <hosts.h> | ||
25 | #include <ieee1394.h> | ||
26 | #include <iso.h> | ||
27 | #include <nodemgr.h> | ||
28 | |||
29 | #include "firedtv.h" | ||
30 | |||
31 | static LIST_HEAD(node_list); | ||
32 | static DEFINE_SPINLOCK(node_list_lock); | ||
33 | |||
34 | #define FIREWIRE_HEADER_SIZE 4 | ||
35 | #define CIP_HEADER_SIZE 8 | ||
36 | |||
37 | static void rawiso_activity_cb(struct hpsb_iso *iso) | ||
38 | { | ||
39 | struct firedtv *f, *fdtv = NULL; | ||
40 | unsigned int i, num, packet; | ||
41 | unsigned char *buf; | ||
42 | unsigned long flags; | ||
43 | int count; | ||
44 | |||
45 | spin_lock_irqsave(&node_list_lock, flags); | ||
46 | list_for_each_entry(f, &node_list, list) | ||
47 | if (f->backend_data == iso) { | ||
48 | fdtv = f; | ||
49 | break; | ||
50 | } | ||
51 | spin_unlock_irqrestore(&node_list_lock, flags); | ||
52 | |||
53 | packet = iso->first_packet; | ||
54 | num = hpsb_iso_n_ready(iso); | ||
55 | |||
56 | if (!fdtv) { | ||
57 | dev_err(fdtv->device, "received at unknown iso channel\n"); | ||
58 | goto out; | ||
59 | } | ||
60 | |||
61 | for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) { | ||
62 | buf = dma_region_i(&iso->data_buf, unsigned char, | ||
63 | iso->infos[packet].offset + CIP_HEADER_SIZE); | ||
64 | count = (iso->infos[packet].len - CIP_HEADER_SIZE) / | ||
65 | (188 + FIREWIRE_HEADER_SIZE); | ||
66 | |||
67 | /* ignore empty packet */ | ||
68 | if (iso->infos[packet].len <= CIP_HEADER_SIZE) | ||
69 | continue; | ||
70 | |||
71 | while (count--) { | ||
72 | if (buf[FIREWIRE_HEADER_SIZE] == 0x47) | ||
73 | dvb_dmx_swfilter_packets(&fdtv->demux, | ||
74 | &buf[FIREWIRE_HEADER_SIZE], 1); | ||
75 | else | ||
76 | dev_err(fdtv->device, | ||
77 | "skipping invalid packet\n"); | ||
78 | buf += 188 + FIREWIRE_HEADER_SIZE; | ||
79 | } | ||
80 | } | ||
81 | out: | ||
82 | hpsb_iso_recv_release_packets(iso, num); | ||
83 | } | ||
84 | |||
85 | static inline struct node_entry *node_of(struct firedtv *fdtv) | ||
86 | { | ||
87 | return container_of(fdtv->device, struct unit_directory, device)->ne; | ||
88 | } | ||
89 | |||
90 | static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg) | ||
91 | { | ||
92 | return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data, | ||
93 | (__force quadlet_t)arg); | ||
94 | } | ||
95 | |||
96 | static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) | ||
97 | { | ||
98 | return hpsb_node_read(node_of(fdtv), addr, data, len); | ||
99 | } | ||
100 | |||
101 | static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) | ||
102 | { | ||
103 | return hpsb_node_write(node_of(fdtv), addr, data, len); | ||
104 | } | ||
105 | |||
106 | #define FDTV_ISO_BUFFER_PACKETS 256 | ||
107 | #define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200) | ||
108 | |||
109 | static int start_iso(struct firedtv *fdtv) | ||
110 | { | ||
111 | struct hpsb_iso *iso_handle; | ||
112 | int ret; | ||
113 | |||
114 | iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host, | ||
115 | FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS, | ||
116 | fdtv->isochannel, HPSB_ISO_DMA_DEFAULT, | ||
117 | -1, /* stat.config.irq_interval */ | ||
118 | rawiso_activity_cb); | ||
119 | if (iso_handle == NULL) { | ||
120 | dev_err(fdtv->device, "cannot initialize iso receive\n"); | ||
121 | return -ENOMEM; | ||
122 | } | ||
123 | fdtv->backend_data = iso_handle; | ||
124 | |||
125 | ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0); | ||
126 | if (ret != 0) { | ||
127 | dev_err(fdtv->device, "cannot start iso receive\n"); | ||
128 | hpsb_iso_shutdown(iso_handle); | ||
129 | fdtv->backend_data = NULL; | ||
130 | } | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static void stop_iso(struct firedtv *fdtv) | ||
135 | { | ||
136 | struct hpsb_iso *iso_handle = fdtv->backend_data; | ||
137 | |||
138 | if (iso_handle != NULL) { | ||
139 | hpsb_iso_stop(iso_handle); | ||
140 | hpsb_iso_shutdown(iso_handle); | ||
141 | } | ||
142 | fdtv->backend_data = NULL; | ||
143 | } | ||
144 | |||
145 | static const struct firedtv_backend fdtv_1394_backend = { | ||
146 | .lock = node_lock, | ||
147 | .read = node_read, | ||
148 | .write = node_write, | ||
149 | .start_iso = start_iso, | ||
150 | .stop_iso = stop_iso, | ||
151 | }; | ||
152 | |||
153 | static void fcp_request(struct hpsb_host *host, int nodeid, int direction, | ||
154 | int cts, u8 *data, size_t length) | ||
155 | { | ||
156 | struct firedtv *f, *fdtv = NULL; | ||
157 | unsigned long flags; | ||
158 | int su; | ||
159 | |||
160 | if (length == 0 || (data[0] & 0xf0) != 0) | ||
161 | return; | ||
162 | |||
163 | su = data[1] & 0x7; | ||
164 | |||
165 | spin_lock_irqsave(&node_list_lock, flags); | ||
166 | list_for_each_entry(f, &node_list, list) | ||
167 | if (node_of(f)->host == host && | ||
168 | node_of(f)->nodeid == nodeid && | ||
169 | (f->subunit == su || (f->subunit == 0 && su == 0x7))) { | ||
170 | fdtv = f; | ||
171 | break; | ||
172 | } | ||
173 | spin_unlock_irqrestore(&node_list_lock, flags); | ||
174 | |||
175 | if (fdtv) | ||
176 | avc_recv(fdtv, data, length); | ||
177 | } | ||
178 | |||
179 | static int node_probe(struct device *dev) | ||
180 | { | ||
181 | struct unit_directory *ud = | ||
182 | container_of(dev, struct unit_directory, device); | ||
183 | struct firedtv *fdtv; | ||
184 | int kv_len, err; | ||
185 | void *kv_str; | ||
186 | |||
187 | kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); | ||
188 | kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); | ||
189 | |||
190 | fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); | ||
191 | if (!fdtv) | ||
192 | return -ENOMEM; | ||
193 | |||
194 | /* | ||
195 | * Work around a bug in udev's path_id script: Use the fw-host's dev | ||
196 | * instead of the unit directory's dev as parent of the input device. | ||
197 | */ | ||
198 | err = fdtv_register_rc(fdtv, dev->parent->parent); | ||
199 | if (err) | ||
200 | goto fail_free; | ||
201 | |||
202 | spin_lock_irq(&node_list_lock); | ||
203 | list_add_tail(&fdtv->list, &node_list); | ||
204 | spin_unlock_irq(&node_list_lock); | ||
205 | |||
206 | err = avc_identify_subunit(fdtv); | ||
207 | if (err) | ||
208 | goto fail; | ||
209 | |||
210 | err = fdtv_dvb_register(fdtv); | ||
211 | if (err) | ||
212 | goto fail; | ||
213 | |||
214 | avc_register_remote_control(fdtv); | ||
215 | return 0; | ||
216 | fail: | ||
217 | spin_lock_irq(&node_list_lock); | ||
218 | list_del(&fdtv->list); | ||
219 | spin_unlock_irq(&node_list_lock); | ||
220 | fdtv_unregister_rc(fdtv); | ||
221 | fail_free: | ||
222 | kfree(fdtv); | ||
223 | return err; | ||
224 | } | ||
225 | |||
226 | static int node_remove(struct device *dev) | ||
227 | { | ||
228 | struct firedtv *fdtv = dev->driver_data; | ||
229 | |||
230 | fdtv_dvb_unregister(fdtv); | ||
231 | |||
232 | spin_lock_irq(&node_list_lock); | ||
233 | list_del(&fdtv->list); | ||
234 | spin_unlock_irq(&node_list_lock); | ||
235 | |||
236 | cancel_work_sync(&fdtv->remote_ctrl_work); | ||
237 | fdtv_unregister_rc(fdtv); | ||
238 | |||
239 | kfree(fdtv); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static int node_update(struct unit_directory *ud) | ||
244 | { | ||
245 | struct firedtv *fdtv = ud->device.driver_data; | ||
246 | |||
247 | if (fdtv->isochannel >= 0) | ||
248 | cmp_establish_pp_connection(fdtv, fdtv->subunit, | ||
249 | fdtv->isochannel); | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static struct hpsb_protocol_driver fdtv_driver = { | ||
254 | .name = "firedtv", | ||
255 | .update = node_update, | ||
256 | .driver = { | ||
257 | .probe = node_probe, | ||
258 | .remove = node_remove, | ||
259 | }, | ||
260 | }; | ||
261 | |||
262 | static struct hpsb_highlevel fdtv_highlevel = { | ||
263 | .name = "firedtv", | ||
264 | .fcp_request = fcp_request, | ||
265 | }; | ||
266 | |||
267 | int __init fdtv_1394_init(struct ieee1394_device_id id_table[]) | ||
268 | { | ||
269 | int ret; | ||
270 | |||
271 | hpsb_register_highlevel(&fdtv_highlevel); | ||
272 | fdtv_driver.id_table = id_table; | ||
273 | ret = hpsb_register_protocol(&fdtv_driver); | ||
274 | if (ret) { | ||
275 | printk(KERN_ERR "firedtv: failed to register protocol\n"); | ||
276 | hpsb_unregister_highlevel(&fdtv_highlevel); | ||
277 | } | ||
278 | return ret; | ||
279 | } | ||
280 | |||
281 | void __exit fdtv_1394_exit(void) | ||
282 | { | ||
283 | hpsb_unregister_protocol(&fdtv_driver); | ||
284 | hpsb_unregister_highlevel(&fdtv_highlevel); | ||
285 | } | ||
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c new file mode 100644 index 000000000000..b55d9ccaf33e --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-avc.c | |||
@@ -0,0 +1,1315 @@ | |||
1 | /* | ||
2 | * FireDTV driver (formerly known as FireSAT) | ||
3 | * | ||
4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | ||
5 | * Copyright (C) 2008 Ben Backx <ben@bbackx.com> | ||
6 | * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of | ||
11 | * the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/bug.h> | ||
15 | #include <linux/crc32.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/jiffies.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/moduleparam.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/string.h> | ||
23 | #include <linux/stringify.h> | ||
24 | #include <linux/wait.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | |||
27 | #include "firedtv.h" | ||
28 | |||
29 | #define FCP_COMMAND_REGISTER 0xfffff0000b00ULL | ||
30 | |||
31 | #define AVC_CTYPE_CONTROL 0x0 | ||
32 | #define AVC_CTYPE_STATUS 0x1 | ||
33 | #define AVC_CTYPE_NOTIFY 0x3 | ||
34 | |||
35 | #define AVC_RESPONSE_ACCEPTED 0x9 | ||
36 | #define AVC_RESPONSE_STABLE 0xc | ||
37 | #define AVC_RESPONSE_CHANGED 0xd | ||
38 | #define AVC_RESPONSE_INTERIM 0xf | ||
39 | |||
40 | #define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3) | ||
41 | #define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3) | ||
42 | |||
43 | #define AVC_OPCODE_VENDOR 0x00 | ||
44 | #define AVC_OPCODE_READ_DESCRIPTOR 0x09 | ||
45 | #define AVC_OPCODE_DSIT 0xc8 | ||
46 | #define AVC_OPCODE_DSD 0xcb | ||
47 | |||
48 | #define DESCRIPTOR_TUNER_STATUS 0x80 | ||
49 | #define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00 | ||
50 | |||
51 | #define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */ | ||
52 | #define SFE_VENDOR_DE_COMPANYID_1 0x12 | ||
53 | #define SFE_VENDOR_DE_COMPANYID_2 0x87 | ||
54 | |||
55 | #define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a | ||
56 | #define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52 | ||
57 | #define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 /* for DVB-S */ | ||
58 | |||
59 | #define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00 | ||
60 | #define SFE_VENDOR_OPCODE_HOST2CA 0x56 | ||
61 | #define SFE_VENDOR_OPCODE_CA2HOST 0x57 | ||
62 | #define SFE_VENDOR_OPCODE_CISTATUS 0x59 | ||
63 | #define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 /* for DVB-S2 */ | ||
64 | |||
65 | #define SFE_VENDOR_TAG_CA_RESET 0x00 | ||
66 | #define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01 | ||
67 | #define SFE_VENDOR_TAG_CA_PMT 0x02 | ||
68 | #define SFE_VENDOR_TAG_CA_DATE_TIME 0x04 | ||
69 | #define SFE_VENDOR_TAG_CA_MMI 0x05 | ||
70 | #define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07 | ||
71 | |||
72 | #define EN50221_LIST_MANAGEMENT_ONLY 0x03 | ||
73 | #define EN50221_TAG_APP_INFO 0x9f8021 | ||
74 | #define EN50221_TAG_CA_INFO 0x9f8031 | ||
75 | |||
76 | struct avc_command_frame { | ||
77 | int length; | ||
78 | u8 ctype; | ||
79 | u8 subunit; | ||
80 | u8 opcode; | ||
81 | u8 operand[509]; | ||
82 | }; | ||
83 | |||
84 | struct avc_response_frame { | ||
85 | int length; | ||
86 | u8 response; | ||
87 | u8 subunit; | ||
88 | u8 opcode; | ||
89 | u8 operand[509]; | ||
90 | }; | ||
91 | |||
92 | #define AVC_DEBUG_FCP_SUBACTIONS 1 | ||
93 | #define AVC_DEBUG_FCP_PAYLOADS 2 | ||
94 | |||
95 | static int avc_debug; | ||
96 | module_param_named(debug, avc_debug, int, 0644); | ||
97 | MODULE_PARM_DESC(debug, "Verbose logging (default = 0" | ||
98 | ", FCP subactions = " __stringify(AVC_DEBUG_FCP_SUBACTIONS) | ||
99 | ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS) | ||
100 | ", or all = -1)"); | ||
101 | |||
102 | static const char *debug_fcp_ctype(unsigned int ctype) | ||
103 | { | ||
104 | static const char *ctypes[] = { | ||
105 | [0x0] = "CONTROL", [0x1] = "STATUS", | ||
106 | [0x2] = "SPECIFIC INQUIRY", [0x3] = "NOTIFY", | ||
107 | [0x4] = "GENERAL INQUIRY", [0x8] = "NOT IMPLEMENTED", | ||
108 | [0x9] = "ACCEPTED", [0xa] = "REJECTED", | ||
109 | [0xb] = "IN TRANSITION", [0xc] = "IMPLEMENTED/STABLE", | ||
110 | [0xd] = "CHANGED", [0xf] = "INTERIM", | ||
111 | }; | ||
112 | const char *ret = ctype < ARRAY_SIZE(ctypes) ? ctypes[ctype] : NULL; | ||
113 | |||
114 | return ret ? ret : "?"; | ||
115 | } | ||
116 | |||
117 | static const char *debug_fcp_opcode(unsigned int opcode, | ||
118 | const u8 *data, size_t length) | ||
119 | { | ||
120 | switch (opcode) { | ||
121 | case AVC_OPCODE_VENDOR: break; | ||
122 | case AVC_OPCODE_READ_DESCRIPTOR: return "ReadDescriptor"; | ||
123 | case AVC_OPCODE_DSIT: return "DirectSelectInfo.Type"; | ||
124 | case AVC_OPCODE_DSD: return "DirectSelectData"; | ||
125 | default: return "?"; | ||
126 | } | ||
127 | |||
128 | if (length < 7 || | ||
129 | data[3] != SFE_VENDOR_DE_COMPANYID_0 || | ||
130 | data[4] != SFE_VENDOR_DE_COMPANYID_1 || | ||
131 | data[5] != SFE_VENDOR_DE_COMPANYID_2) | ||
132 | return "Vendor"; | ||
133 | |||
134 | switch (data[6]) { | ||
135 | case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC"; | ||
136 | case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl"; | ||
137 | case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK"; | ||
138 | case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA"; | ||
139 | case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host"; | ||
140 | } | ||
141 | return "Vendor"; | ||
142 | } | ||
143 | |||
144 | static void debug_fcp(const u8 *data, size_t length) | ||
145 | { | ||
146 | unsigned int subunit_type, subunit_id, op; | ||
147 | const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> "; | ||
148 | |||
149 | if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) { | ||
150 | subunit_type = data[1] >> 3; | ||
151 | subunit_id = data[1] & 7; | ||
152 | op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2]; | ||
153 | printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n", | ||
154 | prefix, subunit_type, subunit_id, length, | ||
155 | debug_fcp_ctype(data[0]), | ||
156 | debug_fcp_opcode(op, data, length)); | ||
157 | } | ||
158 | |||
159 | if (avc_debug & AVC_DEBUG_FCP_PAYLOADS) | ||
160 | print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1, | ||
161 | data, length, false); | ||
162 | } | ||
163 | |||
164 | static int __avc_write(struct firedtv *fdtv, | ||
165 | const struct avc_command_frame *c, struct avc_response_frame *r) | ||
166 | { | ||
167 | int err, retry; | ||
168 | |||
169 | if (r) | ||
170 | fdtv->avc_reply_received = false; | ||
171 | |||
172 | for (retry = 0; retry < 6; retry++) { | ||
173 | if (unlikely(avc_debug)) | ||
174 | debug_fcp(&c->ctype, c->length); | ||
175 | |||
176 | err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, | ||
177 | (void *)&c->ctype, c->length); | ||
178 | if (err) { | ||
179 | fdtv->avc_reply_received = true; | ||
180 | dev_err(fdtv->device, "FCP command write failed\n"); | ||
181 | return err; | ||
182 | } | ||
183 | |||
184 | if (!r) | ||
185 | return 0; | ||
186 | |||
187 | /* | ||
188 | * AV/C specs say that answers should be sent within 150 ms. | ||
189 | * Time out after 200 ms. | ||
190 | */ | ||
191 | if (wait_event_timeout(fdtv->avc_wait, | ||
192 | fdtv->avc_reply_received, | ||
193 | msecs_to_jiffies(200)) != 0) { | ||
194 | r->length = fdtv->response_length; | ||
195 | memcpy(&r->response, fdtv->response, r->length); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | } | ||
200 | dev_err(fdtv->device, "FCP response timed out\n"); | ||
201 | return -ETIMEDOUT; | ||
202 | } | ||
203 | |||
204 | static int avc_write(struct firedtv *fdtv, | ||
205 | const struct avc_command_frame *c, struct avc_response_frame *r) | ||
206 | { | ||
207 | int ret; | ||
208 | |||
209 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
210 | return -EINTR; | ||
211 | |||
212 | ret = __avc_write(fdtv, c, r); | ||
213 | |||
214 | mutex_unlock(&fdtv->avc_mutex); | ||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | int avc_recv(struct firedtv *fdtv, void *data, size_t length) | ||
219 | { | ||
220 | struct avc_response_frame *r = | ||
221 | data - offsetof(struct avc_response_frame, response); | ||
222 | |||
223 | if (unlikely(avc_debug)) | ||
224 | debug_fcp(data, length); | ||
225 | |||
226 | if (length >= 8 && | ||
227 | r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && | ||
228 | r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && | ||
229 | r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && | ||
230 | r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { | ||
231 | if (r->response == AVC_RESPONSE_CHANGED) { | ||
232 | fdtv_handle_rc(fdtv, | ||
233 | r->operand[4] << 8 | r->operand[5]); | ||
234 | schedule_work(&fdtv->remote_ctrl_work); | ||
235 | } else if (r->response != AVC_RESPONSE_INTERIM) { | ||
236 | dev_info(fdtv->device, | ||
237 | "remote control result = %d\n", r->response); | ||
238 | } | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | if (fdtv->avc_reply_received) { | ||
243 | dev_err(fdtv->device, "out-of-order AVC response, ignored\n"); | ||
244 | return -EIO; | ||
245 | } | ||
246 | |||
247 | memcpy(fdtv->response, data, length); | ||
248 | fdtv->response_length = length; | ||
249 | |||
250 | fdtv->avc_reply_received = true; | ||
251 | wake_up(&fdtv->avc_wait); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * tuning command for setting the relative LNB frequency | ||
258 | * (not supported by the AVC standard) | ||
259 | */ | ||
260 | static void avc_tuner_tuneqpsk(struct firedtv *fdtv, | ||
261 | struct dvb_frontend_parameters *params, | ||
262 | struct avc_command_frame *c) | ||
263 | { | ||
264 | c->opcode = AVC_OPCODE_VENDOR; | ||
265 | |||
266 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
267 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
268 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
269 | c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; | ||
270 | |||
271 | c->operand[4] = (params->frequency >> 24) & 0xff; | ||
272 | c->operand[5] = (params->frequency >> 16) & 0xff; | ||
273 | c->operand[6] = (params->frequency >> 8) & 0xff; | ||
274 | c->operand[7] = params->frequency & 0xff; | ||
275 | |||
276 | c->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff; | ||
277 | c->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff; | ||
278 | |||
279 | switch (params->u.qpsk.fec_inner) { | ||
280 | case FEC_1_2: c->operand[10] = 0x1; break; | ||
281 | case FEC_2_3: c->operand[10] = 0x2; break; | ||
282 | case FEC_3_4: c->operand[10] = 0x3; break; | ||
283 | case FEC_5_6: c->operand[10] = 0x4; break; | ||
284 | case FEC_7_8: c->operand[10] = 0x5; break; | ||
285 | case FEC_4_5: | ||
286 | case FEC_8_9: | ||
287 | case FEC_AUTO: | ||
288 | default: c->operand[10] = 0x0; | ||
289 | } | ||
290 | |||
291 | if (fdtv->voltage == 0xff) | ||
292 | c->operand[11] = 0xff; | ||
293 | else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */ | ||
294 | c->operand[11] = 0; | ||
295 | else | ||
296 | c->operand[11] = 1; | ||
297 | |||
298 | if (fdtv->tone == 0xff) | ||
299 | c->operand[12] = 0xff; | ||
300 | else if (fdtv->tone == SEC_TONE_ON) /* band */ | ||
301 | c->operand[12] = 1; | ||
302 | else | ||
303 | c->operand[12] = 0; | ||
304 | |||
305 | if (fdtv->type == FIREDTV_DVB_S2) { | ||
306 | c->operand[13] = 0x1; | ||
307 | c->operand[14] = 0xff; | ||
308 | c->operand[15] = 0xff; | ||
309 | c->length = 20; | ||
310 | } else { | ||
311 | c->length = 16; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, | ||
316 | struct avc_command_frame *c) | ||
317 | { | ||
318 | c->opcode = AVC_OPCODE_DSD; | ||
319 | |||
320 | c->operand[0] = 0; /* source plug */ | ||
321 | c->operand[1] = 0xd2; /* subfunction replace */ | ||
322 | c->operand[2] = 0x20; /* system id = DVB */ | ||
323 | c->operand[3] = 0x00; /* antenna number */ | ||
324 | c->operand[4] = 0x11; /* system_specific_multiplex selection_length */ | ||
325 | |||
326 | /* multiplex_valid_flags, high byte */ | ||
327 | c->operand[5] = 0 << 7 /* reserved */ | ||
328 | | 0 << 6 /* Polarisation */ | ||
329 | | 0 << 5 /* Orbital_Pos */ | ||
330 | | 1 << 4 /* Frequency */ | ||
331 | | 1 << 3 /* Symbol_Rate */ | ||
332 | | 0 << 2 /* FEC_outer */ | ||
333 | | (params->u.qam.fec_inner != FEC_AUTO ? 1 << 1 : 0) | ||
334 | | (params->u.qam.modulation != QAM_AUTO ? 1 << 0 : 0); | ||
335 | |||
336 | /* multiplex_valid_flags, low byte */ | ||
337 | c->operand[6] = 0 << 7 /* NetworkID */ | ||
338 | | 0 << 0 /* reserved */ ; | ||
339 | |||
340 | c->operand[7] = 0x00; | ||
341 | c->operand[8] = 0x00; | ||
342 | c->operand[9] = 0x00; | ||
343 | c->operand[10] = 0x00; | ||
344 | |||
345 | c->operand[11] = (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6); | ||
346 | c->operand[12] = ((params->frequency / 4000) >> 8) & 0xff; | ||
347 | c->operand[13] = (params->frequency / 4000) & 0xff; | ||
348 | c->operand[14] = ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff; | ||
349 | c->operand[15] = ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff; | ||
350 | c->operand[16] = ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0; | ||
351 | c->operand[17] = 0x00; | ||
352 | |||
353 | switch (params->u.qpsk.fec_inner) { | ||
354 | case FEC_1_2: c->operand[18] = 0x1; break; | ||
355 | case FEC_2_3: c->operand[18] = 0x2; break; | ||
356 | case FEC_3_4: c->operand[18] = 0x3; break; | ||
357 | case FEC_5_6: c->operand[18] = 0x4; break; | ||
358 | case FEC_7_8: c->operand[18] = 0x5; break; | ||
359 | case FEC_8_9: c->operand[18] = 0x6; break; | ||
360 | case FEC_4_5: c->operand[18] = 0x8; break; | ||
361 | case FEC_AUTO: | ||
362 | default: c->operand[18] = 0x0; | ||
363 | } | ||
364 | |||
365 | switch (params->u.qam.modulation) { | ||
366 | case QAM_16: c->operand[19] = 0x08; break; | ||
367 | case QAM_32: c->operand[19] = 0x10; break; | ||
368 | case QAM_64: c->operand[19] = 0x18; break; | ||
369 | case QAM_128: c->operand[19] = 0x20; break; | ||
370 | case QAM_256: c->operand[19] = 0x28; break; | ||
371 | case QAM_AUTO: | ||
372 | default: c->operand[19] = 0x00; | ||
373 | } | ||
374 | |||
375 | c->operand[20] = 0x00; | ||
376 | c->operand[21] = 0x00; | ||
377 | /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ | ||
378 | c->operand[22] = 0x00; | ||
379 | |||
380 | c->length = 28; | ||
381 | } | ||
382 | |||
383 | static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, | ||
384 | struct avc_command_frame *c) | ||
385 | { | ||
386 | struct dvb_ofdm_parameters *ofdm = ¶ms->u.ofdm; | ||
387 | |||
388 | c->opcode = AVC_OPCODE_DSD; | ||
389 | |||
390 | c->operand[0] = 0; /* source plug */ | ||
391 | c->operand[1] = 0xd2; /* subfunction replace */ | ||
392 | c->operand[2] = 0x20; /* system id = DVB */ | ||
393 | c->operand[3] = 0x00; /* antenna number */ | ||
394 | c->operand[4] = 0x0c; /* system_specific_multiplex selection_length */ | ||
395 | |||
396 | /* multiplex_valid_flags, high byte */ | ||
397 | c->operand[5] = | ||
398 | 0 << 7 /* reserved */ | ||
399 | | 1 << 6 /* CenterFrequency */ | ||
400 | | (ofdm->bandwidth != BANDWIDTH_AUTO ? 1 << 5 : 0) | ||
401 | | (ofdm->constellation != QAM_AUTO ? 1 << 4 : 0) | ||
402 | | (ofdm->hierarchy_information != HIERARCHY_AUTO ? 1 << 3 : 0) | ||
403 | | (ofdm->code_rate_HP != FEC_AUTO ? 1 << 2 : 0) | ||
404 | | (ofdm->code_rate_LP != FEC_AUTO ? 1 << 1 : 0) | ||
405 | | (ofdm->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0); | ||
406 | |||
407 | /* multiplex_valid_flags, low byte */ | ||
408 | c->operand[6] = | ||
409 | 0 << 7 /* NetworkID */ | ||
410 | | (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0) | ||
411 | | 0 << 5 /* OtherFrequencyFlag */ | ||
412 | | 0 << 0 /* reserved */ ; | ||
413 | |||
414 | c->operand[7] = 0x0; | ||
415 | c->operand[8] = (params->frequency / 10) >> 24; | ||
416 | c->operand[9] = ((params->frequency / 10) >> 16) & 0xff; | ||
417 | c->operand[10] = ((params->frequency / 10) >> 8) & 0xff; | ||
418 | c->operand[11] = (params->frequency / 10) & 0xff; | ||
419 | |||
420 | switch (ofdm->bandwidth) { | ||
421 | case BANDWIDTH_7_MHZ: c->operand[12] = 0x20; break; | ||
422 | case BANDWIDTH_8_MHZ: | ||
423 | case BANDWIDTH_6_MHZ: /* not defined by AVC spec */ | ||
424 | case BANDWIDTH_AUTO: | ||
425 | default: c->operand[12] = 0x00; | ||
426 | } | ||
427 | |||
428 | switch (ofdm->constellation) { | ||
429 | case QAM_16: c->operand[13] = 1 << 6; break; | ||
430 | case QAM_64: c->operand[13] = 2 << 6; break; | ||
431 | case QPSK: | ||
432 | default: c->operand[13] = 0x00; | ||
433 | } | ||
434 | |||
435 | switch (ofdm->hierarchy_information) { | ||
436 | case HIERARCHY_1: c->operand[13] |= 1 << 3; break; | ||
437 | case HIERARCHY_2: c->operand[13] |= 2 << 3; break; | ||
438 | case HIERARCHY_4: c->operand[13] |= 3 << 3; break; | ||
439 | case HIERARCHY_AUTO: | ||
440 | case HIERARCHY_NONE: | ||
441 | default: break; | ||
442 | } | ||
443 | |||
444 | switch (ofdm->code_rate_HP) { | ||
445 | case FEC_2_3: c->operand[13] |= 1; break; | ||
446 | case FEC_3_4: c->operand[13] |= 2; break; | ||
447 | case FEC_5_6: c->operand[13] |= 3; break; | ||
448 | case FEC_7_8: c->operand[13] |= 4; break; | ||
449 | case FEC_1_2: | ||
450 | default: break; | ||
451 | } | ||
452 | |||
453 | switch (ofdm->code_rate_LP) { | ||
454 | case FEC_2_3: c->operand[14] = 1 << 5; break; | ||
455 | case FEC_3_4: c->operand[14] = 2 << 5; break; | ||
456 | case FEC_5_6: c->operand[14] = 3 << 5; break; | ||
457 | case FEC_7_8: c->operand[14] = 4 << 5; break; | ||
458 | case FEC_1_2: | ||
459 | default: c->operand[14] = 0x00; break; | ||
460 | } | ||
461 | |||
462 | switch (ofdm->guard_interval) { | ||
463 | case GUARD_INTERVAL_1_16: c->operand[14] |= 1 << 3; break; | ||
464 | case GUARD_INTERVAL_1_8: c->operand[14] |= 2 << 3; break; | ||
465 | case GUARD_INTERVAL_1_4: c->operand[14] |= 3 << 3; break; | ||
466 | case GUARD_INTERVAL_1_32: | ||
467 | case GUARD_INTERVAL_AUTO: | ||
468 | default: break; | ||
469 | } | ||
470 | |||
471 | switch (ofdm->transmission_mode) { | ||
472 | case TRANSMISSION_MODE_8K: c->operand[14] |= 1 << 1; break; | ||
473 | case TRANSMISSION_MODE_2K: | ||
474 | case TRANSMISSION_MODE_AUTO: | ||
475 | default: break; | ||
476 | } | ||
477 | |||
478 | c->operand[15] = 0x00; /* network_ID[0] */ | ||
479 | c->operand[16] = 0x00; /* network_ID[1] */ | ||
480 | /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ | ||
481 | c->operand[17] = 0x00; | ||
482 | |||
483 | c->length = 24; | ||
484 | } | ||
485 | |||
486 | int avc_tuner_dsd(struct firedtv *fdtv, | ||
487 | struct dvb_frontend_parameters *params) | ||
488 | { | ||
489 | char buffer[sizeof(struct avc_command_frame)]; | ||
490 | struct avc_command_frame *c = (void *)buffer; | ||
491 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
492 | |||
493 | memset(c, 0, sizeof(*c)); | ||
494 | |||
495 | c->ctype = AVC_CTYPE_CONTROL; | ||
496 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
497 | |||
498 | switch (fdtv->type) { | ||
499 | case FIREDTV_DVB_S: | ||
500 | case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break; | ||
501 | case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break; | ||
502 | case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break; | ||
503 | default: | ||
504 | BUG(); | ||
505 | } | ||
506 | |||
507 | if (avc_write(fdtv, c, r) < 0) | ||
508 | return -EIO; | ||
509 | |||
510 | msleep(500); | ||
511 | #if 0 | ||
512 | /* FIXME: */ | ||
513 | /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ | ||
514 | if (status) | ||
515 | *status = r->operand[2]; | ||
516 | #endif | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) | ||
521 | { | ||
522 | char buffer[sizeof(struct avc_command_frame)]; | ||
523 | struct avc_command_frame *c = (void *)buffer; | ||
524 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
525 | int pos, k; | ||
526 | |||
527 | if (pidc > 16 && pidc != 0xff) | ||
528 | return -EINVAL; | ||
529 | |||
530 | memset(c, 0, sizeof(*c)); | ||
531 | |||
532 | c->ctype = AVC_CTYPE_CONTROL; | ||
533 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
534 | c->opcode = AVC_OPCODE_DSD; | ||
535 | |||
536 | c->operand[0] = 0; /* source plug */ | ||
537 | c->operand[1] = 0xd2; /* subfunction replace */ | ||
538 | c->operand[2] = 0x20; /* system id = DVB */ | ||
539 | c->operand[3] = 0x00; /* antenna number */ | ||
540 | c->operand[4] = 0x00; /* system_specific_multiplex selection_length */ | ||
541 | c->operand[5] = pidc; /* Nr_of_dsd_sel_specs */ | ||
542 | |||
543 | pos = 6; | ||
544 | if (pidc != 0xff) | ||
545 | for (k = 0; k < pidc; k++) { | ||
546 | c->operand[pos++] = 0x13; /* flowfunction relay */ | ||
547 | c->operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */ | ||
548 | c->operand[pos++] = (pid[k] >> 8) & 0x1f; | ||
549 | c->operand[pos++] = pid[k] & 0xff; | ||
550 | c->operand[pos++] = 0x00; /* tableID */ | ||
551 | c->operand[pos++] = 0x00; /* filter_length */ | ||
552 | } | ||
553 | |||
554 | c->length = ALIGN(3 + pos, 4); | ||
555 | |||
556 | if (avc_write(fdtv, c, r) < 0) | ||
557 | return -EIO; | ||
558 | |||
559 | msleep(50); | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | int avc_tuner_get_ts(struct firedtv *fdtv) | ||
564 | { | ||
565 | char buffer[sizeof(struct avc_command_frame)]; | ||
566 | struct avc_command_frame *c = (void *)buffer; | ||
567 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
568 | int sl; | ||
569 | |||
570 | memset(c, 0, sizeof(*c)); | ||
571 | |||
572 | c->ctype = AVC_CTYPE_CONTROL; | ||
573 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
574 | c->opcode = AVC_OPCODE_DSIT; | ||
575 | |||
576 | sl = fdtv->type == FIREDTV_DVB_T ? 0x0c : 0x11; | ||
577 | |||
578 | c->operand[0] = 0; /* source plug */ | ||
579 | c->operand[1] = 0xd2; /* subfunction replace */ | ||
580 | c->operand[2] = 0xff; /* status */ | ||
581 | c->operand[3] = 0x20; /* system id = DVB */ | ||
582 | c->operand[4] = 0x00; /* antenna number */ | ||
583 | c->operand[5] = 0x0; /* system_specific_search_flags */ | ||
584 | c->operand[6] = sl; /* system_specific_multiplex selection_length */ | ||
585 | c->operand[7] = 0x00; /* valid_flags [0] */ | ||
586 | c->operand[8] = 0x00; /* valid_flags [1] */ | ||
587 | c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */ | ||
588 | |||
589 | c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; | ||
590 | |||
591 | if (avc_write(fdtv, c, r) < 0) | ||
592 | return -EIO; | ||
593 | |||
594 | msleep(250); | ||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | int avc_identify_subunit(struct firedtv *fdtv) | ||
599 | { | ||
600 | char buffer[sizeof(struct avc_command_frame)]; | ||
601 | struct avc_command_frame *c = (void *)buffer; | ||
602 | struct avc_response_frame *r = (void *)buffer; | ||
603 | |||
604 | memset(c, 0, sizeof(*c)); | ||
605 | |||
606 | c->ctype = AVC_CTYPE_CONTROL; | ||
607 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
608 | c->opcode = AVC_OPCODE_READ_DESCRIPTOR; | ||
609 | |||
610 | c->operand[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER; | ||
611 | c->operand[1] = 0xff; | ||
612 | c->operand[2] = 0x00; | ||
613 | c->operand[3] = 0x00; /* length highbyte */ | ||
614 | c->operand[4] = 0x08; /* length lowbyte */ | ||
615 | c->operand[5] = 0x00; /* offset highbyte */ | ||
616 | c->operand[6] = 0x0d; /* offset lowbyte */ | ||
617 | |||
618 | c->length = 12; | ||
619 | |||
620 | if (avc_write(fdtv, c, r) < 0) | ||
621 | return -EIO; | ||
622 | |||
623 | if ((r->response != AVC_RESPONSE_STABLE && | ||
624 | r->response != AVC_RESPONSE_ACCEPTED) || | ||
625 | (r->operand[3] << 8) + r->operand[4] != 8) { | ||
626 | dev_err(fdtv->device, "cannot read subunit identifier\n"); | ||
627 | return -EINVAL; | ||
628 | } | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | #define SIZEOF_ANTENNA_INPUT_INFO 22 | ||
633 | |||
634 | int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) | ||
635 | { | ||
636 | char buffer[sizeof(struct avc_command_frame)]; | ||
637 | struct avc_command_frame *c = (void *)buffer; | ||
638 | struct avc_response_frame *r = (void *)buffer; | ||
639 | int length; | ||
640 | |||
641 | memset(c, 0, sizeof(*c)); | ||
642 | |||
643 | c->ctype = AVC_CTYPE_CONTROL; | ||
644 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
645 | c->opcode = AVC_OPCODE_READ_DESCRIPTOR; | ||
646 | |||
647 | c->operand[0] = DESCRIPTOR_TUNER_STATUS; | ||
648 | c->operand[1] = 0xff; /* read_result_status */ | ||
649 | c->operand[2] = 0x00; /* reserved */ | ||
650 | c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */ | ||
651 | c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */ | ||
652 | c->operand[5] = 0x00; | ||
653 | c->operand[6] = 0x00; | ||
654 | |||
655 | c->length = 12; | ||
656 | |||
657 | if (avc_write(fdtv, c, r) < 0) | ||
658 | return -EIO; | ||
659 | |||
660 | if (r->response != AVC_RESPONSE_STABLE && | ||
661 | r->response != AVC_RESPONSE_ACCEPTED) { | ||
662 | dev_err(fdtv->device, "cannot read tuner status\n"); | ||
663 | return -EINVAL; | ||
664 | } | ||
665 | |||
666 | length = r->operand[9]; | ||
667 | if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) { | ||
668 | dev_err(fdtv->device, "got invalid tuner status\n"); | ||
669 | return -EINVAL; | ||
670 | } | ||
671 | |||
672 | stat->active_system = r->operand[10]; | ||
673 | stat->searching = r->operand[11] >> 7 & 1; | ||
674 | stat->moving = r->operand[11] >> 6 & 1; | ||
675 | stat->no_rf = r->operand[11] >> 5 & 1; | ||
676 | stat->input = r->operand[12] >> 7 & 1; | ||
677 | stat->selected_antenna = r->operand[12] & 0x7f; | ||
678 | stat->ber = r->operand[13] << 24 | | ||
679 | r->operand[14] << 16 | | ||
680 | r->operand[15] << 8 | | ||
681 | r->operand[16]; | ||
682 | stat->signal_strength = r->operand[17]; | ||
683 | stat->raster_frequency = r->operand[18] >> 6 & 2; | ||
684 | stat->rf_frequency = (r->operand[18] & 0x3f) << 16 | | ||
685 | r->operand[19] << 8 | | ||
686 | r->operand[20]; | ||
687 | stat->man_dep_info_length = r->operand[21]; | ||
688 | stat->front_end_error = r->operand[22] >> 4 & 1; | ||
689 | stat->antenna_error = r->operand[22] >> 3 & 1; | ||
690 | stat->front_end_power_status = r->operand[22] >> 1 & 1; | ||
691 | stat->power_supply = r->operand[22] & 1; | ||
692 | stat->carrier_noise_ratio = r->operand[23] << 8 | | ||
693 | r->operand[24]; | ||
694 | stat->power_supply_voltage = r->operand[27]; | ||
695 | stat->antenna_voltage = r->operand[28]; | ||
696 | stat->firewire_bus_voltage = r->operand[29]; | ||
697 | stat->ca_mmi = r->operand[30] & 1; | ||
698 | stat->ca_pmt_reply = r->operand[31] >> 7 & 1; | ||
699 | stat->ca_date_time_request = r->operand[31] >> 6 & 1; | ||
700 | stat->ca_application_info = r->operand[31] >> 5 & 1; | ||
701 | stat->ca_module_present_status = r->operand[31] >> 4 & 1; | ||
702 | stat->ca_dvb_flag = r->operand[31] >> 3 & 1; | ||
703 | stat->ca_error_flag = r->operand[31] >> 2 & 1; | ||
704 | stat->ca_initialization_status = r->operand[31] >> 1 & 1; | ||
705 | |||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, | ||
710 | char conttone, char nrdiseq, | ||
711 | struct dvb_diseqc_master_cmd *diseqcmd) | ||
712 | { | ||
713 | char buffer[sizeof(struct avc_command_frame)]; | ||
714 | struct avc_command_frame *c = (void *)buffer; | ||
715 | struct avc_response_frame *r = (void *)buffer; | ||
716 | int i, j, k; | ||
717 | |||
718 | memset(c, 0, sizeof(*c)); | ||
719 | |||
720 | c->ctype = AVC_CTYPE_CONTROL; | ||
721 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
722 | c->opcode = AVC_OPCODE_VENDOR; | ||
723 | |||
724 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
725 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
726 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
727 | c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL; | ||
728 | |||
729 | c->operand[4] = voltage; | ||
730 | c->operand[5] = nrdiseq; | ||
731 | |||
732 | i = 6; | ||
733 | |||
734 | for (j = 0; j < nrdiseq; j++) { | ||
735 | c->operand[i++] = diseqcmd[j].msg_len; | ||
736 | |||
737 | for (k = 0; k < diseqcmd[j].msg_len; k++) | ||
738 | c->operand[i++] = diseqcmd[j].msg[k]; | ||
739 | } | ||
740 | |||
741 | c->operand[i++] = burst; | ||
742 | c->operand[i++] = conttone; | ||
743 | |||
744 | c->length = ALIGN(3 + i, 4); | ||
745 | |||
746 | if (avc_write(fdtv, c, r) < 0) | ||
747 | return -EIO; | ||
748 | |||
749 | if (r->response != AVC_RESPONSE_ACCEPTED) { | ||
750 | dev_err(fdtv->device, "LNB control failed\n"); | ||
751 | return -EINVAL; | ||
752 | } | ||
753 | |||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | int avc_register_remote_control(struct firedtv *fdtv) | ||
758 | { | ||
759 | char buffer[sizeof(struct avc_command_frame)]; | ||
760 | struct avc_command_frame *c = (void *)buffer; | ||
761 | |||
762 | memset(c, 0, sizeof(*c)); | ||
763 | |||
764 | c->ctype = AVC_CTYPE_NOTIFY; | ||
765 | c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7; | ||
766 | c->opcode = AVC_OPCODE_VENDOR; | ||
767 | |||
768 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
769 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
770 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
771 | c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; | ||
772 | |||
773 | c->length = 8; | ||
774 | |||
775 | return avc_write(fdtv, c, NULL); | ||
776 | } | ||
777 | |||
778 | void avc_remote_ctrl_work(struct work_struct *work) | ||
779 | { | ||
780 | struct firedtv *fdtv = | ||
781 | container_of(work, struct firedtv, remote_ctrl_work); | ||
782 | |||
783 | /* Should it be rescheduled in failure cases? */ | ||
784 | avc_register_remote_control(fdtv); | ||
785 | } | ||
786 | |||
787 | #if 0 /* FIXME: unused */ | ||
788 | int avc_tuner_host2ca(struct firedtv *fdtv) | ||
789 | { | ||
790 | char buffer[sizeof(struct avc_command_frame)]; | ||
791 | struct avc_command_frame *c = (void *)buffer; | ||
792 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
793 | |||
794 | memset(c, 0, sizeof(*c)); | ||
795 | |||
796 | c->ctype = AVC_CTYPE_CONTROL; | ||
797 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
798 | c->opcode = AVC_OPCODE_VENDOR; | ||
799 | |||
800 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
801 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
802 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
803 | c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; | ||
804 | c->operand[4] = 0; /* slot */ | ||
805 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ | ||
806 | c->operand[6] = 0; /* more/last */ | ||
807 | c->operand[7] = 0; /* length */ | ||
808 | |||
809 | c->length = 12; | ||
810 | |||
811 | if (avc_write(fdtv, c, r) < 0) | ||
812 | return -EIO; | ||
813 | |||
814 | return 0; | ||
815 | } | ||
816 | #endif | ||
817 | |||
818 | static int get_ca_object_pos(struct avc_response_frame *r) | ||
819 | { | ||
820 | int length = 1; | ||
821 | |||
822 | /* Check length of length field */ | ||
823 | if (r->operand[7] & 0x80) | ||
824 | length = (r->operand[7] & 0x7f) + 1; | ||
825 | return length + 7; | ||
826 | } | ||
827 | |||
828 | static int get_ca_object_length(struct avc_response_frame *r) | ||
829 | { | ||
830 | #if 0 /* FIXME: unused */ | ||
831 | int size = 0; | ||
832 | int i; | ||
833 | |||
834 | if (r->operand[7] & 0x80) | ||
835 | for (i = 0; i < (r->operand[7] & 0x7f); i++) { | ||
836 | size <<= 8; | ||
837 | size += r->operand[8 + i]; | ||
838 | } | ||
839 | #endif | ||
840 | return r->operand[7]; | ||
841 | } | ||
842 | |||
843 | int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | ||
844 | { | ||
845 | char buffer[sizeof(struct avc_command_frame)]; | ||
846 | struct avc_command_frame *c = (void *)buffer; | ||
847 | struct avc_response_frame *r = (void *)buffer; | ||
848 | int pos; | ||
849 | |||
850 | memset(c, 0, sizeof(*c)); | ||
851 | |||
852 | c->ctype = AVC_CTYPE_STATUS; | ||
853 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
854 | c->opcode = AVC_OPCODE_VENDOR; | ||
855 | |||
856 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
857 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
858 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
859 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; | ||
860 | c->operand[4] = 0; /* slot */ | ||
861 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ | ||
862 | |||
863 | c->length = 12; | ||
864 | |||
865 | if (avc_write(fdtv, c, r) < 0) | ||
866 | return -EIO; | ||
867 | |||
868 | /* FIXME: check response code and validate response data */ | ||
869 | |||
870 | pos = get_ca_object_pos(r); | ||
871 | app_info[0] = (EN50221_TAG_APP_INFO >> 16) & 0xff; | ||
872 | app_info[1] = (EN50221_TAG_APP_INFO >> 8) & 0xff; | ||
873 | app_info[2] = (EN50221_TAG_APP_INFO >> 0) & 0xff; | ||
874 | app_info[3] = 6 + r->operand[pos + 4]; | ||
875 | app_info[4] = 0x01; | ||
876 | memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]); | ||
877 | *len = app_info[3] + 4; | ||
878 | |||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | ||
883 | { | ||
884 | char buffer[sizeof(struct avc_command_frame)]; | ||
885 | struct avc_command_frame *c = (void *)buffer; | ||
886 | struct avc_response_frame *r = (void *)buffer; | ||
887 | int pos; | ||
888 | |||
889 | memset(c, 0, sizeof(*c)); | ||
890 | |||
891 | c->ctype = AVC_CTYPE_STATUS; | ||
892 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
893 | c->opcode = AVC_OPCODE_VENDOR; | ||
894 | |||
895 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
896 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
897 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
898 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; | ||
899 | c->operand[4] = 0; /* slot */ | ||
900 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ | ||
901 | |||
902 | c->length = 12; | ||
903 | |||
904 | if (avc_write(fdtv, c, r) < 0) | ||
905 | return -EIO; | ||
906 | |||
907 | pos = get_ca_object_pos(r); | ||
908 | app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; | ||
909 | app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff; | ||
910 | app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff; | ||
911 | app_info[3] = 2; | ||
912 | app_info[4] = r->operand[pos + 0]; | ||
913 | app_info[5] = r->operand[pos + 1]; | ||
914 | *len = app_info[3] + 4; | ||
915 | |||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | int avc_ca_reset(struct firedtv *fdtv) | ||
920 | { | ||
921 | char buffer[sizeof(struct avc_command_frame)]; | ||
922 | struct avc_command_frame *c = (void *)buffer; | ||
923 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
924 | |||
925 | memset(c, 0, sizeof(*c)); | ||
926 | |||
927 | c->ctype = AVC_CTYPE_CONTROL; | ||
928 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
929 | c->opcode = AVC_OPCODE_VENDOR; | ||
930 | |||
931 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
932 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
933 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
934 | c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; | ||
935 | c->operand[4] = 0; /* slot */ | ||
936 | c->operand[5] = SFE_VENDOR_TAG_CA_RESET; /* ca tag */ | ||
937 | c->operand[6] = 0; /* more/last */ | ||
938 | c->operand[7] = 1; /* length */ | ||
939 | c->operand[8] = 0; /* force hardware reset */ | ||
940 | |||
941 | c->length = 12; | ||
942 | |||
943 | if (avc_write(fdtv, c, r) < 0) | ||
944 | return -EIO; | ||
945 | |||
946 | return 0; | ||
947 | } | ||
948 | |||
949 | int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) | ||
950 | { | ||
951 | char buffer[sizeof(struct avc_command_frame)]; | ||
952 | struct avc_command_frame *c = (void *)buffer; | ||
953 | struct avc_response_frame *r = (void *)buffer; | ||
954 | int list_management; | ||
955 | int program_info_length; | ||
956 | int pmt_cmd_id; | ||
957 | int read_pos; | ||
958 | int write_pos; | ||
959 | int es_info_length; | ||
960 | int crc32_csum; | ||
961 | |||
962 | memset(c, 0, sizeof(*c)); | ||
963 | |||
964 | c->ctype = AVC_CTYPE_CONTROL; | ||
965 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
966 | c->opcode = AVC_OPCODE_VENDOR; | ||
967 | |||
968 | if (msg[0] != EN50221_LIST_MANAGEMENT_ONLY) { | ||
969 | dev_info(fdtv->device, "forcing list_management to ONLY\n"); | ||
970 | msg[0] = EN50221_LIST_MANAGEMENT_ONLY; | ||
971 | } | ||
972 | /* We take the cmd_id from the programme level only! */ | ||
973 | list_management = msg[0]; | ||
974 | program_info_length = ((msg[4] & 0x0f) << 8) + msg[5]; | ||
975 | if (program_info_length > 0) | ||
976 | program_info_length--; /* Remove pmt_cmd_id */ | ||
977 | pmt_cmd_id = msg[6]; | ||
978 | |||
979 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
980 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
981 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
982 | c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; | ||
983 | c->operand[4] = 0; /* slot */ | ||
984 | c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */ | ||
985 | c->operand[6] = 0; /* more/last */ | ||
986 | /* c->operand[7] = XXXprogram_info_length + 17; */ /* length */ | ||
987 | c->operand[8] = list_management; | ||
988 | c->operand[9] = 0x01; /* pmt_cmd=OK_descramble */ | ||
989 | |||
990 | /* TS program map table */ | ||
991 | |||
992 | c->operand[10] = 0x02; /* Table id=2 */ | ||
993 | c->operand[11] = 0x80; /* Section syntax + length */ | ||
994 | /* c->operand[12] = XXXprogram_info_length + 12; */ | ||
995 | c->operand[13] = msg[1]; /* Program number */ | ||
996 | c->operand[14] = msg[2]; | ||
997 | c->operand[15] = 0x01; /* Version number=0 + current/next=1 */ | ||
998 | c->operand[16] = 0x00; /* Section number=0 */ | ||
999 | c->operand[17] = 0x00; /* Last section number=0 */ | ||
1000 | c->operand[18] = 0x1f; /* PCR_PID=1FFF */ | ||
1001 | c->operand[19] = 0xff; | ||
1002 | c->operand[20] = (program_info_length >> 8); /* Program info length */ | ||
1003 | c->operand[21] = (program_info_length & 0xff); | ||
1004 | |||
1005 | /* CA descriptors at programme level */ | ||
1006 | read_pos = 6; | ||
1007 | write_pos = 22; | ||
1008 | if (program_info_length > 0) { | ||
1009 | pmt_cmd_id = msg[read_pos++]; | ||
1010 | if (pmt_cmd_id != 1 && pmt_cmd_id != 4) | ||
1011 | dev_err(fdtv->device, | ||
1012 | "invalid pmt_cmd_id %d\n", pmt_cmd_id); | ||
1013 | |||
1014 | memcpy(&c->operand[write_pos], &msg[read_pos], | ||
1015 | program_info_length); | ||
1016 | read_pos += program_info_length; | ||
1017 | write_pos += program_info_length; | ||
1018 | } | ||
1019 | while (read_pos < length) { | ||
1020 | c->operand[write_pos++] = msg[read_pos++]; | ||
1021 | c->operand[write_pos++] = msg[read_pos++]; | ||
1022 | c->operand[write_pos++] = msg[read_pos++]; | ||
1023 | es_info_length = | ||
1024 | ((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1]; | ||
1025 | read_pos += 2; | ||
1026 | if (es_info_length > 0) | ||
1027 | es_info_length--; /* Remove pmt_cmd_id */ | ||
1028 | c->operand[write_pos++] = es_info_length >> 8; | ||
1029 | c->operand[write_pos++] = es_info_length & 0xff; | ||
1030 | if (es_info_length > 0) { | ||
1031 | pmt_cmd_id = msg[read_pos++]; | ||
1032 | if (pmt_cmd_id != 1 && pmt_cmd_id != 4) | ||
1033 | dev_err(fdtv->device, "invalid pmt_cmd_id %d " | ||
1034 | "at stream level\n", pmt_cmd_id); | ||
1035 | |||
1036 | memcpy(&c->operand[write_pos], &msg[read_pos], | ||
1037 | es_info_length); | ||
1038 | read_pos += es_info_length; | ||
1039 | write_pos += es_info_length; | ||
1040 | } | ||
1041 | } | ||
1042 | |||
1043 | /* CRC */ | ||
1044 | c->operand[write_pos++] = 0x00; | ||
1045 | c->operand[write_pos++] = 0x00; | ||
1046 | c->operand[write_pos++] = 0x00; | ||
1047 | c->operand[write_pos++] = 0x00; | ||
1048 | |||
1049 | c->operand[7] = write_pos - 8; | ||
1050 | c->operand[12] = write_pos - 13; | ||
1051 | |||
1052 | crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1); | ||
1053 | c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff; | ||
1054 | c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff; | ||
1055 | c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; | ||
1056 | c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; | ||
1057 | |||
1058 | c->length = ALIGN(3 + write_pos, 4); | ||
1059 | |||
1060 | if (avc_write(fdtv, c, r) < 0) | ||
1061 | return -EIO; | ||
1062 | |||
1063 | if (r->response != AVC_RESPONSE_ACCEPTED) { | ||
1064 | dev_err(fdtv->device, | ||
1065 | "CA PMT failed with response 0x%x\n", r->response); | ||
1066 | return -EFAULT; | ||
1067 | } | ||
1068 | |||
1069 | return 0; | ||
1070 | } | ||
1071 | |||
1072 | int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) | ||
1073 | { | ||
1074 | char buffer[sizeof(struct avc_command_frame)]; | ||
1075 | struct avc_command_frame *c = (void *)buffer; | ||
1076 | struct avc_response_frame *r = (void *)buffer; | ||
1077 | |||
1078 | memset(c, 0, sizeof(*c)); | ||
1079 | |||
1080 | c->ctype = AVC_CTYPE_STATUS; | ||
1081 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
1082 | c->opcode = AVC_OPCODE_VENDOR; | ||
1083 | |||
1084 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
1085 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
1086 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
1087 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; | ||
1088 | c->operand[4] = 0; /* slot */ | ||
1089 | c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */ | ||
1090 | c->operand[6] = 0; /* more/last */ | ||
1091 | c->operand[7] = 0; /* length */ | ||
1092 | |||
1093 | c->length = 12; | ||
1094 | |||
1095 | if (avc_write(fdtv, c, r) < 0) | ||
1096 | return -EIO; | ||
1097 | |||
1098 | /* FIXME: check response code and validate response data */ | ||
1099 | |||
1100 | *interval = r->operand[get_ca_object_pos(r)]; | ||
1101 | |||
1102 | return 0; | ||
1103 | } | ||
1104 | |||
1105 | int avc_ca_enter_menu(struct firedtv *fdtv) | ||
1106 | { | ||
1107 | char buffer[sizeof(struct avc_command_frame)]; | ||
1108 | struct avc_command_frame *c = (void *)buffer; | ||
1109 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
1110 | |||
1111 | memset(c, 0, sizeof(*c)); | ||
1112 | |||
1113 | c->ctype = AVC_CTYPE_STATUS; | ||
1114 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
1115 | c->opcode = AVC_OPCODE_VENDOR; | ||
1116 | |||
1117 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
1118 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
1119 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
1120 | c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; | ||
1121 | c->operand[4] = 0; /* slot */ | ||
1122 | c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; | ||
1123 | c->operand[6] = 0; /* more/last */ | ||
1124 | c->operand[7] = 0; /* length */ | ||
1125 | |||
1126 | c->length = 12; | ||
1127 | |||
1128 | if (avc_write(fdtv, c, r) < 0) | ||
1129 | return -EIO; | ||
1130 | |||
1131 | return 0; | ||
1132 | } | ||
1133 | |||
1134 | int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) | ||
1135 | { | ||
1136 | char buffer[sizeof(struct avc_command_frame)]; | ||
1137 | struct avc_command_frame *c = (void *)buffer; | ||
1138 | struct avc_response_frame *r = (void *)buffer; | ||
1139 | |||
1140 | memset(c, 0, sizeof(*c)); | ||
1141 | |||
1142 | c->ctype = AVC_CTYPE_STATUS; | ||
1143 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | ||
1144 | c->opcode = AVC_OPCODE_VENDOR; | ||
1145 | |||
1146 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | ||
1147 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | ||
1148 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | ||
1149 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; | ||
1150 | c->operand[4] = 0; /* slot */ | ||
1151 | c->operand[5] = SFE_VENDOR_TAG_CA_MMI; | ||
1152 | c->operand[6] = 0; /* more/last */ | ||
1153 | c->operand[7] = 0; /* length */ | ||
1154 | |||
1155 | c->length = 12; | ||
1156 | |||
1157 | if (avc_write(fdtv, c, r) < 0) | ||
1158 | return -EIO; | ||
1159 | |||
1160 | /* FIXME: check response code and validate response data */ | ||
1161 | |||
1162 | *len = get_ca_object_length(r); | ||
1163 | memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len); | ||
1164 | |||
1165 | return 0; | ||
1166 | } | ||
1167 | |||
1168 | #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL | ||
1169 | |||
1170 | static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) | ||
1171 | { | ||
1172 | int ret; | ||
1173 | |||
1174 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
1175 | return -EINTR; | ||
1176 | |||
1177 | ret = fdtv->backend->read(fdtv, addr, buf, len); | ||
1178 | if (ret < 0) | ||
1179 | dev_err(fdtv->device, "CMP: read I/O error\n"); | ||
1180 | |||
1181 | mutex_unlock(&fdtv->avc_mutex); | ||
1182 | return ret; | ||
1183 | } | ||
1184 | |||
1185 | static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg) | ||
1186 | { | ||
1187 | int ret; | ||
1188 | |||
1189 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
1190 | return -EINTR; | ||
1191 | |||
1192 | ret = fdtv->backend->lock(fdtv, addr, data, arg); | ||
1193 | if (ret < 0) | ||
1194 | dev_err(fdtv->device, "CMP: lock I/O error\n"); | ||
1195 | |||
1196 | mutex_unlock(&fdtv->avc_mutex); | ||
1197 | return ret; | ||
1198 | } | ||
1199 | |||
1200 | static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift) | ||
1201 | { | ||
1202 | return (be32_to_cpu(opcr) >> shift) & mask; | ||
1203 | } | ||
1204 | |||
1205 | static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) | ||
1206 | { | ||
1207 | *opcr &= ~cpu_to_be32(mask << shift); | ||
1208 | *opcr |= cpu_to_be32((value & mask) << shift); | ||
1209 | } | ||
1210 | |||
1211 | #define get_opcr_online(v) get_opcr((v), 0x1, 31) | ||
1212 | #define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24) | ||
1213 | #define get_opcr_channel(v) get_opcr((v), 0x3f, 16) | ||
1214 | |||
1215 | #define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24) | ||
1216 | #define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16) | ||
1217 | #define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14) | ||
1218 | #define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10) | ||
1219 | |||
1220 | int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) | ||
1221 | { | ||
1222 | __be32 old_opcr, opcr; | ||
1223 | u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); | ||
1224 | int attempts = 0; | ||
1225 | int ret; | ||
1226 | |||
1227 | ret = cmp_read(fdtv, &opcr, opcr_address, 4); | ||
1228 | if (ret < 0) | ||
1229 | return ret; | ||
1230 | |||
1231 | repeat: | ||
1232 | if (!get_opcr_online(opcr)) { | ||
1233 | dev_err(fdtv->device, "CMP: output offline\n"); | ||
1234 | return -EBUSY; | ||
1235 | } | ||
1236 | |||
1237 | old_opcr = opcr; | ||
1238 | |||
1239 | if (get_opcr_p2p_connections(opcr)) { | ||
1240 | if (get_opcr_channel(opcr) != channel) { | ||
1241 | dev_err(fdtv->device, "CMP: cannot change channel\n"); | ||
1242 | return -EBUSY; | ||
1243 | } | ||
1244 | dev_info(fdtv->device, "CMP: overlaying connection\n"); | ||
1245 | |||
1246 | /* We don't allocate isochronous resources. */ | ||
1247 | } else { | ||
1248 | set_opcr_channel(&opcr, channel); | ||
1249 | set_opcr_data_rate(&opcr, 2); /* S400 */ | ||
1250 | |||
1251 | /* FIXME: this is for the worst case - optimize */ | ||
1252 | set_opcr_overhead_id(&opcr, 0); | ||
1253 | |||
1254 | /* | ||
1255 | * FIXME: allocate isochronous channel and bandwidth at IRM | ||
1256 | * fdtv->backend->alloc_resources(fdtv, channels_mask, bw); | ||
1257 | */ | ||
1258 | } | ||
1259 | |||
1260 | set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); | ||
1261 | |||
1262 | ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr); | ||
1263 | if (ret < 0) | ||
1264 | return ret; | ||
1265 | |||
1266 | if (old_opcr != opcr) { | ||
1267 | /* | ||
1268 | * FIXME: if old_opcr.P2P_Connections > 0, | ||
1269 | * deallocate isochronous channel and bandwidth at IRM | ||
1270 | * if (...) | ||
1271 | * fdtv->backend->dealloc_resources(fdtv, channel, bw); | ||
1272 | */ | ||
1273 | |||
1274 | if (++attempts < 6) /* arbitrary limit */ | ||
1275 | goto repeat; | ||
1276 | return -EBUSY; | ||
1277 | } | ||
1278 | |||
1279 | return 0; | ||
1280 | } | ||
1281 | |||
1282 | void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) | ||
1283 | { | ||
1284 | __be32 old_opcr, opcr; | ||
1285 | u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); | ||
1286 | int attempts = 0; | ||
1287 | |||
1288 | if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) | ||
1289 | return; | ||
1290 | |||
1291 | repeat: | ||
1292 | if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || | ||
1293 | get_opcr_channel(opcr) != channel) { | ||
1294 | dev_err(fdtv->device, "CMP: no connection to break\n"); | ||
1295 | return; | ||
1296 | } | ||
1297 | |||
1298 | old_opcr = opcr; | ||
1299 | set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); | ||
1300 | |||
1301 | if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0) | ||
1302 | return; | ||
1303 | |||
1304 | if (old_opcr != opcr) { | ||
1305 | /* | ||
1306 | * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last | ||
1307 | * owner, deallocate isochronous channel and bandwidth at IRM | ||
1308 | * if (...) | ||
1309 | * fdtv->backend->dealloc_resources(fdtv, channel, bw); | ||
1310 | */ | ||
1311 | |||
1312 | if (++attempts < 6) /* arbitrary limit */ | ||
1313 | goto repeat; | ||
1314 | } | ||
1315 | } | ||
diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c new file mode 100644 index 000000000000..eeb80d0ea3ff --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-ci.c | |||
@@ -0,0 +1,260 @@ | |||
1 | /* | ||
2 | * FireDTV driver (formerly known as FireSAT) | ||
3 | * | ||
4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | ||
5 | * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation; either version 2 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/device.h> | ||
14 | #include <linux/dvb/ca.h> | ||
15 | #include <linux/fs.h> | ||
16 | #include <linux/module.h> | ||
17 | |||
18 | #include <dvbdev.h> | ||
19 | |||
20 | #include "firedtv.h" | ||
21 | |||
22 | #define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020 | ||
23 | #define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030 | ||
24 | #define EN50221_TAG_CA_PMT 0x9f8032 | ||
25 | #define EN50221_TAG_ENTER_MENU 0x9f8022 | ||
26 | |||
27 | static int fdtv_ca_ready(struct firedtv_tuner_status *stat) | ||
28 | { | ||
29 | return stat->ca_initialization_status == 1 && | ||
30 | stat->ca_error_flag == 0 && | ||
31 | stat->ca_dvb_flag == 1 && | ||
32 | stat->ca_module_present_status == 1; | ||
33 | } | ||
34 | |||
35 | static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat) | ||
36 | { | ||
37 | int flags = 0; | ||
38 | |||
39 | if (stat->ca_module_present_status == 1) | ||
40 | flags |= CA_CI_MODULE_PRESENT; | ||
41 | if (stat->ca_initialization_status == 1 && | ||
42 | stat->ca_error_flag == 0 && | ||
43 | stat->ca_dvb_flag == 1) | ||
44 | flags |= CA_CI_MODULE_READY; | ||
45 | return flags; | ||
46 | } | ||
47 | |||
48 | static int fdtv_ca_reset(struct firedtv *fdtv) | ||
49 | { | ||
50 | return avc_ca_reset(fdtv) ? -EFAULT : 0; | ||
51 | } | ||
52 | |||
53 | static int fdtv_ca_get_caps(void *arg) | ||
54 | { | ||
55 | struct ca_caps *cap = arg; | ||
56 | |||
57 | cap->slot_num = 1; | ||
58 | cap->slot_type = CA_CI; | ||
59 | cap->descr_num = 1; | ||
60 | cap->descr_type = CA_ECD; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg) | ||
65 | { | ||
66 | struct firedtv_tuner_status stat; | ||
67 | struct ca_slot_info *slot = arg; | ||
68 | |||
69 | if (avc_tuner_status(fdtv, &stat)) | ||
70 | return -EFAULT; | ||
71 | |||
72 | if (slot->num != 0) | ||
73 | return -EFAULT; | ||
74 | |||
75 | slot->type = CA_CI; | ||
76 | slot->flags = fdtv_get_ca_flags(&stat); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg) | ||
81 | { | ||
82 | struct ca_msg *reply = arg; | ||
83 | |||
84 | return avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; | ||
85 | } | ||
86 | |||
87 | static int fdtv_ca_info(struct firedtv *fdtv, void *arg) | ||
88 | { | ||
89 | struct ca_msg *reply = arg; | ||
90 | |||
91 | return avc_ca_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; | ||
92 | } | ||
93 | |||
94 | static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg) | ||
95 | { | ||
96 | struct ca_msg *reply = arg; | ||
97 | |||
98 | return avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; | ||
99 | } | ||
100 | |||
101 | static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg) | ||
102 | { | ||
103 | struct firedtv_tuner_status stat; | ||
104 | int err; | ||
105 | |||
106 | switch (fdtv->ca_last_command) { | ||
107 | case EN50221_TAG_APP_INFO_ENQUIRY: | ||
108 | err = fdtv_ca_app_info(fdtv, arg); | ||
109 | break; | ||
110 | case EN50221_TAG_CA_INFO_ENQUIRY: | ||
111 | err = fdtv_ca_info(fdtv, arg); | ||
112 | break; | ||
113 | default: | ||
114 | if (avc_tuner_status(fdtv, &stat)) | ||
115 | err = -EFAULT; | ||
116 | else if (stat.ca_mmi == 1) | ||
117 | err = fdtv_ca_get_mmi(fdtv, arg); | ||
118 | else { | ||
119 | dev_info(fdtv->device, "unhandled CA message 0x%08x\n", | ||
120 | fdtv->ca_last_command); | ||
121 | err = -EFAULT; | ||
122 | } | ||
123 | } | ||
124 | fdtv->ca_last_command = 0; | ||
125 | return err; | ||
126 | } | ||
127 | |||
128 | static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg) | ||
129 | { | ||
130 | struct ca_msg *msg = arg; | ||
131 | int data_pos; | ||
132 | int data_length; | ||
133 | int i; | ||
134 | |||
135 | data_pos = 4; | ||
136 | if (msg->msg[3] & 0x80) { | ||
137 | data_length = 0; | ||
138 | for (i = 0; i < (msg->msg[3] & 0x7f); i++) | ||
139 | data_length = (data_length << 8) + msg->msg[data_pos++]; | ||
140 | } else { | ||
141 | data_length = msg->msg[3]; | ||
142 | } | ||
143 | |||
144 | return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? -EFAULT : 0; | ||
145 | } | ||
146 | |||
147 | static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) | ||
148 | { | ||
149 | struct ca_msg *msg = arg; | ||
150 | int err; | ||
151 | |||
152 | /* Do we need a semaphore for this? */ | ||
153 | fdtv->ca_last_command = | ||
154 | (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2]; | ||
155 | switch (fdtv->ca_last_command) { | ||
156 | case EN50221_TAG_CA_PMT: | ||
157 | err = fdtv_ca_pmt(fdtv, arg); | ||
158 | break; | ||
159 | case EN50221_TAG_APP_INFO_ENQUIRY: | ||
160 | /* handled in ca_get_msg */ | ||
161 | err = 0; | ||
162 | break; | ||
163 | case EN50221_TAG_CA_INFO_ENQUIRY: | ||
164 | /* handled in ca_get_msg */ | ||
165 | err = 0; | ||
166 | break; | ||
167 | case EN50221_TAG_ENTER_MENU: | ||
168 | err = avc_ca_enter_menu(fdtv); | ||
169 | break; | ||
170 | default: | ||
171 | dev_err(fdtv->device, "unhandled CA message 0x%08x\n", | ||
172 | fdtv->ca_last_command); | ||
173 | err = -EFAULT; | ||
174 | } | ||
175 | return err; | ||
176 | } | ||
177 | |||
178 | static int fdtv_ca_ioctl(struct inode *inode, struct file *file, | ||
179 | unsigned int cmd, void *arg) | ||
180 | { | ||
181 | struct dvb_device *dvbdev = file->private_data; | ||
182 | struct firedtv *fdtv = dvbdev->priv; | ||
183 | struct firedtv_tuner_status stat; | ||
184 | int err; | ||
185 | |||
186 | switch (cmd) { | ||
187 | case CA_RESET: | ||
188 | err = fdtv_ca_reset(fdtv); | ||
189 | break; | ||
190 | case CA_GET_CAP: | ||
191 | err = fdtv_ca_get_caps(arg); | ||
192 | break; | ||
193 | case CA_GET_SLOT_INFO: | ||
194 | err = fdtv_ca_get_slot_info(fdtv, arg); | ||
195 | break; | ||
196 | case CA_GET_MSG: | ||
197 | err = fdtv_ca_get_msg(fdtv, arg); | ||
198 | break; | ||
199 | case CA_SEND_MSG: | ||
200 | err = fdtv_ca_send_msg(fdtv, arg); | ||
201 | break; | ||
202 | default: | ||
203 | dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd); | ||
204 | err = -EOPNOTSUPP; | ||
205 | } | ||
206 | |||
207 | /* FIXME Is this necessary? */ | ||
208 | avc_tuner_status(fdtv, &stat); | ||
209 | |||
210 | return err; | ||
211 | } | ||
212 | |||
213 | static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait) | ||
214 | { | ||
215 | return POLLIN; | ||
216 | } | ||
217 | |||
218 | static struct file_operations fdtv_ca_fops = { | ||
219 | .owner = THIS_MODULE, | ||
220 | .ioctl = dvb_generic_ioctl, | ||
221 | .open = dvb_generic_open, | ||
222 | .release = dvb_generic_release, | ||
223 | .poll = fdtv_ca_io_poll, | ||
224 | }; | ||
225 | |||
226 | static struct dvb_device fdtv_ca = { | ||
227 | .users = 1, | ||
228 | .readers = 1, | ||
229 | .writers = 1, | ||
230 | .fops = &fdtv_ca_fops, | ||
231 | .kernel_ioctl = fdtv_ca_ioctl, | ||
232 | }; | ||
233 | |||
234 | int fdtv_ca_register(struct firedtv *fdtv) | ||
235 | { | ||
236 | struct firedtv_tuner_status stat; | ||
237 | int err; | ||
238 | |||
239 | if (avc_tuner_status(fdtv, &stat)) | ||
240 | return -EINVAL; | ||
241 | |||
242 | if (!fdtv_ca_ready(&stat)) | ||
243 | return -EFAULT; | ||
244 | |||
245 | err = dvb_register_device(&fdtv->adapter, &fdtv->cadev, | ||
246 | &fdtv_ca, fdtv, DVB_DEVICE_CA); | ||
247 | |||
248 | if (stat.ca_application_info == 0) | ||
249 | dev_err(fdtv->device, "CaApplicationInfo is not set\n"); | ||
250 | if (stat.ca_date_time_request == 1) | ||
251 | avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval); | ||
252 | |||
253 | return err; | ||
254 | } | ||
255 | |||
256 | void fdtv_ca_release(struct firedtv *fdtv) | ||
257 | { | ||
258 | if (fdtv->cadev) | ||
259 | dvb_unregister_device(fdtv->cadev); | ||
260 | } | ||
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c new file mode 100644 index 000000000000..9d308dd32a5c --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-dvb.c | |||
@@ -0,0 +1,364 @@ | |||
1 | /* | ||
2 | * FireDTV driver (formerly known as FireSAT) | ||
3 | * | ||
4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | ||
5 | * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation; either version 2 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/bitops.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/mod_devicetable.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/mutex.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/string.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/wait.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | |||
26 | #include <dmxdev.h> | ||
27 | #include <dvb_demux.h> | ||
28 | #include <dvbdev.h> | ||
29 | #include <dvb_frontend.h> | ||
30 | |||
31 | #include "firedtv.h" | ||
32 | |||
33 | static int alloc_channel(struct firedtv *fdtv) | ||
34 | { | ||
35 | int i; | ||
36 | |||
37 | for (i = 0; i < 16; i++) | ||
38 | if (!__test_and_set_bit(i, &fdtv->channel_active)) | ||
39 | break; | ||
40 | return i; | ||
41 | } | ||
42 | |||
43 | static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[]) | ||
44 | { | ||
45 | int i, n; | ||
46 | |||
47 | for (i = 0, n = 0; i < 16; i++) | ||
48 | if (test_bit(i, &fdtv->channel_active)) | ||
49 | pid[n++] = fdtv->channel_pid[i]; | ||
50 | *pidc = n; | ||
51 | } | ||
52 | |||
53 | static inline void dealloc_channel(struct firedtv *fdtv, int i) | ||
54 | { | ||
55 | __clear_bit(i, &fdtv->channel_active); | ||
56 | } | ||
57 | |||
58 | int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
59 | { | ||
60 | struct firedtv *fdtv = dvbdmxfeed->demux->priv; | ||
61 | int pidc, c, ret; | ||
62 | u16 pids[16]; | ||
63 | |||
64 | switch (dvbdmxfeed->type) { | ||
65 | case DMX_TYPE_TS: | ||
66 | case DMX_TYPE_SEC: | ||
67 | break; | ||
68 | default: | ||
69 | dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n", | ||
70 | dvbdmxfeed->type); | ||
71 | return -EINVAL; | ||
72 | } | ||
73 | |||
74 | if (mutex_lock_interruptible(&fdtv->demux_mutex)) | ||
75 | return -EINTR; | ||
76 | |||
77 | if (dvbdmxfeed->type == DMX_TYPE_TS) { | ||
78 | switch (dvbdmxfeed->pes_type) { | ||
79 | case DMX_TS_PES_VIDEO: | ||
80 | case DMX_TS_PES_AUDIO: | ||
81 | case DMX_TS_PES_TELETEXT: | ||
82 | case DMX_TS_PES_PCR: | ||
83 | case DMX_TS_PES_OTHER: | ||
84 | c = alloc_channel(fdtv); | ||
85 | break; | ||
86 | default: | ||
87 | dev_err(fdtv->device, | ||
88 | "can't start dmx feed: invalid pes type %u\n", | ||
89 | dvbdmxfeed->pes_type); | ||
90 | ret = -EINVAL; | ||
91 | goto out; | ||
92 | } | ||
93 | } else { | ||
94 | c = alloc_channel(fdtv); | ||
95 | } | ||
96 | |||
97 | if (c > 15) { | ||
98 | dev_err(fdtv->device, "can't start dmx feed: busy\n"); | ||
99 | ret = -EBUSY; | ||
100 | goto out; | ||
101 | } | ||
102 | |||
103 | dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c; | ||
104 | fdtv->channel_pid[c] = dvbdmxfeed->pid; | ||
105 | collect_channels(fdtv, &pidc, pids); | ||
106 | |||
107 | if (dvbdmxfeed->pid == 8192) { | ||
108 | ret = avc_tuner_get_ts(fdtv); | ||
109 | if (ret) { | ||
110 | dealloc_channel(fdtv, c); | ||
111 | dev_err(fdtv->device, "can't get TS\n"); | ||
112 | goto out; | ||
113 | } | ||
114 | } else { | ||
115 | ret = avc_tuner_set_pids(fdtv, pidc, pids); | ||
116 | if (ret) { | ||
117 | dealloc_channel(fdtv, c); | ||
118 | dev_err(fdtv->device, "can't set PIDs\n"); | ||
119 | goto out; | ||
120 | } | ||
121 | } | ||
122 | out: | ||
123 | mutex_unlock(&fdtv->demux_mutex); | ||
124 | |||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
129 | { | ||
130 | struct dvb_demux *demux = dvbdmxfeed->demux; | ||
131 | struct firedtv *fdtv = demux->priv; | ||
132 | int pidc, c, ret; | ||
133 | u16 pids[16]; | ||
134 | |||
135 | if (dvbdmxfeed->type == DMX_TYPE_TS && | ||
136 | !((dvbdmxfeed->ts_type & TS_PACKET) && | ||
137 | (demux->dmx.frontend->source != DMX_MEMORY_FE))) { | ||
138 | |||
139 | if (dvbdmxfeed->ts_type & TS_DECODER) { | ||
140 | if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER || | ||
141 | !demux->pesfilter[dvbdmxfeed->pes_type]) | ||
142 | return -EINVAL; | ||
143 | |||
144 | demux->pids[dvbdmxfeed->pes_type] |= 0x8000; | ||
145 | demux->pesfilter[dvbdmxfeed->pes_type] = NULL; | ||
146 | } | ||
147 | |||
148 | if (!(dvbdmxfeed->ts_type & TS_DECODER && | ||
149 | dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | if (mutex_lock_interruptible(&fdtv->demux_mutex)) | ||
154 | return -EINTR; | ||
155 | |||
156 | c = (unsigned long)dvbdmxfeed->priv; | ||
157 | dealloc_channel(fdtv, c); | ||
158 | collect_channels(fdtv, &pidc, pids); | ||
159 | |||
160 | ret = avc_tuner_set_pids(fdtv, pidc, pids); | ||
161 | |||
162 | mutex_unlock(&fdtv->demux_mutex); | ||
163 | |||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
168 | |||
169 | int fdtv_dvb_register(struct firedtv *fdtv) | ||
170 | { | ||
171 | int err; | ||
172 | |||
173 | err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type], | ||
174 | THIS_MODULE, fdtv->device, adapter_nr); | ||
175 | if (err < 0) | ||
176 | goto fail_log; | ||
177 | |||
178 | /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/ | ||
179 | fdtv->demux.dmx.capabilities = 0; | ||
180 | |||
181 | fdtv->demux.priv = fdtv; | ||
182 | fdtv->demux.filternum = 16; | ||
183 | fdtv->demux.feednum = 16; | ||
184 | fdtv->demux.start_feed = fdtv_start_feed; | ||
185 | fdtv->demux.stop_feed = fdtv_stop_feed; | ||
186 | fdtv->demux.write_to_decoder = NULL; | ||
187 | |||
188 | err = dvb_dmx_init(&fdtv->demux); | ||
189 | if (err) | ||
190 | goto fail_unreg_adapter; | ||
191 | |||
192 | fdtv->dmxdev.filternum = 16; | ||
193 | fdtv->dmxdev.demux = &fdtv->demux.dmx; | ||
194 | fdtv->dmxdev.capabilities = 0; | ||
195 | |||
196 | err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter); | ||
197 | if (err) | ||
198 | goto fail_dmx_release; | ||
199 | |||
200 | fdtv->frontend.source = DMX_FRONTEND_0; | ||
201 | |||
202 | err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend); | ||
203 | if (err) | ||
204 | goto fail_dmxdev_release; | ||
205 | |||
206 | err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx, | ||
207 | &fdtv->frontend); | ||
208 | if (err) | ||
209 | goto fail_rem_frontend; | ||
210 | |||
211 | dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); | ||
212 | |||
213 | fdtv_frontend_init(fdtv); | ||
214 | err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe); | ||
215 | if (err) | ||
216 | goto fail_net_release; | ||
217 | |||
218 | err = fdtv_ca_register(fdtv); | ||
219 | if (err) | ||
220 | dev_info(fdtv->device, | ||
221 | "Conditional Access Module not enabled\n"); | ||
222 | return 0; | ||
223 | |||
224 | fail_net_release: | ||
225 | dvb_net_release(&fdtv->dvbnet); | ||
226 | fdtv->demux.dmx.close(&fdtv->demux.dmx); | ||
227 | fail_rem_frontend: | ||
228 | fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend); | ||
229 | fail_dmxdev_release: | ||
230 | dvb_dmxdev_release(&fdtv->dmxdev); | ||
231 | fail_dmx_release: | ||
232 | dvb_dmx_release(&fdtv->demux); | ||
233 | fail_unreg_adapter: | ||
234 | dvb_unregister_adapter(&fdtv->adapter); | ||
235 | fail_log: | ||
236 | dev_err(fdtv->device, "DVB initialization failed\n"); | ||
237 | return err; | ||
238 | } | ||
239 | |||
240 | void fdtv_dvb_unregister(struct firedtv *fdtv) | ||
241 | { | ||
242 | fdtv_ca_release(fdtv); | ||
243 | dvb_unregister_frontend(&fdtv->fe); | ||
244 | dvb_net_release(&fdtv->dvbnet); | ||
245 | fdtv->demux.dmx.close(&fdtv->demux.dmx); | ||
246 | fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend); | ||
247 | dvb_dmxdev_release(&fdtv->dmxdev); | ||
248 | dvb_dmx_release(&fdtv->demux); | ||
249 | dvb_unregister_adapter(&fdtv->adapter); | ||
250 | } | ||
251 | |||
252 | const char *fdtv_model_names[] = { | ||
253 | [FIREDTV_UNKNOWN] = "unknown type", | ||
254 | [FIREDTV_DVB_S] = "FireDTV S/CI", | ||
255 | [FIREDTV_DVB_C] = "FireDTV C/CI", | ||
256 | [FIREDTV_DVB_T] = "FireDTV T/CI", | ||
257 | [FIREDTV_DVB_S2] = "FireDTV S2 ", | ||
258 | }; | ||
259 | |||
260 | struct firedtv *fdtv_alloc(struct device *dev, | ||
261 | const struct firedtv_backend *backend, | ||
262 | const char *name, size_t name_len) | ||
263 | { | ||
264 | struct firedtv *fdtv; | ||
265 | int i; | ||
266 | |||
267 | fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); | ||
268 | if (!fdtv) | ||
269 | return NULL; | ||
270 | |||
271 | dev->driver_data = fdtv; | ||
272 | fdtv->device = dev; | ||
273 | fdtv->isochannel = -1; | ||
274 | fdtv->voltage = 0xff; | ||
275 | fdtv->tone = 0xff; | ||
276 | fdtv->backend = backend; | ||
277 | |||
278 | mutex_init(&fdtv->avc_mutex); | ||
279 | init_waitqueue_head(&fdtv->avc_wait); | ||
280 | fdtv->avc_reply_received = true; | ||
281 | mutex_init(&fdtv->demux_mutex); | ||
282 | INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); | ||
283 | |||
284 | for (i = ARRAY_SIZE(fdtv_model_names); --i; ) | ||
285 | if (strlen(fdtv_model_names[i]) <= name_len && | ||
286 | strncmp(name, fdtv_model_names[i], name_len) == 0) | ||
287 | break; | ||
288 | fdtv->type = i; | ||
289 | |||
290 | return fdtv; | ||
291 | } | ||
292 | |||
293 | #define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ | ||
294 | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION) | ||
295 | |||
296 | #define DIGITAL_EVERYWHERE_OUI 0x001287 | ||
297 | #define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d | ||
298 | #define AVC_SW_VERSION_ENTRY 0x010001 | ||
299 | |||
300 | static struct ieee1394_device_id fdtv_id_table[] = { | ||
301 | { | ||
302 | /* FloppyDTV S/CI and FloppyDTV S2 */ | ||
303 | .match_flags = MATCH_FLAGS, | ||
304 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
305 | .model_id = 0x000024, | ||
306 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
307 | .version = AVC_SW_VERSION_ENTRY, | ||
308 | }, { | ||
309 | /* FloppyDTV T/CI */ | ||
310 | .match_flags = MATCH_FLAGS, | ||
311 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
312 | .model_id = 0x000025, | ||
313 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
314 | .version = AVC_SW_VERSION_ENTRY, | ||
315 | }, { | ||
316 | /* FloppyDTV C/CI */ | ||
317 | .match_flags = MATCH_FLAGS, | ||
318 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
319 | .model_id = 0x000026, | ||
320 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
321 | .version = AVC_SW_VERSION_ENTRY, | ||
322 | }, { | ||
323 | /* FireDTV S/CI and FloppyDTV S2 */ | ||
324 | .match_flags = MATCH_FLAGS, | ||
325 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
326 | .model_id = 0x000034, | ||
327 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
328 | .version = AVC_SW_VERSION_ENTRY, | ||
329 | }, { | ||
330 | /* FireDTV T/CI */ | ||
331 | .match_flags = MATCH_FLAGS, | ||
332 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
333 | .model_id = 0x000035, | ||
334 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
335 | .version = AVC_SW_VERSION_ENTRY, | ||
336 | }, { | ||
337 | /* FireDTV C/CI */ | ||
338 | .match_flags = MATCH_FLAGS, | ||
339 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
340 | .model_id = 0x000036, | ||
341 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
342 | .version = AVC_SW_VERSION_ENTRY, | ||
343 | }, {} | ||
344 | }; | ||
345 | MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); | ||
346 | |||
347 | static int __init fdtv_init(void) | ||
348 | { | ||
349 | return fdtv_1394_init(fdtv_id_table); | ||
350 | } | ||
351 | |||
352 | static void __exit fdtv_exit(void) | ||
353 | { | ||
354 | fdtv_1394_exit(); | ||
355 | } | ||
356 | |||
357 | module_init(fdtv_init); | ||
358 | module_exit(fdtv_exit); | ||
359 | |||
360 | MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>"); | ||
361 | MODULE_AUTHOR("Ben Backx <ben@bbackx.com>"); | ||
362 | MODULE_DESCRIPTION("FireDTV DVB Driver"); | ||
363 | MODULE_LICENSE("GPL"); | ||
364 | MODULE_SUPPORTED_DEVICE("FireDTV DVB"); | ||
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c new file mode 100644 index 000000000000..7ba43630a25d --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-fe.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /* | ||
2 | * FireDTV driver (formerly known as FireSAT) | ||
3 | * | ||
4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | ||
5 | * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation; either version 2 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/device.h> | ||
14 | #include <linux/errno.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/types.h> | ||
18 | |||
19 | #include <dvb_frontend.h> | ||
20 | |||
21 | #include "firedtv.h" | ||
22 | |||
23 | static int fdtv_dvb_init(struct dvb_frontend *fe) | ||
24 | { | ||
25 | struct firedtv *fdtv = fe->sec_priv; | ||
26 | int err; | ||
27 | |||
28 | /* FIXME - allocate free channel at IRM */ | ||
29 | fdtv->isochannel = fdtv->adapter.num; | ||
30 | |||
31 | err = cmp_establish_pp_connection(fdtv, fdtv->subunit, | ||
32 | fdtv->isochannel); | ||
33 | if (err) { | ||
34 | dev_err(fdtv->device, | ||
35 | "could not establish point to point connection\n"); | ||
36 | return err; | ||
37 | } | ||
38 | |||
39 | return fdtv->backend->start_iso(fdtv); | ||
40 | } | ||
41 | |||
42 | static int fdtv_sleep(struct dvb_frontend *fe) | ||
43 | { | ||
44 | struct firedtv *fdtv = fe->sec_priv; | ||
45 | |||
46 | fdtv->backend->stop_iso(fdtv); | ||
47 | cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); | ||
48 | fdtv->isochannel = -1; | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | #define LNBCONTROL_DONTCARE 0xff | ||
53 | |||
54 | static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe, | ||
55 | struct dvb_diseqc_master_cmd *cmd) | ||
56 | { | ||
57 | struct firedtv *fdtv = fe->sec_priv; | ||
58 | |||
59 | return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, | ||
60 | LNBCONTROL_DONTCARE, 1, cmd); | ||
61 | } | ||
62 | |||
63 | static int fdtv_diseqc_send_burst(struct dvb_frontend *fe, | ||
64 | fe_sec_mini_cmd_t minicmd) | ||
65 | { | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | ||
70 | { | ||
71 | struct firedtv *fdtv = fe->sec_priv; | ||
72 | |||
73 | fdtv->tone = tone; | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int fdtv_set_voltage(struct dvb_frontend *fe, | ||
78 | fe_sec_voltage_t voltage) | ||
79 | { | ||
80 | struct firedtv *fdtv = fe->sec_priv; | ||
81 | |||
82 | fdtv->voltage = voltage; | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
87 | { | ||
88 | struct firedtv *fdtv = fe->sec_priv; | ||
89 | struct firedtv_tuner_status stat; | ||
90 | |||
91 | if (avc_tuner_status(fdtv, &stat)) | ||
92 | return -EINVAL; | ||
93 | |||
94 | if (stat.no_rf) | ||
95 | *status = 0; | ||
96 | else | ||
97 | *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | | ||
98 | FE_HAS_CARRIER | FE_HAS_LOCK; | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber) | ||
103 | { | ||
104 | struct firedtv *fdtv = fe->sec_priv; | ||
105 | struct firedtv_tuner_status stat; | ||
106 | |||
107 | if (avc_tuner_status(fdtv, &stat)) | ||
108 | return -EINVAL; | ||
109 | |||
110 | *ber = stat.ber; | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||
115 | { | ||
116 | struct firedtv *fdtv = fe->sec_priv; | ||
117 | struct firedtv_tuner_status stat; | ||
118 | |||
119 | if (avc_tuner_status(fdtv, &stat)) | ||
120 | return -EINVAL; | ||
121 | |||
122 | *strength = stat.signal_strength << 8; | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
127 | { | ||
128 | struct firedtv *fdtv = fe->sec_priv; | ||
129 | struct firedtv_tuner_status stat; | ||
130 | |||
131 | if (avc_tuner_status(fdtv, &stat)) | ||
132 | return -EINVAL; | ||
133 | |||
134 | /* C/N[dB] = -10 * log10(snr / 65535) */ | ||
135 | *snr = stat.carrier_noise_ratio * 257; | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
140 | { | ||
141 | return -EOPNOTSUPP; | ||
142 | } | ||
143 | |||
144 | #define ACCEPTED 0x9 | ||
145 | |||
146 | static int fdtv_set_frontend(struct dvb_frontend *fe, | ||
147 | struct dvb_frontend_parameters *params) | ||
148 | { | ||
149 | struct firedtv *fdtv = fe->sec_priv; | ||
150 | |||
151 | /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */ | ||
152 | if (avc_tuner_dsd(fdtv, params) != ACCEPTED) | ||
153 | return -EINVAL; | ||
154 | else | ||
155 | return 0; /* not sure of this... */ | ||
156 | } | ||
157 | |||
158 | static int fdtv_get_frontend(struct dvb_frontend *fe, | ||
159 | struct dvb_frontend_parameters *params) | ||
160 | { | ||
161 | return -EOPNOTSUPP; | ||
162 | } | ||
163 | |||
164 | void fdtv_frontend_init(struct firedtv *fdtv) | ||
165 | { | ||
166 | struct dvb_frontend_ops *ops = &fdtv->fe.ops; | ||
167 | struct dvb_frontend_info *fi = &ops->info; | ||
168 | |||
169 | ops->init = fdtv_dvb_init; | ||
170 | ops->sleep = fdtv_sleep; | ||
171 | |||
172 | ops->set_frontend = fdtv_set_frontend; | ||
173 | ops->get_frontend = fdtv_get_frontend; | ||
174 | |||
175 | ops->read_status = fdtv_read_status; | ||
176 | ops->read_ber = fdtv_read_ber; | ||
177 | ops->read_signal_strength = fdtv_read_signal_strength; | ||
178 | ops->read_snr = fdtv_read_snr; | ||
179 | ops->read_ucblocks = fdtv_read_uncorrected_blocks; | ||
180 | |||
181 | ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd; | ||
182 | ops->diseqc_send_burst = fdtv_diseqc_send_burst; | ||
183 | ops->set_tone = fdtv_set_tone; | ||
184 | ops->set_voltage = fdtv_set_voltage; | ||
185 | |||
186 | switch (fdtv->type) { | ||
187 | case FIREDTV_DVB_S: | ||
188 | case FIREDTV_DVB_S2: | ||
189 | fi->type = FE_QPSK; | ||
190 | |||
191 | fi->frequency_min = 950000; | ||
192 | fi->frequency_max = 2150000; | ||
193 | fi->frequency_stepsize = 125; | ||
194 | fi->symbol_rate_min = 1000000; | ||
195 | fi->symbol_rate_max = 40000000; | ||
196 | |||
197 | fi->caps = FE_CAN_INVERSION_AUTO | | ||
198 | FE_CAN_FEC_1_2 | | ||
199 | FE_CAN_FEC_2_3 | | ||
200 | FE_CAN_FEC_3_4 | | ||
201 | FE_CAN_FEC_5_6 | | ||
202 | FE_CAN_FEC_7_8 | | ||
203 | FE_CAN_FEC_AUTO | | ||
204 | FE_CAN_QPSK; | ||
205 | break; | ||
206 | |||
207 | case FIREDTV_DVB_C: | ||
208 | fi->type = FE_QAM; | ||
209 | |||
210 | fi->frequency_min = 47000000; | ||
211 | fi->frequency_max = 866000000; | ||
212 | fi->frequency_stepsize = 62500; | ||
213 | fi->symbol_rate_min = 870000; | ||
214 | fi->symbol_rate_max = 6900000; | ||
215 | |||
216 | fi->caps = FE_CAN_INVERSION_AUTO | | ||
217 | FE_CAN_QAM_16 | | ||
218 | FE_CAN_QAM_32 | | ||
219 | FE_CAN_QAM_64 | | ||
220 | FE_CAN_QAM_128 | | ||
221 | FE_CAN_QAM_256 | | ||
222 | FE_CAN_QAM_AUTO; | ||
223 | break; | ||
224 | |||
225 | case FIREDTV_DVB_T: | ||
226 | fi->type = FE_OFDM; | ||
227 | |||
228 | fi->frequency_min = 49000000; | ||
229 | fi->frequency_max = 861000000; | ||
230 | fi->frequency_stepsize = 62500; | ||
231 | |||
232 | fi->caps = FE_CAN_INVERSION_AUTO | | ||
233 | FE_CAN_FEC_2_3 | | ||
234 | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
235 | FE_CAN_GUARD_INTERVAL_AUTO | | ||
236 | FE_CAN_HIERARCHY_AUTO; | ||
237 | break; | ||
238 | |||
239 | default: | ||
240 | dev_err(fdtv->device, "no frontend for model type %d\n", | ||
241 | fdtv->type); | ||
242 | } | ||
243 | strcpy(fi->name, fdtv_model_names[fdtv->type]); | ||
244 | |||
245 | fdtv->fe.dvb = &fdtv->adapter; | ||
246 | fdtv->fe.sec_priv = fdtv; | ||
247 | } | ||
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c new file mode 100644 index 000000000000..46a6324d7b73 --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-rc.c | |||
@@ -0,0 +1,190 @@ | |||
1 | /* | ||
2 | * FireDTV driver (formerly known as FireSAT) | ||
3 | * | ||
4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation; either version 2 of | ||
9 | * the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/bitops.h> | ||
13 | #include <linux/input.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/types.h> | ||
17 | |||
18 | #include "firedtv.h" | ||
19 | |||
20 | /* fixed table with older keycodes, geared towards MythTV */ | ||
21 | const static u16 oldtable[] = { | ||
22 | |||
23 | /* code from device: 0x4501...0x451f */ | ||
24 | |||
25 | KEY_ESC, | ||
26 | KEY_F9, | ||
27 | KEY_1, | ||
28 | KEY_2, | ||
29 | KEY_3, | ||
30 | KEY_4, | ||
31 | KEY_5, | ||
32 | KEY_6, | ||
33 | KEY_7, | ||
34 | KEY_8, | ||
35 | KEY_9, | ||
36 | KEY_I, | ||
37 | KEY_0, | ||
38 | KEY_ENTER, | ||
39 | KEY_RED, | ||
40 | KEY_UP, | ||
41 | KEY_GREEN, | ||
42 | KEY_F10, | ||
43 | KEY_SPACE, | ||
44 | KEY_F11, | ||
45 | KEY_YELLOW, | ||
46 | KEY_DOWN, | ||
47 | KEY_BLUE, | ||
48 | KEY_Z, | ||
49 | KEY_P, | ||
50 | KEY_PAGEDOWN, | ||
51 | KEY_LEFT, | ||
52 | KEY_W, | ||
53 | KEY_RIGHT, | ||
54 | KEY_P, | ||
55 | KEY_M, | ||
56 | |||
57 | /* code from device: 0x4540...0x4542 */ | ||
58 | |||
59 | KEY_R, | ||
60 | KEY_V, | ||
61 | KEY_C, | ||
62 | }; | ||
63 | |||
64 | /* user-modifiable table for a remote as sold in 2008 */ | ||
65 | const static u16 keytable[] = { | ||
66 | |||
67 | /* code from device: 0x0300...0x031f */ | ||
68 | |||
69 | [0x00] = KEY_POWER, | ||
70 | [0x01] = KEY_SLEEP, | ||
71 | [0x02] = KEY_STOP, | ||
72 | [0x03] = KEY_OK, | ||
73 | [0x04] = KEY_RIGHT, | ||
74 | [0x05] = KEY_1, | ||
75 | [0x06] = KEY_2, | ||
76 | [0x07] = KEY_3, | ||
77 | [0x08] = KEY_LEFT, | ||
78 | [0x09] = KEY_4, | ||
79 | [0x0a] = KEY_5, | ||
80 | [0x0b] = KEY_6, | ||
81 | [0x0c] = KEY_UP, | ||
82 | [0x0d] = KEY_7, | ||
83 | [0x0e] = KEY_8, | ||
84 | [0x0f] = KEY_9, | ||
85 | [0x10] = KEY_DOWN, | ||
86 | [0x11] = KEY_TITLE, /* "OSD" - fixme */ | ||
87 | [0x12] = KEY_0, | ||
88 | [0x13] = KEY_F20, /* "16:9" - fixme */ | ||
89 | [0x14] = KEY_SCREEN, /* "FULL" - fixme */ | ||
90 | [0x15] = KEY_MUTE, | ||
91 | [0x16] = KEY_SUBTITLE, | ||
92 | [0x17] = KEY_RECORD, | ||
93 | [0x18] = KEY_TEXT, | ||
94 | [0x19] = KEY_AUDIO, | ||
95 | [0x1a] = KEY_RED, | ||
96 | [0x1b] = KEY_PREVIOUS, | ||
97 | [0x1c] = KEY_REWIND, | ||
98 | [0x1d] = KEY_PLAYPAUSE, | ||
99 | [0x1e] = KEY_NEXT, | ||
100 | [0x1f] = KEY_VOLUMEUP, | ||
101 | |||
102 | /* code from device: 0x0340...0x0354 */ | ||
103 | |||
104 | [0x20] = KEY_CHANNELUP, | ||
105 | [0x21] = KEY_F21, /* "4:3" - fixme */ | ||
106 | [0x22] = KEY_TV, | ||
107 | [0x23] = KEY_DVD, | ||
108 | [0x24] = KEY_VCR, | ||
109 | [0x25] = KEY_AUX, | ||
110 | [0x26] = KEY_GREEN, | ||
111 | [0x27] = KEY_YELLOW, | ||
112 | [0x28] = KEY_BLUE, | ||
113 | [0x29] = KEY_CHANNEL, /* "CH.LIST" */ | ||
114 | [0x2a] = KEY_VENDOR, /* "CI" - fixme */ | ||
115 | [0x2b] = KEY_VOLUMEDOWN, | ||
116 | [0x2c] = KEY_CHANNELDOWN, | ||
117 | [0x2d] = KEY_LAST, | ||
118 | [0x2e] = KEY_INFO, | ||
119 | [0x2f] = KEY_FORWARD, | ||
120 | [0x30] = KEY_LIST, | ||
121 | [0x31] = KEY_FAVORITES, | ||
122 | [0x32] = KEY_MENU, | ||
123 | [0x33] = KEY_EPG, | ||
124 | [0x34] = KEY_EXIT, | ||
125 | }; | ||
126 | |||
127 | int fdtv_register_rc(struct firedtv *fdtv, struct device *dev) | ||
128 | { | ||
129 | struct input_dev *idev; | ||
130 | int i, err; | ||
131 | |||
132 | idev = input_allocate_device(); | ||
133 | if (!idev) | ||
134 | return -ENOMEM; | ||
135 | |||
136 | fdtv->remote_ctrl_dev = idev; | ||
137 | idev->name = "FireDTV remote control"; | ||
138 | idev->dev.parent = dev; | ||
139 | idev->evbit[0] = BIT_MASK(EV_KEY); | ||
140 | idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL); | ||
141 | if (!idev->keycode) { | ||
142 | err = -ENOMEM; | ||
143 | goto fail; | ||
144 | } | ||
145 | idev->keycodesize = sizeof(keytable[0]); | ||
146 | idev->keycodemax = ARRAY_SIZE(keytable); | ||
147 | |||
148 | for (i = 0; i < ARRAY_SIZE(keytable); i++) | ||
149 | set_bit(keytable[i], idev->keybit); | ||
150 | |||
151 | err = input_register_device(idev); | ||
152 | if (err) | ||
153 | goto fail_free_keymap; | ||
154 | |||
155 | return 0; | ||
156 | |||
157 | fail_free_keymap: | ||
158 | kfree(idev->keycode); | ||
159 | fail: | ||
160 | input_free_device(idev); | ||
161 | return err; | ||
162 | } | ||
163 | |||
164 | void fdtv_unregister_rc(struct firedtv *fdtv) | ||
165 | { | ||
166 | kfree(fdtv->remote_ctrl_dev->keycode); | ||
167 | input_unregister_device(fdtv->remote_ctrl_dev); | ||
168 | } | ||
169 | |||
170 | void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) | ||
171 | { | ||
172 | u16 *keycode = fdtv->remote_ctrl_dev->keycode; | ||
173 | |||
174 | if (code >= 0x0300 && code <= 0x031f) | ||
175 | code = keycode[code - 0x0300]; | ||
176 | else if (code >= 0x0340 && code <= 0x0354) | ||
177 | code = keycode[code - 0x0320]; | ||
178 | else if (code >= 0x4501 && code <= 0x451f) | ||
179 | code = oldtable[code - 0x4501]; | ||
180 | else if (code >= 0x4540 && code <= 0x4542) | ||
181 | code = oldtable[code - 0x4521]; | ||
182 | else { | ||
183 | printk(KERN_DEBUG "firedtv: invalid key code 0x%04x " | ||
184 | "from remote control\n", code); | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | input_report_key(fdtv->remote_ctrl_dev, code, 1); | ||
189 | input_report_key(fdtv->remote_ctrl_dev, code, 0); | ||
190 | } | ||
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h new file mode 100644 index 000000000000..d48530b81e61 --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv.h | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * FireDTV driver (formerly known as FireSAT) | ||
3 | * | ||
4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | ||
5 | * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation; either version 2 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef _FIREDTV_H | ||
14 | #define _FIREDTV_H | ||
15 | |||
16 | #include <linux/dvb/dmx.h> | ||
17 | #include <linux/dvb/frontend.h> | ||
18 | #include <linux/list.h> | ||
19 | #include <linux/mutex.h> | ||
20 | #include <linux/spinlock_types.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/wait.h> | ||
23 | #include <linux/workqueue.h> | ||
24 | |||
25 | #include <demux.h> | ||
26 | #include <dmxdev.h> | ||
27 | #include <dvb_demux.h> | ||
28 | #include <dvb_frontend.h> | ||
29 | #include <dvb_net.h> | ||
30 | #include <dvbdev.h> | ||
31 | |||
32 | struct firedtv_tuner_status { | ||
33 | unsigned active_system:8; | ||
34 | unsigned searching:1; | ||
35 | unsigned moving:1; | ||
36 | unsigned no_rf:1; | ||
37 | unsigned input:1; | ||
38 | unsigned selected_antenna:7; | ||
39 | unsigned ber:32; | ||
40 | unsigned signal_strength:8; | ||
41 | unsigned raster_frequency:2; | ||
42 | unsigned rf_frequency:22; | ||
43 | unsigned man_dep_info_length:8; | ||
44 | unsigned front_end_error:1; | ||
45 | unsigned antenna_error:1; | ||
46 | unsigned front_end_power_status:1; | ||
47 | unsigned power_supply:1; | ||
48 | unsigned carrier_noise_ratio:16; | ||
49 | unsigned power_supply_voltage:8; | ||
50 | unsigned antenna_voltage:8; | ||
51 | unsigned firewire_bus_voltage:8; | ||
52 | unsigned ca_mmi:1; | ||
53 | unsigned ca_pmt_reply:1; | ||
54 | unsigned ca_date_time_request:1; | ||
55 | unsigned ca_application_info:1; | ||
56 | unsigned ca_module_present_status:1; | ||
57 | unsigned ca_dvb_flag:1; | ||
58 | unsigned ca_error_flag:1; | ||
59 | unsigned ca_initialization_status:1; | ||
60 | }; | ||
61 | |||
62 | enum model_type { | ||
63 | FIREDTV_UNKNOWN = 0, | ||
64 | FIREDTV_DVB_S = 1, | ||
65 | FIREDTV_DVB_C = 2, | ||
66 | FIREDTV_DVB_T = 3, | ||
67 | FIREDTV_DVB_S2 = 4, | ||
68 | }; | ||
69 | |||
70 | struct device; | ||
71 | struct input_dev; | ||
72 | struct firedtv; | ||
73 | |||
74 | struct firedtv_backend { | ||
75 | int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg); | ||
76 | int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len); | ||
77 | int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); | ||
78 | int (*start_iso)(struct firedtv *fdtv); | ||
79 | void (*stop_iso)(struct firedtv *fdtv); | ||
80 | }; | ||
81 | |||
82 | struct firedtv { | ||
83 | struct device *device; | ||
84 | struct list_head list; | ||
85 | |||
86 | struct dvb_adapter adapter; | ||
87 | struct dmxdev dmxdev; | ||
88 | struct dvb_demux demux; | ||
89 | struct dmx_frontend frontend; | ||
90 | struct dvb_net dvbnet; | ||
91 | struct dvb_frontend fe; | ||
92 | |||
93 | struct dvb_device *cadev; | ||
94 | int ca_last_command; | ||
95 | int ca_time_interval; | ||
96 | |||
97 | struct mutex avc_mutex; | ||
98 | wait_queue_head_t avc_wait; | ||
99 | bool avc_reply_received; | ||
100 | struct work_struct remote_ctrl_work; | ||
101 | struct input_dev *remote_ctrl_dev; | ||
102 | |||
103 | enum model_type type; | ||
104 | char subunit; | ||
105 | char isochannel; | ||
106 | fe_sec_voltage_t voltage; | ||
107 | fe_sec_tone_mode_t tone; | ||
108 | |||
109 | const struct firedtv_backend *backend; | ||
110 | void *backend_data; | ||
111 | |||
112 | struct mutex demux_mutex; | ||
113 | unsigned long channel_active; | ||
114 | u16 channel_pid[16]; | ||
115 | |||
116 | size_t response_length; | ||
117 | u8 response[512]; | ||
118 | }; | ||
119 | |||
120 | /* firedtv-1394.c */ | ||
121 | #ifdef CONFIG_DVB_FIREDTV_IEEE1394 | ||
122 | int fdtv_1394_init(struct ieee1394_device_id id_table[]); | ||
123 | void fdtv_1394_exit(void); | ||
124 | #else | ||
125 | static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; } | ||
126 | static inline void fdtv_1394_exit(void) {} | ||
127 | #endif | ||
128 | |||
129 | /* firedtv-avc.c */ | ||
130 | int avc_recv(struct firedtv *fdtv, void *data, size_t length); | ||
131 | int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat); | ||
132 | struct dvb_frontend_parameters; | ||
133 | int avc_tuner_dsd(struct firedtv *fdtv, struct dvb_frontend_parameters *params); | ||
134 | int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]); | ||
135 | int avc_tuner_get_ts(struct firedtv *fdtv); | ||
136 | int avc_identify_subunit(struct firedtv *fdtv); | ||
137 | struct dvb_diseqc_master_cmd; | ||
138 | int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, | ||
139 | char conttone, char nrdiseq, | ||
140 | struct dvb_diseqc_master_cmd *diseqcmd); | ||
141 | void avc_remote_ctrl_work(struct work_struct *work); | ||
142 | int avc_register_remote_control(struct firedtv *fdtv); | ||
143 | int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len); | ||
144 | int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len); | ||
145 | int avc_ca_reset(struct firedtv *fdtv); | ||
146 | int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length); | ||
147 | int avc_ca_get_time_date(struct firedtv *fdtv, int *interval); | ||
148 | int avc_ca_enter_menu(struct firedtv *fdtv); | ||
149 | int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len); | ||
150 | int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel); | ||
151 | void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel); | ||
152 | |||
153 | /* firedtv-ci.c */ | ||
154 | int fdtv_ca_register(struct firedtv *fdtv); | ||
155 | void fdtv_ca_release(struct firedtv *fdtv); | ||
156 | |||
157 | /* firedtv-dvb.c */ | ||
158 | int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed); | ||
159 | int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed); | ||
160 | int fdtv_dvb_register(struct firedtv *fdtv); | ||
161 | void fdtv_dvb_unregister(struct firedtv *fdtv); | ||
162 | struct firedtv *fdtv_alloc(struct device *dev, | ||
163 | const struct firedtv_backend *backend, | ||
164 | const char *name, size_t name_len); | ||
165 | extern const char *fdtv_model_names[]; | ||
166 | |||
167 | /* firedtv-fe.c */ | ||
168 | void fdtv_frontend_init(struct firedtv *fdtv); | ||
169 | |||
170 | /* firedtv-rc.c */ | ||
171 | #ifdef CONFIG_DVB_FIREDTV_INPUT | ||
172 | int fdtv_register_rc(struct firedtv *fdtv, struct device *dev); | ||
173 | void fdtv_unregister_rc(struct firedtv *fdtv); | ||
174 | void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code); | ||
175 | #else | ||
176 | static inline int fdtv_register_rc(struct firedtv *fdtv, | ||
177 | struct device *dev) { return 0; } | ||
178 | static inline void fdtv_unregister_rc(struct firedtv *fdtv) {} | ||
179 | static inline void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) {} | ||
180 | #endif | ||
181 | |||
182 | #endif /* _FIREDTV_H */ | ||
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 5d882a44e3ee..2ac738fa6a07 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
@@ -463,6 +463,8 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
463 | pcm->info_flags = 0; | 463 | pcm->info_flags = 0; |
464 | pcm->private_data = dev; | 464 | pcm->private_data = dev; |
465 | strcpy(pcm->name, "Empia 28xx Capture"); | 465 | strcpy(pcm->name, "Empia 28xx Capture"); |
466 | |||
467 | snd_card_set_dev(card, &dev->udev->dev); | ||
466 | strcpy(card->driver, "Empia Em28xx Audio"); | 468 | strcpy(card->driver, "Empia Em28xx Audio"); |
467 | strcpy(card->shortname, "Em28xx Audio"); | 469 | strcpy(card->shortname, "Em28xx Audio"); |
468 | strcpy(card->longname, "Empia Em28xx Audio"); | 470 | strcpy(card->longname, "Empia Em28xx Audio"); |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index a1d6008efcbb..07c334f25aae 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -1155,23 +1155,23 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1155 | { | 1155 | { |
1156 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 1156 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
1157 | struct pxa_camera_dev *pcdev = ici->priv; | 1157 | struct pxa_camera_dev *pcdev = ici->priv; |
1158 | const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL; | 1158 | const struct soc_camera_data_format *cam_fmt = NULL; |
1159 | const struct soc_camera_format_xlate *xlate; | 1159 | const struct soc_camera_format_xlate *xlate = NULL; |
1160 | struct soc_camera_sense sense = { | 1160 | struct soc_camera_sense sense = { |
1161 | .master_clock = pcdev->mclk, | 1161 | .master_clock = pcdev->mclk, |
1162 | .pixel_clock_max = pcdev->ciclk / 4, | 1162 | .pixel_clock_max = pcdev->ciclk / 4, |
1163 | }; | 1163 | }; |
1164 | int ret, buswidth; | 1164 | int ret; |
1165 | 1165 | ||
1166 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 1166 | if (pixfmt) { |
1167 | if (!xlate) { | 1167 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
1168 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 1168 | if (!xlate) { |
1169 | return -EINVAL; | 1169 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); |
1170 | } | 1170 | return -EINVAL; |
1171 | } | ||
1171 | 1172 | ||
1172 | buswidth = xlate->buswidth; | 1173 | cam_fmt = xlate->cam_fmt; |
1173 | host_fmt = xlate->host_fmt; | 1174 | } |
1174 | cam_fmt = xlate->cam_fmt; | ||
1175 | 1175 | ||
1176 | /* If PCLK is used to latch data from the sensor, check sense */ | 1176 | /* If PCLK is used to latch data from the sensor, check sense */ |
1177 | if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) | 1177 | if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) |
@@ -1201,8 +1201,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1201 | } | 1201 | } |
1202 | 1202 | ||
1203 | if (pixfmt && !ret) { | 1203 | if (pixfmt && !ret) { |
1204 | icd->buswidth = buswidth; | 1204 | icd->buswidth = xlate->buswidth; |
1205 | icd->current_fmt = host_fmt; | 1205 | icd->current_fmt = xlate->host_fmt; |
1206 | } | 1206 | } |
1207 | 1207 | ||
1208 | return ret; | 1208 | return ret; |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 9a2586b07a05..ddcb81d0b81a 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -603,21 +603,18 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, | |||
603 | const struct soc_camera_format_xlate *xlate; | 603 | const struct soc_camera_format_xlate *xlate; |
604 | int ret; | 604 | int ret; |
605 | 605 | ||
606 | if (!pixfmt) | ||
607 | return icd->ops->set_fmt(icd, pixfmt, rect); | ||
608 | |||
606 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 609 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
607 | if (!xlate) { | 610 | if (!xlate) { |
608 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 611 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); |
609 | return -EINVAL; | 612 | return -EINVAL; |
610 | } | 613 | } |
611 | 614 | ||
612 | switch (pixfmt) { | 615 | ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); |
613 | case 0: /* Only geometry change */ | ||
614 | ret = icd->ops->set_fmt(icd, pixfmt, rect); | ||
615 | break; | ||
616 | default: | ||
617 | ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); | ||
618 | } | ||
619 | 616 | ||
620 | if (pixfmt && !ret) { | 617 | if (!ret) { |
621 | icd->buswidth = xlate->buswidth; | 618 | icd->buswidth = xlate->buswidth; |
622 | icd->current_fmt = xlate->host_fmt; | 619 | icd->current_fmt = xlate->host_fmt; |
623 | pcdev->camera_fmt = xlate->cam_fmt; | 620 | pcdev->camera_fmt = xlate->cam_fmt; |
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index f26667a7abf7..cf991850f01b 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c | |||
@@ -710,6 +710,7 @@ out: | |||
710 | 710 | ||
711 | static struct pci_device_id ilo_devices[] = { | 711 | static struct pci_device_id ilo_devices[] = { |
712 | { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) }, | 712 | { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) }, |
713 | { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3307) }, | ||
713 | { } | 714 | { } |
714 | }; | 715 | }; |
715 | MODULE_DEVICE_TABLE(pci, ilo_devices); | 716 | MODULE_DEVICE_TABLE(pci, ilo_devices); |
@@ -758,7 +759,7 @@ static void __exit ilo_exit(void) | |||
758 | class_destroy(ilo_class); | 759 | class_destroy(ilo_class); |
759 | } | 760 | } |
760 | 761 | ||
761 | MODULE_VERSION("0.06"); | 762 | MODULE_VERSION("1.0"); |
762 | MODULE_ALIAS(ILO_NAME); | 763 | MODULE_ALIAS(ILO_NAME); |
763 | MODULE_DESCRIPTION(ILO_NAME); | 764 | MODULE_DESCRIPTION(ILO_NAME); |
764 | MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); | 765 | MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); |
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c index 821d0ed6bae3..c76d6e5f47ee 100644 --- a/drivers/mtd/chips/map_rom.c +++ b/drivers/mtd/chips/map_rom.c | |||
@@ -19,6 +19,7 @@ static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | |||
19 | static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 19 | static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
20 | static void maprom_nop (struct mtd_info *); | 20 | static void maprom_nop (struct mtd_info *); |
21 | static struct mtd_info *map_rom_probe(struct map_info *map); | 21 | static struct mtd_info *map_rom_probe(struct map_info *map); |
22 | static int maprom_erase (struct mtd_info *mtd, struct erase_info *info); | ||
22 | 23 | ||
23 | static struct mtd_chip_driver maprom_chipdrv = { | 24 | static struct mtd_chip_driver maprom_chipdrv = { |
24 | .probe = map_rom_probe, | 25 | .probe = map_rom_probe, |
@@ -42,6 +43,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map) | |||
42 | mtd->read = maprom_read; | 43 | mtd->read = maprom_read; |
43 | mtd->write = maprom_write; | 44 | mtd->write = maprom_write; |
44 | mtd->sync = maprom_nop; | 45 | mtd->sync = maprom_nop; |
46 | mtd->erase = maprom_erase; | ||
45 | mtd->flags = MTD_CAP_ROM; | 47 | mtd->flags = MTD_CAP_ROM; |
46 | mtd->erasesize = map->size; | 48 | mtd->erasesize = map->size; |
47 | mtd->writesize = 1; | 49 | mtd->writesize = 1; |
@@ -71,6 +73,12 @@ static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *re | |||
71 | return -EIO; | 73 | return -EIO; |
72 | } | 74 | } |
73 | 75 | ||
76 | static int maprom_erase (struct mtd_info *mtd, struct erase_info *info) | ||
77 | { | ||
78 | /* We do our best 8) */ | ||
79 | return -EROFS; | ||
80 | } | ||
81 | |||
74 | static int __init map_rom_init(void) | 82 | static int __init map_rom_init(void) |
75 | { | 83 | { |
76 | register_mtd_chip_driver(&maprom_chipdrv); | 84 | register_mtd_chip_driver(&maprom_chipdrv); |
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index a425d09f35a0..00248e81ecd5 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c | |||
@@ -267,22 +267,28 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) | |||
267 | if (*(szlength) != '+') { | 267 | if (*(szlength) != '+') { |
268 | devlength = simple_strtoul(szlength, &buffer, 0); | 268 | devlength = simple_strtoul(szlength, &buffer, 0); |
269 | devlength = handle_unit(devlength, buffer) - devstart; | 269 | devlength = handle_unit(devlength, buffer) - devstart; |
270 | if (devlength < devstart) | ||
271 | goto err_out; | ||
272 | |||
273 | devlength -= devstart; | ||
270 | } else { | 274 | } else { |
271 | devlength = simple_strtoul(szlength + 1, &buffer, 0); | 275 | devlength = simple_strtoul(szlength + 1, &buffer, 0); |
272 | devlength = handle_unit(devlength, buffer); | 276 | devlength = handle_unit(devlength, buffer); |
273 | } | 277 | } |
274 | T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", | 278 | T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", |
275 | devname, devstart, devlength); | 279 | devname, devstart, devlength); |
276 | if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) { | 280 | if (devlength % SLRAM_BLK_SZ != 0) |
277 | E("slram: Illegal start / length parameter.\n"); | 281 | goto err_out; |
278 | return(-EINVAL); | ||
279 | } | ||
280 | 282 | ||
281 | if ((devstart = register_device(devname, devstart, devlength))){ | 283 | if ((devstart = register_device(devname, devstart, devlength))){ |
282 | unregister_devices(); | 284 | unregister_devices(); |
283 | return((int)devstart); | 285 | return((int)devstart); |
284 | } | 286 | } |
285 | return(0); | 287 | return(0); |
288 | |||
289 | err_out: | ||
290 | E("slram: Illegal length parameter.\n"); | ||
291 | return(-EINVAL); | ||
286 | } | 292 | } |
287 | 293 | ||
288 | #ifndef MODULE | 294 | #ifndef MODULE |
diff --git a/drivers/mtd/lpddr/Kconfig b/drivers/mtd/lpddr/Kconfig index acd4ea9b2278..5a401d8047ab 100644 --- a/drivers/mtd/lpddr/Kconfig +++ b/drivers/mtd/lpddr/Kconfig | |||
@@ -12,6 +12,7 @@ config MTD_LPDDR | |||
12 | DDR memories, intended for battery-operated systems. | 12 | DDR memories, intended for battery-operated systems. |
13 | 13 | ||
14 | config MTD_QINFO_PROBE | 14 | config MTD_QINFO_PROBE |
15 | depends on MTD_LPDDR | ||
15 | tristate "Detect flash chips by QINFO probe" | 16 | tristate "Detect flash chips by QINFO probe" |
16 | help | 17 | help |
17 | Device Information for LPDDR chips is offered through the Overlay | 18 | Device Information for LPDDR chips is offered through the Overlay |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 0225cbbf22de..043d50fb6ef6 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -491,7 +491,7 @@ config MTD_PCMCIA_ANONYMOUS | |||
491 | 491 | ||
492 | config MTD_BFIN_ASYNC | 492 | config MTD_BFIN_ASYNC |
493 | tristate "Blackfin BF533-STAMP Flash Chip Support" | 493 | tristate "Blackfin BF533-STAMP Flash Chip Support" |
494 | depends on BFIN533_STAMP && MTD_CFI | 494 | depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS |
495 | select MTD_PARTITIONS | 495 | select MTD_PARTITIONS |
496 | default y | 496 | default y |
497 | help | 497 | help |
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index 6fec86aaed7e..576611f605db 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c | |||
@@ -152,14 +152,18 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev) | |||
152 | 152 | ||
153 | if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { | 153 | if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { |
154 | pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); | 154 | pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); |
155 | kfree(state); | ||
155 | return -EBUSY; | 156 | return -EBUSY; |
156 | } | 157 | } |
157 | gpio_direction_output(state->enet_flash_pin, 1); | 158 | gpio_direction_output(state->enet_flash_pin, 1); |
158 | 159 | ||
159 | pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); | 160 | pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); |
160 | state->mtd = do_map_probe(memory->name, &state->map); | 161 | state->mtd = do_map_probe(memory->name, &state->map); |
161 | if (!state->mtd) | 162 | if (!state->mtd) { |
163 | gpio_free(state->enet_flash_pin); | ||
164 | kfree(state); | ||
162 | return -ENXIO; | 165 | return -ENXIO; |
166 | } | ||
163 | 167 | ||
164 | #ifdef CONFIG_MTD_PARTITIONS | 168 | #ifdef CONFIG_MTD_PARTITIONS |
165 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); | 169 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); |
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 5f7a245ed132..424f17d6ffd1 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c | |||
@@ -342,9 +342,9 @@ static struct pci_device_id ck804xrom_pci_tbl[] = { | |||
342 | { 0, } | 342 | { 0, } |
343 | }; | 343 | }; |
344 | 344 | ||
345 | #if 0 | ||
345 | MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); | 346 | MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); |
346 | 347 | ||
347 | #if 0 | ||
348 | static struct pci_driver ck804xrom_driver = { | 348 | static struct pci_driver ck804xrom_driver = { |
349 | .name = MOD_NAME, | 349 | .name = MOD_NAME, |
350 | .id_table = ck804xrom_pci_tbl, | 350 | .id_table = ck804xrom_pci_tbl, |
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 87743661d48e..4b122e7ab4b3 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c | |||
@@ -29,6 +29,7 @@ struct physmap_flash_info { | |||
29 | struct map_info map[MAX_RESOURCES]; | 29 | struct map_info map[MAX_RESOURCES]; |
30 | #ifdef CONFIG_MTD_PARTITIONS | 30 | #ifdef CONFIG_MTD_PARTITIONS |
31 | int nr_parts; | 31 | int nr_parts; |
32 | struct mtd_partition *parts; | ||
32 | #endif | 33 | #endif |
33 | }; | 34 | }; |
34 | 35 | ||
@@ -45,25 +46,26 @@ static int physmap_flash_remove(struct platform_device *dev) | |||
45 | 46 | ||
46 | physmap_data = dev->dev.platform_data; | 47 | physmap_data = dev->dev.platform_data; |
47 | 48 | ||
48 | #ifdef CONFIG_MTD_CONCAT | 49 | #ifdef CONFIG_MTD_PARTITIONS |
49 | if (info->cmtd != info->mtd[0]) { | 50 | if (info->nr_parts) { |
51 | del_mtd_partitions(info->cmtd); | ||
52 | kfree(info->parts); | ||
53 | } else if (physmap_data->nr_parts) | ||
54 | del_mtd_partitions(info->cmtd); | ||
55 | else | ||
50 | del_mtd_device(info->cmtd); | 56 | del_mtd_device(info->cmtd); |
57 | #else | ||
58 | del_mtd_device(info->cmtd); | ||
59 | #endif | ||
60 | |||
61 | #ifdef CONFIG_MTD_CONCAT | ||
62 | if (info->cmtd != info->mtd[0]) | ||
51 | mtd_concat_destroy(info->cmtd); | 63 | mtd_concat_destroy(info->cmtd); |
52 | } | ||
53 | #endif | 64 | #endif |
54 | 65 | ||
55 | for (i = 0; i < MAX_RESOURCES; i++) { | 66 | for (i = 0; i < MAX_RESOURCES; i++) { |
56 | if (info->mtd[i] != NULL) { | 67 | if (info->mtd[i] != NULL) |
57 | #ifdef CONFIG_MTD_PARTITIONS | ||
58 | if (info->nr_parts || physmap_data->nr_parts) | ||
59 | del_mtd_partitions(info->mtd[i]); | ||
60 | else | ||
61 | del_mtd_device(info->mtd[i]); | ||
62 | #else | ||
63 | del_mtd_device(info->mtd[i]); | ||
64 | #endif | ||
65 | map_destroy(info->mtd[i]); | 68 | map_destroy(info->mtd[i]); |
66 | } | ||
67 | } | 69 | } |
68 | return 0; | 70 | return 0; |
69 | } | 71 | } |
@@ -86,9 +88,6 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
86 | int err = 0; | 88 | int err = 0; |
87 | int i; | 89 | int i; |
88 | int devices_found = 0; | 90 | int devices_found = 0; |
89 | #ifdef CONFIG_MTD_PARTITIONS | ||
90 | struct mtd_partition *parts; | ||
91 | #endif | ||
92 | 91 | ||
93 | physmap_data = dev->dev.platform_data; | 92 | physmap_data = dev->dev.platform_data; |
94 | if (physmap_data == NULL) | 93 | if (physmap_data == NULL) |
@@ -167,10 +166,11 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
167 | goto err_out; | 166 | goto err_out; |
168 | 167 | ||
169 | #ifdef CONFIG_MTD_PARTITIONS | 168 | #ifdef CONFIG_MTD_PARTITIONS |
170 | err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0); | 169 | err = parse_mtd_partitions(info->cmtd, part_probe_types, |
170 | &info->parts, 0); | ||
171 | if (err > 0) { | 171 | if (err > 0) { |
172 | add_mtd_partitions(info->cmtd, parts, err); | 172 | add_mtd_partitions(info->cmtd, info->parts, err); |
173 | kfree(parts); | 173 | info->nr_parts = err; |
174 | return 0; | 174 | return 0; |
175 | } | 175 | } |
176 | 176 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index b0ee86c62685..ab13ff22a8c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -148,7 +148,7 @@ static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
148 | pci_unmap_single(dev, | 148 | pci_unmap_single(dev, |
149 | pci_unmap_addr(&txq->cmd[index]->meta, mapping), | 149 | pci_unmap_addr(&txq->cmd[index]->meta, mapping), |
150 | pci_unmap_len(&txq->cmd[index]->meta, len), | 150 | pci_unmap_len(&txq->cmd[index]->meta, len), |
151 | PCI_DMA_TODEVICE); | 151 | PCI_DMA_BIDIRECTIONAL); |
152 | 152 | ||
153 | /* Unmap chunks, if any. */ | 153 | /* Unmap chunks, if any. */ |
154 | for (i = 1; i < num_tbs; i++) { | 154 | for (i = 1; i < num_tbs; i++) { |
@@ -964,7 +964,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
964 | * within command buffer array. */ | 964 | * within command buffer array. */ |
965 | txcmd_phys = pci_map_single(priv->pci_dev, | 965 | txcmd_phys = pci_map_single(priv->pci_dev, |
966 | out_cmd, sizeof(struct iwl_cmd), | 966 | out_cmd, sizeof(struct iwl_cmd), |
967 | PCI_DMA_TODEVICE); | 967 | PCI_DMA_BIDIRECTIONAL); |
968 | pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); | 968 | pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); |
969 | pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd)); | 969 | pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd)); |
970 | /* Add buffer containing Tx command and MAC(!) header to TFD's | 970 | /* Add buffer containing Tx command and MAC(!) header to TFD's |
@@ -1115,7 +1115,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1115 | IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd); | 1115 | IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd); |
1116 | 1116 | ||
1117 | phys_addr = pci_map_single(priv->pci_dev, out_cmd, | 1117 | phys_addr = pci_map_single(priv->pci_dev, out_cmd, |
1118 | len, PCI_DMA_TODEVICE); | 1118 | len, PCI_DMA_BIDIRECTIONAL); |
1119 | pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr); | 1119 | pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr); |
1120 | pci_unmap_len_set(&out_cmd->meta, len, len); | 1120 | pci_unmap_len_set(&out_cmd->meta, len, len); |
1121 | phys_addr += offsetof(struct iwl_cmd, hdr); | 1121 | phys_addr += offsetof(struct iwl_cmd, hdr); |
@@ -1212,7 +1212,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, | |||
1212 | pci_unmap_single(priv->pci_dev, | 1212 | pci_unmap_single(priv->pci_dev, |
1213 | pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping), | 1213 | pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping), |
1214 | pci_unmap_len(&txq->cmd[cmd_idx]->meta, len), | 1214 | pci_unmap_len(&txq->cmd[cmd_idx]->meta, len), |
1215 | PCI_DMA_TODEVICE); | 1215 | PCI_DMA_BIDIRECTIONAL); |
1216 | 1216 | ||
1217 | for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; | 1217 | for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; |
1218 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | 1218 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index f5a662a50acb..26c536b51c5a 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -330,6 +330,14 @@ parse_dmar_table(void) | |||
330 | entry_header = (struct acpi_dmar_header *)(dmar + 1); | 330 | entry_header = (struct acpi_dmar_header *)(dmar + 1); |
331 | while (((unsigned long)entry_header) < | 331 | while (((unsigned long)entry_header) < |
332 | (((unsigned long)dmar) + dmar_tbl->length)) { | 332 | (((unsigned long)dmar) + dmar_tbl->length)) { |
333 | /* Avoid looping forever on bad ACPI tables */ | ||
334 | if (entry_header->length == 0) { | ||
335 | printk(KERN_WARNING PREFIX | ||
336 | "Invalid 0-length structure\n"); | ||
337 | ret = -EINVAL; | ||
338 | break; | ||
339 | } | ||
340 | |||
333 | dmar_table_print_dmar_entry(entry_header); | 341 | dmar_table_print_dmar_entry(entry_header); |
334 | 342 | ||
335 | switch (entry_header->type) { | 343 | switch (entry_header->type) { |
@@ -491,7 +499,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
491 | int map_size; | 499 | int map_size; |
492 | u32 ver; | 500 | u32 ver; |
493 | static int iommu_allocated = 0; | 501 | static int iommu_allocated = 0; |
494 | int agaw; | 502 | int agaw = 0; |
495 | 503 | ||
496 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); | 504 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); |
497 | if (!iommu) | 505 | if (!iommu) |
@@ -507,6 +515,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
507 | iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); | 515 | iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); |
508 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); | 516 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); |
509 | 517 | ||
518 | #ifdef CONFIG_DMAR | ||
510 | agaw = iommu_calculate_agaw(iommu); | 519 | agaw = iommu_calculate_agaw(iommu); |
511 | if (agaw < 0) { | 520 | if (agaw < 0) { |
512 | printk(KERN_ERR | 521 | printk(KERN_ERR |
@@ -514,6 +523,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
514 | iommu->seq_id); | 523 | iommu->seq_id); |
515 | goto error; | 524 | goto error; |
516 | } | 525 | } |
526 | #endif | ||
517 | iommu->agaw = agaw; | 527 | iommu->agaw = agaw; |
518 | 528 | ||
519 | /* the registers might be more than one page */ | 529 | /* the registers might be more than one page */ |
@@ -571,19 +581,49 @@ static inline void reclaim_free_desc(struct q_inval *qi) | |||
571 | } | 581 | } |
572 | } | 582 | } |
573 | 583 | ||
584 | static int qi_check_fault(struct intel_iommu *iommu, int index) | ||
585 | { | ||
586 | u32 fault; | ||
587 | int head; | ||
588 | struct q_inval *qi = iommu->qi; | ||
589 | int wait_index = (index + 1) % QI_LENGTH; | ||
590 | |||
591 | fault = readl(iommu->reg + DMAR_FSTS_REG); | ||
592 | |||
593 | /* | ||
594 | * If IQE happens, the head points to the descriptor associated | ||
595 | * with the error. No new descriptors are fetched until the IQE | ||
596 | * is cleared. | ||
597 | */ | ||
598 | if (fault & DMA_FSTS_IQE) { | ||
599 | head = readl(iommu->reg + DMAR_IQH_REG); | ||
600 | if ((head >> 4) == index) { | ||
601 | memcpy(&qi->desc[index], &qi->desc[wait_index], | ||
602 | sizeof(struct qi_desc)); | ||
603 | __iommu_flush_cache(iommu, &qi->desc[index], | ||
604 | sizeof(struct qi_desc)); | ||
605 | writel(DMA_FSTS_IQE, iommu->reg + DMAR_FSTS_REG); | ||
606 | return -EINVAL; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | return 0; | ||
611 | } | ||
612 | |||
574 | /* | 613 | /* |
575 | * Submit the queued invalidation descriptor to the remapping | 614 | * Submit the queued invalidation descriptor to the remapping |
576 | * hardware unit and wait for its completion. | 615 | * hardware unit and wait for its completion. |
577 | */ | 616 | */ |
578 | void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) | 617 | int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) |
579 | { | 618 | { |
619 | int rc = 0; | ||
580 | struct q_inval *qi = iommu->qi; | 620 | struct q_inval *qi = iommu->qi; |
581 | struct qi_desc *hw, wait_desc; | 621 | struct qi_desc *hw, wait_desc; |
582 | int wait_index, index; | 622 | int wait_index, index; |
583 | unsigned long flags; | 623 | unsigned long flags; |
584 | 624 | ||
585 | if (!qi) | 625 | if (!qi) |
586 | return; | 626 | return 0; |
587 | 627 | ||
588 | hw = qi->desc; | 628 | hw = qi->desc; |
589 | 629 | ||
@@ -601,7 +641,8 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) | |||
601 | 641 | ||
602 | hw[index] = *desc; | 642 | hw[index] = *desc; |
603 | 643 | ||
604 | wait_desc.low = QI_IWD_STATUS_DATA(2) | QI_IWD_STATUS_WRITE | QI_IWD_TYPE; | 644 | wait_desc.low = QI_IWD_STATUS_DATA(QI_DONE) | |
645 | QI_IWD_STATUS_WRITE | QI_IWD_TYPE; | ||
605 | wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]); | 646 | wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]); |
606 | 647 | ||
607 | hw[wait_index] = wait_desc; | 648 | hw[wait_index] = wait_desc; |
@@ -612,13 +653,11 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) | |||
612 | qi->free_head = (qi->free_head + 2) % QI_LENGTH; | 653 | qi->free_head = (qi->free_head + 2) % QI_LENGTH; |
613 | qi->free_cnt -= 2; | 654 | qi->free_cnt -= 2; |
614 | 655 | ||
615 | spin_lock(&iommu->register_lock); | ||
616 | /* | 656 | /* |
617 | * update the HW tail register indicating the presence of | 657 | * update the HW tail register indicating the presence of |
618 | * new descriptors. | 658 | * new descriptors. |
619 | */ | 659 | */ |
620 | writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG); | 660 | writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG); |
621 | spin_unlock(&iommu->register_lock); | ||
622 | 661 | ||
623 | while (qi->desc_status[wait_index] != QI_DONE) { | 662 | while (qi->desc_status[wait_index] != QI_DONE) { |
624 | /* | 663 | /* |
@@ -628,15 +667,21 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) | |||
628 | * a deadlock where the interrupt context can wait indefinitely | 667 | * a deadlock where the interrupt context can wait indefinitely |
629 | * for free slots in the queue. | 668 | * for free slots in the queue. |
630 | */ | 669 | */ |
670 | rc = qi_check_fault(iommu, index); | ||
671 | if (rc) | ||
672 | goto out; | ||
673 | |||
631 | spin_unlock(&qi->q_lock); | 674 | spin_unlock(&qi->q_lock); |
632 | cpu_relax(); | 675 | cpu_relax(); |
633 | spin_lock(&qi->q_lock); | 676 | spin_lock(&qi->q_lock); |
634 | } | 677 | } |
635 | 678 | out: | |
636 | qi->desc_status[index] = QI_DONE; | 679 | qi->desc_status[index] = qi->desc_status[wait_index] = QI_DONE; |
637 | 680 | ||
638 | reclaim_free_desc(qi); | 681 | reclaim_free_desc(qi); |
639 | spin_unlock_irqrestore(&qi->q_lock, flags); | 682 | spin_unlock_irqrestore(&qi->q_lock, flags); |
683 | |||
684 | return rc; | ||
640 | } | 685 | } |
641 | 686 | ||
642 | /* | 687 | /* |
@@ -649,13 +694,13 @@ void qi_global_iec(struct intel_iommu *iommu) | |||
649 | desc.low = QI_IEC_TYPE; | 694 | desc.low = QI_IEC_TYPE; |
650 | desc.high = 0; | 695 | desc.high = 0; |
651 | 696 | ||
697 | /* should never fail */ | ||
652 | qi_submit_sync(&desc, iommu); | 698 | qi_submit_sync(&desc, iommu); |
653 | } | 699 | } |
654 | 700 | ||
655 | int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, | 701 | int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, |
656 | u64 type, int non_present_entry_flush) | 702 | u64 type, int non_present_entry_flush) |
657 | { | 703 | { |
658 | |||
659 | struct qi_desc desc; | 704 | struct qi_desc desc; |
660 | 705 | ||
661 | if (non_present_entry_flush) { | 706 | if (non_present_entry_flush) { |
@@ -669,10 +714,7 @@ int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, | |||
669 | | QI_CC_GRAN(type) | QI_CC_TYPE; | 714 | | QI_CC_GRAN(type) | QI_CC_TYPE; |
670 | desc.high = 0; | 715 | desc.high = 0; |
671 | 716 | ||
672 | qi_submit_sync(&desc, iommu); | 717 | return qi_submit_sync(&desc, iommu); |
673 | |||
674 | return 0; | ||
675 | |||
676 | } | 718 | } |
677 | 719 | ||
678 | int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, | 720 | int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, |
@@ -702,10 +744,7 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, | |||
702 | desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih) | 744 | desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih) |
703 | | QI_IOTLB_AM(size_order); | 745 | | QI_IOTLB_AM(size_order); |
704 | 746 | ||
705 | qi_submit_sync(&desc, iommu); | 747 | return qi_submit_sync(&desc, iommu); |
706 | |||
707 | return 0; | ||
708 | |||
709 | } | 748 | } |
710 | 749 | ||
711 | /* | 750 | /* |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index db85284ffb62..39ae37589fda 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -111,6 +111,7 @@ struct controller { | |||
111 | int cmd_busy; | 111 | int cmd_busy; |
112 | unsigned int no_cmd_complete:1; | 112 | unsigned int no_cmd_complete:1; |
113 | unsigned int link_active_reporting:1; | 113 | unsigned int link_active_reporting:1; |
114 | unsigned int notification_enabled:1; | ||
114 | }; | 115 | }; |
115 | 116 | ||
116 | #define INT_BUTTON_IGNORE 0 | 117 | #define INT_BUTTON_IGNORE 0 |
@@ -170,6 +171,7 @@ extern int pciehp_configure_device(struct slot *p_slot); | |||
170 | extern int pciehp_unconfigure_device(struct slot *p_slot); | 171 | extern int pciehp_unconfigure_device(struct slot *p_slot); |
171 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); | 172 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); |
172 | struct controller *pcie_init(struct pcie_device *dev); | 173 | struct controller *pcie_init(struct pcie_device *dev); |
174 | int pcie_init_notification(struct controller *ctrl); | ||
173 | int pciehp_enable_slot(struct slot *p_slot); | 175 | int pciehp_enable_slot(struct slot *p_slot); |
174 | int pciehp_disable_slot(struct slot *p_slot); | 176 | int pciehp_disable_slot(struct slot *p_slot); |
175 | int pcie_enable_notification(struct controller *ctrl); | 177 | int pcie_enable_notification(struct controller *ctrl); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index c2485542f543..681e3912b821 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -434,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
434 | goto err_out_release_ctlr; | 434 | goto err_out_release_ctlr; |
435 | } | 435 | } |
436 | 436 | ||
437 | /* Enable events after we have setup the data structures */ | ||
438 | rc = pcie_init_notification(ctrl); | ||
439 | if (rc) { | ||
440 | ctrl_err(ctrl, "Notification initialization failed\n"); | ||
441 | goto err_out_release_ctlr; | ||
442 | } | ||
443 | |||
437 | /* Check if slot is occupied */ | 444 | /* Check if slot is occupied */ |
438 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); | 445 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); |
439 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); | 446 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 71a8012886b0..7a16c6897bb9 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
934 | ctrl_warn(ctrl, "Cannot disable software notification\n"); | 934 | ctrl_warn(ctrl, "Cannot disable software notification\n"); |
935 | } | 935 | } |
936 | 936 | ||
937 | static int pcie_init_notification(struct controller *ctrl) | 937 | int pcie_init_notification(struct controller *ctrl) |
938 | { | 938 | { |
939 | if (pciehp_request_irq(ctrl)) | 939 | if (pciehp_request_irq(ctrl)) |
940 | return -1; | 940 | return -1; |
@@ -942,13 +942,17 @@ static int pcie_init_notification(struct controller *ctrl) | |||
942 | pciehp_free_irq(ctrl); | 942 | pciehp_free_irq(ctrl); |
943 | return -1; | 943 | return -1; |
944 | } | 944 | } |
945 | ctrl->notification_enabled = 1; | ||
945 | return 0; | 946 | return 0; |
946 | } | 947 | } |
947 | 948 | ||
948 | static void pcie_shutdown_notification(struct controller *ctrl) | 949 | static void pcie_shutdown_notification(struct controller *ctrl) |
949 | { | 950 | { |
950 | pcie_disable_notification(ctrl); | 951 | if (ctrl->notification_enabled) { |
951 | pciehp_free_irq(ctrl); | 952 | pcie_disable_notification(ctrl); |
953 | pciehp_free_irq(ctrl); | ||
954 | ctrl->notification_enabled = 0; | ||
955 | } | ||
952 | } | 956 | } |
953 | 957 | ||
954 | static int pcie_init_slot(struct controller *ctrl) | 958 | static int pcie_init_slot(struct controller *ctrl) |
@@ -1110,13 +1114,8 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
1110 | if (pcie_init_slot(ctrl)) | 1114 | if (pcie_init_slot(ctrl)) |
1111 | goto abort_ctrl; | 1115 | goto abort_ctrl; |
1112 | 1116 | ||
1113 | if (pcie_init_notification(ctrl)) | ||
1114 | goto abort_slot; | ||
1115 | |||
1116 | return ctrl; | 1117 | return ctrl; |
1117 | 1118 | ||
1118 | abort_slot: | ||
1119 | pcie_cleanup_slot(ctrl); | ||
1120 | abort_ctrl: | 1119 | abort_ctrl: |
1121 | kfree(ctrl); | 1120 | kfree(ctrl); |
1122 | abort: | 1121 | abort: |
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index f78371b22529..45effc5726c0 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -207,7 +207,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | |||
207 | return index; | 207 | return index; |
208 | } | 208 | } |
209 | 209 | ||
210 | static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask) | 210 | static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask) |
211 | { | 211 | { |
212 | struct qi_desc desc; | 212 | struct qi_desc desc; |
213 | 213 | ||
@@ -215,7 +215,7 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask) | |||
215 | | QI_IEC_SELECTIVE; | 215 | | QI_IEC_SELECTIVE; |
216 | desc.high = 0; | 216 | desc.high = 0; |
217 | 217 | ||
218 | qi_submit_sync(&desc, iommu); | 218 | return qi_submit_sync(&desc, iommu); |
219 | } | 219 | } |
220 | 220 | ||
221 | int map_irq_to_irte_handle(int irq, u16 *sub_handle) | 221 | int map_irq_to_irte_handle(int irq, u16 *sub_handle) |
@@ -283,6 +283,7 @@ int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) | |||
283 | 283 | ||
284 | int modify_irte(int irq, struct irte *irte_modified) | 284 | int modify_irte(int irq, struct irte *irte_modified) |
285 | { | 285 | { |
286 | int rc; | ||
286 | int index; | 287 | int index; |
287 | struct irte *irte; | 288 | struct irte *irte; |
288 | struct intel_iommu *iommu; | 289 | struct intel_iommu *iommu; |
@@ -303,14 +304,15 @@ int modify_irte(int irq, struct irte *irte_modified) | |||
303 | set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); | 304 | set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); |
304 | __iommu_flush_cache(iommu, irte, sizeof(*irte)); | 305 | __iommu_flush_cache(iommu, irte, sizeof(*irte)); |
305 | 306 | ||
306 | qi_flush_iec(iommu, index, 0); | 307 | rc = qi_flush_iec(iommu, index, 0); |
307 | |||
308 | spin_unlock(&irq_2_ir_lock); | 308 | spin_unlock(&irq_2_ir_lock); |
309 | return 0; | 309 | |
310 | return rc; | ||
310 | } | 311 | } |
311 | 312 | ||
312 | int flush_irte(int irq) | 313 | int flush_irte(int irq) |
313 | { | 314 | { |
315 | int rc; | ||
314 | int index; | 316 | int index; |
315 | struct intel_iommu *iommu; | 317 | struct intel_iommu *iommu; |
316 | struct irq_2_iommu *irq_iommu; | 318 | struct irq_2_iommu *irq_iommu; |
@@ -326,10 +328,10 @@ int flush_irte(int irq) | |||
326 | 328 | ||
327 | index = irq_iommu->irte_index + irq_iommu->sub_handle; | 329 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
328 | 330 | ||
329 | qi_flush_iec(iommu, index, irq_iommu->irte_mask); | 331 | rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); |
330 | spin_unlock(&irq_2_ir_lock); | 332 | spin_unlock(&irq_2_ir_lock); |
331 | 333 | ||
332 | return 0; | 334 | return rc; |
333 | } | 335 | } |
334 | 336 | ||
335 | struct intel_iommu *map_ioapic_to_ir(int apic) | 337 | struct intel_iommu *map_ioapic_to_ir(int apic) |
@@ -355,6 +357,7 @@ struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) | |||
355 | 357 | ||
356 | int free_irte(int irq) | 358 | int free_irte(int irq) |
357 | { | 359 | { |
360 | int rc = 0; | ||
358 | int index, i; | 361 | int index, i; |
359 | struct irte *irte; | 362 | struct irte *irte; |
360 | struct intel_iommu *iommu; | 363 | struct intel_iommu *iommu; |
@@ -375,7 +378,7 @@ int free_irte(int irq) | |||
375 | if (!irq_iommu->sub_handle) { | 378 | if (!irq_iommu->sub_handle) { |
376 | for (i = 0; i < (1 << irq_iommu->irte_mask); i++) | 379 | for (i = 0; i < (1 << irq_iommu->irte_mask); i++) |
377 | set_64bit((unsigned long *)irte, 0); | 380 | set_64bit((unsigned long *)irte, 0); |
378 | qi_flush_iec(iommu, index, irq_iommu->irte_mask); | 381 | rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); |
379 | } | 382 | } |
380 | 383 | ||
381 | irq_iommu->iommu = NULL; | 384 | irq_iommu->iommu = NULL; |
@@ -385,7 +388,7 @@ int free_irte(int irq) | |||
385 | 388 | ||
386 | spin_unlock(&irq_2_ir_lock); | 389 | spin_unlock(&irq_2_ir_lock); |
387 | 390 | ||
388 | return 0; | 391 | return rc; |
389 | } | 392 | } |
390 | 393 | ||
391 | static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) | 394 | static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index aac7006949f1..d0c973685868 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -108,6 +108,34 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) | |||
108 | } | 108 | } |
109 | #endif /* 0 */ | 109 | #endif /* 0 */ |
110 | 110 | ||
111 | |||
112 | static void set_device_error_reporting(struct pci_dev *dev, void *data) | ||
113 | { | ||
114 | bool enable = *((bool *)data); | ||
115 | |||
116 | if (dev->pcie_type != PCIE_RC_PORT && | ||
117 | dev->pcie_type != PCIE_SW_UPSTREAM_PORT && | ||
118 | dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT) | ||
119 | return; | ||
120 | |||
121 | if (enable) | ||
122 | pci_enable_pcie_error_reporting(dev); | ||
123 | else | ||
124 | pci_disable_pcie_error_reporting(dev); | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. | ||
129 | * @dev: pointer to root port's pci_dev data structure | ||
130 | * @enable: true = enable error reporting, false = disable error reporting. | ||
131 | */ | ||
132 | static void set_downstream_devices_error_reporting(struct pci_dev *dev, | ||
133 | bool enable) | ||
134 | { | ||
135 | set_device_error_reporting(dev, &enable); | ||
136 | pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable); | ||
137 | } | ||
138 | |||
111 | static int find_device_iter(struct device *device, void *data) | 139 | static int find_device_iter(struct device *device, void *data) |
112 | { | 140 | { |
113 | struct pci_dev *dev; | 141 | struct pci_dev *dev; |
@@ -525,15 +553,11 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
525 | pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); | 553 | pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); |
526 | pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); | 554 | pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); |
527 | 555 | ||
528 | /* Enable Root Port device reporting error itself */ | 556 | /* |
529 | pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, ®16); | 557 | * Enable error reporting for the root port device and downstream port |
530 | reg16 = reg16 | | 558 | * devices. |
531 | PCI_EXP_DEVCTL_CERE | | 559 | */ |
532 | PCI_EXP_DEVCTL_NFERE | | 560 | set_downstream_devices_error_reporting(pdev, true); |
533 | PCI_EXP_DEVCTL_FERE | | ||
534 | PCI_EXP_DEVCTL_URRE; | ||
535 | pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL, | ||
536 | reg16); | ||
537 | 561 | ||
538 | /* Enable Root Port's interrupt in response to error messages */ | 562 | /* Enable Root Port's interrupt in response to error messages */ |
539 | pci_write_config_dword(pdev, | 563 | pci_write_config_dword(pdev, |
@@ -553,6 +577,12 @@ static void disable_root_aer(struct aer_rpc *rpc) | |||
553 | u32 reg32; | 577 | u32 reg32; |
554 | int pos; | 578 | int pos; |
555 | 579 | ||
580 | /* | ||
581 | * Disable error reporting for the root port device and downstream port | ||
582 | * devices. | ||
583 | */ | ||
584 | set_downstream_devices_error_reporting(pdev, false); | ||
585 | |||
556 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); | 586 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); |
557 | /* Disable Root's interrupt in response to error messages */ | 587 | /* Disable Root's interrupt in response to error messages */ |
558 | pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); | 588 | pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index f9b874eaeb9f..248b4db91552 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -97,8 +97,6 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | |||
97 | 97 | ||
98 | pcie_portdrv_save_config(dev); | 98 | pcie_portdrv_save_config(dev); |
99 | 99 | ||
100 | pci_enable_pcie_error_reporting(dev); | ||
101 | |||
102 | return 0; | 100 | return 0; |
103 | } | 101 | } |
104 | 102 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index baad093aafe3..f20d55368edb 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1584,6 +1584,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_ | |||
1584 | */ | 1584 | */ |
1585 | #define AMD_813X_MISC 0x40 | 1585 | #define AMD_813X_MISC 0x40 |
1586 | #define AMD_813X_NOIOAMODE (1<<0) | 1586 | #define AMD_813X_NOIOAMODE (1<<0) |
1587 | #define AMD_813X_REV_B2 0x13 | ||
1587 | 1588 | ||
1588 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | 1589 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) |
1589 | { | 1590 | { |
@@ -1591,6 +1592,8 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | |||
1591 | 1592 | ||
1592 | if (noioapicquirk) | 1593 | if (noioapicquirk) |
1593 | return; | 1594 | return; |
1595 | if (dev->revision == AMD_813X_REV_B2) | ||
1596 | return; | ||
1594 | 1597 | ||
1595 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); | 1598 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); |
1596 | pci_config_dword &= ~AMD_813X_NOIOAMODE; | 1599 | pci_config_dword &= ~AMD_813X_NOIOAMODE; |
@@ -1981,7 +1984,6 @@ static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) | |||
1981 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, | 1984 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, |
1982 | quirk_msi_ht_cap); | 1985 | quirk_msi_ht_cap); |
1983 | 1986 | ||
1984 | |||
1985 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. | 1987 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. |
1986 | * MSI are supported if the MSI capability set in any of these mappings. | 1988 | * MSI are supported if the MSI capability set in any of these mappings. |
1987 | */ | 1989 | */ |
@@ -2032,6 +2034,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, | |||
2032 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, | 2034 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, |
2033 | ht_enable_msi_mapping); | 2035 | ht_enable_msi_mapping); |
2034 | 2036 | ||
2037 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, | ||
2038 | ht_enable_msi_mapping); | ||
2039 | |||
2035 | /* The P5N32-SLI Premium motherboard from Asus has a problem with msi | 2040 | /* The P5N32-SLI Premium motherboard from Asus has a problem with msi |
2036 | * for the MCP55 NIC. It is not yet determined whether the msi problem | 2041 | * for the MCP55 NIC. It is not yet determined whether the msi problem |
2037 | * also affects other devices. As for now, turn off msi for this device. | 2042 | * also affects other devices. As for now, turn off msi for this device. |
@@ -2048,10 +2053,100 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, | |||
2048 | PCI_DEVICE_ID_NVIDIA_NVENET_15, | 2053 | PCI_DEVICE_ID_NVIDIA_NVENET_15, |
2049 | nvenet_msi_disable); | 2054 | nvenet_msi_disable); |
2050 | 2055 | ||
2051 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | 2056 | static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev) |
2052 | { | 2057 | { |
2053 | struct pci_dev *host_bridge; | 2058 | struct pci_dev *host_bridge; |
2059 | int pos; | ||
2060 | int i, dev_no; | ||
2061 | int found = 0; | ||
2062 | |||
2063 | dev_no = dev->devfn >> 3; | ||
2064 | for (i = dev_no; i >= 0; i--) { | ||
2065 | host_bridge = pci_get_slot(dev->bus, PCI_DEVFN(i, 0)); | ||
2066 | if (!host_bridge) | ||
2067 | continue; | ||
2068 | |||
2069 | pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); | ||
2070 | if (pos != 0) { | ||
2071 | found = 1; | ||
2072 | break; | ||
2073 | } | ||
2074 | pci_dev_put(host_bridge); | ||
2075 | } | ||
2076 | |||
2077 | if (!found) | ||
2078 | return; | ||
2079 | |||
2080 | /* root did that ! */ | ||
2081 | if (msi_ht_cap_enabled(host_bridge)) | ||
2082 | goto out; | ||
2083 | |||
2084 | ht_enable_msi_mapping(dev); | ||
2085 | |||
2086 | out: | ||
2087 | pci_dev_put(host_bridge); | ||
2088 | } | ||
2089 | |||
2090 | static void __devinit ht_disable_msi_mapping(struct pci_dev *dev) | ||
2091 | { | ||
2092 | int pos, ttl = 48; | ||
2093 | |||
2094 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); | ||
2095 | while (pos && ttl--) { | ||
2096 | u8 flags; | ||
2097 | |||
2098 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, | ||
2099 | &flags) == 0) { | ||
2100 | dev_info(&dev->dev, "Enabling HT MSI Mapping\n"); | ||
2101 | |||
2102 | pci_write_config_byte(dev, pos + HT_MSI_FLAGS, | ||
2103 | flags & ~HT_MSI_FLAGS_ENABLE); | ||
2104 | } | ||
2105 | pos = pci_find_next_ht_capability(dev, pos, | ||
2106 | HT_CAPTYPE_MSI_MAPPING); | ||
2107 | } | ||
2108 | } | ||
2109 | |||
2110 | static int __devinit ht_check_msi_mapping(struct pci_dev *dev) | ||
2111 | { | ||
2054 | int pos, ttl = 48; | 2112 | int pos, ttl = 48; |
2113 | int found = 0; | ||
2114 | |||
2115 | /* check if there is HT MSI cap or enabled on this device */ | ||
2116 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); | ||
2117 | while (pos && ttl--) { | ||
2118 | u8 flags; | ||
2119 | |||
2120 | if (found < 1) | ||
2121 | found = 1; | ||
2122 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, | ||
2123 | &flags) == 0) { | ||
2124 | if (flags & HT_MSI_FLAGS_ENABLE) { | ||
2125 | if (found < 2) { | ||
2126 | found = 2; | ||
2127 | break; | ||
2128 | } | ||
2129 | } | ||
2130 | } | ||
2131 | pos = pci_find_next_ht_capability(dev, pos, | ||
2132 | HT_CAPTYPE_MSI_MAPPING); | ||
2133 | } | ||
2134 | |||
2135 | return found; | ||
2136 | } | ||
2137 | |||
2138 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | ||
2139 | { | ||
2140 | struct pci_dev *host_bridge; | ||
2141 | int pos; | ||
2142 | int found; | ||
2143 | |||
2144 | /* check if there is HT MSI cap or enabled on this device */ | ||
2145 | found = ht_check_msi_mapping(dev); | ||
2146 | |||
2147 | /* no HT MSI CAP */ | ||
2148 | if (found == 0) | ||
2149 | return; | ||
2055 | 2150 | ||
2056 | /* | 2151 | /* |
2057 | * HT MSI mapping should be disabled on devices that are below | 2152 | * HT MSI mapping should be disabled on devices that are below |
@@ -2067,24 +2162,19 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | |||
2067 | pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); | 2162 | pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); |
2068 | if (pos != 0) { | 2163 | if (pos != 0) { |
2069 | /* Host bridge is to HT */ | 2164 | /* Host bridge is to HT */ |
2070 | ht_enable_msi_mapping(dev); | 2165 | if (found == 1) { |
2166 | /* it is not enabled, try to enable it */ | ||
2167 | nv_ht_enable_msi_mapping(dev); | ||
2168 | } | ||
2071 | return; | 2169 | return; |
2072 | } | 2170 | } |
2073 | 2171 | ||
2074 | /* Host bridge is not to HT, disable HT MSI mapping on this device */ | 2172 | /* HT MSI is not enabled */ |
2075 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); | 2173 | if (found == 1) |
2076 | while (pos && ttl--) { | 2174 | return; |
2077 | u8 flags; | ||
2078 | 2175 | ||
2079 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, | 2176 | /* Host bridge is not to HT, disable HT MSI mapping on this device */ |
2080 | &flags) == 0) { | 2177 | ht_disable_msi_mapping(dev); |
2081 | dev_info(&dev->dev, "Disabling HT MSI mapping"); | ||
2082 | pci_write_config_byte(dev, pos + HT_MSI_FLAGS, | ||
2083 | flags & ~HT_MSI_FLAGS_ENABLE); | ||
2084 | } | ||
2085 | pos = pci_find_next_ht_capability(dev, pos, | ||
2086 | HT_CAPTYPE_MSI_MAPPING); | ||
2087 | } | ||
2088 | } | 2178 | } |
2089 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); | 2179 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); |
2090 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); | 2180 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 3599828b9766..022e89ffec1d 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -133,7 +133,7 @@ | |||
133 | # define SCSPTR3 0xffed0024 /* 16 bit SCIF */ | 133 | # define SCSPTR3 0xffed0024 /* 16 bit SCIF */ |
134 | # define SCSPTR4 0xffee0024 /* 16 bit SCIF */ | 134 | # define SCSPTR4 0xffee0024 /* 16 bit SCIF */ |
135 | # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ | 135 | # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ |
136 | # define SCIF_OPER 0x0001 /* Overrun error bit */ | 136 | # define SCIF_ORER 0x0001 /* Overrun error bit */ |
137 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 137 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
138 | #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ | 138 | #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ |
139 | defined(CONFIG_CPU_SUBTYPE_SH7203) || \ | 139 | defined(CONFIG_CPU_SUBTYPE_SH7203) || \ |
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index ab69c1bf36a8..c2747bc88c6f 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c | |||
@@ -2164,19 +2164,20 @@ static void __exit panel_cleanup_module(void) | |||
2164 | if (scan_timer.function != NULL) | 2164 | if (scan_timer.function != NULL) |
2165 | del_timer(&scan_timer); | 2165 | del_timer(&scan_timer); |
2166 | 2166 | ||
2167 | if (keypad_enabled) | 2167 | if (pprt != NULL) { |
2168 | misc_deregister(&keypad_dev); | 2168 | if (keypad_enabled) |
2169 | misc_deregister(&keypad_dev); | ||
2170 | |||
2171 | if (lcd_enabled) { | ||
2172 | panel_lcd_print("\x0cLCD driver " PANEL_VERSION | ||
2173 | "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); | ||
2174 | misc_deregister(&lcd_dev); | ||
2175 | } | ||
2169 | 2176 | ||
2170 | if (lcd_enabled) { | 2177 | /* TODO: free all input signals */ |
2171 | panel_lcd_print("\x0cLCD driver " PANEL_VERSION | 2178 | parport_release(pprt); |
2172 | "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); | 2179 | parport_unregister_device(pprt); |
2173 | misc_deregister(&lcd_dev); | ||
2174 | } | 2180 | } |
2175 | |||
2176 | /* TODO: free all input signals */ | ||
2177 | |||
2178 | parport_release(pprt); | ||
2179 | parport_unregister_device(pprt); | ||
2180 | parport_unregister_driver(&panel_driver); | 2181 | parport_unregister_driver(&panel_driver); |
2181 | } | 2182 | } |
2182 | 2183 | ||
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig index 79c225acd1ad..f636296b54bc 100644 --- a/drivers/staging/rtl8187se/Kconfig +++ b/drivers/staging/rtl8187se/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config RTL8187SE | 1 | config RTL8187SE |
2 | tristate "RealTek RTL8187SE Wireless LAN NIC driver" | 2 | tristate "RealTek RTL8187SE Wireless LAN NIC driver" |
3 | depends on PCI | 3 | depends on PCI |
4 | depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS | ||
4 | default N | 5 | default N |
5 | ---help--- | 6 | ---help--- |
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c index af64cfbe16db..7370296225e1 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c | |||
@@ -234,20 +234,21 @@ out: | |||
234 | void ieee80211_crypto_deinit(void) | 234 | void ieee80211_crypto_deinit(void) |
235 | { | 235 | { |
236 | struct list_head *ptr, *n; | 236 | struct list_head *ptr, *n; |
237 | struct ieee80211_crypto_alg *alg = NULL; | ||
237 | 238 | ||
238 | if (hcrypt == NULL) | 239 | if (hcrypt == NULL) |
239 | return; | 240 | return; |
240 | 241 | ||
241 | for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; | 242 | list_for_each_safe(ptr, n, &hcrypt->algs) { |
242 | ptr = n, n = ptr->next) { | 243 | alg = list_entry(ptr, struct ieee80211_crypto_alg, list); |
243 | struct ieee80211_crypto_alg *alg = | 244 | if (alg) { |
244 | (struct ieee80211_crypto_alg *) ptr; | 245 | list_del(ptr); |
245 | list_del(ptr); | 246 | printk(KERN_DEBUG |
246 | printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " | 247 | "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n", |
247 | "'%s' (deinit)\n", alg->ops->name); | 248 | alg->ops->name); |
248 | kfree(alg); | 249 | kfree(alg); |
250 | } | ||
249 | } | 251 | } |
250 | |||
251 | kfree(hcrypt); | 252 | kfree(hcrypt); |
252 | } | 253 | } |
253 | 254 | ||
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 94534955e38b..66de5cc8ddf1 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c | |||
@@ -6161,10 +6161,10 @@ static void __exit rtl8180_pci_module_exit(void) | |||
6161 | { | 6161 | { |
6162 | pci_unregister_driver (&rtl8180_pci_driver); | 6162 | pci_unregister_driver (&rtl8180_pci_driver); |
6163 | rtl8180_proc_module_remove(); | 6163 | rtl8180_proc_module_remove(); |
6164 | ieee80211_crypto_deinit(); | ||
6165 | ieee80211_crypto_tkip_exit(); | 6164 | ieee80211_crypto_tkip_exit(); |
6166 | ieee80211_crypto_ccmp_exit(); | 6165 | ieee80211_crypto_ccmp_exit(); |
6167 | ieee80211_crypto_wep_exit(); | 6166 | ieee80211_crypto_wep_exit(); |
6167 | ieee80211_crypto_deinit(); | ||
6168 | DMESG("Exiting"); | 6168 | DMESG("Exiting"); |
6169 | } | 6169 | } |
6170 | 6170 | ||
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index b003f9a7e151..f716b2e92b65 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c | |||
@@ -319,16 +319,18 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
319 | struct usb_device *udev = interface_to_usbdev(intf); | 319 | struct usb_device *udev = interface_to_usbdev(intf); |
320 | struct wbsoft_priv *priv; | 320 | struct wbsoft_priv *priv; |
321 | struct ieee80211_hw *dev; | 321 | struct ieee80211_hw *dev; |
322 | int err; | 322 | int nr, err; |
323 | 323 | ||
324 | usb_get_dev(udev); | 324 | usb_get_dev(udev); |
325 | 325 | ||
326 | // 20060630.2 Check the device if it already be opened | 326 | // 20060630.2 Check the device if it already be opened |
327 | err = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ), | 327 | nr = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ), |
328 | 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, | 328 | 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, |
329 | 0x0, 0x400, <mp, 4, HZ*100 ); | 329 | 0x0, 0x400, <mp, 4, HZ*100 ); |
330 | if (err) | 330 | if (nr < 0) { |
331 | err = nr; | ||
331 | goto error; | 332 | goto error; |
333 | } | ||
332 | 334 | ||
333 | ltmp = cpu_to_le32(ltmp); | 335 | ltmp = cpu_to_le32(ltmp); |
334 | if (ltmp) { // Is already initialized? | 336 | if (ltmp) { // Is already initialized? |
@@ -337,8 +339,10 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
337 | } | 339 | } |
338 | 340 | ||
339 | dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops); | 341 | dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops); |
340 | if (!dev) | 342 | if (!dev) { |
343 | err = -ENOMEM; | ||
341 | goto error; | 344 | goto error; |
345 | } | ||
342 | 346 | ||
343 | priv = dev->priv; | 347 | priv = dev->priv; |
344 | 348 | ||
@@ -369,9 +373,11 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
369 | } | 373 | } |
370 | 374 | ||
371 | dev->extra_tx_headroom = 12; /* FIXME */ | 375 | dev->extra_tx_headroom = 12; /* FIXME */ |
372 | dev->flags = 0; | 376 | dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; |
377 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | ||
373 | 378 | ||
374 | dev->channel_change_time = 1000; | 379 | dev->channel_change_time = 1000; |
380 | dev->max_signal = 100; | ||
375 | dev->queues = 1; | 381 | dev->queues = 1; |
376 | 382 | ||
377 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz; | 383 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz; |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 326dd7f65ee9..b3d5a23ab56f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1376,6 +1376,15 @@ static struct usb_device_id acm_ids[] = { | |||
1376 | { USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */ | 1376 | { USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */ |
1377 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | 1377 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
1378 | }, | 1378 | }, |
1379 | { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ | ||
1380 | }, | ||
1381 | { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ | ||
1382 | .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on | ||
1383 | data interface instead of | ||
1384 | communications interface. | ||
1385 | Maybe we should define a new | ||
1386 | quirk for this. */ | ||
1387 | }, | ||
1379 | 1388 | ||
1380 | /* control interfaces with various AT-command sets */ | 1389 | /* control interfaces with various AT-command sets */ |
1381 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1390 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 31fb204f44c6..49e7f56e0d7f 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -653,7 +653,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, | |||
653 | if (result <= 0 && result != -ETIMEDOUT) | 653 | if (result <= 0 && result != -ETIMEDOUT) |
654 | continue; | 654 | continue; |
655 | if (result > 1 && ((u8 *)buf)[1] != type) { | 655 | if (result > 1 && ((u8 *)buf)[1] != type) { |
656 | result = -EPROTO; | 656 | result = -ENODATA; |
657 | continue; | 657 | continue; |
658 | } | 658 | } |
659 | break; | 659 | break; |
@@ -696,8 +696,13 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid, | |||
696 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, | 696 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, |
697 | (USB_DT_STRING << 8) + index, langid, buf, size, | 697 | (USB_DT_STRING << 8) + index, langid, buf, size, |
698 | USB_CTRL_GET_TIMEOUT); | 698 | USB_CTRL_GET_TIMEOUT); |
699 | if (!(result == 0 || result == -EPIPE)) | 699 | if (result == 0 || result == -EPIPE) |
700 | break; | 700 | continue; |
701 | if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) { | ||
702 | result = -ENODATA; | ||
703 | continue; | ||
704 | } | ||
705 | break; | ||
701 | } | 706 | } |
702 | return result; | 707 | return result; |
703 | } | 708 | } |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 3219d137340a..e55fef52a5dc 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -191,6 +191,7 @@ config USB_GADGET_OMAP | |||
191 | boolean "OMAP USB Device Controller" | 191 | boolean "OMAP USB Device Controller" |
192 | depends on ARCH_OMAP | 192 | depends on ARCH_OMAP |
193 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG | 193 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG |
194 | select USB_OTG_UTILS if ARCH_OMAP | ||
194 | help | 195 | help |
195 | Many Texas Instruments OMAP processors have flexible full | 196 | Many Texas Instruments OMAP processors have flexible full |
196 | speed USB device controllers, with support for up to 30 | 197 | speed USB device controllers, with support for up to 30 |
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index 80c2e7e9622f..38aa896cc5db 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c | |||
@@ -366,9 +366,9 @@ obex_bind(struct usb_configuration *c, struct usb_function *f) | |||
366 | f->hs_descriptors = usb_copy_descriptors(hs_function); | 366 | f->hs_descriptors = usb_copy_descriptors(hs_function); |
367 | 367 | ||
368 | obex->hs.obex_in = usb_find_endpoint(hs_function, | 368 | obex->hs.obex_in = usb_find_endpoint(hs_function, |
369 | f->descriptors, &obex_hs_ep_in_desc); | 369 | f->hs_descriptors, &obex_hs_ep_in_desc); |
370 | obex->hs.obex_out = usb_find_endpoint(hs_function, | 370 | obex->hs.obex_out = usb_find_endpoint(hs_function, |
371 | f->descriptors, &obex_hs_ep_out_desc); | 371 | f->hs_descriptors, &obex_hs_ep_out_desc); |
372 | } | 372 | } |
373 | 373 | ||
374 | /* Avoid letting this gadget enumerate until the userspace | 374 | /* Avoid letting this gadget enumerate until the userspace |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index b10fa31cc915..1ab9dac7e12d 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -3879,7 +3879,11 @@ static int __init check_parameters(struct fsg_dev *fsg) | |||
3879 | mod_data.protocol_type = USB_SC_SCSI; | 3879 | mod_data.protocol_type = USB_SC_SCSI; |
3880 | mod_data.protocol_name = "Transparent SCSI"; | 3880 | mod_data.protocol_name = "Transparent SCSI"; |
3881 | 3881 | ||
3882 | if (gadget_is_sh(fsg->gadget)) | 3882 | /* Some peripheral controllers are known not to be able to |
3883 | * halt bulk endpoints correctly. If one of them is present, | ||
3884 | * disable stalls. | ||
3885 | */ | ||
3886 | if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget)) | ||
3883 | mod_data.can_stall = 0; | 3887 | mod_data.can_stall = 0; |
3884 | 3888 | ||
3885 | if (mod_data.release == 0xffff) { // Parameter wasn't set | 3889 | if (mod_data.release == 0xffff) { // Parameter wasn't set |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index f3c6703cffda..d8d9a52a44b3 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -404,7 +404,10 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num, | |||
404 | } | 404 | } |
405 | if (zlt) | 405 | if (zlt) |
406 | tmp |= EP_QUEUE_HEAD_ZLT_SEL; | 406 | tmp |= EP_QUEUE_HEAD_ZLT_SEL; |
407 | |||
407 | p_QH->max_pkt_length = cpu_to_le32(tmp); | 408 | p_QH->max_pkt_length = cpu_to_le32(tmp); |
409 | p_QH->next_dtd_ptr = 1; | ||
410 | p_QH->size_ioc_int_sts = 0; | ||
408 | 411 | ||
409 | return; | 412 | return; |
410 | } | 413 | } |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 4725d15d096f..e551bb38852b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -485,6 +485,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
485 | * periodic_size can shrink by USBCMD update if hcc_params allows. | 485 | * periodic_size can shrink by USBCMD update if hcc_params allows. |
486 | */ | 486 | */ |
487 | ehci->periodic_size = DEFAULT_I_TDPS; | 487 | ehci->periodic_size = DEFAULT_I_TDPS; |
488 | INIT_LIST_HEAD(&ehci->cached_itd_list); | ||
488 | if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) | 489 | if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) |
489 | return retval; | 490 | return retval; |
490 | 491 | ||
@@ -497,6 +498,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
497 | 498 | ||
498 | ehci->reclaim = NULL; | 499 | ehci->reclaim = NULL; |
499 | ehci->next_uframe = -1; | 500 | ehci->next_uframe = -1; |
501 | ehci->clock_frame = -1; | ||
500 | 502 | ||
501 | /* | 503 | /* |
502 | * dedicate a qh for the async ring head, since we couldn't unlink | 504 | * dedicate a qh for the async ring head, since we couldn't unlink |
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 0431397836f6..10d52919abbb 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
@@ -128,6 +128,7 @@ static inline void qh_put (struct ehci_qh *qh) | |||
128 | 128 | ||
129 | static void ehci_mem_cleanup (struct ehci_hcd *ehci) | 129 | static void ehci_mem_cleanup (struct ehci_hcd *ehci) |
130 | { | 130 | { |
131 | free_cached_itd_list(ehci); | ||
131 | if (ehci->async) | 132 | if (ehci->async) |
132 | qh_put (ehci->async); | 133 | qh_put (ehci->async); |
133 | ehci->async = NULL; | 134 | ehci->async = NULL; |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index a081ee65bde6..07bcb931021b 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1004,7 +1004,8 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream) | |||
1004 | 1004 | ||
1005 | is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; | 1005 | is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; |
1006 | stream->bEndpointAddress &= 0x0f; | 1006 | stream->bEndpointAddress &= 0x0f; |
1007 | stream->ep->hcpriv = NULL; | 1007 | if (stream->ep) |
1008 | stream->ep->hcpriv = NULL; | ||
1008 | 1009 | ||
1009 | if (stream->rescheduled) { | 1010 | if (stream->rescheduled) { |
1010 | ehci_info (ehci, "ep%d%s-iso rescheduled " | 1011 | ehci_info (ehci, "ep%d%s-iso rescheduled " |
@@ -1653,14 +1654,28 @@ itd_complete ( | |||
1653 | (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); | 1654 | (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); |
1654 | } | 1655 | } |
1655 | iso_stream_put (ehci, stream); | 1656 | iso_stream_put (ehci, stream); |
1656 | /* OK to recycle this ITD now that its completion callback ran. */ | 1657 | |
1657 | done: | 1658 | done: |
1658 | usb_put_urb(urb); | 1659 | usb_put_urb(urb); |
1659 | itd->urb = NULL; | 1660 | itd->urb = NULL; |
1660 | itd->stream = NULL; | 1661 | if (ehci->clock_frame != itd->frame || itd->index[7] != -1) { |
1661 | list_move(&itd->itd_list, &stream->free_list); | 1662 | /* OK to recycle this ITD now. */ |
1662 | iso_stream_put(ehci, stream); | 1663 | itd->stream = NULL; |
1663 | 1664 | list_move(&itd->itd_list, &stream->free_list); | |
1665 | iso_stream_put(ehci, stream); | ||
1666 | } else { | ||
1667 | /* HW might remember this ITD, so we can't recycle it yet. | ||
1668 | * Move it to a safe place until a new frame starts. | ||
1669 | */ | ||
1670 | list_move(&itd->itd_list, &ehci->cached_itd_list); | ||
1671 | if (stream->refcount == 2) { | ||
1672 | /* If iso_stream_put() were called here, stream | ||
1673 | * would be freed. Instead, just prevent reuse. | ||
1674 | */ | ||
1675 | stream->ep->hcpriv = NULL; | ||
1676 | stream->ep = NULL; | ||
1677 | } | ||
1678 | } | ||
1664 | return retval; | 1679 | return retval; |
1665 | } | 1680 | } |
1666 | 1681 | ||
@@ -2101,6 +2116,20 @@ done: | |||
2101 | 2116 | ||
2102 | /*-------------------------------------------------------------------------*/ | 2117 | /*-------------------------------------------------------------------------*/ |
2103 | 2118 | ||
2119 | static void free_cached_itd_list(struct ehci_hcd *ehci) | ||
2120 | { | ||
2121 | struct ehci_itd *itd, *n; | ||
2122 | |||
2123 | list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) { | ||
2124 | struct ehci_iso_stream *stream = itd->stream; | ||
2125 | itd->stream = NULL; | ||
2126 | list_move(&itd->itd_list, &stream->free_list); | ||
2127 | iso_stream_put(ehci, stream); | ||
2128 | } | ||
2129 | } | ||
2130 | |||
2131 | /*-------------------------------------------------------------------------*/ | ||
2132 | |||
2104 | static void | 2133 | static void |
2105 | scan_periodic (struct ehci_hcd *ehci) | 2134 | scan_periodic (struct ehci_hcd *ehci) |
2106 | { | 2135 | { |
@@ -2115,10 +2144,17 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2115 | * Touches as few pages as possible: cache-friendly. | 2144 | * Touches as few pages as possible: cache-friendly. |
2116 | */ | 2145 | */ |
2117 | now_uframe = ehci->next_uframe; | 2146 | now_uframe = ehci->next_uframe; |
2118 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 2147 | if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { |
2119 | clock = ehci_readl(ehci, &ehci->regs->frame_index); | 2148 | clock = ehci_readl(ehci, &ehci->regs->frame_index); |
2120 | else | 2149 | clock_frame = (clock >> 3) % ehci->periodic_size; |
2150 | } else { | ||
2121 | clock = now_uframe + mod - 1; | 2151 | clock = now_uframe + mod - 1; |
2152 | clock_frame = -1; | ||
2153 | } | ||
2154 | if (ehci->clock_frame != clock_frame) { | ||
2155 | free_cached_itd_list(ehci); | ||
2156 | ehci->clock_frame = clock_frame; | ||
2157 | } | ||
2122 | clock %= mod; | 2158 | clock %= mod; |
2123 | clock_frame = clock >> 3; | 2159 | clock_frame = clock >> 3; |
2124 | 2160 | ||
@@ -2277,6 +2313,10 @@ restart: | |||
2277 | /* rescan the rest of this frame, then ... */ | 2313 | /* rescan the rest of this frame, then ... */ |
2278 | clock = now; | 2314 | clock = now; |
2279 | clock_frame = clock >> 3; | 2315 | clock_frame = clock >> 3; |
2316 | if (ehci->clock_frame != clock_frame) { | ||
2317 | free_cached_itd_list(ehci); | ||
2318 | ehci->clock_frame = clock_frame; | ||
2319 | } | ||
2280 | } else { | 2320 | } else { |
2281 | now_uframe++; | 2321 | now_uframe++; |
2282 | now_uframe %= mod; | 2322 | now_uframe %= mod; |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index fb7054ccf4fc..262b00c9b334 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -87,6 +87,10 @@ struct ehci_hcd { /* one per controller */ | |||
87 | int next_uframe; /* scan periodic, start here */ | 87 | int next_uframe; /* scan periodic, start here */ |
88 | unsigned periodic_sched; /* periodic activity count */ | 88 | unsigned periodic_sched; /* periodic activity count */ |
89 | 89 | ||
90 | /* list of itds completed while clock_frame was still active */ | ||
91 | struct list_head cached_itd_list; | ||
92 | unsigned clock_frame; | ||
93 | |||
90 | /* per root hub port */ | 94 | /* per root hub port */ |
91 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; | 95 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; |
92 | 96 | ||
@@ -220,6 +224,8 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
220 | } | 224 | } |
221 | } | 225 | } |
222 | 226 | ||
227 | static void free_cached_itd_list(struct ehci_hcd *ehci); | ||
228 | |||
223 | /*-------------------------------------------------------------------------*/ | 229 | /*-------------------------------------------------------------------------*/ |
224 | 230 | ||
225 | #include <linux/usb/ehci_def.h> | 231 | #include <linux/usb/ehci_def.h> |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 5a8fd5d57a11..2dc7606f319c 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -377,18 +377,8 @@ int __init musb_platform_init(struct musb *musb) | |||
377 | u32 revision; | 377 | u32 revision; |
378 | 378 | ||
379 | musb->mregs += DAVINCI_BASE_OFFSET; | 379 | musb->mregs += DAVINCI_BASE_OFFSET; |
380 | #if 0 | ||
381 | /* REVISIT there's something odd about clocking, this | ||
382 | * didn't appear do the job ... | ||
383 | */ | ||
384 | musb->clock = clk_get(pDevice, "usb"); | ||
385 | if (IS_ERR(musb->clock)) | ||
386 | return PTR_ERR(musb->clock); | ||
387 | 380 | ||
388 | status = clk_enable(musb->clock); | 381 | clk_enable(musb->clock); |
389 | if (status < 0) | ||
390 | return -ENODEV; | ||
391 | #endif | ||
392 | 382 | ||
393 | /* returns zero if e.g. not clocked */ | 383 | /* returns zero if e.g. not clocked */ |
394 | revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); | 384 | revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); |
@@ -453,5 +443,8 @@ int musb_platform_exit(struct musb *musb) | |||
453 | } | 443 | } |
454 | 444 | ||
455 | phy_off(); | 445 | phy_off(); |
446 | |||
447 | clk_disable(musb->clock); | ||
448 | |||
456 | return 0; | 449 | return 0; |
457 | } | 450 | } |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 2cc34fa05b73..af77e4659006 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -115,7 +115,7 @@ | |||
115 | 115 | ||
116 | 116 | ||
117 | unsigned musb_debug; | 117 | unsigned musb_debug; |
118 | module_param(musb_debug, uint, S_IRUGO | S_IWUSR); | 118 | module_param_named(debug, musb_debug, uint, S_IRUGO | S_IWUSR); |
119 | MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); | 119 | MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); |
120 | 120 | ||
121 | #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" | 121 | #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" |
@@ -767,6 +767,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | |||
767 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 767 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
768 | case OTG_STATE_A_HOST: | 768 | case OTG_STATE_A_HOST: |
769 | case OTG_STATE_A_SUSPEND: | 769 | case OTG_STATE_A_SUSPEND: |
770 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | ||
770 | musb_root_disconnect(musb); | 771 | musb_root_disconnect(musb); |
771 | if (musb->a_wait_bcon != 0) | 772 | if (musb->a_wait_bcon != 0) |
772 | musb_platform_try_idle(musb, jiffies | 773 | musb_platform_try_idle(musb, jiffies |
@@ -1815,7 +1816,7 @@ static void musb_free(struct musb *musb) | |||
1815 | #ifdef CONFIG_SYSFS | 1816 | #ifdef CONFIG_SYSFS |
1816 | device_remove_file(musb->controller, &dev_attr_mode); | 1817 | device_remove_file(musb->controller, &dev_attr_mode); |
1817 | device_remove_file(musb->controller, &dev_attr_vbus); | 1818 | device_remove_file(musb->controller, &dev_attr_vbus); |
1818 | #ifdef CONFIG_USB_MUSB_OTG | 1819 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
1819 | device_remove_file(musb->controller, &dev_attr_srp); | 1820 | device_remove_file(musb->controller, &dev_attr_srp); |
1820 | #endif | 1821 | #endif |
1821 | #endif | 1822 | #endif |
@@ -2063,7 +2064,7 @@ fail2: | |||
2063 | #ifdef CONFIG_SYSFS | 2064 | #ifdef CONFIG_SYSFS |
2064 | device_remove_file(musb->controller, &dev_attr_mode); | 2065 | device_remove_file(musb->controller, &dev_attr_mode); |
2065 | device_remove_file(musb->controller, &dev_attr_vbus); | 2066 | device_remove_file(musb->controller, &dev_attr_vbus); |
2066 | #ifdef CONFIG_USB_MUSB_OTG | 2067 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
2067 | device_remove_file(musb->controller, &dev_attr_srp); | 2068 | device_remove_file(musb->controller, &dev_attr_srp); |
2068 | #endif | 2069 | #endif |
2069 | #endif | 2070 | #endif |
@@ -2243,10 +2244,10 @@ static int __init musb_init(void) | |||
2243 | return platform_driver_probe(&musb_driver, musb_probe); | 2244 | return platform_driver_probe(&musb_driver, musb_probe); |
2244 | } | 2245 | } |
2245 | 2246 | ||
2246 | /* make us init after usbcore and before usb | 2247 | /* make us init after usbcore and i2c (transceivers, regulators, etc) |
2247 | * gadget and host-side drivers start to register | 2248 | * and before usb gadget and host-side drivers start to register |
2248 | */ | 2249 | */ |
2249 | subsys_initcall(musb_init); | 2250 | fs_initcall(musb_init); |
2250 | 2251 | ||
2251 | static void __exit musb_cleanup(void) | 2252 | static void __exit musb_cleanup(void) |
2252 | { | 2253 | { |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 4ea305387981..c7ebd0867fcc 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -575,7 +575,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
575 | struct usb_request *request = &req->request; | 575 | struct usb_request *request = &req->request; |
576 | struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; | 576 | struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; |
577 | void __iomem *epio = musb->endpoints[epnum].regs; | 577 | void __iomem *epio = musb->endpoints[epnum].regs; |
578 | u16 fifo_count = 0; | 578 | unsigned fifo_count = 0; |
579 | u16 len = musb_ep->packet_sz; | 579 | u16 len = musb_ep->packet_sz; |
580 | 580 | ||
581 | csr = musb_readw(epio, MUSB_RXCSR); | 581 | csr = musb_readw(epio, MUSB_RXCSR); |
@@ -687,7 +687,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
687 | len, fifo_count, | 687 | len, fifo_count, |
688 | musb_ep->packet_sz); | 688 | musb_ep->packet_sz); |
689 | 689 | ||
690 | fifo_count = min(len, fifo_count); | 690 | fifo_count = min_t(unsigned, len, fifo_count); |
691 | 691 | ||
692 | #ifdef CONFIG_USB_TUSB_OMAP_DMA | 692 | #ifdef CONFIG_USB_TUSB_OMAP_DMA |
693 | if (tusb_dma_omap() && musb_ep->dma) { | 693 | if (tusb_dma_omap() && musb_ep->dma) { |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index a035ceccf950..6dbbd0786a6a 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -335,16 +335,11 @@ musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb) | |||
335 | static struct musb_qh * | 335 | static struct musb_qh * |
336 | musb_giveback(struct musb_qh *qh, struct urb *urb, int status) | 336 | musb_giveback(struct musb_qh *qh, struct urb *urb, int status) |
337 | { | 337 | { |
338 | int is_in; | ||
339 | struct musb_hw_ep *ep = qh->hw_ep; | 338 | struct musb_hw_ep *ep = qh->hw_ep; |
340 | struct musb *musb = ep->musb; | 339 | struct musb *musb = ep->musb; |
340 | int is_in = usb_pipein(urb->pipe); | ||
341 | int ready = qh->is_ready; | 341 | int ready = qh->is_ready; |
342 | 342 | ||
343 | if (ep->is_shared_fifo) | ||
344 | is_in = 1; | ||
345 | else | ||
346 | is_in = usb_pipein(urb->pipe); | ||
347 | |||
348 | /* save toggle eagerly, for paranoia */ | 343 | /* save toggle eagerly, for paranoia */ |
349 | switch (qh->type) { | 344 | switch (qh->type) { |
350 | case USB_ENDPOINT_XFER_BULK: | 345 | case USB_ENDPOINT_XFER_BULK: |
@@ -432,7 +427,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb, | |||
432 | else | 427 | else |
433 | qh = musb_giveback(qh, urb, urb->status); | 428 | qh = musb_giveback(qh, urb, urb->status); |
434 | 429 | ||
435 | if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) { | 430 | if (qh != NULL && qh->is_ready) { |
436 | DBG(4, "... next ep%d %cX urb %p\n", | 431 | DBG(4, "... next ep%d %cX urb %p\n", |
437 | hw_ep->epnum, is_in ? 'R' : 'T', | 432 | hw_ep->epnum, is_in ? 'R' : 'T', |
438 | next_urb(qh)); | 433 | next_urb(qh)); |
@@ -942,8 +937,8 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) | |||
942 | switch (musb->ep0_stage) { | 937 | switch (musb->ep0_stage) { |
943 | case MUSB_EP0_IN: | 938 | case MUSB_EP0_IN: |
944 | fifo_dest = urb->transfer_buffer + urb->actual_length; | 939 | fifo_dest = urb->transfer_buffer + urb->actual_length; |
945 | fifo_count = min(len, ((u16) (urb->transfer_buffer_length | 940 | fifo_count = min_t(size_t, len, urb->transfer_buffer_length - |
946 | - urb->actual_length))); | 941 | urb->actual_length); |
947 | if (fifo_count < len) | 942 | if (fifo_count < len) |
948 | urb->status = -EOVERFLOW; | 943 | urb->status = -EOVERFLOW; |
949 | 944 | ||
@@ -976,10 +971,9 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) | |||
976 | } | 971 | } |
977 | /* FALLTHROUGH */ | 972 | /* FALLTHROUGH */ |
978 | case MUSB_EP0_OUT: | 973 | case MUSB_EP0_OUT: |
979 | fifo_count = min(qh->maxpacket, ((u16) | 974 | fifo_count = min_t(size_t, qh->maxpacket, |
980 | (urb->transfer_buffer_length | 975 | urb->transfer_buffer_length - |
981 | - urb->actual_length))); | 976 | urb->actual_length); |
982 | |||
983 | if (fifo_count) { | 977 | if (fifo_count) { |
984 | fifo_dest = (u8 *) (urb->transfer_buffer | 978 | fifo_dest = (u8 *) (urb->transfer_buffer |
985 | + urb->actual_length); | 979 | + urb->actual_length); |
@@ -1161,7 +1155,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1161 | struct urb *urb; | 1155 | struct urb *urb; |
1162 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; | 1156 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; |
1163 | void __iomem *epio = hw_ep->regs; | 1157 | void __iomem *epio = hw_ep->regs; |
1164 | struct musb_qh *qh = hw_ep->out_qh; | 1158 | struct musb_qh *qh = hw_ep->is_shared_fifo ? hw_ep->in_qh |
1159 | : hw_ep->out_qh; | ||
1165 | u32 status = 0; | 1160 | u32 status = 0; |
1166 | void __iomem *mbase = musb->mregs; | 1161 | void __iomem *mbase = musb->mregs; |
1167 | struct dma_channel *dma; | 1162 | struct dma_channel *dma; |
@@ -1308,7 +1303,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1308 | * packets before updating TXCSR ... other docs disagree ... | 1303 | * packets before updating TXCSR ... other docs disagree ... |
1309 | */ | 1304 | */ |
1310 | /* PIO: start next packet in this URB */ | 1305 | /* PIO: start next packet in this URB */ |
1311 | wLength = min(qh->maxpacket, (u16) wLength); | 1306 | if (wLength > qh->maxpacket) |
1307 | wLength = qh->maxpacket; | ||
1312 | musb_write_fifo(hw_ep, wLength, buf); | 1308 | musb_write_fifo(hw_ep, wLength, buf); |
1313 | qh->segsize = wLength; | 1309 | qh->segsize = wLength; |
1314 | 1310 | ||
@@ -1867,19 +1863,21 @@ static int musb_urb_enqueue( | |||
1867 | } | 1863 | } |
1868 | qh->type_reg = type_reg; | 1864 | qh->type_reg = type_reg; |
1869 | 1865 | ||
1870 | /* precompute rxinterval/txinterval register */ | 1866 | /* Precompute RXINTERVAL/TXINTERVAL register */ |
1871 | interval = min((u8)16, epd->bInterval); /* log encoding */ | ||
1872 | switch (qh->type) { | 1867 | switch (qh->type) { |
1873 | case USB_ENDPOINT_XFER_INT: | 1868 | case USB_ENDPOINT_XFER_INT: |
1874 | /* fullspeed uses linear encoding */ | 1869 | /* |
1875 | if (USB_SPEED_FULL == urb->dev->speed) { | 1870 | * Full/low speeds use the linear encoding, |
1876 | interval = epd->bInterval; | 1871 | * high speed uses the logarithmic encoding. |
1877 | if (!interval) | 1872 | */ |
1878 | interval = 1; | 1873 | if (urb->dev->speed <= USB_SPEED_FULL) { |
1874 | interval = max_t(u8, epd->bInterval, 1); | ||
1875 | break; | ||
1879 | } | 1876 | } |
1880 | /* FALLTHROUGH */ | 1877 | /* FALLTHROUGH */ |
1881 | case USB_ENDPOINT_XFER_ISOC: | 1878 | case USB_ENDPOINT_XFER_ISOC: |
1882 | /* iso always uses log encoding */ | 1879 | /* ISO always uses logarithmic encoding */ |
1880 | interval = min_t(u8, epd->bInterval, 16); | ||
1883 | break; | 1881 | break; |
1884 | default: | 1882 | default: |
1885 | /* REVISIT we actually want to use NAK limits, hinting to the | 1883 | /* REVISIT we actually want to use NAK limits, hinting to the |
@@ -2037,9 +2035,9 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
2037 | goto done; | 2035 | goto done; |
2038 | 2036 | ||
2039 | /* Any URB not actively programmed into endpoint hardware can be | 2037 | /* Any URB not actively programmed into endpoint hardware can be |
2040 | * immediately given back. Such an URB must be at the head of its | 2038 | * immediately given back; that's any URB not at the head of an |
2041 | * endpoint queue, unless someday we get real DMA queues. And even | 2039 | * endpoint queue, unless someday we get real DMA queues. And even |
2042 | * then, it might not be known to the hardware... | 2040 | * if it's at the head, it might not be known to the hardware... |
2043 | * | 2041 | * |
2044 | * Otherwise abort current transfer, pending dma, etc.; urb->status | 2042 | * Otherwise abort current transfer, pending dma, etc.; urb->status |
2045 | * has already been updated. This is a synchronous abort; it'd be | 2043 | * has already been updated. This is a synchronous abort; it'd be |
@@ -2078,6 +2076,15 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
2078 | qh->is_ready = 0; | 2076 | qh->is_ready = 0; |
2079 | __musb_giveback(musb, urb, 0); | 2077 | __musb_giveback(musb, urb, 0); |
2080 | qh->is_ready = ready; | 2078 | qh->is_ready = ready; |
2079 | |||
2080 | /* If nothing else (usually musb_giveback) is using it | ||
2081 | * and its URB list has emptied, recycle this qh. | ||
2082 | */ | ||
2083 | if (ready && list_empty(&qh->hep->urb_list)) { | ||
2084 | qh->hep->hcpriv = NULL; | ||
2085 | list_del(&qh->ring); | ||
2086 | kfree(qh); | ||
2087 | } | ||
2081 | } else | 2088 | } else |
2082 | ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); | 2089 | ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); |
2083 | done: | 2090 | done: |
@@ -2093,15 +2100,16 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) | |||
2093 | unsigned long flags; | 2100 | unsigned long flags; |
2094 | struct musb *musb = hcd_to_musb(hcd); | 2101 | struct musb *musb = hcd_to_musb(hcd); |
2095 | u8 is_in = epnum & USB_DIR_IN; | 2102 | u8 is_in = epnum & USB_DIR_IN; |
2096 | struct musb_qh *qh = hep->hcpriv; | 2103 | struct musb_qh *qh; |
2097 | struct urb *urb, *tmp; | 2104 | struct urb *urb; |
2098 | struct list_head *sched; | 2105 | struct list_head *sched; |
2099 | 2106 | ||
2100 | if (!qh) | ||
2101 | return; | ||
2102 | |||
2103 | spin_lock_irqsave(&musb->lock, flags); | 2107 | spin_lock_irqsave(&musb->lock, flags); |
2104 | 2108 | ||
2109 | qh = hep->hcpriv; | ||
2110 | if (qh == NULL) | ||
2111 | goto exit; | ||
2112 | |||
2105 | switch (qh->type) { | 2113 | switch (qh->type) { |
2106 | case USB_ENDPOINT_XFER_CONTROL: | 2114 | case USB_ENDPOINT_XFER_CONTROL: |
2107 | sched = &musb->control; | 2115 | sched = &musb->control; |
@@ -2135,13 +2143,28 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) | |||
2135 | 2143 | ||
2136 | /* cleanup */ | 2144 | /* cleanup */ |
2137 | musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); | 2145 | musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); |
2138 | } else | ||
2139 | urb = NULL; | ||
2140 | 2146 | ||
2141 | /* then just nuke all the others */ | 2147 | /* Then nuke all the others ... and advance the |
2142 | list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list) | 2148 | * queue on hw_ep (e.g. bulk ring) when we're done. |
2143 | musb_giveback(qh, urb, -ESHUTDOWN); | 2149 | */ |
2150 | while (!list_empty(&hep->urb_list)) { | ||
2151 | urb = next_urb(qh); | ||
2152 | urb->status = -ESHUTDOWN; | ||
2153 | musb_advance_schedule(musb, urb, qh->hw_ep, is_in); | ||
2154 | } | ||
2155 | } else { | ||
2156 | /* Just empty the queue; the hardware is busy with | ||
2157 | * other transfers, and since !qh->is_ready nothing | ||
2158 | * will activate any of these as it advances. | ||
2159 | */ | ||
2160 | while (!list_empty(&hep->urb_list)) | ||
2161 | __musb_giveback(musb, next_urb(qh), -ESHUTDOWN); | ||
2144 | 2162 | ||
2163 | hep->hcpriv = NULL; | ||
2164 | list_del(&qh->ring); | ||
2165 | kfree(qh); | ||
2166 | } | ||
2167 | exit: | ||
2145 | spin_unlock_irqrestore(&musb->lock, flags); | 2168 | spin_unlock_irqrestore(&musb->lock, flags); |
2146 | } | 2169 | } |
2147 | 2170 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index bfd0b68ceccd..b7c132bded7f 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -294,7 +294,11 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po | |||
294 | 294 | ||
295 | /* Ericsson products */ | 295 | /* Ericsson products */ |
296 | #define ERICSSON_VENDOR_ID 0x0bdb | 296 | #define ERICSSON_VENDOR_ID 0x0bdb |
297 | #define ERICSSON_PRODUCT_F3507G 0x1900 | 297 | #define ERICSSON_PRODUCT_F3507G_1 0x1900 |
298 | #define ERICSSON_PRODUCT_F3507G_2 0x1902 | ||
299 | |||
300 | #define BENQ_VENDOR_ID 0x04a5 | ||
301 | #define BENQ_PRODUCT_H10 0x4068 | ||
298 | 302 | ||
299 | static struct usb_device_id option_ids[] = { | 303 | static struct usb_device_id option_ids[] = { |
300 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 304 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
@@ -509,7 +513,10 @@ static struct usb_device_id option_ids[] = { | |||
509 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, | 513 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, |
510 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, | 514 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, |
511 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, | 515 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, |
512 | { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) }, | 516 | { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_1) }, |
517 | { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_2) }, | ||
518 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | ||
519 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ | ||
513 | { } /* Terminating entry */ | 520 | { } /* Terminating entry */ |
514 | }; | 521 | }; |
515 | MODULE_DEVICE_TABLE(usb, option_ids); | 522 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 50dc33a6065b..6f59c8e510ea 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -907,13 +907,13 @@ UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff, | |||
907 | "Genesys Logic", | 907 | "Genesys Logic", |
908 | "USB to IDE Optical", | 908 | "USB to IDE Optical", |
909 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 909 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
910 | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), | 910 | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), |
911 | 911 | ||
912 | UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff, | 912 | UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff, |
913 | "Genesys Logic", | 913 | "Genesys Logic", |
914 | "USB to IDE Disk", | 914 | "USB to IDE Disk", |
915 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 915 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
916 | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), | 916 | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), |
917 | 917 | ||
918 | /* Reported by Ben Efros <ben@pc-doctor.com> */ | 918 | /* Reported by Ben Efros <ben@pc-doctor.com> */ |
919 | UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, | 919 | UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, |
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index 8d0b1fb1e52e..1f51366417b9 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig | |||
@@ -16,6 +16,12 @@ config W1_SLAVE_SMEM | |||
16 | Say Y here if you want to connect 1-wire | 16 | Say Y here if you want to connect 1-wire |
17 | simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire. | 17 | simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire. |
18 | 18 | ||
19 | config W1_SLAVE_DS2431 | ||
20 | tristate "1kb EEPROM family support (DS2431)" | ||
21 | help | ||
22 | Say Y here if you want to use a 1-wire | ||
23 | 1kb EEPROM family device (DS2431) | ||
24 | |||
19 | config W1_SLAVE_DS2433 | 25 | config W1_SLAVE_DS2433 |
20 | tristate "4kb EEPROM family support (DS2433)" | 26 | tristate "4kb EEPROM family support (DS2433)" |
21 | help | 27 | help |
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index 990f400b6d22..f1f51f19b129 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o | 5 | obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o |
6 | obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o | 6 | obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o |
7 | obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o | ||
7 | obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o | 8 | obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o |
8 | obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o | 9 | obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o |
9 | obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o | 10 | obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o |
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index 858c16a544c2..139447148822 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c | |||
@@ -156,6 +156,9 @@ out_up: | |||
156 | */ | 156 | */ |
157 | static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) | 157 | static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) |
158 | { | 158 | { |
159 | #ifdef CONFIG_W1_SLAVE_DS2433_CRC | ||
160 | struct w1_f23_data *f23 = sl->family_data; | ||
161 | #endif | ||
159 | u8 wrbuf[4]; | 162 | u8 wrbuf[4]; |
160 | u8 rdbuf[W1_PAGE_SIZE + 3]; | 163 | u8 rdbuf[W1_PAGE_SIZE + 3]; |
161 | u8 es = (addr + len - 1) & 0x1f; | 164 | u8 es = (addr + len - 1) & 0x1f; |
@@ -196,7 +199,9 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) | |||
196 | 199 | ||
197 | /* Reset the bus to wake up the EEPROM (this may not be needed) */ | 200 | /* Reset the bus to wake up the EEPROM (this may not be needed) */ |
198 | w1_reset_bus(sl->master); | 201 | w1_reset_bus(sl->master); |
199 | 202 | #ifdef CONFIG_W1_SLAVE_DS2433_CRC | |
203 | f23->validcrc &= ~(1 << (addr >> W1_PAGE_BITS)); | ||
204 | #endif | ||
200 | return 0; | 205 | return 0; |
201 | } | 206 | } |
202 | 207 | ||