diff options
Diffstat (limited to 'drivers')
423 files changed, 10961 insertions, 6312 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 15a23031833f..958c1fa41900 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -513,11 +513,16 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
513 | { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */ | 513 | { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */ |
514 | { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */ | 514 | { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */ |
515 | { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */ | 515 | { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */ |
516 | { PCI_VDEVICE(INTEL, 0x3a22), board_ahci }, /* ICH10 */ | ||
516 | { PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */ | 517 | { PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */ |
518 | { PCI_VDEVICE(INTEL, 0x3b22), board_ahci }, /* PCH AHCI */ | ||
519 | { PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */ | ||
517 | { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ | 520 | { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ |
518 | { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ | 521 | { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ |
522 | { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH AHCI */ | ||
519 | { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ | 523 | { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ |
520 | { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ | 524 | { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ |
525 | { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ | ||
521 | 526 | ||
522 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 527 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
523 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 528 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index d0a14cf2bd74..56b8a3ff1286 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -596,9 +596,12 @@ static const struct ich_laptop ich_laptop[] = { | |||
596 | { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */ | 596 | { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */ |
597 | { 0x27DF, 0x1025, 0x0102 }, /* ICH7 on Acer 5602aWLMi */ | 597 | { 0x27DF, 0x1025, 0x0102 }, /* ICH7 on Acer 5602aWLMi */ |
598 | { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ | 598 | { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ |
599 | { 0x27DF, 0x1028, 0x02b0 }, /* ICH7 on unknown Dell */ | ||
599 | { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ | 600 | { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ |
600 | { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ | 601 | { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ |
602 | { 0x27DF, 0x103C, 0x361a }, /* ICH7 on unkown HP */ | ||
601 | { 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */ | 603 | { 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */ |
604 | { 0x27DF, 0x152D, 0x0778 }, /* ICH7 on unknown Intel */ | ||
602 | { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ | 605 | { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ |
603 | { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ | 606 | { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ |
604 | { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ | 607 | { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 045a486a09ea..8ac98ff16d7d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1515,6 +1515,7 @@ static int ata_hpa_resize(struct ata_device *dev) | |||
1515 | 1515 | ||
1516 | return rc; | 1516 | return rc; |
1517 | } | 1517 | } |
1518 | dev->n_native_sectors = native_sectors; | ||
1518 | 1519 | ||
1519 | /* nothing to do? */ | 1520 | /* nothing to do? */ |
1520 | if (native_sectors <= sectors || !ata_ignore_hpa) { | 1521 | if (native_sectors <= sectors || !ata_ignore_hpa) { |
@@ -3392,17 +3393,27 @@ int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel) | |||
3392 | 3393 | ||
3393 | static int ata_dev_set_mode(struct ata_device *dev) | 3394 | static int ata_dev_set_mode(struct ata_device *dev) |
3394 | { | 3395 | { |
3396 | struct ata_port *ap = dev->link->ap; | ||
3395 | struct ata_eh_context *ehc = &dev->link->eh_context; | 3397 | struct ata_eh_context *ehc = &dev->link->eh_context; |
3398 | const bool nosetxfer = dev->horkage & ATA_HORKAGE_NOSETXFER; | ||
3396 | const char *dev_err_whine = ""; | 3399 | const char *dev_err_whine = ""; |
3397 | int ign_dev_err = 0; | 3400 | int ign_dev_err = 0; |
3398 | unsigned int err_mask; | 3401 | unsigned int err_mask = 0; |
3399 | int rc; | 3402 | int rc; |
3400 | 3403 | ||
3401 | dev->flags &= ~ATA_DFLAG_PIO; | 3404 | dev->flags &= ~ATA_DFLAG_PIO; |
3402 | if (dev->xfer_shift == ATA_SHIFT_PIO) | 3405 | if (dev->xfer_shift == ATA_SHIFT_PIO) |
3403 | dev->flags |= ATA_DFLAG_PIO; | 3406 | dev->flags |= ATA_DFLAG_PIO; |
3404 | 3407 | ||
3405 | err_mask = ata_dev_set_xfermode(dev); | 3408 | if (nosetxfer && ap->flags & ATA_FLAG_SATA && ata_id_is_sata(dev->id)) |
3409 | dev_err_whine = " (SET_XFERMODE skipped)"; | ||
3410 | else { | ||
3411 | if (nosetxfer) | ||
3412 | ata_dev_printk(dev, KERN_WARNING, | ||
3413 | "NOSETXFER but PATA detected - can't " | ||
3414 | "skip SETXFER, might malfunction\n"); | ||
3415 | err_mask = ata_dev_set_xfermode(dev); | ||
3416 | } | ||
3406 | 3417 | ||
3407 | if (err_mask & ~AC_ERR_DEV) | 3418 | if (err_mask & ~AC_ERR_DEV) |
3408 | goto fail; | 3419 | goto fail; |
@@ -4089,6 +4100,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, | |||
4089 | unsigned int readid_flags) | 4100 | unsigned int readid_flags) |
4090 | { | 4101 | { |
4091 | u64 n_sectors = dev->n_sectors; | 4102 | u64 n_sectors = dev->n_sectors; |
4103 | u64 n_native_sectors = dev->n_native_sectors; | ||
4092 | int rc; | 4104 | int rc; |
4093 | 4105 | ||
4094 | if (!ata_dev_enabled(dev)) | 4106 | if (!ata_dev_enabled(dev)) |
@@ -4118,16 +4130,30 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, | |||
4118 | /* verify n_sectors hasn't changed */ | 4130 | /* verify n_sectors hasn't changed */ |
4119 | if (dev->class == ATA_DEV_ATA && n_sectors && | 4131 | if (dev->class == ATA_DEV_ATA && n_sectors && |
4120 | dev->n_sectors != n_sectors) { | 4132 | dev->n_sectors != n_sectors) { |
4121 | ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch " | 4133 | ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch " |
4122 | "%llu != %llu\n", | 4134 | "%llu != %llu\n", |
4123 | (unsigned long long)n_sectors, | 4135 | (unsigned long long)n_sectors, |
4124 | (unsigned long long)dev->n_sectors); | 4136 | (unsigned long long)dev->n_sectors); |
4125 | 4137 | /* | |
4126 | /* restore original n_sectors */ | 4138 | * Something could have caused HPA to be unlocked |
4127 | dev->n_sectors = n_sectors; | 4139 | * involuntarily. If n_native_sectors hasn't changed |
4128 | 4140 | * and the new size matches it, keep the device. | |
4129 | rc = -ENODEV; | 4141 | */ |
4130 | goto fail; | 4142 | if (dev->n_native_sectors == n_native_sectors && |
4143 | dev->n_sectors > n_sectors && | ||
4144 | dev->n_sectors == n_native_sectors) { | ||
4145 | ata_dev_printk(dev, KERN_WARNING, | ||
4146 | "new n_sectors matches native, probably " | ||
4147 | "late HPA unlock, continuing\n"); | ||
4148 | /* keep using the old n_sectors */ | ||
4149 | dev->n_sectors = n_sectors; | ||
4150 | } else { | ||
4151 | /* restore original n_[native]_sectors and fail */ | ||
4152 | dev->n_native_sectors = n_native_sectors; | ||
4153 | dev->n_sectors = n_sectors; | ||
4154 | rc = -ENODEV; | ||
4155 | goto fail; | ||
4156 | } | ||
4131 | } | 4157 | } |
4132 | 4158 | ||
4133 | return 0; | 4159 | return 0; |
@@ -4297,6 +4323,12 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4297 | /* Devices which aren't very happy with higher link speeds */ | 4323 | /* Devices which aren't very happy with higher link speeds */ |
4298 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, | 4324 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, |
4299 | 4325 | ||
4326 | /* | ||
4327 | * Devices which choke on SETXFER. Applies only if both the | ||
4328 | * device and controller are SATA. | ||
4329 | */ | ||
4330 | { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, | ||
4331 | |||
4300 | /* End Marker */ | 4332 | /* End Marker */ |
4301 | { } | 4333 | { } |
4302 | }; | 4334 | }; |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index fa22f94ca415..79711b64054b 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2327,7 +2327,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2327 | struct ata_port *ap = link->ap; | 2327 | struct ata_port *ap = link->ap; |
2328 | struct ata_link *slave = ap->slave_link; | 2328 | struct ata_link *slave = ap->slave_link; |
2329 | struct ata_eh_context *ehc = &link->eh_context; | 2329 | struct ata_eh_context *ehc = &link->eh_context; |
2330 | struct ata_eh_context *sehc = &slave->eh_context; | 2330 | struct ata_eh_context *sehc = slave ? &slave->eh_context : NULL; |
2331 | unsigned int *classes = ehc->classes; | 2331 | unsigned int *classes = ehc->classes; |
2332 | unsigned int lflags = link->flags; | 2332 | unsigned int lflags = link->flags; |
2333 | int verbose = !(ehc->i.flags & ATA_EHI_QUIET); | 2333 | int verbose = !(ehc->i.flags & ATA_EHI_QUIET); |
@@ -2517,6 +2517,10 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2517 | 2517 | ||
2518 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); | 2518 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); |
2519 | rc = ata_do_reset(link, reset, classes, deadline, true); | 2519 | rc = ata_do_reset(link, reset, classes, deadline, true); |
2520 | if (rc) { | ||
2521 | failed_link = link; | ||
2522 | goto fail; | ||
2523 | } | ||
2520 | } | 2524 | } |
2521 | } else { | 2525 | } else { |
2522 | if (verbose) | 2526 | if (verbose) |
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index 4b27617be26d..5702affcb325 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c | |||
@@ -26,9 +26,7 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/ata_platform.h> | 27 | #include <linux/ata_platform.h> |
28 | 28 | ||
29 | #include <mach/at91sam9260_matrix.h> | ||
30 | #include <mach/at91sam9_smc.h> | 29 | #include <mach/at91sam9_smc.h> |
31 | #include <mach/at91sam9260.h> | ||
32 | #include <mach/board.h> | 30 | #include <mach/board.h> |
33 | #include <mach/gpio.h> | 31 | #include <mach/gpio.h> |
34 | 32 | ||
@@ -44,65 +42,62 @@ struct at91_ide_info { | |||
44 | unsigned long mode; | 42 | unsigned long mode; |
45 | unsigned int cs; | 43 | unsigned int cs; |
46 | 44 | ||
45 | struct clk *mck; | ||
46 | |||
47 | void __iomem *ide_addr; | 47 | void __iomem *ide_addr; |
48 | void __iomem *alt_addr; | 48 | void __iomem *alt_addr; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | const struct ata_timing initial_timing = | 51 | static const struct ata_timing initial_timing = |
52 | {XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0}; | 52 | {XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0}; |
53 | 53 | ||
54 | static unsigned int calc_mck_cycles(unsigned int ns, unsigned int mck_hz) | 54 | static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz) |
55 | { | 55 | { |
56 | unsigned long mul; | 56 | unsigned long mul; |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * cycles = x [nsec] * f [Hz] / 10^9 [ns in sec] = | 59 | * cycles = x [nsec] * f [Hz] / 10^9 [ns in sec] = |
60 | * x * (f / 1_000_000_000) = | 60 | * x * (f / 1_000_000_000) = |
61 | * x * ((f * 65536) / 1_000_000_000) / 65536 = | 61 | * x * ((f * 65536) / 1_000_000_000) / 65536 = |
62 | * x * (((f / 10_000) * 65536) / 100_000) / 65536 = | 62 | * x * (((f / 10_000) * 65536) / 100_000) / 65536 = |
63 | */ | 63 | */ |
64 | 64 | ||
65 | mul = (mck_hz / 10000) << 16; | 65 | mul = (mck_hz / 10000) << 16; |
66 | mul /= 100000; | 66 | mul /= 100000; |
67 | 67 | ||
68 | return (ns * mul + 65536) >> 16; /* rounding */ | 68 | return (ns * mul + 65536) >> 16; /* rounding */ |
69 | } | 69 | } |
70 | 70 | ||
71 | static void set_smc_mode(struct at91_ide_info *info) | 71 | static void set_smc_mode(struct at91_ide_info *info) |
72 | { | 72 | { |
73 | at91_sys_write(AT91_SMC_MODE(info->cs), info->mode); | 73 | at91_sys_write(AT91_SMC_MODE(info->cs), info->mode); |
74 | return; | 74 | return; |
75 | } | 75 | } |
76 | 76 | ||
77 | static void set_smc_timing(struct device *dev, | 77 | static void set_smc_timing(struct device *dev, |
78 | struct at91_ide_info *info, const struct ata_timing *ata) | 78 | struct at91_ide_info *info, const struct ata_timing *ata) |
79 | { | 79 | { |
80 | int read_cycle, write_cycle, active, recover; | 80 | unsigned long read_cycle, write_cycle, active, recover; |
81 | int nrd_setup, nrd_pulse, nrd_recover; | 81 | unsigned long nrd_setup, nrd_pulse, nrd_recover; |
82 | int nwe_setup, nwe_pulse; | 82 | unsigned long nwe_setup, nwe_pulse; |
83 | 83 | ||
84 | int ncs_write_setup, ncs_write_pulse; | 84 | unsigned long ncs_write_setup, ncs_write_pulse; |
85 | int ncs_read_setup, ncs_read_pulse; | 85 | unsigned long ncs_read_setup, ncs_read_pulse; |
86 | 86 | ||
87 | unsigned int mck_hz; | 87 | unsigned long mck_hz; |
88 | struct clk *mck; | ||
89 | 88 | ||
90 | read_cycle = ata->cyc8b; | 89 | read_cycle = ata->cyc8b; |
91 | nrd_setup = ata->setup; | 90 | nrd_setup = ata->setup; |
92 | nrd_pulse = ata->act8b; | 91 | nrd_pulse = ata->act8b; |
93 | nrd_recover = ata->rec8b; | 92 | nrd_recover = ata->rec8b; |
94 | 93 | ||
95 | mck = clk_get(NULL, "mck"); | 94 | mck_hz = clk_get_rate(info->mck); |
96 | BUG_ON(IS_ERR(mck)); | ||
97 | mck_hz = clk_get_rate(mck); | ||
98 | 95 | ||
99 | read_cycle = calc_mck_cycles(read_cycle, mck_hz); | 96 | read_cycle = calc_mck_cycles(read_cycle, mck_hz); |
100 | nrd_setup = calc_mck_cycles(nrd_setup, mck_hz); | 97 | nrd_setup = calc_mck_cycles(nrd_setup, mck_hz); |
101 | nrd_pulse = calc_mck_cycles(nrd_pulse, mck_hz); | 98 | nrd_pulse = calc_mck_cycles(nrd_pulse, mck_hz); |
102 | nrd_recover = calc_mck_cycles(nrd_recover, mck_hz); | 99 | nrd_recover = calc_mck_cycles(nrd_recover, mck_hz); |
103 | 100 | ||
104 | clk_put(mck); | ||
105 | |||
106 | active = nrd_setup + nrd_pulse; | 101 | active = nrd_setup + nrd_pulse; |
107 | recover = read_cycle - active; | 102 | recover = read_cycle - active; |
108 | 103 | ||
@@ -121,13 +116,13 @@ static void set_smc_timing(struct device *dev, | |||
121 | ncs_write_setup = ncs_read_setup; | 116 | ncs_write_setup = ncs_read_setup; |
122 | ncs_write_pulse = ncs_read_pulse; | 117 | ncs_write_pulse = ncs_read_pulse; |
123 | 118 | ||
124 | dev_dbg(dev, "ATA timings: nrd_setup = %d nrd_pulse = %d nrd_cycle = %d\n", | 119 | dev_dbg(dev, "ATA timings: nrd_setup = %lu nrd_pulse = %lu nrd_cycle = %lu\n", |
125 | nrd_setup, nrd_pulse, read_cycle); | 120 | nrd_setup, nrd_pulse, read_cycle); |
126 | dev_dbg(dev, "ATA timings: nwe_setup = %d nwe_pulse = %d nwe_cycle = %d\n", | 121 | dev_dbg(dev, "ATA timings: nwe_setup = %lu nwe_pulse = %lu nwe_cycle = %lu\n", |
127 | nwe_setup, nwe_pulse, write_cycle); | 122 | nwe_setup, nwe_pulse, write_cycle); |
128 | dev_dbg(dev, "ATA timings: ncs_read_setup = %d ncs_read_pulse = %d\n", | 123 | dev_dbg(dev, "ATA timings: ncs_read_setup = %lu ncs_read_pulse = %lu\n", |
129 | ncs_read_setup, ncs_read_pulse); | 124 | ncs_read_setup, ncs_read_pulse); |
130 | dev_dbg(dev, "ATA timings: ncs_write_setup = %d ncs_write_pulse = %d\n", | 125 | dev_dbg(dev, "ATA timings: ncs_write_setup = %lu ncs_write_pulse = %lu\n", |
131 | ncs_write_setup, ncs_write_pulse); | 126 | ncs_write_setup, ncs_write_pulse); |
132 | 127 | ||
133 | at91_sys_write(AT91_SMC_SETUP(info->cs), | 128 | at91_sys_write(AT91_SMC_SETUP(info->cs), |
@@ -217,6 +212,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev) | |||
217 | struct resource *mem_res; | 212 | struct resource *mem_res; |
218 | struct ata_host *host; | 213 | struct ata_host *host; |
219 | struct ata_port *ap; | 214 | struct ata_port *ap; |
215 | |||
220 | int irq_flags = 0; | 216 | int irq_flags = 0; |
221 | int irq = 0; | 217 | int irq = 0; |
222 | int ret; | 218 | int ret; |
@@ -261,6 +257,13 @@ static int __devinit pata_at91_probe(struct platform_device *pdev) | |||
261 | return -ENOMEM; | 257 | return -ENOMEM; |
262 | } | 258 | } |
263 | 259 | ||
260 | info->mck = clk_get(NULL, "mck"); | ||
261 | |||
262 | if (IS_ERR(info->mck)) { | ||
263 | dev_err(dev, "failed to get access to mck clock\n"); | ||
264 | return -ENODEV; | ||
265 | } | ||
266 | |||
264 | info->cs = board->chipselect; | 267 | info->cs = board->chipselect; |
265 | info->mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | | 268 | info->mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | |
266 | AT91_SMC_EXNWMODE_READY | AT91_SMC_BAT_SELECT | | 269 | AT91_SMC_EXNWMODE_READY | AT91_SMC_BAT_SELECT | |
@@ -304,6 +307,7 @@ err_alt_ioremap: | |||
304 | devm_iounmap(dev, info->ide_addr); | 307 | devm_iounmap(dev, info->ide_addr); |
305 | 308 | ||
306 | err_ide_ioremap: | 309 | err_ide_ioremap: |
310 | clk_put(info->mck); | ||
307 | kfree(info); | 311 | kfree(info); |
308 | 312 | ||
309 | return ret; | 313 | return ret; |
@@ -312,11 +316,12 @@ err_ide_ioremap: | |||
312 | static int __devexit pata_at91_remove(struct platform_device *pdev) | 316 | static int __devexit pata_at91_remove(struct platform_device *pdev) |
313 | { | 317 | { |
314 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | 318 | struct ata_host *host = dev_get_drvdata(&pdev->dev); |
315 | struct at91_ide_info *info = host->private_data; | 319 | struct at91_ide_info *info; |
316 | struct device *dev = &pdev->dev; | 320 | struct device *dev = &pdev->dev; |
317 | 321 | ||
318 | if (!host) | 322 | if (!host) |
319 | return 0; | 323 | return 0; |
324 | info = host->private_data; | ||
320 | 325 | ||
321 | ata_host_detach(host); | 326 | ata_host_detach(host); |
322 | 327 | ||
@@ -325,6 +330,7 @@ static int __devexit pata_at91_remove(struct platform_device *pdev) | |||
325 | 330 | ||
326 | devm_iounmap(dev, info->ide_addr); | 331 | devm_iounmap(dev, info->ide_addr); |
327 | devm_iounmap(dev, info->alt_addr); | 332 | devm_iounmap(dev, info->alt_addr); |
333 | clk_put(info->mck); | ||
328 | 334 | ||
329 | kfree(info); | 335 | kfree(info); |
330 | return 0; | 336 | return 0; |
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 8d9343accf3c..abdd19fe990a 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c | |||
@@ -653,7 +653,8 @@ static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance) | |||
653 | 653 | ||
654 | ap = host->ports[i]; | 654 | ap = host->ports[i]; |
655 | ocd = ap->dev->platform_data; | 655 | ocd = ap->dev->platform_data; |
656 | if (!ap || (ap->flags & ATA_FLAG_DISABLED)) | 656 | |
657 | if (ap->flags & ATA_FLAG_DISABLED) | ||
657 | continue; | 658 | continue; |
658 | 659 | ||
659 | ocd = ap->dev->platform_data; | 660 | ocd = ap->dev->platform_data; |
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index f4d009ed50ac..dc99e26f8e5b 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -411,6 +411,7 @@ static struct pcmcia_device_id pcmcia_devices[] = { | |||
411 | PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9), | 411 | PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9), |
412 | PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591), | 412 | PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591), |
413 | PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728), | 413 | PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728), |
414 | PCMCIA_DEVICE_PROD_ID12("CNF ", "CD-ROM", 0x46d7db81, 0x66536591), | ||
414 | PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), | 415 | PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), |
415 | PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), | 416 | PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), |
416 | PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), | 417 | PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 23714aefb825..c19417e02208 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -2514,7 +2514,7 @@ static void mv_unexpected_intr(struct ata_port *ap, int edma_was_enabled) | |||
2514 | char *when = "idle"; | 2514 | char *when = "idle"; |
2515 | 2515 | ||
2516 | ata_ehi_clear_desc(ehi); | 2516 | ata_ehi_clear_desc(ehi); |
2517 | if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { | 2517 | if (ap->flags & ATA_FLAG_DISABLED) { |
2518 | when = "disabled"; | 2518 | when = "disabled"; |
2519 | } else if (edma_was_enabled) { | 2519 | } else if (edma_was_enabled) { |
2520 | when = "EDMA enabled"; | 2520 | when = "EDMA enabled"; |
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 030ec079b184..35bd5cc7f285 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -532,7 +532,7 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance) | |||
532 | struct ata_port *ap = host->ports[i]; | 532 | struct ata_port *ap = host->ports[i]; |
533 | u32 bmdma2 = readl(mmio_base + sil_port[ap->port_no].bmdma2); | 533 | u32 bmdma2 = readl(mmio_base + sil_port[ap->port_no].bmdma2); |
534 | 534 | ||
535 | if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED)) | 535 | if (unlikely(ap->flags & ATA_FLAG_DISABLED)) |
536 | continue; | 536 | continue; |
537 | 537 | ||
538 | /* turn off SATA_IRQ if not supported */ | 538 | /* turn off SATA_IRQ if not supported */ |
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index e8beb8e5b626..05dd307e8f02 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
@@ -428,6 +428,9 @@ int devres_release_all(struct device *dev) | |||
428 | { | 428 | { |
429 | unsigned long flags; | 429 | unsigned long flags; |
430 | 430 | ||
431 | /* Looks like an uninitialized device structure */ | ||
432 | if (WARN_ON(dev->devres_head.next == NULL)) | ||
433 | return -ENODEV; | ||
431 | spin_lock_irqsave(&dev->devres_lock, flags); | 434 | spin_lock_irqsave(&dev->devres_lock, flags); |
432 | return release_nodes(dev, dev->devres_head.next, &dev->devres_head, | 435 | return release_nodes(dev, dev->devres_head.next, &dev->devres_head, |
433 | flags); | 436 | flags); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index fc466531260e..7376367bcb80 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -180,7 +180,6 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
180 | goto err; | 180 | goto err; |
181 | } | 181 | } |
182 | /* Pages will be freed by vfree() */ | 182 | /* Pages will be freed by vfree() */ |
183 | fw_priv->pages = NULL; | ||
184 | fw_priv->page_array_size = 0; | 183 | fw_priv->page_array_size = 0; |
185 | fw_priv->nr_pages = 0; | 184 | fw_priv->nr_pages = 0; |
186 | complete(&fw_priv->completion); | 185 | complete(&fw_priv->completion); |
@@ -217,8 +216,10 @@ firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
217 | ret_count = -ENODEV; | 216 | ret_count = -ENODEV; |
218 | goto out; | 217 | goto out; |
219 | } | 218 | } |
220 | if (offset > fw->size) | 219 | if (offset > fw->size) { |
221 | return 0; | 220 | ret_count = 0; |
221 | goto out; | ||
222 | } | ||
222 | if (count > fw->size - offset) | 223 | if (count > fw->size - offset) |
223 | count = fw->size - offset; | 224 | count = fw->size - offset; |
224 | 225 | ||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 79a9ae5238ac..0d903909af7e 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -275,9 +275,9 @@ int sysdev_register(struct sys_device *sysdev) | |||
275 | drv->add(sysdev); | 275 | drv->add(sysdev); |
276 | } | 276 | } |
277 | mutex_unlock(&sysdev_drivers_lock); | 277 | mutex_unlock(&sysdev_drivers_lock); |
278 | kobject_uevent(&sysdev->kobj, KOBJ_ADD); | ||
278 | } | 279 | } |
279 | 280 | ||
280 | kobject_uevent(&sysdev->kobj, KOBJ_ADD); | ||
281 | return error; | 281 | return error; |
282 | } | 282 | } |
283 | 283 | ||
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 668dc234b8e2..1e6b7c14f697 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/ioport.h> | 36 | #include <linux/ioport.h> |
37 | #include <linux/mm.h> | 37 | #include <linux/mm.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/smp_lock.h> | ||
39 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
40 | #include <linux/reboot.h> | 41 | #include <linux/reboot.h> |
41 | #include <linux/spinlock.h> | 42 | #include <linux/spinlock.h> |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index bb72ada9f074..1d886e079c58 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -298,6 +298,22 @@ config BLK_DEV_NBD | |||
298 | 298 | ||
299 | If unsure, say N. | 299 | If unsure, say N. |
300 | 300 | ||
301 | config BLK_DEV_OSD | ||
302 | tristate "OSD object-as-blkdev support" | ||
303 | depends on SCSI_OSD_ULD | ||
304 | ---help--- | ||
305 | Saying Y or M here will allow the exporting of a single SCSI | ||
306 | OSD (object-based storage) object as a Linux block device. | ||
307 | |||
308 | For example, if you create a 2G object on an OSD device, | ||
309 | you can then use this module to present that 2G object as | ||
310 | a Linux block device. | ||
311 | |||
312 | To compile this driver as a module, choose M here: the | ||
313 | module will be called osdblk. | ||
314 | |||
315 | If unsure, say N. | ||
316 | |||
301 | config BLK_DEV_SX8 | 317 | config BLK_DEV_SX8 |
302 | tristate "Promise SATA SX8 support" | 318 | tristate "Promise SATA SX8 support" |
303 | depends on PCI | 319 | depends on PCI |
diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 7755a5e2a85e..cdaa3f8fddf0 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile | |||
@@ -23,6 +23,7 @@ obj-$(CONFIG_XILINX_SYSACE) += xsysace.o | |||
23 | obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o | 23 | obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o |
24 | obj-$(CONFIG_MG_DISK) += mg_disk.o | 24 | obj-$(CONFIG_MG_DISK) += mg_disk.o |
25 | obj-$(CONFIG_SUNVDC) += sunvdc.o | 25 | obj-$(CONFIG_SUNVDC) += sunvdc.o |
26 | obj-$(CONFIG_BLK_DEV_OSD) += osdblk.o | ||
26 | 27 | ||
27 | obj-$(CONFIG_BLK_DEV_UMEM) += umem.o | 28 | obj-$(CONFIG_BLK_DEV_UMEM) += umem.o |
28 | obj-$(CONFIG_BLK_DEV_NBD) += nbd.o | 29 | obj-$(CONFIG_BLK_DEV_NBD) += nbd.o |
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index f5e7180d7f47..3ff02941b3dd 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c | |||
@@ -1627,7 +1627,7 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, | |||
1627 | drive, dtp->blocks, dtp->spt, dtp->stretch); | 1627 | drive, dtp->blocks, dtp->spt, dtp->stretch); |
1628 | 1628 | ||
1629 | /* sanity check */ | 1629 | /* sanity check */ |
1630 | if (!dtp || setprm.track != dtp->blocks/dtp->spt/2 || | 1630 | if (setprm.track != dtp->blocks/dtp->spt/2 || |
1631 | setprm.head != 2) { | 1631 | setprm.head != 2) { |
1632 | redo_fd_request(); | 1632 | redo_fd_request(); |
1633 | return -EINVAL; | 1633 | return -EINVAL; |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 65a0655e7fc8..a52cc7fe45ea 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <linux/major.h> | 31 | #include <linux/major.h> |
31 | #include <linux/fs.h> | 32 | #include <linux/fs.h> |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 801f4ab83302..5757188cd1fb 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -61,7 +61,6 @@ | |||
61 | #include <linux/blkdev.h> | 61 | #include <linux/blkdev.h> |
62 | #include <linux/blkpg.h> | 62 | #include <linux/blkpg.h> |
63 | #include <linux/init.h> | 63 | #include <linux/init.h> |
64 | #include <linux/smp_lock.h> | ||
65 | #include <linux/swap.h> | 64 | #include <linux/swap.h> |
66 | #include <linux/slab.h> | 65 | #include <linux/slab.h> |
67 | #include <linux/loop.h> | 66 | #include <linux/loop.h> |
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c new file mode 100644 index 000000000000..13c1aee6aa3f --- /dev/null +++ b/drivers/block/osdblk.c | |||
@@ -0,0 +1,701 @@ | |||
1 | |||
2 | /* | ||
3 | osdblk.c -- Export a single SCSI OSD object as a Linux block device | ||
4 | |||
5 | |||
6 | Copyright 2009 Red Hat, Inc. | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; see the file COPYING. If not, write to | ||
19 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | |||
21 | |||
22 | Instructions for use | ||
23 | -------------------- | ||
24 | |||
25 | 1) Map a Linux block device to an existing OSD object. | ||
26 | |||
27 | In this example, we will use partition id 1234, object id 5678, | ||
28 | OSD device /dev/osd1. | ||
29 | |||
30 | $ echo "1234 5678 /dev/osd1" > /sys/class/osdblk/add | ||
31 | |||
32 | |||
33 | 2) List all active blkdev<->object mappings. | ||
34 | |||
35 | In this example, we have performed step #1 twice, creating two blkdevs, | ||
36 | mapped to two separate OSD objects. | ||
37 | |||
38 | $ cat /sys/class/osdblk/list | ||
39 | 0 174 1234 5678 /dev/osd1 | ||
40 | 1 179 1994 897123 /dev/osd0 | ||
41 | |||
42 | The columns, in order, are: | ||
43 | - blkdev unique id | ||
44 | - blkdev assigned major | ||
45 | - OSD object partition id | ||
46 | - OSD object id | ||
47 | - OSD device | ||
48 | |||
49 | |||
50 | 3) Remove an active blkdev<->object mapping. | ||
51 | |||
52 | In this example, we remove the mapping with blkdev unique id 1. | ||
53 | |||
54 | $ echo 1 > /sys/class/osdblk/remove | ||
55 | |||
56 | |||
57 | NOTE: The actual creation and deletion of OSD objects is outside the scope | ||
58 | of this driver. | ||
59 | |||
60 | */ | ||
61 | |||
62 | #include <linux/kernel.h> | ||
63 | #include <linux/device.h> | ||
64 | #include <linux/module.h> | ||
65 | #include <linux/fs.h> | ||
66 | #include <scsi/osd_initiator.h> | ||
67 | #include <scsi/osd_attributes.h> | ||
68 | #include <scsi/osd_sec.h> | ||
69 | #include <scsi/scsi_device.h> | ||
70 | |||
71 | #define DRV_NAME "osdblk" | ||
72 | #define PFX DRV_NAME ": " | ||
73 | |||
74 | /* #define _OSDBLK_DEBUG */ | ||
75 | #ifdef _OSDBLK_DEBUG | ||
76 | #define OSDBLK_DEBUG(fmt, a...) \ | ||
77 | printk(KERN_NOTICE "osdblk @%s:%d: " fmt, __func__, __LINE__, ##a) | ||
78 | #else | ||
79 | #define OSDBLK_DEBUG(fmt, a...) \ | ||
80 | do { if (0) printk(fmt, ##a); } while (0) | ||
81 | #endif | ||
82 | |||
83 | MODULE_AUTHOR("Jeff Garzik <jeff@garzik.org>"); | ||
84 | MODULE_DESCRIPTION("block device inside an OSD object osdblk.ko"); | ||
85 | MODULE_LICENSE("GPL"); | ||
86 | |||
87 | struct osdblk_device; | ||
88 | |||
89 | enum { | ||
90 | OSDBLK_MINORS_PER_MAJOR = 256, /* max minors per blkdev */ | ||
91 | OSDBLK_MAX_REQ = 32, /* max parallel requests */ | ||
92 | OSDBLK_OP_TIMEOUT = 4 * 60, /* sync OSD req timeout */ | ||
93 | }; | ||
94 | |||
95 | struct osdblk_request { | ||
96 | struct request *rq; /* blk layer request */ | ||
97 | struct bio *bio; /* cloned bio */ | ||
98 | struct osdblk_device *osdev; /* associated blkdev */ | ||
99 | }; | ||
100 | |||
101 | struct osdblk_device { | ||
102 | int id; /* blkdev unique id */ | ||
103 | |||
104 | int major; /* blkdev assigned major */ | ||
105 | struct gendisk *disk; /* blkdev's gendisk and rq */ | ||
106 | struct request_queue *q; | ||
107 | |||
108 | struct osd_dev *osd; /* associated OSD */ | ||
109 | |||
110 | char name[32]; /* blkdev name, e.g. osdblk34 */ | ||
111 | |||
112 | spinlock_t lock; /* queue lock */ | ||
113 | |||
114 | struct osd_obj_id obj; /* OSD partition, obj id */ | ||
115 | uint8_t obj_cred[OSD_CAP_LEN]; /* OSD cred */ | ||
116 | |||
117 | struct osdblk_request req[OSDBLK_MAX_REQ]; /* request table */ | ||
118 | |||
119 | struct list_head node; | ||
120 | |||
121 | char osd_path[0]; /* OSD device path */ | ||
122 | }; | ||
123 | |||
124 | static struct class *class_osdblk; /* /sys/class/osdblk */ | ||
125 | static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */ | ||
126 | static LIST_HEAD(osdblkdev_list); | ||
127 | |||
128 | static struct block_device_operations osdblk_bd_ops = { | ||
129 | .owner = THIS_MODULE, | ||
130 | }; | ||
131 | |||
132 | static const struct osd_attr g_attr_logical_length = ATTR_DEF( | ||
133 | OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8); | ||
134 | |||
135 | static void osdblk_make_credential(u8 cred_a[OSD_CAP_LEN], | ||
136 | const struct osd_obj_id *obj) | ||
137 | { | ||
138 | osd_sec_init_nosec_doall_caps(cred_a, obj, false, true); | ||
139 | } | ||
140 | |||
141 | /* copied from exofs; move to libosd? */ | ||
142 | /* | ||
143 | * Perform a synchronous OSD operation. copied from exofs; move to libosd? | ||
144 | */ | ||
145 | static int osd_sync_op(struct osd_request *or, int timeout, uint8_t *credential) | ||
146 | { | ||
147 | int ret; | ||
148 | |||
149 | or->timeout = timeout; | ||
150 | ret = osd_finalize_request(or, 0, credential, NULL); | ||
151 | if (ret) | ||
152 | return ret; | ||
153 | |||
154 | ret = osd_execute_request(or); | ||
155 | |||
156 | /* osd_req_decode_sense(or, ret); */ | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Perform an asynchronous OSD operation. copied from exofs; move to libosd? | ||
162 | */ | ||
163 | static int osd_async_op(struct osd_request *or, osd_req_done_fn *async_done, | ||
164 | void *caller_context, u8 *cred) | ||
165 | { | ||
166 | int ret; | ||
167 | |||
168 | ret = osd_finalize_request(or, 0, cred, NULL); | ||
169 | if (ret) | ||
170 | return ret; | ||
171 | |||
172 | ret = osd_execute_request_async(or, async_done, caller_context); | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | /* copied from exofs; move to libosd? */ | ||
178 | static int extract_attr_from_req(struct osd_request *or, struct osd_attr *attr) | ||
179 | { | ||
180 | struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */ | ||
181 | void *iter = NULL; | ||
182 | int nelem; | ||
183 | |||
184 | do { | ||
185 | nelem = 1; | ||
186 | osd_req_decode_get_attr_list(or, &cur_attr, &nelem, &iter); | ||
187 | if ((cur_attr.attr_page == attr->attr_page) && | ||
188 | (cur_attr.attr_id == attr->attr_id)) { | ||
189 | attr->len = cur_attr.len; | ||
190 | attr->val_ptr = cur_attr.val_ptr; | ||
191 | return 0; | ||
192 | } | ||
193 | } while (iter); | ||
194 | |||
195 | return -EIO; | ||
196 | } | ||
197 | |||
198 | static int osdblk_get_obj_size(struct osdblk_device *osdev, u64 *size_out) | ||
199 | { | ||
200 | struct osd_request *or; | ||
201 | struct osd_attr attr; | ||
202 | int ret; | ||
203 | |||
204 | /* start request */ | ||
205 | or = osd_start_request(osdev->osd, GFP_KERNEL); | ||
206 | if (!or) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | /* create a get-attributes(length) request */ | ||
210 | osd_req_get_attributes(or, &osdev->obj); | ||
211 | |||
212 | osd_req_add_get_attr_list(or, &g_attr_logical_length, 1); | ||
213 | |||
214 | /* execute op synchronously */ | ||
215 | ret = osd_sync_op(or, OSDBLK_OP_TIMEOUT, osdev->obj_cred); | ||
216 | if (ret) | ||
217 | goto out; | ||
218 | |||
219 | /* extract length from returned attribute info */ | ||
220 | attr = g_attr_logical_length; | ||
221 | ret = extract_attr_from_req(or, &attr); | ||
222 | if (ret) | ||
223 | goto out; | ||
224 | |||
225 | *size_out = get_unaligned_be64(attr.val_ptr); | ||
226 | |||
227 | out: | ||
228 | osd_end_request(or); | ||
229 | return ret; | ||
230 | |||
231 | } | ||
232 | |||
233 | static void osdblk_osd_complete(struct osd_request *or, void *private) | ||
234 | { | ||
235 | struct osdblk_request *orq = private; | ||
236 | struct osd_sense_info osi; | ||
237 | int ret = osd_req_decode_sense(or, &osi); | ||
238 | |||
239 | if (ret) { | ||
240 | ret = -EIO; | ||
241 | OSDBLK_DEBUG("osdblk_osd_complete with err=%d\n", ret); | ||
242 | } | ||
243 | |||
244 | /* complete OSD request */ | ||
245 | osd_end_request(or); | ||
246 | |||
247 | /* complete request passed to osdblk by block layer */ | ||
248 | __blk_end_request_all(orq->rq, ret); | ||
249 | } | ||
250 | |||
251 | static void bio_chain_put(struct bio *chain) | ||
252 | { | ||
253 | struct bio *tmp; | ||
254 | |||
255 | while (chain) { | ||
256 | tmp = chain; | ||
257 | chain = chain->bi_next; | ||
258 | |||
259 | bio_put(tmp); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | static struct bio *bio_chain_clone(struct bio *old_chain, gfp_t gfpmask) | ||
264 | { | ||
265 | struct bio *tmp, *new_chain = NULL, *tail = NULL; | ||
266 | |||
267 | while (old_chain) { | ||
268 | tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs); | ||
269 | if (!tmp) | ||
270 | goto err_out; | ||
271 | |||
272 | __bio_clone(tmp, old_chain); | ||
273 | tmp->bi_bdev = NULL; | ||
274 | gfpmask &= ~__GFP_WAIT; | ||
275 | tmp->bi_next = NULL; | ||
276 | |||
277 | if (!new_chain) | ||
278 | new_chain = tail = tmp; | ||
279 | else { | ||
280 | tail->bi_next = tmp; | ||
281 | tail = tmp; | ||
282 | } | ||
283 | |||
284 | old_chain = old_chain->bi_next; | ||
285 | } | ||
286 | |||
287 | return new_chain; | ||
288 | |||
289 | err_out: | ||
290 | OSDBLK_DEBUG("bio_chain_clone with err\n"); | ||
291 | bio_chain_put(new_chain); | ||
292 | return NULL; | ||
293 | } | ||
294 | |||
295 | static void osdblk_rq_fn(struct request_queue *q) | ||
296 | { | ||
297 | struct osdblk_device *osdev = q->queuedata; | ||
298 | |||
299 | while (1) { | ||
300 | struct request *rq; | ||
301 | struct osdblk_request *orq; | ||
302 | struct osd_request *or; | ||
303 | struct bio *bio; | ||
304 | bool do_write, do_flush; | ||
305 | |||
306 | /* peek at request from block layer */ | ||
307 | rq = blk_fetch_request(q); | ||
308 | if (!rq) | ||
309 | break; | ||
310 | |||
311 | /* filter out block requests we don't understand */ | ||
312 | if (!blk_fs_request(rq) && !blk_barrier_rq(rq)) { | ||
313 | blk_end_request_all(rq, 0); | ||
314 | continue; | ||
315 | } | ||
316 | |||
317 | /* deduce our operation (read, write, flush) */ | ||
318 | /* I wish the block layer simplified cmd_type/cmd_flags/cmd[] | ||
319 | * into a clearly defined set of RPC commands: | ||
320 | * read, write, flush, scsi command, power mgmt req, | ||
321 | * driver-specific, etc. | ||
322 | */ | ||
323 | |||
324 | do_flush = (rq->special == (void *) 0xdeadbeefUL); | ||
325 | do_write = (rq_data_dir(rq) == WRITE); | ||
326 | |||
327 | if (!do_flush) { /* osd_flush does not use a bio */ | ||
328 | /* a bio clone to be passed down to OSD request */ | ||
329 | bio = bio_chain_clone(rq->bio, GFP_ATOMIC); | ||
330 | if (!bio) | ||
331 | break; | ||
332 | } else | ||
333 | bio = NULL; | ||
334 | |||
335 | /* alloc internal OSD request, for OSD command execution */ | ||
336 | or = osd_start_request(osdev->osd, GFP_ATOMIC); | ||
337 | if (!or) { | ||
338 | bio_chain_put(bio); | ||
339 | OSDBLK_DEBUG("osd_start_request with err\n"); | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | orq = &osdev->req[rq->tag]; | ||
344 | orq->rq = rq; | ||
345 | orq->bio = bio; | ||
346 | orq->osdev = osdev; | ||
347 | |||
348 | /* init OSD command: flush, write or read */ | ||
349 | if (do_flush) | ||
350 | osd_req_flush_object(or, &osdev->obj, | ||
351 | OSD_CDB_FLUSH_ALL, 0, 0); | ||
352 | else if (do_write) | ||
353 | osd_req_write(or, &osdev->obj, blk_rq_pos(rq) * 512ULL, | ||
354 | bio, blk_rq_bytes(rq)); | ||
355 | else | ||
356 | osd_req_read(or, &osdev->obj, blk_rq_pos(rq) * 512ULL, | ||
357 | bio, blk_rq_bytes(rq)); | ||
358 | |||
359 | OSDBLK_DEBUG("%s 0x%x bytes at 0x%llx\n", | ||
360 | do_flush ? "flush" : do_write ? | ||
361 | "write" : "read", blk_rq_bytes(rq), | ||
362 | blk_rq_pos(rq) * 512ULL); | ||
363 | |||
364 | /* begin OSD command execution */ | ||
365 | if (osd_async_op(or, osdblk_osd_complete, orq, | ||
366 | osdev->obj_cred)) { | ||
367 | osd_end_request(or); | ||
368 | blk_requeue_request(q, rq); | ||
369 | bio_chain_put(bio); | ||
370 | OSDBLK_DEBUG("osd_execute_request_async with err\n"); | ||
371 | break; | ||
372 | } | ||
373 | |||
374 | /* remove the special 'flush' marker, now that the command | ||
375 | * is executing | ||
376 | */ | ||
377 | rq->special = NULL; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | static void osdblk_prepare_flush(struct request_queue *q, struct request *rq) | ||
382 | { | ||
383 | /* add driver-specific marker, to indicate that this request | ||
384 | * is a flush command | ||
385 | */ | ||
386 | rq->special = (void *) 0xdeadbeefUL; | ||
387 | } | ||
388 | |||
389 | static void osdblk_free_disk(struct osdblk_device *osdev) | ||
390 | { | ||
391 | struct gendisk *disk = osdev->disk; | ||
392 | |||
393 | if (!disk) | ||
394 | return; | ||
395 | |||
396 | if (disk->flags & GENHD_FL_UP) | ||
397 | del_gendisk(disk); | ||
398 | if (disk->queue) | ||
399 | blk_cleanup_queue(disk->queue); | ||
400 | put_disk(disk); | ||
401 | } | ||
402 | |||
403 | static int osdblk_init_disk(struct osdblk_device *osdev) | ||
404 | { | ||
405 | struct gendisk *disk; | ||
406 | struct request_queue *q; | ||
407 | int rc; | ||
408 | u64 obj_size = 0; | ||
409 | |||
410 | /* contact OSD, request size info about the object being mapped */ | ||
411 | rc = osdblk_get_obj_size(osdev, &obj_size); | ||
412 | if (rc) | ||
413 | return rc; | ||
414 | |||
415 | /* create gendisk info */ | ||
416 | disk = alloc_disk(OSDBLK_MINORS_PER_MAJOR); | ||
417 | if (!disk) | ||
418 | return -ENOMEM; | ||
419 | |||
420 | sprintf(disk->disk_name, DRV_NAME "%d", osdev->id); | ||
421 | disk->major = osdev->major; | ||
422 | disk->first_minor = 0; | ||
423 | disk->fops = &osdblk_bd_ops; | ||
424 | disk->private_data = osdev; | ||
425 | |||
426 | /* init rq */ | ||
427 | q = blk_init_queue(osdblk_rq_fn, &osdev->lock); | ||
428 | if (!q) { | ||
429 | put_disk(disk); | ||
430 | return -ENOMEM; | ||
431 | } | ||
432 | |||
433 | /* switch queue to TCQ mode; allocate tag map */ | ||
434 | rc = blk_queue_init_tags(q, OSDBLK_MAX_REQ, NULL); | ||
435 | if (rc) { | ||
436 | blk_cleanup_queue(q); | ||
437 | put_disk(disk); | ||
438 | return rc; | ||
439 | } | ||
440 | |||
441 | /* Set our limits to the lower device limits, because osdblk cannot | ||
442 | * sleep when allocating a lower-request and therefore cannot be | ||
443 | * bouncing. | ||
444 | */ | ||
445 | blk_queue_stack_limits(q, osd_request_queue(osdev->osd)); | ||
446 | |||
447 | blk_queue_prep_rq(q, blk_queue_start_tag); | ||
448 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH, osdblk_prepare_flush); | ||
449 | |||
450 | disk->queue = q; | ||
451 | |||
452 | q->queuedata = osdev; | ||
453 | |||
454 | osdev->disk = disk; | ||
455 | osdev->q = q; | ||
456 | |||
457 | /* finally, announce the disk to the world */ | ||
458 | set_capacity(disk, obj_size / 512ULL); | ||
459 | add_disk(disk); | ||
460 | |||
461 | printk(KERN_INFO "%s: Added of size 0x%llx\n", | ||
462 | disk->disk_name, (unsigned long long)obj_size); | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | /******************************************************************** | ||
468 | * /sys/class/osdblk/ | ||
469 | * add map OSD object to blkdev | ||
470 | * remove unmap OSD object | ||
471 | * list show mappings | ||
472 | *******************************************************************/ | ||
473 | |||
474 | static void class_osdblk_release(struct class *cls) | ||
475 | { | ||
476 | kfree(cls); | ||
477 | } | ||
478 | |||
479 | static ssize_t class_osdblk_list(struct class *c, char *data) | ||
480 | { | ||
481 | int n = 0; | ||
482 | struct list_head *tmp; | ||
483 | |||
484 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
485 | |||
486 | list_for_each(tmp, &osdblkdev_list) { | ||
487 | struct osdblk_device *osdev; | ||
488 | |||
489 | osdev = list_entry(tmp, struct osdblk_device, node); | ||
490 | |||
491 | n += sprintf(data+n, "%d %d %llu %llu %s\n", | ||
492 | osdev->id, | ||
493 | osdev->major, | ||
494 | osdev->obj.partition, | ||
495 | osdev->obj.id, | ||
496 | osdev->osd_path); | ||
497 | } | ||
498 | |||
499 | mutex_unlock(&ctl_mutex); | ||
500 | return n; | ||
501 | } | ||
502 | |||
503 | static ssize_t class_osdblk_add(struct class *c, const char *buf, size_t count) | ||
504 | { | ||
505 | struct osdblk_device *osdev; | ||
506 | ssize_t rc; | ||
507 | int irc, new_id = 0; | ||
508 | struct list_head *tmp; | ||
509 | |||
510 | if (!try_module_get(THIS_MODULE)) | ||
511 | return -ENODEV; | ||
512 | |||
513 | /* new osdblk_device object */ | ||
514 | osdev = kzalloc(sizeof(*osdev) + strlen(buf) + 1, GFP_KERNEL); | ||
515 | if (!osdev) { | ||
516 | rc = -ENOMEM; | ||
517 | goto err_out_mod; | ||
518 | } | ||
519 | |||
520 | /* static osdblk_device initialization */ | ||
521 | spin_lock_init(&osdev->lock); | ||
522 | INIT_LIST_HEAD(&osdev->node); | ||
523 | |||
524 | /* generate unique id: find highest unique id, add one */ | ||
525 | |||
526 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
527 | |||
528 | list_for_each(tmp, &osdblkdev_list) { | ||
529 | struct osdblk_device *osdev; | ||
530 | |||
531 | osdev = list_entry(tmp, struct osdblk_device, node); | ||
532 | if (osdev->id > new_id) | ||
533 | new_id = osdev->id + 1; | ||
534 | } | ||
535 | |||
536 | osdev->id = new_id; | ||
537 | |||
538 | /* add to global list */ | ||
539 | list_add_tail(&osdev->node, &osdblkdev_list); | ||
540 | |||
541 | mutex_unlock(&ctl_mutex); | ||
542 | |||
543 | /* parse add command */ | ||
544 | if (sscanf(buf, "%llu %llu %s", &osdev->obj.partition, &osdev->obj.id, | ||
545 | osdev->osd_path) != 3) { | ||
546 | rc = -EINVAL; | ||
547 | goto err_out_slot; | ||
548 | } | ||
549 | |||
550 | /* initialize rest of new object */ | ||
551 | sprintf(osdev->name, DRV_NAME "%d", osdev->id); | ||
552 | |||
553 | /* contact requested OSD */ | ||
554 | osdev->osd = osduld_path_lookup(osdev->osd_path); | ||
555 | if (IS_ERR(osdev->osd)) { | ||
556 | rc = PTR_ERR(osdev->osd); | ||
557 | goto err_out_slot; | ||
558 | } | ||
559 | |||
560 | /* build OSD credential */ | ||
561 | osdblk_make_credential(osdev->obj_cred, &osdev->obj); | ||
562 | |||
563 | /* register our block device */ | ||
564 | irc = register_blkdev(0, osdev->name); | ||
565 | if (irc < 0) { | ||
566 | rc = irc; | ||
567 | goto err_out_osd; | ||
568 | } | ||
569 | |||
570 | osdev->major = irc; | ||
571 | |||
572 | /* set up and announce blkdev mapping */ | ||
573 | rc = osdblk_init_disk(osdev); | ||
574 | if (rc) | ||
575 | goto err_out_blkdev; | ||
576 | |||
577 | return count; | ||
578 | |||
579 | err_out_blkdev: | ||
580 | unregister_blkdev(osdev->major, osdev->name); | ||
581 | err_out_osd: | ||
582 | osduld_put_device(osdev->osd); | ||
583 | err_out_slot: | ||
584 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
585 | list_del_init(&osdev->node); | ||
586 | mutex_unlock(&ctl_mutex); | ||
587 | |||
588 | kfree(osdev); | ||
589 | err_out_mod: | ||
590 | OSDBLK_DEBUG("Error adding device %s\n", buf); | ||
591 | module_put(THIS_MODULE); | ||
592 | return rc; | ||
593 | } | ||
594 | |||
595 | static ssize_t class_osdblk_remove(struct class *c, const char *buf, | ||
596 | size_t count) | ||
597 | { | ||
598 | struct osdblk_device *osdev = NULL; | ||
599 | int target_id, rc; | ||
600 | unsigned long ul; | ||
601 | struct list_head *tmp; | ||
602 | |||
603 | rc = strict_strtoul(buf, 10, &ul); | ||
604 | if (rc) | ||
605 | return rc; | ||
606 | |||
607 | /* convert to int; abort if we lost anything in the conversion */ | ||
608 | target_id = (int) ul; | ||
609 | if (target_id != ul) | ||
610 | return -EINVAL; | ||
611 | |||
612 | /* remove object from list immediately */ | ||
613 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
614 | |||
615 | list_for_each(tmp, &osdblkdev_list) { | ||
616 | osdev = list_entry(tmp, struct osdblk_device, node); | ||
617 | if (osdev->id == target_id) { | ||
618 | list_del_init(&osdev->node); | ||
619 | break; | ||
620 | } | ||
621 | osdev = NULL; | ||
622 | } | ||
623 | |||
624 | mutex_unlock(&ctl_mutex); | ||
625 | |||
626 | if (!osdev) | ||
627 | return -ENOENT; | ||
628 | |||
629 | /* clean up and free blkdev and associated OSD connection */ | ||
630 | osdblk_free_disk(osdev); | ||
631 | unregister_blkdev(osdev->major, osdev->name); | ||
632 | osduld_put_device(osdev->osd); | ||
633 | kfree(osdev); | ||
634 | |||
635 | /* release module ref */ | ||
636 | module_put(THIS_MODULE); | ||
637 | |||
638 | return count; | ||
639 | } | ||
640 | |||
641 | static struct class_attribute class_osdblk_attrs[] = { | ||
642 | __ATTR(add, 0200, NULL, class_osdblk_add), | ||
643 | __ATTR(remove, 0200, NULL, class_osdblk_remove), | ||
644 | __ATTR(list, 0444, class_osdblk_list, NULL), | ||
645 | __ATTR_NULL | ||
646 | }; | ||
647 | |||
648 | static int osdblk_sysfs_init(void) | ||
649 | { | ||
650 | int ret = 0; | ||
651 | |||
652 | /* | ||
653 | * create control files in sysfs | ||
654 | * /sys/class/osdblk/... | ||
655 | */ | ||
656 | class_osdblk = kzalloc(sizeof(*class_osdblk), GFP_KERNEL); | ||
657 | if (!class_osdblk) | ||
658 | return -ENOMEM; | ||
659 | |||
660 | class_osdblk->name = DRV_NAME; | ||
661 | class_osdblk->owner = THIS_MODULE; | ||
662 | class_osdblk->class_release = class_osdblk_release; | ||
663 | class_osdblk->class_attrs = class_osdblk_attrs; | ||
664 | |||
665 | ret = class_register(class_osdblk); | ||
666 | if (ret) { | ||
667 | kfree(class_osdblk); | ||
668 | class_osdblk = NULL; | ||
669 | printk(PFX "failed to create class osdblk\n"); | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static void osdblk_sysfs_cleanup(void) | ||
677 | { | ||
678 | if (class_osdblk) | ||
679 | class_destroy(class_osdblk); | ||
680 | class_osdblk = NULL; | ||
681 | } | ||
682 | |||
683 | static int __init osdblk_init(void) | ||
684 | { | ||
685 | int rc; | ||
686 | |||
687 | rc = osdblk_sysfs_init(); | ||
688 | if (rc) | ||
689 | return rc; | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | static void __exit osdblk_exit(void) | ||
695 | { | ||
696 | osdblk_sysfs_cleanup(); | ||
697 | } | ||
698 | |||
699 | module_init(osdblk_init); | ||
700 | module_exit(osdblk_exit); | ||
701 | |||
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 83650e00632d..99a506f619b7 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -1372,8 +1372,10 @@ try_next_bio: | |||
1372 | wakeup = (pd->write_congestion_on > 0 | 1372 | wakeup = (pd->write_congestion_on > 0 |
1373 | && pd->bio_queue_size <= pd->write_congestion_off); | 1373 | && pd->bio_queue_size <= pd->write_congestion_off); |
1374 | spin_unlock(&pd->lock); | 1374 | spin_unlock(&pd->lock); |
1375 | if (wakeup) | 1375 | if (wakeup) { |
1376 | clear_bdi_congested(&pd->disk->queue->backing_dev_info, WRITE); | 1376 | clear_bdi_congested(&pd->disk->queue->backing_dev_info, |
1377 | BLK_RW_ASYNC); | ||
1378 | } | ||
1377 | 1379 | ||
1378 | pkt->sleep_time = max(PACKET_WAIT_TIME, 1); | 1380 | pkt->sleep_time = max(PACKET_WAIT_TIME, 1); |
1379 | pkt_set_state(pkt, PACKET_WAITING_STATE); | 1381 | pkt_set_state(pkt, PACKET_WAITING_STATE); |
@@ -2592,10 +2594,10 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio) | |||
2592 | spin_lock(&pd->lock); | 2594 | spin_lock(&pd->lock); |
2593 | if (pd->write_congestion_on > 0 | 2595 | if (pd->write_congestion_on > 0 |
2594 | && pd->bio_queue_size >= pd->write_congestion_on) { | 2596 | && pd->bio_queue_size >= pd->write_congestion_on) { |
2595 | set_bdi_congested(&q->backing_dev_info, WRITE); | 2597 | set_bdi_congested(&q->backing_dev_info, BLK_RW_ASYNC); |
2596 | do { | 2598 | do { |
2597 | spin_unlock(&pd->lock); | 2599 | spin_unlock(&pd->lock); |
2598 | congestion_wait(WRITE, HZ); | 2600 | congestion_wait(BLK_RW_ASYNC, HZ); |
2599 | spin_lock(&pd->lock); | 2601 | spin_lock(&pd->lock); |
2600 | } while(pd->bio_queue_size > pd->write_congestion_off); | 2602 | } while(pd->bio_queue_size > pd->write_congestion_off); |
2601 | } | 2603 | } |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 43db3ea15b54..aa1a3d5a3e2b 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -213,7 +213,7 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | |||
213 | * Only allow the generic SCSI ioctls if the host can support it. | 213 | * Only allow the generic SCSI ioctls if the host can support it. |
214 | */ | 214 | */ |
215 | if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI)) | 215 | if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI)) |
216 | return -ENOIOCTLCMD; | 216 | return -ENOTTY; |
217 | 217 | ||
218 | return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); | 218 | return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); |
219 | } | 219 | } |
@@ -360,6 +360,9 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
360 | blk_queue_max_phys_segments(vblk->disk->queue, vblk->sg_elems-2); | 360 | blk_queue_max_phys_segments(vblk->disk->queue, vblk->sg_elems-2); |
361 | blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2); | 361 | blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2); |
362 | 362 | ||
363 | /* No need to bounce any requests */ | ||
364 | blk_queue_bounce_limit(vblk->disk->queue, BLK_BOUNCE_ANY); | ||
365 | |||
363 | /* No real sector limit. */ | 366 | /* No real sector limit. */ |
364 | blk_queue_max_sectors(vblk->disk->queue, -1U); | 367 | blk_queue_max_sectors(vblk->disk->queue, -1U); |
365 | 368 | ||
@@ -424,7 +427,12 @@ static unsigned int features[] = { | |||
424 | VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY | 427 | VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY |
425 | }; | 428 | }; |
426 | 429 | ||
427 | static struct virtio_driver virtio_blk = { | 430 | /* |
431 | * virtio_blk causes spurious section mismatch warning by | ||
432 | * simultaneously referring to a __devinit and a __devexit function. | ||
433 | * Use __refdata to avoid this warning. | ||
434 | */ | ||
435 | static struct virtio_driver __refdata virtio_blk = { | ||
428 | .feature_table = features, | 436 | .feature_table = features, |
429 | .feature_table_size = ARRAY_SIZE(features), | 437 | .feature_table_size = ARRAY_SIZE(features), |
430 | .driver.name = KBUILD_MODNAME, | 438 | .driver.name = KBUILD_MODNAME, |
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 4575171e5beb..b2590409f25e 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c | |||
@@ -374,7 +374,7 @@ err: | |||
374 | static void __exit z2_exit(void) | 374 | static void __exit z2_exit(void) |
375 | { | 375 | { |
376 | int i, j; | 376 | int i, j; |
377 | blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256); | 377 | blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT); |
378 | unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME); | 378 | unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME); |
379 | del_gendisk(z2ram_gendisk); | 379 | del_gendisk(z2ram_gendisk); |
380 | put_disk(z2ram_gendisk); | 380 | put_disk(z2ram_gendisk); |
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 1df9dda2e377..d5cde6d86f89 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/types.h> | 31 | #include <linux/types.h> |
33 | #include <linux/errno.h> | 32 | #include <linux/errno.h> |
34 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 72429b6b2fa8..6c32fbf07164 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -81,6 +81,7 @@ static char *serial_version = "4.30"; | |||
81 | #include <linux/mm.h> | 81 | #include <linux/mm.h> |
82 | #include <linux/seq_file.h> | 82 | #include <linux/seq_file.h> |
83 | #include <linux/slab.h> | 83 | #include <linux/slab.h> |
84 | #include <linux/smp_lock.h> | ||
84 | #include <linux/init.h> | 85 | #include <linux/init.h> |
85 | #include <linux/bitops.h> | 86 | #include <linux/bitops.h> |
86 | 87 | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index f3366d3f06cf..2dafc2da0648 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -633,6 +633,7 @@ | |||
633 | #include <linux/tty.h> | 633 | #include <linux/tty.h> |
634 | #include <linux/tty_flip.h> | 634 | #include <linux/tty_flip.h> |
635 | #include <linux/serial.h> | 635 | #include <linux/serial.h> |
636 | #include <linux/smp_lock.h> | ||
636 | #include <linux/major.h> | 637 | #include <linux/major.h> |
637 | #include <linux/string.h> | 638 | #include <linux/string.h> |
638 | #include <linux/fcntl.h> | 639 | #include <linux/fcntl.h> |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index abef1f7d84fe..ff647ca1c489 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/tty.h> | 36 | #include <linux/tty.h> |
37 | #include <linux/tty_flip.h> | 37 | #include <linux/tty_flip.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/smp_lock.h> | ||
39 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
40 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
41 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 94e7e3c8c05a..d97779ef72cb 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -552,7 +552,7 @@ static int hvc_chars_in_buffer(struct tty_struct *tty) | |||
552 | struct hvc_struct *hp = tty->driver_data; | 552 | struct hvc_struct *hp = tty->driver_data; |
553 | 553 | ||
554 | if (!hp) | 554 | if (!hp) |
555 | return -1; | 555 | return 0; |
556 | return hp->n_outbuf; | 556 | return hp->n_outbuf; |
557 | } | 557 | } |
558 | 558 | ||
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 621d1184673c..4f1f4cd670da 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -122,6 +122,7 @@ | |||
122 | #include <linux/fs.h> | 122 | #include <linux/fs.h> |
123 | #include <linux/sched.h> | 123 | #include <linux/sched.h> |
124 | #include <linux/serial.h> | 124 | #include <linux/serial.h> |
125 | #include <linux/smp_lock.h> | ||
125 | #include <linux/mm.h> | 126 | #include <linux/mm.h> |
126 | #include <linux/interrupt.h> | 127 | #include <linux/interrupt.h> |
127 | #include <linux/timer.h> | 128 | #include <linux/timer.h> |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 0c999f5bb3db..ab2f3349c5c4 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/smp_lock.h> | ||
23 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
24 | #include <linux/tty.h> | 25 | #include <linux/tty.h> |
25 | #include <linux/tty_flip.h> | 26 | #include <linux/tty_flip.h> |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 65b6ff2442c6..dd0083bbb64a 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/tty.h> | 34 | #include <linux/tty.h> |
35 | #include <linux/tty_flip.h> | 35 | #include <linux/tty_flip.h> |
36 | #include <linux/major.h> | 36 | #include <linux/major.h> |
37 | #include <linux/smp_lock.h> | ||
37 | #include <linux/string.h> | 38 | #include <linux/string.h> |
38 | #include <linux/fcntl.h> | 39 | #include <linux/fcntl.h> |
39 | #include <linux/ptrace.h> | 40 | #include <linux/ptrace.h> |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 52d953eb30c3..dbf8d52f31d0 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/signal.h> | 24 | #include <linux/signal.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/smp_lock.h> | ||
26 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
27 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
28 | #include <linux/tty.h> | 29 | #include <linux/tty.h> |
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index 1c43c8cdee25..c68118efad84 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -97,6 +97,7 @@ | |||
97 | #include <linux/slab.h> | 97 | #include <linux/slab.h> |
98 | #include <linux/tty.h> | 98 | #include <linux/tty.h> |
99 | #include <linux/errno.h> | 99 | #include <linux/errno.h> |
100 | #include <linux/smp_lock.h> | ||
100 | #include <linux/string.h> /* used in new tty drivers */ | 101 | #include <linux/string.h> /* used in new tty drivers */ |
101 | #include <linux/signal.h> /* used in new tty drivers */ | 102 | #include <linux/signal.h> /* used in new tty drivers */ |
102 | #include <linux/if.h> | 103 | #include <linux/if.h> |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 2e99158ebb8a..6934025a1ac1 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/ioport.h> | 58 | #include <linux/ioport.h> |
59 | #include <linux/in.h> | 59 | #include <linux/in.h> |
60 | #include <linux/slab.h> | 60 | #include <linux/slab.h> |
61 | #include <linux/smp_lock.h> | ||
61 | #include <linux/tty.h> | 62 | #include <linux/tty.h> |
62 | #include <linux/errno.h> | 63 | #include <linux/errno.h> |
63 | #include <linux/string.h> /* used in new tty drivers */ | 64 | #include <linux/string.h> /* used in new tty drivers */ |
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 94a5d5020abc..973be2f44195 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -1331,9 +1331,6 @@ handle_newline: | |||
1331 | 1331 | ||
1332 | static void n_tty_write_wakeup(struct tty_struct *tty) | 1332 | static void n_tty_write_wakeup(struct tty_struct *tty) |
1333 | { | 1333 | { |
1334 | /* Write out any echoed characters that are still pending */ | ||
1335 | process_echoes(tty); | ||
1336 | |||
1337 | if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) | 1334 | if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) |
1338 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); | 1335 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); |
1339 | } | 1336 | } |
@@ -1586,6 +1583,7 @@ static int n_tty_open(struct tty_struct *tty) | |||
1586 | 1583 | ||
1587 | static inline int input_available_p(struct tty_struct *tty, int amt) | 1584 | static inline int input_available_p(struct tty_struct *tty, int amt) |
1588 | { | 1585 | { |
1586 | tty_flush_to_ldisc(tty); | ||
1589 | if (tty->icanon) { | 1587 | if (tty->icanon) { |
1590 | if (tty->canon_data) | 1588 | if (tty->canon_data) |
1591 | return 1; | 1589 | return 1; |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 574f1c79b6e6..ec58d8c387ff 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -828,7 +828,7 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
828 | struct port *port = &dc->port[index]; | 828 | struct port *port = &dc->port[index]; |
829 | void __iomem *addr = port->dl_addr[port->toggle_dl]; | 829 | void __iomem *addr = port->dl_addr[port->toggle_dl]; |
830 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 830 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
831 | int i; | 831 | int i, ret; |
832 | 832 | ||
833 | if (unlikely(!tty)) { | 833 | if (unlikely(!tty)) { |
834 | DBG1("tty not open for port: %d?", index); | 834 | DBG1("tty not open for port: %d?", index); |
@@ -844,12 +844,14 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
844 | 844 | ||
845 | /* disable interrupt in downlink... */ | 845 | /* disable interrupt in downlink... */ |
846 | disable_transmit_dl(index, dc); | 846 | disable_transmit_dl(index, dc); |
847 | return 0; | 847 | ret = 0; |
848 | goto put; | ||
848 | } | 849 | } |
849 | 850 | ||
850 | if (unlikely(size == 0)) { | 851 | if (unlikely(size == 0)) { |
851 | dev_err(&dc->pdev->dev, "size == 0?\n"); | 852 | dev_err(&dc->pdev->dev, "size == 0?\n"); |
852 | return 1; | 853 | ret = 1; |
854 | goto put; | ||
853 | } | 855 | } |
854 | 856 | ||
855 | tty_buffer_request_room(tty, size); | 857 | tty_buffer_request_room(tty, size); |
@@ -871,8 +873,10 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
871 | } | 873 | } |
872 | 874 | ||
873 | set_bit(index, &dc->flip); | 875 | set_bit(index, &dc->flip); |
876 | ret = 1; | ||
877 | put: | ||
874 | tty_kref_put(tty); | 878 | tty_kref_put(tty); |
875 | return 1; | 879 | return ret; |
876 | } | 880 | } |
877 | 881 | ||
878 | /* Debug for interrupts */ | 882 | /* Debug for interrupts */ |
@@ -1862,16 +1866,14 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty) | |||
1862 | { | 1866 | { |
1863 | struct port *port = tty->driver_data; | 1867 | struct port *port = tty->driver_data; |
1864 | struct nozomi *dc = get_dc_by_tty(tty); | 1868 | struct nozomi *dc = get_dc_by_tty(tty); |
1865 | s32 rval; | 1869 | s32 rval = 0; |
1866 | 1870 | ||
1867 | if (unlikely(!dc || !port)) { | 1871 | if (unlikely(!dc || !port)) { |
1868 | rval = -ENODEV; | ||
1869 | goto exit_in_buffer; | 1872 | goto exit_in_buffer; |
1870 | } | 1873 | } |
1871 | 1874 | ||
1872 | if (unlikely(!port->port.count)) { | 1875 | if (unlikely(!port->port.count)) { |
1873 | dev_err(&dc->pdev->dev, "No tty open?\n"); | 1876 | dev_err(&dc->pdev->dev, "No tty open?\n"); |
1874 | rval = -ENODEV; | ||
1875 | goto exit_in_buffer; | 1877 | goto exit_in_buffer; |
1876 | } | 1878 | } |
1877 | 1879 | ||
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 569f2f7743a7..674b3ab3587d 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c | |||
@@ -320,10 +320,10 @@ static int ipw_chars_in_buffer(struct tty_struct *linux_tty) | |||
320 | struct ipw_tty *tty = linux_tty->driver_data; | 320 | struct ipw_tty *tty = linux_tty->driver_data; |
321 | 321 | ||
322 | if (!tty) | 322 | if (!tty) |
323 | return -ENODEV; | 323 | return 0; |
324 | 324 | ||
325 | if (!tty->open_count) | 325 | if (!tty->open_count) |
326 | return -EINVAL; | 326 | return 0; |
327 | 327 | ||
328 | return tty->tx_bytes_queued; | 328 | return tty->tx_bytes_queued; |
329 | } | 329 | } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 9d1b4f548f67..6e6942c45f5b 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/major.h> | 22 | #include <linux/major.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/smp_lock.h> | ||
25 | #include <linux/sysctl.h> | 26 | #include <linux/sysctl.h> |
26 | #include <linux/device.h> | 27 | #include <linux/device.h> |
27 | #include <linux/uaccess.h> | 28 | #include <linux/uaccess.h> |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index ce81da5b2da9..d58c2eb07f07 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
45 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/smp_lock.h> | ||
47 | #include <linux/miscdevice.h> | 48 | #include <linux/miscdevice.h> |
48 | #include <linux/init.h> | 49 | #include <linux/init.h> |
49 | 50 | ||
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 217660451237..171711acf5cd 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/tty_flip.h> | 49 | #include <linux/tty_flip.h> |
50 | #include <linux/smp_lock.h> | ||
50 | #include <linux/spinlock.h> | 51 | #include <linux/spinlock.h> |
51 | #include <linux/device.h> | 52 | #include <linux/device.h> |
52 | 53 | ||
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 63d5b628477a..0e29a23ec4c5 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -73,6 +73,7 @@ | |||
73 | #include <linux/tty_driver.h> | 73 | #include <linux/tty_driver.h> |
74 | #include <linux/tty_flip.h> | 74 | #include <linux/tty_flip.h> |
75 | #include <linux/serial.h> | 75 | #include <linux/serial.h> |
76 | #include <linux/smp_lock.h> | ||
76 | #include <linux/string.h> | 77 | #include <linux/string.h> |
77 | #include <linux/fcntl.h> | 78 | #include <linux/fcntl.h> |
78 | #include <linux/ptrace.h> | 79 | #include <linux/ptrace.h> |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index f1f24f0ee26f..51e7a46787be 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/interrupt.h> | 52 | #include <linux/interrupt.h> |
53 | #include <linux/serial.h> | 53 | #include <linux/serial.h> |
54 | #include <linux/serialP.h> | 54 | #include <linux/serialP.h> |
55 | #include <linux/smp_lock.h> | ||
55 | #include <linux/string.h> | 56 | #include <linux/string.h> |
56 | #include <linux/fcntl.h> | 57 | #include <linux/fcntl.h> |
57 | #include <linux/ptrace.h> | 58 | #include <linux/ptrace.h> |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index e72be4190a44..268e17f9ec3f 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -87,6 +87,7 @@ | |||
87 | #include <linux/tty_flip.h> | 87 | #include <linux/tty_flip.h> |
88 | #include <linux/mm.h> | 88 | #include <linux/mm.h> |
89 | #include <linux/serial.h> | 89 | #include <linux/serial.h> |
90 | #include <linux/smp_lock.h> | ||
90 | #include <linux/fcntl.h> | 91 | #include <linux/fcntl.h> |
91 | #include <linux/major.h> | 92 | #include <linux/major.h> |
92 | #include <linux/delay.h> | 93 | #include <linux/delay.h> |
@@ -1808,10 +1809,10 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, | |||
1808 | if (clear & TIOCM_DTR) | 1809 | if (clear & TIOCM_DTR) |
1809 | port->MSVR &= ~MSVR_DTR; | 1810 | port->MSVR &= ~MSVR_DTR; |
1810 | } | 1811 | } |
1811 | spin_lock_irqsave(&bp->lock, flags); | 1812 | spin_lock(&bp->lock); |
1812 | sx_out(bp, CD186x_CAR, port_No(port)); | 1813 | sx_out(bp, CD186x_CAR, port_No(port)); |
1813 | sx_out(bp, CD186x_MSVR, port->MSVR); | 1814 | sx_out(bp, CD186x_MSVR, port->MSVR); |
1814 | spin_unlock_irqrestore(&bp->lock, flags); | 1815 | spin_unlock(&bp->lock); |
1815 | spin_unlock_irqrestore(&port->lock, flags); | 1816 | spin_unlock_irqrestore(&port->lock, flags); |
1816 | func_exit(); | 1817 | func_exit(); |
1817 | return 0; | 1818 | return 0; |
@@ -1832,11 +1833,11 @@ static int sx_send_break(struct tty_struct *tty, int length) | |||
1832 | port->break_length = SPECIALIX_TPS / HZ * length; | 1833 | port->break_length = SPECIALIX_TPS / HZ * length; |
1833 | port->COR2 |= COR2_ETC; | 1834 | port->COR2 |= COR2_ETC; |
1834 | port->IER |= IER_TXRDY; | 1835 | port->IER |= IER_TXRDY; |
1835 | spin_lock_irqsave(&bp->lock, flags); | 1836 | spin_lock(&bp->lock); |
1836 | sx_out(bp, CD186x_CAR, port_No(port)); | 1837 | sx_out(bp, CD186x_CAR, port_No(port)); |
1837 | sx_out(bp, CD186x_COR2, port->COR2); | 1838 | sx_out(bp, CD186x_COR2, port->COR2); |
1838 | sx_out(bp, CD186x_IER, port->IER); | 1839 | sx_out(bp, CD186x_IER, port->IER); |
1839 | spin_unlock_irqrestore(&bp->lock, flags); | 1840 | spin_unlock(&bp->lock); |
1840 | spin_unlock_irqrestore(&port->lock, flags); | 1841 | spin_unlock_irqrestore(&port->lock, flags); |
1841 | sx_wait_CCR(bp); | 1842 | sx_wait_CCR(bp); |
1842 | spin_lock_irqsave(&bp->lock, flags); | 1843 | spin_lock_irqsave(&bp->lock, flags); |
@@ -2022,9 +2023,9 @@ static void sx_unthrottle(struct tty_struct *tty) | |||
2022 | if (sx_crtscts(tty)) | 2023 | if (sx_crtscts(tty)) |
2023 | port->MSVR |= MSVR_DTR; | 2024 | port->MSVR |= MSVR_DTR; |
2024 | /* Else clause: see remark in "sx_throttle"... */ | 2025 | /* Else clause: see remark in "sx_throttle"... */ |
2025 | spin_lock_irqsave(&bp->lock, flags); | 2026 | spin_lock(&bp->lock); |
2026 | sx_out(bp, CD186x_CAR, port_No(port)); | 2027 | sx_out(bp, CD186x_CAR, port_No(port)); |
2027 | spin_unlock_irqrestore(&bp->lock, flags); | 2028 | spin_unlock(&bp->lock); |
2028 | if (I_IXOFF(tty)) { | 2029 | if (I_IXOFF(tty)) { |
2029 | spin_unlock_irqrestore(&port->lock, flags); | 2030 | spin_unlock_irqrestore(&port->lock, flags); |
2030 | sx_wait_CCR(bp); | 2031 | sx_wait_CCR(bp); |
@@ -2034,9 +2035,9 @@ static void sx_unthrottle(struct tty_struct *tty) | |||
2034 | sx_wait_CCR(bp); | 2035 | sx_wait_CCR(bp); |
2035 | spin_lock_irqsave(&port->lock, flags); | 2036 | spin_lock_irqsave(&port->lock, flags); |
2036 | } | 2037 | } |
2037 | spin_lock_irqsave(&bp->lock, flags); | 2038 | spin_lock(&bp->lock); |
2038 | sx_out(bp, CD186x_MSVR, port->MSVR); | 2039 | sx_out(bp, CD186x_MSVR, port->MSVR); |
2039 | spin_unlock_irqrestore(&bp->lock, flags); | 2040 | spin_unlock(&bp->lock); |
2040 | spin_unlock_irqrestore(&port->lock, flags); | 2041 | spin_unlock_irqrestore(&port->lock, flags); |
2041 | 2042 | ||
2042 | func_exit(); | 2043 | func_exit(); |
@@ -2060,10 +2061,10 @@ static void sx_stop(struct tty_struct *tty) | |||
2060 | 2061 | ||
2061 | spin_lock_irqsave(&port->lock, flags); | 2062 | spin_lock_irqsave(&port->lock, flags); |
2062 | port->IER &= ~IER_TXRDY; | 2063 | port->IER &= ~IER_TXRDY; |
2063 | spin_lock_irqsave(&bp->lock, flags); | 2064 | spin_lock(&bp->lock); |
2064 | sx_out(bp, CD186x_CAR, port_No(port)); | 2065 | sx_out(bp, CD186x_CAR, port_No(port)); |
2065 | sx_out(bp, CD186x_IER, port->IER); | 2066 | sx_out(bp, CD186x_IER, port->IER); |
2066 | spin_unlock_irqrestore(&bp->lock, flags); | 2067 | spin_unlock(&bp->lock); |
2067 | spin_unlock_irqrestore(&port->lock, flags); | 2068 | spin_unlock_irqrestore(&port->lock, flags); |
2068 | 2069 | ||
2069 | func_exit(); | 2070 | func_exit(); |
@@ -2088,10 +2089,10 @@ static void sx_start(struct tty_struct *tty) | |||
2088 | spin_lock_irqsave(&port->lock, flags); | 2089 | spin_lock_irqsave(&port->lock, flags); |
2089 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { | 2090 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { |
2090 | port->IER |= IER_TXRDY; | 2091 | port->IER |= IER_TXRDY; |
2091 | spin_lock_irqsave(&bp->lock, flags); | 2092 | spin_lock(&bp->lock); |
2092 | sx_out(bp, CD186x_CAR, port_No(port)); | 2093 | sx_out(bp, CD186x_CAR, port_No(port)); |
2093 | sx_out(bp, CD186x_IER, port->IER); | 2094 | sx_out(bp, CD186x_IER, port->IER); |
2094 | spin_unlock_irqrestore(&bp->lock, flags); | 2095 | spin_unlock(&bp->lock); |
2095 | } | 2096 | } |
2096 | spin_unlock_irqrestore(&port->lock, flags); | 2097 | spin_unlock_irqrestore(&port->lock, flags); |
2097 | 2098 | ||
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 518f2a25d91e..a81ec4fcf6ff 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -216,6 +216,7 @@ | |||
216 | #include <linux/eisa.h> | 216 | #include <linux/eisa.h> |
217 | #include <linux/pci.h> | 217 | #include <linux/pci.h> |
218 | #include <linux/slab.h> | 218 | #include <linux/slab.h> |
219 | #include <linux/smp_lock.h> | ||
219 | #include <linux/init.h> | 220 | #include <linux/init.h> |
220 | #include <linux/miscdevice.h> | 221 | #include <linux/miscdevice.h> |
221 | #include <linux/bitops.h> | 222 | #include <linux/bitops.h> |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index afded3a2379c..813552f14884 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -81,6 +81,7 @@ | |||
81 | #include <linux/mm.h> | 81 | #include <linux/mm.h> |
82 | #include <linux/seq_file.h> | 82 | #include <linux/seq_file.h> |
83 | #include <linux/slab.h> | 83 | #include <linux/slab.h> |
84 | #include <linux/smp_lock.h> | ||
84 | #include <linux/delay.h> | 85 | #include <linux/delay.h> |
85 | #include <linux/netdevice.h> | 86 | #include <linux/netdevice.h> |
86 | #include <linux/vmalloc.h> | 87 | #include <linux/vmalloc.h> |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index a2e67e6df3a1..91f20a92fddf 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/mm.h> | 62 | #include <linux/mm.h> |
63 | #include <linux/seq_file.h> | 63 | #include <linux/seq_file.h> |
64 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
65 | #include <linux/smp_lock.h> | ||
65 | #include <linux/netdevice.h> | 66 | #include <linux/netdevice.h> |
66 | #include <linux/vmalloc.h> | 67 | #include <linux/vmalloc.h> |
67 | #include <linux/init.h> | 68 | #include <linux/init.h> |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 6f727e3c53ad..8d4a2a8a0a70 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/mm.h> | 52 | #include <linux/mm.h> |
53 | #include <linux/seq_file.h> | 53 | #include <linux/seq_file.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/smp_lock.h> | ||
55 | #include <linux/netdevice.h> | 56 | #include <linux/netdevice.h> |
56 | #include <linux/vmalloc.h> | 57 | #include <linux/vmalloc.h> |
57 | #include <linux/init.h> | 58 | #include <linux/init.h> |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index ccdd828adcef..b0603b2e5684 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/poll.h> | 26 | #include <linux/poll.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
29 | #include <linux/smp_lock.h> | ||
30 | 29 | ||
31 | #include "tpm.h" | 30 | #include "tpm.h" |
32 | 31 | ||
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index 810ee25d66a4..3108991c5c8b 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c | |||
@@ -462,6 +462,19 @@ static void flush_to_ldisc(struct work_struct *work) | |||
462 | } | 462 | } |
463 | 463 | ||
464 | /** | 464 | /** |
465 | * tty_flush_to_ldisc | ||
466 | * @tty: tty to push | ||
467 | * | ||
468 | * Push the terminal flip buffers to the line discipline. | ||
469 | * | ||
470 | * Must not be called from IRQ context. | ||
471 | */ | ||
472 | void tty_flush_to_ldisc(struct tty_struct *tty) | ||
473 | { | ||
474 | flush_to_ldisc(&tty->buf.work.work); | ||
475 | } | ||
476 | |||
477 | /** | ||
465 | * tty_flip_buffer_push - terminal | 478 | * tty_flip_buffer_push - terminal |
466 | * @tty: tty to push | 479 | * @tty: tty to push |
467 | * | 480 | * |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index b24f6c6a1ea3..ad6ba4ed2808 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/smp_lock.h> | ||
25 | 24 | ||
26 | #include <asm/io.h> | 25 | #include <asm/io.h> |
27 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 913aa8d3f1c5..acd76b767d4c 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/device.h> | 24 | #include <linux/device.h> |
26 | #include <linux/wait.h> | 25 | #include <linux/wait.h> |
27 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
@@ -791,17 +790,20 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
791 | * N_TTY. | 790 | * N_TTY. |
792 | */ | 791 | */ |
793 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | 792 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { |
794 | /* Avoid racing set_ldisc */ | 793 | /* Avoid racing set_ldisc or tty_ldisc_release */ |
795 | mutex_lock(&tty->ldisc_mutex); | 794 | mutex_lock(&tty->ldisc_mutex); |
796 | /* Switch back to N_TTY */ | 795 | if (tty->ldisc) { /* Not yet closed */ |
797 | tty_ldisc_halt(tty); | 796 | /* Switch back to N_TTY */ |
798 | tty_ldisc_wait_idle(tty); | 797 | tty_ldisc_halt(tty); |
799 | tty_ldisc_reinit(tty); | 798 | tty_ldisc_wait_idle(tty); |
800 | /* At this point we have a closed ldisc and we want to | 799 | tty_ldisc_reinit(tty); |
801 | reopen it. We could defer this to the next open but | 800 | /* At this point we have a closed ldisc and we want to |
802 | it means auditing a lot of other paths so this is a FIXME */ | 801 | reopen it. We could defer this to the next open but |
803 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); | 802 | it means auditing a lot of other paths so this is |
804 | tty_ldisc_enable(tty); | 803 | a FIXME */ |
804 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); | ||
805 | tty_ldisc_enable(tty); | ||
806 | } | ||
805 | mutex_unlock(&tty->ldisc_mutex); | 807 | mutex_unlock(&tty->ldisc_mutex); |
806 | tty_reset_termios(tty); | 808 | tty_reset_termios(tty); |
807 | } | 809 | } |
@@ -866,6 +868,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
866 | 868 | ||
867 | tty_ldisc_wait_idle(tty); | 869 | tty_ldisc_wait_idle(tty); |
868 | 870 | ||
871 | mutex_lock(&tty->ldisc_mutex); | ||
869 | /* | 872 | /* |
870 | * Now kill off the ldisc | 873 | * Now kill off the ldisc |
871 | */ | 874 | */ |
@@ -876,6 +879,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
876 | 879 | ||
877 | /* Ensure the next open requests the N_TTY ldisc */ | 880 | /* Ensure the next open requests the N_TTY ldisc */ |
878 | tty_set_termios_ldisc(tty, N_TTY); | 881 | tty_set_termios_ldisc(tty, N_TTY); |
882 | mutex_unlock(&tty->ldisc_mutex); | ||
879 | 883 | ||
880 | /* This will need doing differently if we need to lock */ | 884 | /* This will need doing differently if we need to lock */ |
881 | if (o_tty) | 885 | if (o_tty) |
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index 4e862a75f7ff..9769b1149f76 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c | |||
@@ -267,7 +267,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
267 | if (retval == 0) | 267 | if (retval == 0) |
268 | port->flags |= ASYNC_NORMAL_ACTIVE; | 268 | port->flags |= ASYNC_NORMAL_ACTIVE; |
269 | spin_unlock_irqrestore(&port->lock, flags); | 269 | spin_unlock_irqrestore(&port->lock, flags); |
270 | return 0; | 270 | return retval; |
271 | 271 | ||
272 | } | 272 | } |
273 | EXPORT_SYMBOL(tty_port_block_til_ready); | 273 | EXPORT_SYMBOL(tty_port_block_til_ready); |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index d94d25c12aa8..c1791a63d99d 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -495,11 +495,15 @@ void vcs_remove_sysfs(int index) | |||
495 | 495 | ||
496 | int __init vcs_init(void) | 496 | int __init vcs_init(void) |
497 | { | 497 | { |
498 | unsigned int i; | ||
499 | |||
498 | if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) | 500 | if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) |
499 | panic("unable to get major %d for vcs device", VCS_MAJOR); | 501 | panic("unable to get major %d for vcs device", VCS_MAJOR); |
500 | vc_class = class_create(THIS_MODULE, "vc"); | 502 | vc_class = class_create(THIS_MODULE, "vc"); |
501 | 503 | ||
502 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); | 504 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); |
503 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); | 505 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); |
506 | for (i = 0; i < MIN_NR_CONSOLES; i++) | ||
507 | vcs_make_sysfs(i); | ||
504 | return 0; | 508 | return 0; |
505 | } | 509 | } |
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/char/vr41xx_giu.c +++ /dev/null | |||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index d9113b4c76e3..404f4c1ee431 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -89,6 +89,7 @@ | |||
89 | #include <linux/mutex.h> | 89 | #include <linux/mutex.h> |
90 | #include <linux/vt_kern.h> | 90 | #include <linux/vt_kern.h> |
91 | #include <linux/selection.h> | 91 | #include <linux/selection.h> |
92 | #include <linux/smp_lock.h> | ||
92 | #include <linux/tiocl.h> | 93 | #include <linux/tiocl.h> |
93 | #include <linux/kbd_kern.h> | 94 | #include <linux/kbd_kern.h> |
94 | #include <linux/consolemap.h> | 95 | #include <linux/consolemap.h> |
@@ -769,14 +770,12 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ | |||
769 | visual_init(vc, currcons, 1); | 770 | visual_init(vc, currcons, 1); |
770 | if (!*vc->vc_uni_pagedir_loc) | 771 | if (!*vc->vc_uni_pagedir_loc) |
771 | con_set_default_unimap(vc); | 772 | con_set_default_unimap(vc); |
772 | if (!vc->vc_kmalloced) | 773 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); |
773 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); | ||
774 | if (!vc->vc_screenbuf) { | 774 | if (!vc->vc_screenbuf) { |
775 | kfree(vc); | 775 | kfree(vc); |
776 | vc_cons[currcons].d = NULL; | 776 | vc_cons[currcons].d = NULL; |
777 | return -ENOMEM; | 777 | return -ENOMEM; |
778 | } | 778 | } |
779 | vc->vc_kmalloced = 1; | ||
780 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); | 779 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); |
781 | vcs_make_sysfs(currcons); | 780 | vcs_make_sysfs(currcons); |
782 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); | 781 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); |
@@ -912,10 +911,8 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
912 | if (new_scr_end > new_origin) | 911 | if (new_scr_end > new_origin) |
913 | scr_memsetw((void *)new_origin, vc->vc_video_erase_char, | 912 | scr_memsetw((void *)new_origin, vc->vc_video_erase_char, |
914 | new_scr_end - new_origin); | 913 | new_scr_end - new_origin); |
915 | if (vc->vc_kmalloced) | 914 | kfree(vc->vc_screenbuf); |
916 | kfree(vc->vc_screenbuf); | ||
917 | vc->vc_screenbuf = newscreen; | 915 | vc->vc_screenbuf = newscreen; |
918 | vc->vc_kmalloced = 1; | ||
919 | vc->vc_screenbuf_size = new_screen_size; | 916 | vc->vc_screenbuf_size = new_screen_size; |
920 | set_origin(vc); | 917 | set_origin(vc); |
921 | 918 | ||
@@ -994,8 +991,7 @@ void vc_deallocate(unsigned int currcons) | |||
994 | vc->vc_sw->con_deinit(vc); | 991 | vc->vc_sw->con_deinit(vc); |
995 | put_pid(vc->vt_pid); | 992 | put_pid(vc->vt_pid); |
996 | module_put(vc->vc_sw->owner); | 993 | module_put(vc->vc_sw->owner); |
997 | if (vc->vc_kmalloced) | 994 | kfree(vc->vc_screenbuf); |
998 | kfree(vc->vc_screenbuf); | ||
999 | if (currcons >= MIN_NR_CONSOLES) | 995 | if (currcons >= MIN_NR_CONSOLES) |
1000 | kfree(vc); | 996 | kfree(vc); |
1001 | vc_cons[currcons].d = NULL; | 997 | vc_cons[currcons].d = NULL; |
@@ -2880,7 +2876,6 @@ static int __init con_init(void) | |||
2880 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); | 2876 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); |
2881 | visual_init(vc, currcons, 1); | 2877 | visual_init(vc, currcons, 1); |
2882 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); | 2878 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); |
2883 | vc->vc_kmalloced = 0; | ||
2884 | vc_init(vc, vc->vc_rows, vc->vc_cols, | 2879 | vc_init(vc, vc->vc_rows, vc->vc_cols, |
2885 | currcons || !vc->vc_sw->con_save_screen); | 2880 | currcons || !vc->vc_sw->con_save_screen); |
2886 | } | 2881 | } |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 7539bed0f7e0..95189f288f8c 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/console.h> | 25 | #include <linux/console.h> |
26 | #include <linux/consolemap.h> | 26 | #include <linux/consolemap.h> |
27 | #include <linux/signal.h> | 27 | #include <linux/signal.h> |
28 | #include <linux/smp_lock.h> | ||
28 | #include <linux/timex.h> | 29 | #include <linux/timex.h> |
29 | 30 | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index c769ef269fb5..408c2af25d50 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * cn_queue.c | 2 | * cn_queue.c |
3 | * | 3 | * |
4 | * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index fd336c5a9057..08b2500f21ec 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * connector.c | 2 | * connector.c |
3 | * | 3 | * |
4 | * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -33,7 +33,7 @@ | |||
33 | #include <net/sock.h> | 33 | #include <net/sock.h> |
34 | 34 | ||
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | 36 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); |
37 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); | 37 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); |
38 | 38 | ||
39 | static u32 cn_idx = CN_IDX_CONNECTOR; | 39 | static u32 cn_idx = CN_IDX_CONNECTOR; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c668ac855f71..b90eda8b3440 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -776,9 +776,6 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
776 | struct sys_device *cpu_sys_dev; | 776 | struct sys_device *cpu_sys_dev; |
777 | unsigned long flags; | 777 | unsigned long flags; |
778 | unsigned int j; | 778 | unsigned int j; |
779 | #ifdef CONFIG_SMP | ||
780 | struct cpufreq_policy *managed_policy; | ||
781 | #endif | ||
782 | 779 | ||
783 | if (cpu_is_offline(cpu)) | 780 | if (cpu_is_offline(cpu)) |
784 | return 0; | 781 | return 0; |
@@ -854,6 +851,8 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
854 | #endif | 851 | #endif |
855 | 852 | ||
856 | for_each_cpu(j, policy->cpus) { | 853 | for_each_cpu(j, policy->cpus) { |
854 | struct cpufreq_policy *managed_policy; | ||
855 | |||
857 | if (cpu == j) | 856 | if (cpu == j) |
858 | continue; | 857 | continue; |
859 | 858 | ||
@@ -932,6 +931,8 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
932 | 931 | ||
933 | /* symlink affected CPUs */ | 932 | /* symlink affected CPUs */ |
934 | for_each_cpu(j, policy->cpus) { | 933 | for_each_cpu(j, policy->cpus) { |
934 | struct cpufreq_policy *managed_policy; | ||
935 | |||
935 | if (j == cpu) | 936 | if (j == cpu) |
936 | continue; | 937 | continue; |
937 | if (!cpu_online(j)) | 938 | if (!cpu_online(j)) |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 858fe6037223..24964c1d0af9 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -970,7 +970,7 @@ static void amd64_read_dct_base_mask(struct amd64_pvt *pvt) | |||
970 | } | 970 | } |
971 | 971 | ||
972 | for (cs = 0; cs < pvt->num_dcsm; cs++) { | 972 | for (cs = 0; cs < pvt->num_dcsm; cs++) { |
973 | reg = K8_DCSB0 + (cs * 4); | 973 | reg = K8_DCSM0 + (cs * 4); |
974 | err = pci_read_config_dword(pvt->dram_f2_ctl, reg, | 974 | err = pci_read_config_dword(pvt->dram_f2_ctl, reg, |
975 | &pvt->dcsm0[cs]); | 975 | &pvt->dcsm0[cs]); |
976 | if (unlikely(err)) | 976 | if (unlikely(err)) |
diff --git a/drivers/gpio/vr41xx_giu.c b/drivers/gpio/vr41xx_giu.c index b70e06133e78..b16c9a8c03f5 100644 --- a/drivers/gpio/vr41xx_giu.c +++ b/drivers/gpio/vr41xx_giu.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
34 | #include <linux/types.h> | 33 | #include <linux/types.h> |
35 | 34 | ||
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index a6f73f1e99d9..3da9cfa31848 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -1090,6 +1090,8 @@ int drm_helper_resume_force_mode(struct drm_device *dev) | |||
1090 | if (ret == false) | 1090 | if (ret == false) |
1091 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); | 1091 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); |
1092 | } | 1092 | } |
1093 | /* disable the unused connectors while restoring the modesetting */ | ||
1094 | drm_helper_disable_unused_functions(dev); | ||
1093 | return 0; | 1095 | return 0; |
1094 | } | 1096 | } |
1095 | EXPORT_SYMBOL(drm_helper_resume_force_mode); | 1097 | EXPORT_SYMBOL(drm_helper_resume_force_mode); |
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 2960b6d73456..9903f270e440 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c | |||
@@ -101,6 +101,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count, | |||
101 | continue; | 101 | continue; |
102 | 102 | ||
103 | tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); | 103 | tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); |
104 | if (tmp == NULL) { | ||
105 | ret = -1; | ||
106 | goto fail; | ||
107 | } | ||
104 | ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, | 108 | ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, |
105 | root, tmp, &drm_debugfs_fops); | 109 | root, tmp, &drm_debugfs_fops); |
106 | if (!ent) { | 110 | if (!ent) { |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 8104ecaea26f..ffe8f4394d50 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -134,26 +134,29 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) | |||
134 | BUG_ON((size & (PAGE_SIZE - 1)) != 0); | 134 | BUG_ON((size & (PAGE_SIZE - 1)) != 0); |
135 | 135 | ||
136 | obj = kzalloc(sizeof(*obj), GFP_KERNEL); | 136 | obj = kzalloc(sizeof(*obj), GFP_KERNEL); |
137 | if (!obj) | ||
138 | goto free; | ||
137 | 139 | ||
138 | obj->dev = dev; | 140 | obj->dev = dev; |
139 | obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); | 141 | obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); |
140 | if (IS_ERR(obj->filp)) { | 142 | if (IS_ERR(obj->filp)) |
141 | kfree(obj); | 143 | goto free; |
142 | return NULL; | ||
143 | } | ||
144 | 144 | ||
145 | kref_init(&obj->refcount); | 145 | kref_init(&obj->refcount); |
146 | kref_init(&obj->handlecount); | 146 | kref_init(&obj->handlecount); |
147 | obj->size = size; | 147 | obj->size = size; |
148 | if (dev->driver->gem_init_object != NULL && | 148 | if (dev->driver->gem_init_object != NULL && |
149 | dev->driver->gem_init_object(obj) != 0) { | 149 | dev->driver->gem_init_object(obj) != 0) { |
150 | fput(obj->filp); | 150 | goto fput; |
151 | kfree(obj); | ||
152 | return NULL; | ||
153 | } | 151 | } |
154 | atomic_inc(&dev->object_count); | 152 | atomic_inc(&dev->object_count); |
155 | atomic_add(obj->size, &dev->object_memory); | 153 | atomic_add(obj->size, &dev->object_memory); |
156 | return obj; | 154 | return obj; |
155 | fput: | ||
156 | fput(obj->filp); | ||
157 | free: | ||
158 | kfree(obj); | ||
159 | return NULL; | ||
157 | } | 160 | } |
158 | EXPORT_SYMBOL(drm_gem_object_alloc); | 161 | EXPORT_SYMBOL(drm_gem_object_alloc); |
159 | 162 | ||
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 155a5bbce680..55bb8a82d612 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -489,7 +489,7 @@ int drm_put_minor(struct drm_minor **minor_p) | |||
489 | */ | 489 | */ |
490 | void drm_put_dev(struct drm_device *dev) | 490 | void drm_put_dev(struct drm_device *dev) |
491 | { | 491 | { |
492 | struct drm_driver *driver = dev->driver; | 492 | struct drm_driver *driver; |
493 | struct drm_map_list *r_list, *list_temp; | 493 | struct drm_map_list *r_list, *list_temp; |
494 | 494 | ||
495 | DRM_DEBUG("\n"); | 495 | DRM_DEBUG("\n"); |
@@ -498,6 +498,7 @@ void drm_put_dev(struct drm_device *dev) | |||
498 | DRM_ERROR("cleanup called no dev\n"); | 498 | DRM_ERROR("cleanup called no dev\n"); |
499 | return; | 499 | return; |
500 | } | 500 | } |
501 | driver = dev->driver; | ||
501 | 502 | ||
502 | drm_vblank_cleanup(dev); | 503 | drm_vblank_cleanup(dev); |
503 | 504 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f112c769d533..8c4783180bf6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -846,7 +846,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
846 | return 0; | 846 | return 0; |
847 | } | 847 | } |
848 | 848 | ||
849 | printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr); | 849 | DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); |
850 | 850 | ||
851 | dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); | 851 | dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); |
852 | 852 | ||
@@ -885,8 +885,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
885 | * some RAM for the framebuffer at early boot. This code figures out | 885 | * some RAM for the framebuffer at early boot. This code figures out |
886 | * how much was set aside so we can use it for our own purposes. | 886 | * how much was set aside so we can use it for our own purposes. |
887 | */ | 887 | */ |
888 | static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, | 888 | static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, |
889 | unsigned long *preallocated_size) | 889 | uint32_t *preallocated_size) |
890 | { | 890 | { |
891 | struct pci_dev *bridge_dev; | 891 | struct pci_dev *bridge_dev; |
892 | u16 tmp = 0; | 892 | u16 tmp = 0; |
@@ -984,10 +984,11 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, | |||
984 | return 0; | 984 | return 0; |
985 | } | 985 | } |
986 | 986 | ||
987 | static int i915_load_modeset_init(struct drm_device *dev) | 987 | static int i915_load_modeset_init(struct drm_device *dev, |
988 | unsigned long prealloc_size, | ||
989 | unsigned long agp_size) | ||
988 | { | 990 | { |
989 | struct drm_i915_private *dev_priv = dev->dev_private; | 991 | struct drm_i915_private *dev_priv = dev->dev_private; |
990 | unsigned long agp_size, prealloc_size; | ||
991 | int fb_bar = IS_I9XX(dev) ? 2 : 0; | 992 | int fb_bar = IS_I9XX(dev) ? 2 : 0; |
992 | int ret = 0; | 993 | int ret = 0; |
993 | 994 | ||
@@ -1002,10 +1003,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1002 | if (IS_I965G(dev) || IS_G33(dev)) | 1003 | if (IS_I965G(dev) || IS_G33(dev)) |
1003 | dev_priv->cursor_needs_physical = false; | 1004 | dev_priv->cursor_needs_physical = false; |
1004 | 1005 | ||
1005 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | ||
1006 | if (ret) | ||
1007 | goto out; | ||
1008 | |||
1009 | /* Basic memrange allocator for stolen space (aka vram) */ | 1006 | /* Basic memrange allocator for stolen space (aka vram) */ |
1010 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | 1007 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); |
1011 | 1008 | ||
@@ -1082,6 +1079,44 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) | |||
1082 | master->driver_priv = NULL; | 1079 | master->driver_priv = NULL; |
1083 | } | 1080 | } |
1084 | 1081 | ||
1082 | static void i915_get_mem_freq(struct drm_device *dev) | ||
1083 | { | ||
1084 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1085 | u32 tmp; | ||
1086 | |||
1087 | if (!IS_IGD(dev)) | ||
1088 | return; | ||
1089 | |||
1090 | tmp = I915_READ(CLKCFG); | ||
1091 | |||
1092 | switch (tmp & CLKCFG_FSB_MASK) { | ||
1093 | case CLKCFG_FSB_533: | ||
1094 | dev_priv->fsb_freq = 533; /* 133*4 */ | ||
1095 | break; | ||
1096 | case CLKCFG_FSB_800: | ||
1097 | dev_priv->fsb_freq = 800; /* 200*4 */ | ||
1098 | break; | ||
1099 | case CLKCFG_FSB_667: | ||
1100 | dev_priv->fsb_freq = 667; /* 167*4 */ | ||
1101 | break; | ||
1102 | case CLKCFG_FSB_400: | ||
1103 | dev_priv->fsb_freq = 400; /* 100*4 */ | ||
1104 | break; | ||
1105 | } | ||
1106 | |||
1107 | switch (tmp & CLKCFG_MEM_MASK) { | ||
1108 | case CLKCFG_MEM_533: | ||
1109 | dev_priv->mem_freq = 533; | ||
1110 | break; | ||
1111 | case CLKCFG_MEM_667: | ||
1112 | dev_priv->mem_freq = 667; | ||
1113 | break; | ||
1114 | case CLKCFG_MEM_800: | ||
1115 | dev_priv->mem_freq = 800; | ||
1116 | break; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1085 | /** | 1120 | /** |
1086 | * i915_driver_load - setup chip and create an initial config | 1121 | * i915_driver_load - setup chip and create an initial config |
1087 | * @dev: DRM device | 1122 | * @dev: DRM device |
@@ -1098,6 +1133,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1098 | struct drm_i915_private *dev_priv = dev->dev_private; | 1133 | struct drm_i915_private *dev_priv = dev->dev_private; |
1099 | resource_size_t base, size; | 1134 | resource_size_t base, size; |
1100 | int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; | 1135 | int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; |
1136 | uint32_t agp_size, prealloc_size; | ||
1101 | 1137 | ||
1102 | /* i915 has 4 more counters */ | 1138 | /* i915 has 4 more counters */ |
1103 | dev->counters += 4; | 1139 | dev->counters += 4; |
@@ -1146,9 +1182,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1146 | "performance may suffer.\n"); | 1182 | "performance may suffer.\n"); |
1147 | } | 1183 | } |
1148 | 1184 | ||
1185 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | ||
1186 | if (ret) | ||
1187 | goto out_iomapfree; | ||
1188 | |||
1149 | /* enable GEM by default */ | 1189 | /* enable GEM by default */ |
1150 | dev_priv->has_gem = 1; | 1190 | dev_priv->has_gem = 1; |
1151 | 1191 | ||
1192 | if (prealloc_size > agp_size * 3 / 4) { | ||
1193 | DRM_ERROR("Detected broken video BIOS with %d/%dkB of video " | ||
1194 | "memory stolen.\n", | ||
1195 | prealloc_size / 1024, agp_size / 1024); | ||
1196 | DRM_ERROR("Disabling GEM. (try reducing stolen memory or " | ||
1197 | "updating the BIOS to fix).\n"); | ||
1198 | dev_priv->has_gem = 0; | ||
1199 | } | ||
1200 | |||
1152 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1201 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
1153 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 1202 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
1154 | if (IS_G4X(dev) || IS_IGDNG(dev)) { | 1203 | if (IS_G4X(dev) || IS_IGDNG(dev)) { |
@@ -1165,6 +1214,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1165 | goto out_iomapfree; | 1214 | goto out_iomapfree; |
1166 | } | 1215 | } |
1167 | 1216 | ||
1217 | i915_get_mem_freq(dev); | ||
1218 | |||
1168 | /* On the 945G/GM, the chipset reports the MSI capability on the | 1219 | /* On the 945G/GM, the chipset reports the MSI capability on the |
1169 | * integrated graphics even though the support isn't actually there | 1220 | * integrated graphics even though the support isn't actually there |
1170 | * according to the published specs. It doesn't appear to function | 1221 | * according to the published specs. It doesn't appear to function |
@@ -1180,6 +1231,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1180 | pci_enable_msi(dev->pdev); | 1231 | pci_enable_msi(dev->pdev); |
1181 | 1232 | ||
1182 | spin_lock_init(&dev_priv->user_irq_lock); | 1233 | spin_lock_init(&dev_priv->user_irq_lock); |
1234 | spin_lock_init(&dev_priv->error_lock); | ||
1183 | dev_priv->user_irq_refcount = 0; | 1235 | dev_priv->user_irq_refcount = 0; |
1184 | 1236 | ||
1185 | ret = drm_vblank_init(dev, I915_NUM_PIPE); | 1237 | ret = drm_vblank_init(dev, I915_NUM_PIPE); |
@@ -1190,7 +1242,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1190 | } | 1242 | } |
1191 | 1243 | ||
1192 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1244 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1193 | ret = i915_load_modeset_init(dev); | 1245 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); |
1194 | if (ret < 0) { | 1246 | if (ret < 0) { |
1195 | DRM_ERROR("failed to init modeset\n"); | 1247 | DRM_ERROR("failed to init modeset\n"); |
1196 | goto out_rmmap; | 1248 | goto out_rmmap; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index e3cb4025e323..fc4b68aa2d05 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "drm_pciids.h" | 36 | #include "drm_pciids.h" |
37 | #include <linux/console.h> | 37 | #include <linux/console.h> |
38 | #include "drm_crtc_helper.h" | ||
38 | 39 | ||
39 | static unsigned int i915_modeset = -1; | 40 | static unsigned int i915_modeset = -1; |
40 | module_param_named(modeset, i915_modeset, int, 0400); | 41 | module_param_named(modeset, i915_modeset, int, 0400); |
@@ -57,8 +58,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
57 | struct drm_i915_private *dev_priv = dev->dev_private; | 58 | struct drm_i915_private *dev_priv = dev->dev_private; |
58 | 59 | ||
59 | if (!dev || !dev_priv) { | 60 | if (!dev || !dev_priv) { |
60 | printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); | 61 | DRM_ERROR("dev: %p, dev_priv: %p\n", dev, dev_priv); |
61 | printk(KERN_ERR "DRM not initialized, aborting suspend.\n"); | 62 | DRM_ERROR("DRM not initialized, aborting suspend.\n"); |
62 | return -ENODEV; | 63 | return -ENODEV; |
63 | } | 64 | } |
64 | 65 | ||
@@ -115,6 +116,10 @@ static int i915_resume(struct drm_device *dev) | |||
115 | 116 | ||
116 | drm_irq_install(dev); | 117 | drm_irq_install(dev); |
117 | } | 118 | } |
119 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
120 | /* Resume the modeset for every activated CRTC */ | ||
121 | drm_helper_resume_force_mode(dev); | ||
122 | } | ||
118 | 123 | ||
119 | return ret; | 124 | return ret; |
120 | } | 125 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bb4c2d387b6c..d08752875885 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -133,6 +133,22 @@ struct sdvo_device_mapping { | |||
133 | u8 initialized; | 133 | u8 initialized; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | struct drm_i915_error_state { | ||
137 | u32 eir; | ||
138 | u32 pgtbl_er; | ||
139 | u32 pipeastat; | ||
140 | u32 pipebstat; | ||
141 | u32 ipeir; | ||
142 | u32 ipehr; | ||
143 | u32 instdone; | ||
144 | u32 acthd; | ||
145 | u32 instpm; | ||
146 | u32 instps; | ||
147 | u32 instdone1; | ||
148 | u32 seqno; | ||
149 | struct timeval time; | ||
150 | }; | ||
151 | |||
136 | typedef struct drm_i915_private { | 152 | typedef struct drm_i915_private { |
137 | struct drm_device *dev; | 153 | struct drm_device *dev; |
138 | 154 | ||
@@ -209,6 +225,11 @@ typedef struct drm_i915_private { | |||
209 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 225 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
210 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 226 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
211 | 227 | ||
228 | unsigned int fsb_freq, mem_freq; | ||
229 | |||
230 | spinlock_t error_lock; | ||
231 | struct drm_i915_error_state *first_error; | ||
232 | |||
212 | /* Register state */ | 233 | /* Register state */ |
213 | u8 saveLBB; | 234 | u8 saveLBB; |
214 | u32 saveDSPACNTR; | 235 | u32 saveDSPACNTR; |
@@ -468,9 +489,6 @@ struct drm_i915_gem_object { | |||
468 | */ | 489 | */ |
469 | int fence_reg; | 490 | int fence_reg; |
470 | 491 | ||
471 | /** Boolean whether this object has a valid gtt offset. */ | ||
472 | int gtt_bound; | ||
473 | |||
474 | /** How many users have pinned this object in GTT space */ | 492 | /** How many users have pinned this object in GTT space */ |
475 | int pin_count; | 493 | int pin_count; |
476 | 494 | ||
@@ -655,6 +673,7 @@ void i915_gem_free_object(struct drm_gem_object *obj); | |||
655 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); | 673 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); |
656 | void i915_gem_object_unpin(struct drm_gem_object *obj); | 674 | void i915_gem_object_unpin(struct drm_gem_object *obj); |
657 | int i915_gem_object_unbind(struct drm_gem_object *obj); | 675 | int i915_gem_object_unbind(struct drm_gem_object *obj); |
676 | void i915_gem_release_mmap(struct drm_gem_object *obj); | ||
658 | void i915_gem_lastclose(struct drm_device *dev); | 677 | void i915_gem_lastclose(struct drm_device *dev); |
659 | uint32_t i915_get_gem_seqno(struct drm_device *dev); | 678 | uint32_t i915_get_gem_seqno(struct drm_device *dev); |
660 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); | 679 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); |
@@ -870,6 +889,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
870 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 889 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
871 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 890 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
872 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) | 891 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) |
892 | /* dsparb controlled by hw only */ | ||
893 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
873 | 894 | ||
874 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 895 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
875 | 896 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 876b65cb7629..5bf420378b6d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1252,6 +1252,31 @@ out_free_list: | |||
1252 | return ret; | 1252 | return ret; |
1253 | } | 1253 | } |
1254 | 1254 | ||
1255 | /** | ||
1256 | * i915_gem_release_mmap - remove physical page mappings | ||
1257 | * @obj: obj in question | ||
1258 | * | ||
1259 | * Preserve the reservation of the mmaping with the DRM core code, but | ||
1260 | * relinquish ownership of the pages back to the system. | ||
1261 | * | ||
1262 | * It is vital that we remove the page mapping if we have mapped a tiled | ||
1263 | * object through the GTT and then lose the fence register due to | ||
1264 | * resource pressure. Similarly if the object has been moved out of the | ||
1265 | * aperture, than pages mapped into userspace must be revoked. Removing the | ||
1266 | * mapping will then trigger a page fault on the next user access, allowing | ||
1267 | * fixup by i915_gem_fault(). | ||
1268 | */ | ||
1269 | void | ||
1270 | i915_gem_release_mmap(struct drm_gem_object *obj) | ||
1271 | { | ||
1272 | struct drm_device *dev = obj->dev; | ||
1273 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1274 | |||
1275 | if (dev->dev_mapping) | ||
1276 | unmap_mapping_range(dev->dev_mapping, | ||
1277 | obj_priv->mmap_offset, obj->size, 1); | ||
1278 | } | ||
1279 | |||
1255 | static void | 1280 | static void |
1256 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) | 1281 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) |
1257 | { | 1282 | { |
@@ -1861,7 +1886,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1861 | { | 1886 | { |
1862 | struct drm_device *dev = obj->dev; | 1887 | struct drm_device *dev = obj->dev; |
1863 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1888 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
1864 | loff_t offset; | ||
1865 | int ret = 0; | 1889 | int ret = 0; |
1866 | 1890 | ||
1867 | #if WATCH_BUF | 1891 | #if WATCH_BUF |
@@ -1898,9 +1922,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1898 | BUG_ON(obj_priv->active); | 1922 | BUG_ON(obj_priv->active); |
1899 | 1923 | ||
1900 | /* blow away mappings if mapped through GTT */ | 1924 | /* blow away mappings if mapped through GTT */ |
1901 | offset = ((loff_t) obj->map_list.hash.key) << PAGE_SHIFT; | 1925 | i915_gem_release_mmap(obj); |
1902 | if (dev->dev_mapping) | ||
1903 | unmap_mapping_range(dev->dev_mapping, offset, obj->size, 1); | ||
1904 | 1926 | ||
1905 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1927 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
1906 | i915_gem_clear_fence_reg(obj); | 1928 | i915_gem_clear_fence_reg(obj); |
@@ -2222,7 +2244,6 @@ try_again: | |||
2222 | /* None available, try to steal one or wait for a user to finish */ | 2244 | /* None available, try to steal one or wait for a user to finish */ |
2223 | if (i == dev_priv->num_fence_regs) { | 2245 | if (i == dev_priv->num_fence_regs) { |
2224 | uint32_t seqno = dev_priv->mm.next_gem_seqno; | 2246 | uint32_t seqno = dev_priv->mm.next_gem_seqno; |
2225 | loff_t offset; | ||
2226 | 2247 | ||
2227 | if (avail == 0) | 2248 | if (avail == 0) |
2228 | return -ENOSPC; | 2249 | return -ENOSPC; |
@@ -2274,10 +2295,7 @@ try_again: | |||
2274 | * Zap this virtual mapping so we can set up a fence again | 2295 | * Zap this virtual mapping so we can set up a fence again |
2275 | * for this object next time we need it. | 2296 | * for this object next time we need it. |
2276 | */ | 2297 | */ |
2277 | offset = ((loff_t) reg->obj->map_list.hash.key) << PAGE_SHIFT; | 2298 | i915_gem_release_mmap(reg->obj); |
2278 | if (dev->dev_mapping) | ||
2279 | unmap_mapping_range(dev->dev_mapping, offset, | ||
2280 | reg->obj->size, 1); | ||
2281 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2299 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2282 | } | 2300 | } |
2283 | 2301 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c index 28146e405e87..9a44bfcb8139 100644 --- a/drivers/gpu/drm/i915/i915_gem_debugfs.c +++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c | |||
@@ -75,11 +75,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
75 | case ACTIVE_LIST: | 75 | case ACTIVE_LIST: |
76 | seq_printf(m, "Active:\n"); | 76 | seq_printf(m, "Active:\n"); |
77 | lock = &dev_priv->mm.active_list_lock; | 77 | lock = &dev_priv->mm.active_list_lock; |
78 | spin_lock(lock); | ||
79 | head = &dev_priv->mm.active_list; | 78 | head = &dev_priv->mm.active_list; |
80 | break; | 79 | break; |
81 | case INACTIVE_LIST: | 80 | case INACTIVE_LIST: |
82 | seq_printf(m, "Inctive:\n"); | 81 | seq_printf(m, "Inactive:\n"); |
83 | head = &dev_priv->mm.inactive_list; | 82 | head = &dev_priv->mm.inactive_list; |
84 | break; | 83 | break; |
85 | case FLUSHING_LIST: | 84 | case FLUSHING_LIST: |
@@ -91,6 +90,8 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
91 | return 0; | 90 | return 0; |
92 | } | 91 | } |
93 | 92 | ||
93 | if (lock) | ||
94 | spin_lock(lock); | ||
94 | list_for_each_entry(obj_priv, head, list) | 95 | list_for_each_entry(obj_priv, head, list) |
95 | { | 96 | { |
96 | struct drm_gem_object *obj = obj_priv->obj; | 97 | struct drm_gem_object *obj = obj_priv->obj; |
@@ -104,7 +105,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
104 | if (obj->name) | 105 | if (obj->name) |
105 | seq_printf(m, " (name: %d)", obj->name); | 106 | seq_printf(m, " (name: %d)", obj->name); |
106 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 107 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
107 | seq_printf(m, " (fence: %d)\n", obj_priv->fence_reg); | 108 | seq_printf(m, " (fence: %d)", obj_priv->fence_reg); |
109 | if (obj_priv->gtt_space != NULL) | ||
110 | seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset); | ||
111 | |||
108 | seq_printf(m, "\n"); | 112 | seq_printf(m, "\n"); |
109 | } | 113 | } |
110 | 114 | ||
@@ -323,6 +327,39 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
323 | return 0; | 327 | return 0; |
324 | } | 328 | } |
325 | 329 | ||
330 | static int i915_error_state(struct seq_file *m, void *unused) | ||
331 | { | ||
332 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
333 | struct drm_device *dev = node->minor->dev; | ||
334 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
335 | struct drm_i915_error_state *error; | ||
336 | unsigned long flags; | ||
337 | |||
338 | spin_lock_irqsave(&dev_priv->error_lock, flags); | ||
339 | if (!dev_priv->first_error) { | ||
340 | seq_printf(m, "no error state collected\n"); | ||
341 | goto out; | ||
342 | } | ||
343 | |||
344 | error = dev_priv->first_error; | ||
345 | |||
346 | seq_printf(m, "EIR: 0x%08x\n", error->eir); | ||
347 | seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); | ||
348 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); | ||
349 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); | ||
350 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); | ||
351 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); | ||
352 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); | ||
353 | if (IS_I965G(dev)) { | ||
354 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps); | ||
355 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); | ||
356 | } | ||
357 | |||
358 | out: | ||
359 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | ||
360 | |||
361 | return 0; | ||
362 | } | ||
326 | 363 | ||
327 | static struct drm_info_list i915_gem_debugfs_list[] = { | 364 | static struct drm_info_list i915_gem_debugfs_list[] = { |
328 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 365 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
@@ -336,6 +373,7 @@ static struct drm_info_list i915_gem_debugfs_list[] = { | |||
336 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, | 373 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, |
337 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, | 374 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, |
338 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, | 375 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, |
376 | {"i915_error_state", i915_error_state, 0}, | ||
339 | }; | 377 | }; |
340 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) | 378 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) |
341 | 379 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index daeae62e1c28..a2d527b22ec4 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -521,6 +521,12 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
521 | goto err; | 521 | goto err; |
522 | } | 522 | } |
523 | 523 | ||
524 | /* If we've changed tiling, GTT-mappings of the object | ||
525 | * need to re-fault to ensure that the correct fence register | ||
526 | * setup is in place. | ||
527 | */ | ||
528 | i915_gem_release_mmap(obj); | ||
529 | |||
524 | obj_priv->tiling_mode = args->tiling_mode; | 530 | obj_priv->tiling_mode = args->tiling_mode; |
525 | obj_priv->stride = args->stride; | 531 | obj_priv->stride = args->stride; |
526 | } | 532 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 228546f6eaa4..7ba23a69a0c0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -26,6 +26,7 @@ | |||
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/sysrq.h> | ||
29 | #include "drmP.h" | 30 | #include "drmP.h" |
30 | #include "drm.h" | 31 | #include "drm.h" |
31 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
@@ -41,9 +42,10 @@ | |||
41 | * we leave them always unmasked in IMR and then control enabling them through | 42 | * we leave them always unmasked in IMR and then control enabling them through |
42 | * PIPESTAT alone. | 43 | * PIPESTAT alone. |
43 | */ | 44 | */ |
44 | #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ | 45 | #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ |
45 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ | 46 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ |
46 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) | 47 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \ |
48 | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | ||
47 | 49 | ||
48 | /** Interrupts that we mask and unmask at runtime. */ | 50 | /** Interrupts that we mask and unmask at runtime. */ |
49 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) | 51 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) |
@@ -288,6 +290,47 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
288 | return ret; | 290 | return ret; |
289 | } | 291 | } |
290 | 292 | ||
293 | static void i915_capture_error_state(struct drm_device *dev) | ||
294 | { | ||
295 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
296 | struct drm_i915_error_state *error; | ||
297 | unsigned long flags; | ||
298 | |||
299 | spin_lock_irqsave(&dev_priv->error_lock, flags); | ||
300 | if (dev_priv->first_error) | ||
301 | goto out; | ||
302 | |||
303 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | ||
304 | if (!error) { | ||
305 | DRM_DEBUG("out ot memory, not capturing error state\n"); | ||
306 | goto out; | ||
307 | } | ||
308 | |||
309 | error->eir = I915_READ(EIR); | ||
310 | error->pgtbl_er = I915_READ(PGTBL_ER); | ||
311 | error->pipeastat = I915_READ(PIPEASTAT); | ||
312 | error->pipebstat = I915_READ(PIPEBSTAT); | ||
313 | error->instpm = I915_READ(INSTPM); | ||
314 | if (!IS_I965G(dev)) { | ||
315 | error->ipeir = I915_READ(IPEIR); | ||
316 | error->ipehr = I915_READ(IPEHR); | ||
317 | error->instdone = I915_READ(INSTDONE); | ||
318 | error->acthd = I915_READ(ACTHD); | ||
319 | } else { | ||
320 | error->ipeir = I915_READ(IPEIR_I965); | ||
321 | error->ipehr = I915_READ(IPEHR_I965); | ||
322 | error->instdone = I915_READ(INSTDONE_I965); | ||
323 | error->instps = I915_READ(INSTPS); | ||
324 | error->instdone1 = I915_READ(INSTDONE1); | ||
325 | error->acthd = I915_READ(ACTHD_I965); | ||
326 | } | ||
327 | |||
328 | dev_priv->first_error = error; | ||
329 | |||
330 | out: | ||
331 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | ||
332 | } | ||
333 | |||
291 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 334 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
292 | { | 335 | { |
293 | struct drm_device *dev = (struct drm_device *) arg; | 336 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -333,11 +376,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
333 | * Clear the PIPE(A|B)STAT regs before the IIR | 376 | * Clear the PIPE(A|B)STAT regs before the IIR |
334 | */ | 377 | */ |
335 | if (pipea_stats & 0x8000ffff) { | 378 | if (pipea_stats & 0x8000ffff) { |
379 | if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS) | ||
380 | DRM_DEBUG("pipe a underrun\n"); | ||
336 | I915_WRITE(PIPEASTAT, pipea_stats); | 381 | I915_WRITE(PIPEASTAT, pipea_stats); |
337 | irq_received = 1; | 382 | irq_received = 1; |
338 | } | 383 | } |
339 | 384 | ||
340 | if (pipeb_stats & 0x8000ffff) { | 385 | if (pipeb_stats & 0x8000ffff) { |
386 | if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS) | ||
387 | DRM_DEBUG("pipe b underrun\n"); | ||
341 | I915_WRITE(PIPEBSTAT, pipeb_stats); | 388 | I915_WRITE(PIPEBSTAT, pipeb_stats); |
342 | irq_received = 1; | 389 | irq_received = 1; |
343 | } | 390 | } |
@@ -362,6 +409,80 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
362 | I915_READ(PORT_HOTPLUG_STAT); | 409 | I915_READ(PORT_HOTPLUG_STAT); |
363 | } | 410 | } |
364 | 411 | ||
412 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) { | ||
413 | u32 eir = I915_READ(EIR); | ||
414 | |||
415 | i915_capture_error_state(dev); | ||
416 | |||
417 | printk(KERN_ERR "render error detected, EIR: 0x%08x\n", | ||
418 | eir); | ||
419 | if (eir & I915_ERROR_PAGE_TABLE) { | ||
420 | u32 pgtbl_err = I915_READ(PGTBL_ER); | ||
421 | printk(KERN_ERR "page table error\n"); | ||
422 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | ||
423 | pgtbl_err); | ||
424 | I915_WRITE(PGTBL_ER, pgtbl_err); | ||
425 | (void)I915_READ(PGTBL_ER); | ||
426 | } | ||
427 | if (eir & I915_ERROR_MEMORY_REFRESH) { | ||
428 | printk(KERN_ERR "memory refresh error\n"); | ||
429 | printk(KERN_ERR "PIPEASTAT: 0x%08x\n", | ||
430 | pipea_stats); | ||
431 | printk(KERN_ERR "PIPEBSTAT: 0x%08x\n", | ||
432 | pipeb_stats); | ||
433 | /* pipestat has already been acked */ | ||
434 | } | ||
435 | if (eir & I915_ERROR_INSTRUCTION) { | ||
436 | printk(KERN_ERR "instruction error\n"); | ||
437 | printk(KERN_ERR " INSTPM: 0x%08x\n", | ||
438 | I915_READ(INSTPM)); | ||
439 | if (!IS_I965G(dev)) { | ||
440 | u32 ipeir = I915_READ(IPEIR); | ||
441 | |||
442 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
443 | I915_READ(IPEIR)); | ||
444 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
445 | I915_READ(IPEHR)); | ||
446 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
447 | I915_READ(INSTDONE)); | ||
448 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
449 | I915_READ(ACTHD)); | ||
450 | I915_WRITE(IPEIR, ipeir); | ||
451 | (void)I915_READ(IPEIR); | ||
452 | } else { | ||
453 | u32 ipeir = I915_READ(IPEIR_I965); | ||
454 | |||
455 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
456 | I915_READ(IPEIR_I965)); | ||
457 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
458 | I915_READ(IPEHR_I965)); | ||
459 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
460 | I915_READ(INSTDONE_I965)); | ||
461 | printk(KERN_ERR " INSTPS: 0x%08x\n", | ||
462 | I915_READ(INSTPS)); | ||
463 | printk(KERN_ERR " INSTDONE1: 0x%08x\n", | ||
464 | I915_READ(INSTDONE1)); | ||
465 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
466 | I915_READ(ACTHD_I965)); | ||
467 | I915_WRITE(IPEIR_I965, ipeir); | ||
468 | (void)I915_READ(IPEIR_I965); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | I915_WRITE(EIR, eir); | ||
473 | (void)I915_READ(EIR); | ||
474 | eir = I915_READ(EIR); | ||
475 | if (eir) { | ||
476 | /* | ||
477 | * some errors might have become stuck, | ||
478 | * mask them. | ||
479 | */ | ||
480 | DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir); | ||
481 | I915_WRITE(EMR, I915_READ(EMR) | eir); | ||
482 | I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); | ||
483 | } | ||
484 | } | ||
485 | |||
365 | I915_WRITE(IIR, iir); | 486 | I915_WRITE(IIR, iir); |
366 | new_iir = I915_READ(IIR); /* Flush posted writes */ | 487 | new_iir = I915_READ(IIR); /* Flush posted writes */ |
367 | 488 | ||
@@ -732,6 +853,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
732 | { | 853 | { |
733 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 854 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
734 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; | 855 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; |
856 | u32 error_mask; | ||
735 | 857 | ||
736 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | 858 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); |
737 | 859 | ||
@@ -768,6 +890,21 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
768 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); | 890 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); |
769 | } | 891 | } |
770 | 892 | ||
893 | /* | ||
894 | * Enable some error detection, note the instruction error mask | ||
895 | * bit is reserved, so we leave it masked. | ||
896 | */ | ||
897 | if (IS_G4X(dev)) { | ||
898 | error_mask = ~(GM45_ERROR_PAGE_TABLE | | ||
899 | GM45_ERROR_MEM_PRIV | | ||
900 | GM45_ERROR_CP_PRIV | | ||
901 | I915_ERROR_MEMORY_REFRESH); | ||
902 | } else { | ||
903 | error_mask = ~(I915_ERROR_PAGE_TABLE | | ||
904 | I915_ERROR_MEMORY_REFRESH); | ||
905 | } | ||
906 | I915_WRITE(EMR, error_mask); | ||
907 | |||
771 | /* Disable pipe interrupt enables, clear pending pipe status */ | 908 | /* Disable pipe interrupt enables, clear pending pipe status */ |
772 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); | 909 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); |
773 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); | 910 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 88bf7521405f..6c0858484094 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -206,6 +206,7 @@ | |||
206 | /* | 206 | /* |
207 | * Instruction and interrupt control regs | 207 | * Instruction and interrupt control regs |
208 | */ | 208 | */ |
209 | #define PGTBL_ER 0x02024 | ||
209 | #define PRB0_TAIL 0x02030 | 210 | #define PRB0_TAIL 0x02030 |
210 | #define PRB0_HEAD 0x02034 | 211 | #define PRB0_HEAD 0x02034 |
211 | #define PRB0_START 0x02038 | 212 | #define PRB0_START 0x02038 |
@@ -226,11 +227,18 @@ | |||
226 | #define PRB1_HEAD 0x02044 /* 915+ only */ | 227 | #define PRB1_HEAD 0x02044 /* 915+ only */ |
227 | #define PRB1_START 0x02048 /* 915+ only */ | 228 | #define PRB1_START 0x02048 /* 915+ only */ |
228 | #define PRB1_CTL 0x0204c /* 915+ only */ | 229 | #define PRB1_CTL 0x0204c /* 915+ only */ |
230 | #define IPEIR_I965 0x02064 | ||
231 | #define IPEHR_I965 0x02068 | ||
232 | #define INSTDONE_I965 0x0206c | ||
233 | #define INSTPS 0x02070 /* 965+ only */ | ||
234 | #define INSTDONE1 0x0207c /* 965+ only */ | ||
229 | #define ACTHD_I965 0x02074 | 235 | #define ACTHD_I965 0x02074 |
230 | #define HWS_PGA 0x02080 | 236 | #define HWS_PGA 0x02080 |
231 | #define HWS_ADDRESS_MASK 0xfffff000 | 237 | #define HWS_ADDRESS_MASK 0xfffff000 |
232 | #define HWS_START_ADDRESS_SHIFT 4 | 238 | #define HWS_START_ADDRESS_SHIFT 4 |
233 | #define IPEIR 0x02088 | 239 | #define IPEIR 0x02088 |
240 | #define IPEHR 0x0208c | ||
241 | #define INSTDONE 0x02090 | ||
234 | #define NOPID 0x02094 | 242 | #define NOPID 0x02094 |
235 | #define HWSTAM 0x02098 | 243 | #define HWSTAM 0x02098 |
236 | #define SCPD0 0x0209c /* 915+ only */ | 244 | #define SCPD0 0x0209c /* 915+ only */ |
@@ -258,10 +266,22 @@ | |||
258 | #define EIR 0x020b0 | 266 | #define EIR 0x020b0 |
259 | #define EMR 0x020b4 | 267 | #define EMR 0x020b4 |
260 | #define ESR 0x020b8 | 268 | #define ESR 0x020b8 |
269 | #define GM45_ERROR_PAGE_TABLE (1<<5) | ||
270 | #define GM45_ERROR_MEM_PRIV (1<<4) | ||
271 | #define I915_ERROR_PAGE_TABLE (1<<4) | ||
272 | #define GM45_ERROR_CP_PRIV (1<<3) | ||
273 | #define I915_ERROR_MEMORY_REFRESH (1<<1) | ||
274 | #define I915_ERROR_INSTRUCTION (1<<0) | ||
261 | #define INSTPM 0x020c0 | 275 | #define INSTPM 0x020c0 |
262 | #define ACTHD 0x020c8 | 276 | #define ACTHD 0x020c8 |
263 | #define FW_BLC 0x020d8 | 277 | #define FW_BLC 0x020d8 |
278 | #define FW_BLC2 0x020dc | ||
264 | #define FW_BLC_SELF 0x020e0 /* 915+ only */ | 279 | #define FW_BLC_SELF 0x020e0 /* 915+ only */ |
280 | #define FW_BLC_SELF_EN (1<<15) | ||
281 | #define MM_BURST_LENGTH 0x00700000 | ||
282 | #define MM_FIFO_WATERMARK 0x0001F000 | ||
283 | #define LM_BURST_LENGTH 0x00000700 | ||
284 | #define LM_FIFO_WATERMARK 0x0000001F | ||
265 | #define MI_ARB_STATE 0x020e4 /* 915+ only */ | 285 | #define MI_ARB_STATE 0x020e4 /* 915+ only */ |
266 | #define CACHE_MODE_0 0x02120 /* 915+ only */ | 286 | #define CACHE_MODE_0 0x02120 /* 915+ only */ |
267 | #define CM0_MASK_SHIFT 16 | 287 | #define CM0_MASK_SHIFT 16 |
@@ -571,17 +591,21 @@ | |||
571 | 591 | ||
572 | /* Clocking configuration register */ | 592 | /* Clocking configuration register */ |
573 | #define CLKCFG 0x10c00 | 593 | #define CLKCFG 0x10c00 |
574 | #define CLKCFG_FSB_400 (0 << 0) /* hrawclk 100 */ | 594 | #define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ |
575 | #define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ | 595 | #define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ |
576 | #define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ | 596 | #define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ |
577 | #define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ | 597 | #define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ |
578 | #define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ | 598 | #define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ |
579 | #define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ | 599 | #define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ |
580 | /* this is a guess, could be 5 as well */ | 600 | /* Note, below two are guess */ |
581 | #define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ | 601 | #define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ |
582 | #define CLKCFG_FSB_1600_ALT (5 << 0) /* hrawclk 400 */ | 602 | #define CLKCFG_FSB_1600_ALT (0 << 0) /* hrawclk 400 */ |
583 | #define CLKCFG_FSB_MASK (7 << 0) | 603 | #define CLKCFG_FSB_MASK (7 << 0) |
584 | 604 | #define CLKCFG_MEM_533 (1 << 4) | |
605 | #define CLKCFG_MEM_667 (2 << 4) | ||
606 | #define CLKCFG_MEM_800 (3 << 4) | ||
607 | #define CLKCFG_MEM_MASK (7 << 4) | ||
608 | |||
585 | /** GM965 GM45 render standby register */ | 609 | /** GM965 GM45 render standby register */ |
586 | #define MCHBAR_RENDER_STANDBY 0x111B8 | 610 | #define MCHBAR_RENDER_STANDBY 0x111B8 |
587 | 611 | ||
@@ -1581,6 +1605,34 @@ | |||
1581 | #define DSPARB_CSTART_SHIFT 7 | 1605 | #define DSPARB_CSTART_SHIFT 7 |
1582 | #define DSPARB_BSTART_MASK (0x7f) | 1606 | #define DSPARB_BSTART_MASK (0x7f) |
1583 | #define DSPARB_BSTART_SHIFT 0 | 1607 | #define DSPARB_BSTART_SHIFT 0 |
1608 | #define DSPARB_BEND_SHIFT 9 /* on 855 */ | ||
1609 | #define DSPARB_AEND_SHIFT 0 | ||
1610 | |||
1611 | #define DSPFW1 0x70034 | ||
1612 | #define DSPFW2 0x70038 | ||
1613 | #define DSPFW3 0x7003c | ||
1614 | #define IGD_SELF_REFRESH_EN (1<<30) | ||
1615 | |||
1616 | /* FIFO watermark sizes etc */ | ||
1617 | #define I915_FIFO_LINE_SIZE 64 | ||
1618 | #define I830_FIFO_LINE_SIZE 32 | ||
1619 | #define I945_FIFO_SIZE 127 /* 945 & 965 */ | ||
1620 | #define I915_FIFO_SIZE 95 | ||
1621 | #define I855GM_FIFO_SIZE 255 | ||
1622 | #define I830_FIFO_SIZE 95 | ||
1623 | #define I915_MAX_WM 0x3f | ||
1624 | |||
1625 | #define IGD_DISPLAY_FIFO 512 /* in 64byte unit */ | ||
1626 | #define IGD_FIFO_LINE_SIZE 64 | ||
1627 | #define IGD_MAX_WM 0x1ff | ||
1628 | #define IGD_DFT_WM 0x3f | ||
1629 | #define IGD_DFT_HPLLOFF_WM 0 | ||
1630 | #define IGD_GUARD_WM 10 | ||
1631 | #define IGD_CURSOR_FIFO 64 | ||
1632 | #define IGD_CURSOR_MAX_WM 0x3f | ||
1633 | #define IGD_CURSOR_DFT_WM 0 | ||
1634 | #define IGD_CURSOR_GUARD_WM 5 | ||
1635 | |||
1584 | /* | 1636 | /* |
1585 | * The two pipe frame counter registers are not synchronized, so | 1637 | * The two pipe frame counter registers are not synchronized, so |
1586 | * reading a stable value is somewhat tricky. The following code | 1638 | * reading a stable value is somewhat tricky. The following code |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 8d8e083d14ab..9e1d16e5c3ea 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -222,23 +222,12 @@ static void i915_restore_vga(struct drm_device *dev) | |||
222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); | 222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); |
223 | } | 223 | } |
224 | 224 | ||
225 | int i915_save_state(struct drm_device *dev) | 225 | static void i915_save_modeset_reg(struct drm_device *dev) |
226 | { | 226 | { |
227 | struct drm_i915_private *dev_priv = dev->dev_private; | 227 | struct drm_i915_private *dev_priv = dev->dev_private; |
228 | int i; | ||
229 | |||
230 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
231 | |||
232 | /* Render Standby */ | ||
233 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
234 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
235 | |||
236 | /* Hardware status page */ | ||
237 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
238 | |||
239 | /* Display arbitration control */ | ||
240 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
241 | 228 | ||
229 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
230 | return; | ||
242 | /* Pipe & plane A info */ | 231 | /* Pipe & plane A info */ |
243 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 232 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
244 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 233 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
@@ -294,7 +283,122 @@ int i915_save_state(struct drm_device *dev) | |||
294 | } | 283 | } |
295 | i915_save_palette(dev, PIPE_B); | 284 | i915_save_palette(dev, PIPE_B); |
296 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); | 285 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); |
286 | return; | ||
287 | } | ||
288 | static void i915_restore_modeset_reg(struct drm_device *dev) | ||
289 | { | ||
290 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
291 | |||
292 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
293 | return; | ||
294 | |||
295 | /* Pipe & plane A info */ | ||
296 | /* Prime the clock */ | ||
297 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
298 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
299 | ~DPLL_VCO_ENABLE); | ||
300 | DRM_UDELAY(150); | ||
301 | } | ||
302 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
303 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
304 | /* Actually enable it */ | ||
305 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
306 | DRM_UDELAY(150); | ||
307 | if (IS_I965G(dev)) | ||
308 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
309 | DRM_UDELAY(150); | ||
310 | |||
311 | /* Restore mode */ | ||
312 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
313 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
314 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
315 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
316 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
317 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
318 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
319 | |||
320 | /* Restore plane info */ | ||
321 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
322 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
323 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
324 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
325 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
326 | if (IS_I965G(dev)) { | ||
327 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
328 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
329 | } | ||
330 | |||
331 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
332 | |||
333 | i915_restore_palette(dev, PIPE_A); | ||
334 | /* Enable the plane */ | ||
335 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
336 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
337 | |||
338 | /* Pipe & plane B info */ | ||
339 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
340 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
341 | ~DPLL_VCO_ENABLE); | ||
342 | DRM_UDELAY(150); | ||
343 | } | ||
344 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
345 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
346 | /* Actually enable it */ | ||
347 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
348 | DRM_UDELAY(150); | ||
349 | if (IS_I965G(dev)) | ||
350 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
351 | DRM_UDELAY(150); | ||
352 | |||
353 | /* Restore mode */ | ||
354 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
355 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
356 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
357 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
358 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
359 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
360 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
361 | |||
362 | /* Restore plane info */ | ||
363 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
364 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
365 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
366 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
367 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
368 | if (IS_I965G(dev)) { | ||
369 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
370 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
371 | } | ||
372 | |||
373 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
374 | |||
375 | i915_restore_palette(dev, PIPE_B); | ||
376 | /* Enable the plane */ | ||
377 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
378 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
297 | 379 | ||
380 | return; | ||
381 | } | ||
382 | int i915_save_state(struct drm_device *dev) | ||
383 | { | ||
384 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
385 | int i; | ||
386 | |||
387 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
388 | |||
389 | /* Render Standby */ | ||
390 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
391 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
392 | |||
393 | /* Hardware status page */ | ||
394 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
395 | |||
396 | /* Display arbitration control */ | ||
397 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
398 | |||
399 | /* This is only meaningful in non-KMS mode */ | ||
400 | /* Don't save them in KMS mode */ | ||
401 | i915_save_modeset_reg(dev); | ||
298 | /* Cursor state */ | 402 | /* Cursor state */ |
299 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); | 403 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); |
300 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); | 404 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); |
@@ -430,92 +534,9 @@ int i915_restore_state(struct drm_device *dev) | |||
430 | I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); | 534 | I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); |
431 | I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); | 535 | I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); |
432 | } | 536 | } |
433 | 537 | /* This is only meaningful in non-KMS mode */ | |
434 | /* Pipe & plane A info */ | 538 | /* Don't restore them in KMS mode */ |
435 | /* Prime the clock */ | 539 | i915_restore_modeset_reg(dev); |
436 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
437 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
438 | ~DPLL_VCO_ENABLE); | ||
439 | DRM_UDELAY(150); | ||
440 | } | ||
441 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
442 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
443 | /* Actually enable it */ | ||
444 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
445 | DRM_UDELAY(150); | ||
446 | if (IS_I965G(dev)) | ||
447 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
448 | DRM_UDELAY(150); | ||
449 | |||
450 | /* Restore mode */ | ||
451 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
452 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
453 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
454 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
455 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
456 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
457 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
458 | |||
459 | /* Restore plane info */ | ||
460 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
461 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
462 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
463 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
464 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
465 | if (IS_I965G(dev)) { | ||
466 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
467 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
468 | } | ||
469 | |||
470 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
471 | |||
472 | i915_restore_palette(dev, PIPE_A); | ||
473 | /* Enable the plane */ | ||
474 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
475 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
476 | |||
477 | /* Pipe & plane B info */ | ||
478 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
479 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
480 | ~DPLL_VCO_ENABLE); | ||
481 | DRM_UDELAY(150); | ||
482 | } | ||
483 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
484 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
485 | /* Actually enable it */ | ||
486 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
487 | DRM_UDELAY(150); | ||
488 | if (IS_I965G(dev)) | ||
489 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
490 | DRM_UDELAY(150); | ||
491 | |||
492 | /* Restore mode */ | ||
493 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
494 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
495 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
496 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
497 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
498 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
499 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
500 | |||
501 | /* Restore plane info */ | ||
502 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
503 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
504 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
505 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
506 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
507 | if (IS_I965G(dev)) { | ||
508 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
509 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
510 | } | ||
511 | |||
512 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
513 | |||
514 | i915_restore_palette(dev, PIPE_B); | ||
515 | /* Enable the plane */ | ||
516 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
517 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
518 | |||
519 | /* Cursor state */ | 540 | /* Cursor state */ |
520 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); | 541 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); |
521 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); | 542 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 716409a57244..7cc447191028 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -97,6 +97,7 @@ static void | |||
97 | parse_lfp_panel_data(struct drm_i915_private *dev_priv, | 97 | parse_lfp_panel_data(struct drm_i915_private *dev_priv, |
98 | struct bdb_header *bdb) | 98 | struct bdb_header *bdb) |
99 | { | 99 | { |
100 | struct drm_device *dev = dev_priv->dev; | ||
100 | struct bdb_lvds_options *lvds_options; | 101 | struct bdb_lvds_options *lvds_options; |
101 | struct bdb_lvds_lfp_data *lvds_lfp_data; | 102 | struct bdb_lvds_lfp_data *lvds_lfp_data; |
102 | struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; | 103 | struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; |
@@ -132,7 +133,14 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
132 | entry = (struct bdb_lvds_lfp_data_entry *) | 133 | entry = (struct bdb_lvds_lfp_data_entry *) |
133 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * | 134 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * |
134 | lvds_options->panel_type)); | 135 | lvds_options->panel_type)); |
135 | dvo_timing = &entry->dvo_timing; | 136 | |
137 | /* On IGDNG mobile, LVDS data block removes panel fitting registers. | ||
138 | So dec 2 dword from dvo_timing offset */ | ||
139 | if (IS_IGDNG(dev)) | ||
140 | dvo_timing = (struct lvds_dvo_timing *) | ||
141 | ((u8 *)&entry->dvo_timing - 8); | ||
142 | else | ||
143 | dvo_timing = &entry->dvo_timing; | ||
136 | 144 | ||
137 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); | 145 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); |
138 | 146 | ||
@@ -195,10 +203,12 @@ parse_general_features(struct drm_i915_private *dev_priv, | |||
195 | dev_priv->lvds_use_ssc = general->enable_ssc; | 203 | dev_priv->lvds_use_ssc = general->enable_ssc; |
196 | 204 | ||
197 | if (dev_priv->lvds_use_ssc) { | 205 | if (dev_priv->lvds_use_ssc) { |
198 | if (IS_I855(dev_priv->dev)) | 206 | if (IS_I85X(dev_priv->dev)) |
199 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; | 207 | dev_priv->lvds_ssc_freq = |
200 | else | 208 | general->ssc_freq ? 66 : 48; |
201 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; | 209 | else |
210 | dev_priv->lvds_ssc_freq = | ||
211 | general->ssc_freq ? 100 : 96; | ||
202 | } | 212 | } |
203 | } | 213 | } |
204 | } | 214 | } |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 6de97fc66029..d6a1a6e5539a 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -46,7 +46,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) | |||
46 | 46 | ||
47 | temp = I915_READ(reg); | 47 | temp = I915_READ(reg); |
48 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); | 48 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); |
49 | temp |= ADPA_DAC_ENABLE; | 49 | temp &= ~ADPA_DAC_ENABLE; |
50 | 50 | ||
51 | switch(mode) { | 51 | switch(mode) { |
52 | case DRM_MODE_DPMS_ON: | 52 | case DRM_MODE_DPMS_ON: |
@@ -428,8 +428,34 @@ static void intel_crt_destroy(struct drm_connector *connector) | |||
428 | 428 | ||
429 | static int intel_crt_get_modes(struct drm_connector *connector) | 429 | static int intel_crt_get_modes(struct drm_connector *connector) |
430 | { | 430 | { |
431 | int ret; | ||
431 | struct intel_output *intel_output = to_intel_output(connector); | 432 | struct intel_output *intel_output = to_intel_output(connector); |
432 | return intel_ddc_get_modes(intel_output); | 433 | struct i2c_adapter *ddcbus; |
434 | struct drm_device *dev = connector->dev; | ||
435 | |||
436 | |||
437 | ret = intel_ddc_get_modes(intel_output); | ||
438 | if (ret || !IS_G4X(dev)) | ||
439 | goto end; | ||
440 | |||
441 | ddcbus = intel_output->ddc_bus; | ||
442 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | ||
443 | intel_output->ddc_bus = | ||
444 | intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); | ||
445 | |||
446 | if (!intel_output->ddc_bus) { | ||
447 | intel_output->ddc_bus = ddcbus; | ||
448 | dev_printk(KERN_ERR, &connector->dev->pdev->dev, | ||
449 | "DDC bus registration failed for CRTDDC_D.\n"); | ||
450 | goto end; | ||
451 | } | ||
452 | /* Try to get modes by GPIOD port */ | ||
453 | ret = intel_ddc_get_modes(intel_output); | ||
454 | intel_i2c_destroy(ddcbus); | ||
455 | |||
456 | end: | ||
457 | return ret; | ||
458 | |||
433 | } | 459 | } |
434 | 460 | ||
435 | static int intel_crt_set_property(struct drm_connector *connector, | 461 | static int intel_crt_set_property(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 73e7b9cecac8..508838ee31e0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/kernel.h> | ||
28 | #include "drmP.h" | 29 | #include "drmP.h" |
29 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
30 | #include "i915_drm.h" | 31 | #include "i915_drm.h" |
@@ -34,6 +35,7 @@ | |||
34 | #include "drm_crtc_helper.h" | 35 | #include "drm_crtc_helper.h" |
35 | 36 | ||
36 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 37 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
38 | static void intel_update_watermarks(struct drm_device *dev); | ||
37 | 39 | ||
38 | typedef struct { | 40 | typedef struct { |
39 | /* given values */ | 41 | /* given values */ |
@@ -814,24 +816,21 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
814 | { | 816 | { |
815 | intel_clock_t clock; | 817 | intel_clock_t clock; |
816 | if (target < 200000) { | 818 | if (target < 200000) { |
817 | clock.dot = 161670; | ||
818 | clock.p = 20; | ||
819 | clock.p1 = 2; | 819 | clock.p1 = 2; |
820 | clock.p2 = 10; | 820 | clock.p2 = 10; |
821 | clock.n = 0x01; | 821 | clock.n = 2; |
822 | clock.m = 97; | 822 | clock.m1 = 23; |
823 | clock.m1 = 0x10; | 823 | clock.m2 = 8; |
824 | clock.m2 = 0x05; | ||
825 | } else { | 824 | } else { |
826 | clock.dot = 270000; | ||
827 | clock.p = 10; | ||
828 | clock.p1 = 1; | 825 | clock.p1 = 1; |
829 | clock.p2 = 10; | 826 | clock.p2 = 10; |
830 | clock.n = 0x02; | 827 | clock.n = 1; |
831 | clock.m = 108; | 828 | clock.m1 = 14; |
832 | clock.m1 = 0x12; | 829 | clock.m2 = 2; |
833 | clock.m2 = 0x06; | ||
834 | } | 830 | } |
831 | clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); | ||
832 | clock.p = (clock.p1 * clock.p2); | ||
833 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; | ||
835 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | 834 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); |
836 | return true; | 835 | return true; |
837 | } | 836 | } |
@@ -1005,7 +1004,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1005 | struct drm_i915_private *dev_priv = dev->dev_private; | 1004 | struct drm_i915_private *dev_priv = dev->dev_private; |
1006 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1005 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1007 | int pipe = intel_crtc->pipe; | 1006 | int pipe = intel_crtc->pipe; |
1008 | int plane = intel_crtc->pipe; | 1007 | int plane = intel_crtc->plane; |
1009 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; | 1008 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; |
1010 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | 1009 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; |
1011 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | 1010 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; |
@@ -1335,8 +1334,10 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1335 | 1334 | ||
1336 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | 1335 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
1337 | //intel_crtc_dpms_video(crtc, true); TODO | 1336 | //intel_crtc_dpms_video(crtc, true); TODO |
1337 | intel_update_watermarks(dev); | ||
1338 | break; | 1338 | break; |
1339 | case DRM_MODE_DPMS_OFF: | 1339 | case DRM_MODE_DPMS_OFF: |
1340 | intel_update_watermarks(dev); | ||
1340 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 1341 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
1341 | //intel_crtc_dpms_video(crtc, FALSE); TODO | 1342 | //intel_crtc_dpms_video(crtc, FALSE); TODO |
1342 | 1343 | ||
@@ -1515,7 +1516,6 @@ static int intel_get_core_clock_speed(struct drm_device *dev) | |||
1515 | return 0; /* Silence gcc warning */ | 1516 | return 0; /* Silence gcc warning */ |
1516 | } | 1517 | } |
1517 | 1518 | ||
1518 | |||
1519 | /** | 1519 | /** |
1520 | * Return the pipe currently connected to the panel fitter, | 1520 | * Return the pipe currently connected to the panel fitter, |
1521 | * or -1 if the panel fitter is not present or not in use | 1521 | * or -1 if the panel fitter is not present or not in use |
@@ -1574,7 +1574,7 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1574 | 1574 | ||
1575 | temp = (u64) DATA_N * pixel_clock; | 1575 | temp = (u64) DATA_N * pixel_clock; |
1576 | temp = div_u64(temp, link_clock); | 1576 | temp = div_u64(temp, link_clock); |
1577 | m_n->gmch_m = (temp * bytes_per_pixel) / nlanes; | 1577 | m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes); |
1578 | m_n->gmch_n = DATA_N; | 1578 | m_n->gmch_n = DATA_N; |
1579 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 1579 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
1580 | 1580 | ||
@@ -1585,6 +1585,420 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1585 | } | 1585 | } |
1586 | 1586 | ||
1587 | 1587 | ||
1588 | struct intel_watermark_params { | ||
1589 | unsigned long fifo_size; | ||
1590 | unsigned long max_wm; | ||
1591 | unsigned long default_wm; | ||
1592 | unsigned long guard_size; | ||
1593 | unsigned long cacheline_size; | ||
1594 | }; | ||
1595 | |||
1596 | /* IGD has different values for various configs */ | ||
1597 | static struct intel_watermark_params igd_display_wm = { | ||
1598 | IGD_DISPLAY_FIFO, | ||
1599 | IGD_MAX_WM, | ||
1600 | IGD_DFT_WM, | ||
1601 | IGD_GUARD_WM, | ||
1602 | IGD_FIFO_LINE_SIZE | ||
1603 | }; | ||
1604 | static struct intel_watermark_params igd_display_hplloff_wm = { | ||
1605 | IGD_DISPLAY_FIFO, | ||
1606 | IGD_MAX_WM, | ||
1607 | IGD_DFT_HPLLOFF_WM, | ||
1608 | IGD_GUARD_WM, | ||
1609 | IGD_FIFO_LINE_SIZE | ||
1610 | }; | ||
1611 | static struct intel_watermark_params igd_cursor_wm = { | ||
1612 | IGD_CURSOR_FIFO, | ||
1613 | IGD_CURSOR_MAX_WM, | ||
1614 | IGD_CURSOR_DFT_WM, | ||
1615 | IGD_CURSOR_GUARD_WM, | ||
1616 | IGD_FIFO_LINE_SIZE, | ||
1617 | }; | ||
1618 | static struct intel_watermark_params igd_cursor_hplloff_wm = { | ||
1619 | IGD_CURSOR_FIFO, | ||
1620 | IGD_CURSOR_MAX_WM, | ||
1621 | IGD_CURSOR_DFT_WM, | ||
1622 | IGD_CURSOR_GUARD_WM, | ||
1623 | IGD_FIFO_LINE_SIZE | ||
1624 | }; | ||
1625 | static struct intel_watermark_params i945_wm_info = { | ||
1626 | I915_FIFO_LINE_SIZE, | ||
1627 | I915_MAX_WM, | ||
1628 | 1, | ||
1629 | 0, | ||
1630 | IGD_FIFO_LINE_SIZE | ||
1631 | }; | ||
1632 | static struct intel_watermark_params i915_wm_info = { | ||
1633 | I945_FIFO_SIZE, | ||
1634 | I915_MAX_WM, | ||
1635 | 1, | ||
1636 | 0, | ||
1637 | I915_FIFO_LINE_SIZE | ||
1638 | }; | ||
1639 | static struct intel_watermark_params i855_wm_info = { | ||
1640 | I855GM_FIFO_SIZE, | ||
1641 | I915_MAX_WM, | ||
1642 | 1, | ||
1643 | 0, | ||
1644 | I830_FIFO_LINE_SIZE | ||
1645 | }; | ||
1646 | static struct intel_watermark_params i830_wm_info = { | ||
1647 | I830_FIFO_SIZE, | ||
1648 | I915_MAX_WM, | ||
1649 | 1, | ||
1650 | 0, | ||
1651 | I830_FIFO_LINE_SIZE | ||
1652 | }; | ||
1653 | |||
1654 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | ||
1655 | struct intel_watermark_params *wm, | ||
1656 | int pixel_size, | ||
1657 | unsigned long latency_ns) | ||
1658 | { | ||
1659 | unsigned long bytes_required, wm_size; | ||
1660 | |||
1661 | bytes_required = (clock_in_khz * pixel_size * latency_ns) / 1000000; | ||
1662 | bytes_required /= wm->cacheline_size; | ||
1663 | wm_size = wm->fifo_size - bytes_required - wm->guard_size; | ||
1664 | |||
1665 | if (wm_size > wm->max_wm) | ||
1666 | wm_size = wm->max_wm; | ||
1667 | if (wm_size == 0) | ||
1668 | wm_size = wm->default_wm; | ||
1669 | return wm_size; | ||
1670 | } | ||
1671 | |||
1672 | struct cxsr_latency { | ||
1673 | int is_desktop; | ||
1674 | unsigned long fsb_freq; | ||
1675 | unsigned long mem_freq; | ||
1676 | unsigned long display_sr; | ||
1677 | unsigned long display_hpll_disable; | ||
1678 | unsigned long cursor_sr; | ||
1679 | unsigned long cursor_hpll_disable; | ||
1680 | }; | ||
1681 | |||
1682 | static struct cxsr_latency cxsr_latency_table[] = { | ||
1683 | {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | ||
1684 | {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | ||
1685 | {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | ||
1686 | |||
1687 | {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | ||
1688 | {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | ||
1689 | {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | ||
1690 | |||
1691 | {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | ||
1692 | {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | ||
1693 | {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | ||
1694 | |||
1695 | {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | ||
1696 | {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | ||
1697 | {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | ||
1698 | |||
1699 | {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | ||
1700 | {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | ||
1701 | {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | ||
1702 | |||
1703 | {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | ||
1704 | {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | ||
1705 | {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | ||
1706 | }; | ||
1707 | |||
1708 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | ||
1709 | int mem) | ||
1710 | { | ||
1711 | int i; | ||
1712 | struct cxsr_latency *latency; | ||
1713 | |||
1714 | if (fsb == 0 || mem == 0) | ||
1715 | return NULL; | ||
1716 | |||
1717 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { | ||
1718 | latency = &cxsr_latency_table[i]; | ||
1719 | if (is_desktop == latency->is_desktop && | ||
1720 | fsb == latency->fsb_freq && mem == latency->mem_freq) | ||
1721 | break; | ||
1722 | } | ||
1723 | if (i >= ARRAY_SIZE(cxsr_latency_table)) { | ||
1724 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1725 | return NULL; | ||
1726 | } | ||
1727 | return latency; | ||
1728 | } | ||
1729 | |||
1730 | static void igd_disable_cxsr(struct drm_device *dev) | ||
1731 | { | ||
1732 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1733 | u32 reg; | ||
1734 | |||
1735 | /* deactivate cxsr */ | ||
1736 | reg = I915_READ(DSPFW3); | ||
1737 | reg &= ~(IGD_SELF_REFRESH_EN); | ||
1738 | I915_WRITE(DSPFW3, reg); | ||
1739 | DRM_INFO("Big FIFO is disabled\n"); | ||
1740 | } | ||
1741 | |||
1742 | static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, | ||
1743 | int pixel_size) | ||
1744 | { | ||
1745 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1746 | u32 reg; | ||
1747 | unsigned long wm; | ||
1748 | struct cxsr_latency *latency; | ||
1749 | |||
1750 | latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq, | ||
1751 | dev_priv->mem_freq); | ||
1752 | if (!latency) { | ||
1753 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1754 | igd_disable_cxsr(dev); | ||
1755 | return; | ||
1756 | } | ||
1757 | |||
1758 | /* Display SR */ | ||
1759 | wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size, | ||
1760 | latency->display_sr); | ||
1761 | reg = I915_READ(DSPFW1); | ||
1762 | reg &= 0x7fffff; | ||
1763 | reg |= wm << 23; | ||
1764 | I915_WRITE(DSPFW1, reg); | ||
1765 | DRM_DEBUG("DSPFW1 register is %x\n", reg); | ||
1766 | |||
1767 | /* cursor SR */ | ||
1768 | wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size, | ||
1769 | latency->cursor_sr); | ||
1770 | reg = I915_READ(DSPFW3); | ||
1771 | reg &= ~(0x3f << 24); | ||
1772 | reg |= (wm & 0x3f) << 24; | ||
1773 | I915_WRITE(DSPFW3, reg); | ||
1774 | |||
1775 | /* Display HPLL off SR */ | ||
1776 | wm = intel_calculate_wm(clock, &igd_display_hplloff_wm, | ||
1777 | latency->display_hpll_disable, I915_FIFO_LINE_SIZE); | ||
1778 | reg = I915_READ(DSPFW3); | ||
1779 | reg &= 0xfffffe00; | ||
1780 | reg |= wm & 0x1ff; | ||
1781 | I915_WRITE(DSPFW3, reg); | ||
1782 | |||
1783 | /* cursor HPLL off SR */ | ||
1784 | wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size, | ||
1785 | latency->cursor_hpll_disable); | ||
1786 | reg = I915_READ(DSPFW3); | ||
1787 | reg &= ~(0x3f << 16); | ||
1788 | reg |= (wm & 0x3f) << 16; | ||
1789 | I915_WRITE(DSPFW3, reg); | ||
1790 | DRM_DEBUG("DSPFW3 register is %x\n", reg); | ||
1791 | |||
1792 | /* activate cxsr */ | ||
1793 | reg = I915_READ(DSPFW3); | ||
1794 | reg |= IGD_SELF_REFRESH_EN; | ||
1795 | I915_WRITE(DSPFW3, reg); | ||
1796 | |||
1797 | DRM_INFO("Big FIFO is enabled\n"); | ||
1798 | |||
1799 | return; | ||
1800 | } | ||
1801 | |||
1802 | const static int latency_ns = 5000; /* default for non-igd platforms */ | ||
1803 | |||
1804 | |||
1805 | static void i965_update_wm(struct drm_device *dev) | ||
1806 | { | ||
1807 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1808 | |||
1809 | DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n"); | ||
1810 | |||
1811 | /* 965 has limitations... */ | ||
1812 | I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0)); | ||
1813 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); | ||
1814 | } | ||
1815 | |||
1816 | static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | ||
1817 | int planeb_clock, int sr_hdisplay, int pixel_size) | ||
1818 | { | ||
1819 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1820 | uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; | ||
1821 | uint32_t fwater_hi = I915_READ(FW_BLC2) & LM_FIFO_WATERMARK; | ||
1822 | int bsize, asize, cwm, bwm = 1, awm = 1, srwm = 1; | ||
1823 | uint32_t dsparb = I915_READ(DSPARB); | ||
1824 | int planea_entries, planeb_entries; | ||
1825 | struct intel_watermark_params *wm_params; | ||
1826 | unsigned long line_time_us; | ||
1827 | int sr_clock, sr_entries = 0; | ||
1828 | |||
1829 | if (IS_I965GM(dev) || IS_I945GM(dev)) | ||
1830 | wm_params = &i945_wm_info; | ||
1831 | else if (IS_I9XX(dev)) | ||
1832 | wm_params = &i915_wm_info; | ||
1833 | else | ||
1834 | wm_params = &i855_wm_info; | ||
1835 | |||
1836 | planea_entries = intel_calculate_wm(planea_clock, wm_params, | ||
1837 | pixel_size, latency_ns); | ||
1838 | planeb_entries = intel_calculate_wm(planeb_clock, wm_params, | ||
1839 | pixel_size, latency_ns); | ||
1840 | |||
1841 | DRM_DEBUG("FIFO entries - A: %d, B: %d\n", planea_entries, | ||
1842 | planeb_entries); | ||
1843 | |||
1844 | if (IS_I9XX(dev)) { | ||
1845 | asize = dsparb & 0x7f; | ||
1846 | bsize = (dsparb >> DSPARB_CSTART_SHIFT) & 0x7f; | ||
1847 | } else { | ||
1848 | asize = dsparb & 0x1ff; | ||
1849 | bsize = (dsparb >> DSPARB_BEND_SHIFT) & 0x1ff; | ||
1850 | } | ||
1851 | DRM_DEBUG("FIFO size - A: %d, B: %d\n", asize, bsize); | ||
1852 | |||
1853 | /* Two extra entries for padding */ | ||
1854 | awm = asize - (planea_entries + 2); | ||
1855 | bwm = bsize - (planeb_entries + 2); | ||
1856 | |||
1857 | /* Sanity check against potentially bad FIFO allocations */ | ||
1858 | if (awm <= 0) { | ||
1859 | /* pipe is on but has too few FIFO entries */ | ||
1860 | if (planea_entries != 0) | ||
1861 | DRM_DEBUG("plane A needs more FIFO entries\n"); | ||
1862 | awm = 1; | ||
1863 | } | ||
1864 | if (bwm <= 0) { | ||
1865 | if (planeb_entries != 0) | ||
1866 | DRM_DEBUG("plane B needs more FIFO entries\n"); | ||
1867 | bwm = 1; | ||
1868 | } | ||
1869 | |||
1870 | /* | ||
1871 | * Overlay gets an aggressive default since video jitter is bad. | ||
1872 | */ | ||
1873 | cwm = 2; | ||
1874 | |||
1875 | /* Calc sr entries for one pipe configs */ | ||
1876 | if (!planea_clock || !planeb_clock) { | ||
1877 | sr_clock = planea_clock ? planea_clock : planeb_clock; | ||
1878 | line_time_us = (sr_hdisplay * 1000) / sr_clock; | ||
1879 | sr_entries = (((latency_ns / line_time_us) + 1) * pixel_size * | ||
1880 | sr_hdisplay) / 1000; | ||
1881 | sr_entries = roundup(sr_entries / wm_params->cacheline_size, 1); | ||
1882 | if (sr_entries < wm_params->fifo_size) | ||
1883 | srwm = wm_params->fifo_size - sr_entries; | ||
1884 | } | ||
1885 | |||
1886 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | ||
1887 | awm, bwm, cwm, srwm); | ||
1888 | |||
1889 | fwater_lo = fwater_lo | ((bwm & 0x3f) << 16) | (awm & 0x3f); | ||
1890 | fwater_hi = fwater_hi | (cwm & 0x1f); | ||
1891 | |||
1892 | I915_WRITE(FW_BLC, fwater_lo); | ||
1893 | I915_WRITE(FW_BLC2, fwater_hi); | ||
1894 | if (IS_I9XX(dev)) | ||
1895 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); | ||
1896 | } | ||
1897 | |||
1898 | static void i830_update_wm(struct drm_device *dev, int planea_clock, | ||
1899 | int pixel_size) | ||
1900 | { | ||
1901 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1902 | uint32_t dsparb = I915_READ(DSPARB); | ||
1903 | uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; | ||
1904 | unsigned int asize, awm; | ||
1905 | int planea_entries; | ||
1906 | |||
1907 | planea_entries = intel_calculate_wm(planea_clock, &i830_wm_info, | ||
1908 | pixel_size, latency_ns); | ||
1909 | |||
1910 | asize = dsparb & 0x7f; | ||
1911 | |||
1912 | awm = asize - planea_entries; | ||
1913 | |||
1914 | fwater_lo = fwater_lo | awm; | ||
1915 | |||
1916 | I915_WRITE(FW_BLC, fwater_lo); | ||
1917 | } | ||
1918 | |||
1919 | /** | ||
1920 | * intel_update_watermarks - update FIFO watermark values based on current modes | ||
1921 | * | ||
1922 | * Calculate watermark values for the various WM regs based on current mode | ||
1923 | * and plane configuration. | ||
1924 | * | ||
1925 | * There are several cases to deal with here: | ||
1926 | * - normal (i.e. non-self-refresh) | ||
1927 | * - self-refresh (SR) mode | ||
1928 | * - lines are large relative to FIFO size (buffer can hold up to 2) | ||
1929 | * - lines are small relative to FIFO size (buffer can hold more than 2 | ||
1930 | * lines), so need to account for TLB latency | ||
1931 | * | ||
1932 | * The normal calculation is: | ||
1933 | * watermark = dotclock * bytes per pixel * latency | ||
1934 | * where latency is platform & configuration dependent (we assume pessimal | ||
1935 | * values here). | ||
1936 | * | ||
1937 | * The SR calculation is: | ||
1938 | * watermark = (trunc(latency/line time)+1) * surface width * | ||
1939 | * bytes per pixel | ||
1940 | * where | ||
1941 | * line time = htotal / dotclock | ||
1942 | * and latency is assumed to be high, as above. | ||
1943 | * | ||
1944 | * The final value programmed to the register should always be rounded up, | ||
1945 | * and include an extra 2 entries to account for clock crossings. | ||
1946 | * | ||
1947 | * We don't use the sprite, so we can ignore that. And on Crestline we have | ||
1948 | * to set the non-SR watermarks to 8. | ||
1949 | */ | ||
1950 | static void intel_update_watermarks(struct drm_device *dev) | ||
1951 | { | ||
1952 | struct drm_crtc *crtc; | ||
1953 | struct intel_crtc *intel_crtc; | ||
1954 | int sr_hdisplay = 0; | ||
1955 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | ||
1956 | int enabled = 0, pixel_size = 0; | ||
1957 | |||
1958 | if (DSPARB_HWCONTROL(dev)) | ||
1959 | return; | ||
1960 | |||
1961 | /* Get the clock config from both planes */ | ||
1962 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
1963 | intel_crtc = to_intel_crtc(crtc); | ||
1964 | if (crtc->enabled) { | ||
1965 | enabled++; | ||
1966 | if (intel_crtc->plane == 0) { | ||
1967 | DRM_DEBUG("plane A (pipe %d) clock: %d\n", | ||
1968 | intel_crtc->pipe, crtc->mode.clock); | ||
1969 | planea_clock = crtc->mode.clock; | ||
1970 | } else { | ||
1971 | DRM_DEBUG("plane B (pipe %d) clock: %d\n", | ||
1972 | intel_crtc->pipe, crtc->mode.clock); | ||
1973 | planeb_clock = crtc->mode.clock; | ||
1974 | } | ||
1975 | sr_hdisplay = crtc->mode.hdisplay; | ||
1976 | sr_clock = crtc->mode.clock; | ||
1977 | if (crtc->fb) | ||
1978 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
1979 | else | ||
1980 | pixel_size = 4; /* by default */ | ||
1981 | } | ||
1982 | } | ||
1983 | |||
1984 | if (enabled <= 0) | ||
1985 | return; | ||
1986 | |||
1987 | /* Single pipe configs can enable self refresh */ | ||
1988 | if (enabled == 1 && IS_IGD(dev)) | ||
1989 | igd_enable_cxsr(dev, sr_clock, pixel_size); | ||
1990 | else if (IS_IGD(dev)) | ||
1991 | igd_disable_cxsr(dev); | ||
1992 | |||
1993 | if (IS_I965G(dev)) | ||
1994 | i965_update_wm(dev); | ||
1995 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) | ||
1996 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, | ||
1997 | pixel_size); | ||
1998 | else | ||
1999 | i830_update_wm(dev, planea_clock, pixel_size); | ||
2000 | } | ||
2001 | |||
1588 | static int intel_crtc_mode_set(struct drm_crtc *crtc, | 2002 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
1589 | struct drm_display_mode *mode, | 2003 | struct drm_display_mode *mode, |
1590 | struct drm_display_mode *adjusted_mode, | 2004 | struct drm_display_mode *adjusted_mode, |
@@ -1951,6 +2365,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1951 | 2365 | ||
1952 | /* Flush the plane changes */ | 2366 | /* Flush the plane changes */ |
1953 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 2367 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
2368 | |||
2369 | intel_update_watermarks(dev); | ||
2370 | |||
1954 | drm_vblank_post_modeset(dev, pipe); | 2371 | drm_vblank_post_modeset(dev, pipe); |
1955 | 2372 | ||
1956 | return ret; | 2373 | return ret; |
@@ -2439,6 +2856,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
2439 | 2856 | ||
2440 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); | 2857 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); |
2441 | intel_crtc->pipe = pipe; | 2858 | intel_crtc->pipe = pipe; |
2859 | intel_crtc->plane = pipe; | ||
2442 | for (i = 0; i < 256; i++) { | 2860 | for (i = 0; i < 256; i++) { |
2443 | intel_crtc->lut_r[i] = i; | 2861 | intel_crtc->lut_r[i] = i; |
2444 | intel_crtc->lut_g[i] = i; | 2862 | intel_crtc->lut_g[i] = i; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8f8d37d5663a..6770ae88370d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -246,7 +246,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
246 | } | 246 | } |
247 | 247 | ||
248 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { | 248 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { |
249 | printk(KERN_ERR "dp_aux_ch not done status 0x%08x\n", status); | 249 | DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status); |
250 | return -EBUSY; | 250 | return -EBUSY; |
251 | } | 251 | } |
252 | 252 | ||
@@ -254,11 +254,14 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
254 | * Timeouts occur when the sink is not connected | 254 | * Timeouts occur when the sink is not connected |
255 | */ | 255 | */ |
256 | if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { | 256 | if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { |
257 | printk(KERN_ERR "dp_aux_ch receive error status 0x%08x\n", status); | 257 | DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status); |
258 | return -EIO; | 258 | return -EIO; |
259 | } | 259 | } |
260 | |||
261 | /* Timeouts occur when the device isn't connected, so they're | ||
262 | * "normal" -- don't fill the kernel log with these */ | ||
260 | if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { | 263 | if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { |
261 | printk(KERN_ERR "dp_aux_ch timeout status 0x%08x\n", status); | 264 | DRM_DEBUG("dp_aux_ch timeout status 0x%08x\n", status); |
262 | return -ETIMEDOUT; | 265 | return -ETIMEDOUT; |
263 | } | 266 | } |
264 | 267 | ||
@@ -411,7 +414,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
411 | dp_priv->link_bw = bws[clock]; | 414 | dp_priv->link_bw = bws[clock]; |
412 | dp_priv->lane_count = lane_count; | 415 | dp_priv->lane_count = lane_count; |
413 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 416 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); |
414 | printk(KERN_ERR "link bw %02x lane count %d clock %d\n", | 417 | DRM_DEBUG("Display port link bw %02x lane count %d clock %d\n", |
415 | dp_priv->link_bw, dp_priv->lane_count, | 418 | dp_priv->link_bw, dp_priv->lane_count, |
416 | adjusted_mode->clock); | 419 | adjusted_mode->clock); |
417 | return true; | 420 | return true; |
diff --git a/drivers/gpu/drm/i915/intel_dp_i2c.c b/drivers/gpu/drm/i915/intel_dp_i2c.c index 4e60f14b1a6d..a63b6f57d2d4 100644 --- a/drivers/gpu/drm/i915/intel_dp_i2c.c +++ b/drivers/gpu/drm/i915/intel_dp_i2c.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
31 | #include "intel_dp.h" | 31 | #include "intel_dp.h" |
32 | #include "drmP.h" | ||
32 | 33 | ||
33 | /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ | 34 | /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ |
34 | 35 | ||
@@ -84,7 +85,7 @@ i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, | |||
84 | msg, msg_bytes, | 85 | msg, msg_bytes, |
85 | reply, reply_bytes); | 86 | reply, reply_bytes); |
86 | if (ret < 0) { | 87 | if (ret < 0) { |
87 | printk(KERN_ERR "aux_ch failed %d\n", ret); | 88 | DRM_DEBUG("aux_ch failed %d\n", ret); |
88 | return ret; | 89 | return ret; |
89 | } | 90 | } |
90 | switch (reply[0] & AUX_I2C_REPLY_MASK) { | 91 | switch (reply[0] & AUX_I2C_REPLY_MASK) { |
@@ -94,14 +95,14 @@ i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, | |||
94 | } | 95 | } |
95 | return reply_bytes - 1; | 96 | return reply_bytes - 1; |
96 | case AUX_I2C_REPLY_NACK: | 97 | case AUX_I2C_REPLY_NACK: |
97 | printk(KERN_ERR "aux_ch nack\n"); | 98 | DRM_DEBUG("aux_ch nack\n"); |
98 | return -EREMOTEIO; | 99 | return -EREMOTEIO; |
99 | case AUX_I2C_REPLY_DEFER: | 100 | case AUX_I2C_REPLY_DEFER: |
100 | printk(KERN_ERR "aux_ch defer\n"); | 101 | DRM_DEBUG("aux_ch defer\n"); |
101 | udelay(100); | 102 | udelay(100); |
102 | break; | 103 | break; |
103 | default: | 104 | default: |
104 | printk(KERN_ERR "aux_ch invalid reply 0x%02x\n", reply[0]); | 105 | DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]); |
105 | return -EREMOTEIO; | 106 | return -EREMOTEIO; |
106 | } | 107 | } |
107 | } | 108 | } |
@@ -223,7 +224,7 @@ i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, | |||
223 | if (ret >= 0) | 224 | if (ret >= 0) |
224 | ret = num; | 225 | ret = num; |
225 | i2c_algo_dp_aux_stop(adapter, reading); | 226 | i2c_algo_dp_aux_stop(adapter, reading); |
226 | printk(KERN_ERR "dp_aux_xfer return %d\n", ret); | 227 | DRM_DEBUG("dp_aux_xfer return %d\n", ret); |
227 | return ret; | 228 | return ret; |
228 | } | 229 | } |
229 | 230 | ||
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 1af7d68e3807..1d30802e773e 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -453,7 +453,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
453 | size = ALIGN(size, PAGE_SIZE); | 453 | size = ALIGN(size, PAGE_SIZE); |
454 | fbo = drm_gem_object_alloc(dev, size); | 454 | fbo = drm_gem_object_alloc(dev, size); |
455 | if (!fbo) { | 455 | if (!fbo) { |
456 | printk(KERN_ERR "failed to allocate framebuffer\n"); | 456 | DRM_ERROR("failed to allocate framebuffer\n"); |
457 | ret = -ENOMEM; | 457 | ret = -ENOMEM; |
458 | goto out; | 458 | goto out; |
459 | } | 459 | } |
@@ -610,8 +610,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
610 | par->dev = dev; | 610 | par->dev = dev; |
611 | 611 | ||
612 | /* To allow resizeing without swapping buffers */ | 612 | /* To allow resizeing without swapping buffers */ |
613 | printk("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, | 613 | DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, |
614 | intel_fb->base.height, obj_priv->gtt_offset, fbo); | 614 | intel_fb->base.height, obj_priv->gtt_offset, fbo); |
615 | 615 | ||
616 | mutex_unlock(&dev->struct_mutex); | 616 | mutex_unlock(&dev->struct_mutex); |
617 | return 0; | 617 | return 0; |
@@ -698,13 +698,13 @@ static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc * | |||
698 | } else | 698 | } else |
699 | intelfb_set_par(info); | 699 | intelfb_set_par(info); |
700 | 700 | ||
701 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, | 701 | DRM_INFO("fb%d: %s frame buffer device\n", info->node, |
702 | info->fix.id); | 702 | info->fix.id); |
703 | 703 | ||
704 | /* Switch back to kernel console on panic */ | 704 | /* Switch back to kernel console on panic */ |
705 | kernelfb_mode = *modeset; | 705 | kernelfb_mode = *modeset; |
706 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); | 706 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); |
707 | printk(KERN_INFO "registered panic notifier\n"); | 707 | DRM_DEBUG("registered panic notifier\n"); |
708 | 708 | ||
709 | return 0; | 709 | return 0; |
710 | } | 710 | } |
@@ -852,13 +852,13 @@ static int intelfb_single_fb_probe(struct drm_device *dev) | |||
852 | } else | 852 | } else |
853 | intelfb_set_par(info); | 853 | intelfb_set_par(info); |
854 | 854 | ||
855 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, | 855 | DRM_INFO("fb%d: %s frame buffer device\n", info->node, |
856 | info->fix.id); | 856 | info->fix.id); |
857 | 857 | ||
858 | /* Switch back to kernel console on panic */ | 858 | /* Switch back to kernel console on panic */ |
859 | kernelfb_mode = *modeset; | 859 | kernelfb_mode = *modeset; |
860 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); | 860 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); |
861 | printk(KERN_INFO "registered panic notifier\n"); | 861 | DRM_DEBUG("registered panic notifier\n"); |
862 | 862 | ||
863 | return 0; | 863 | return 0; |
864 | } | 864 | } |
@@ -872,8 +872,8 @@ void intelfb_restore(void) | |||
872 | { | 872 | { |
873 | int ret; | 873 | int ret; |
874 | if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { | 874 | if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { |
875 | printk(KERN_ERR "Failed to restore crtc configuration: %d\n", | 875 | DRM_ERROR("Failed to restore crtc configuration: %d\n", |
876 | ret); | 876 | ret); |
877 | } | 877 | } |
878 | } | 878 | } |
879 | 879 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 9564ca44a977..9ab38efffecf 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "intel_drv.h" | 36 | #include "intel_drv.h" |
37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | #include <linux/acpi.h> | ||
39 | 40 | ||
40 | #define I915_LVDS "i915_lvds" | 41 | #define I915_LVDS "i915_lvds" |
41 | 42 | ||
@@ -252,14 +253,14 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
252 | 253 | ||
253 | /* Should never happen!! */ | 254 | /* Should never happen!! */ |
254 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { | 255 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { |
255 | printk(KERN_ERR "Can't support LVDS on pipe A\n"); | 256 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
256 | return false; | 257 | return false; |
257 | } | 258 | } |
258 | 259 | ||
259 | /* Should never happen!! */ | 260 | /* Should never happen!! */ |
260 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { | 261 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { |
261 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { | 262 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { |
262 | printk(KERN_ERR "Can't enable LVDS and another " | 263 | DRM_ERROR("Can't enable LVDS and another " |
263 | "encoder on the same pipe\n"); | 264 | "encoder on the same pipe\n"); |
264 | return false; | 265 | return false; |
265 | } | 266 | } |
@@ -788,6 +789,65 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
788 | { } /* terminating entry */ | 789 | { } /* terminating entry */ |
789 | }; | 790 | }; |
790 | 791 | ||
792 | #ifdef CONFIG_ACPI | ||
793 | /* | ||
794 | * check_lid_device -- check whether @handle is an ACPI LID device. | ||
795 | * @handle: ACPI device handle | ||
796 | * @level : depth in the ACPI namespace tree | ||
797 | * @context: the number of LID device when we find the device | ||
798 | * @rv: a return value to fill if desired (Not use) | ||
799 | */ | ||
800 | static acpi_status | ||
801 | check_lid_device(acpi_handle handle, u32 level, void *context, | ||
802 | void **return_value) | ||
803 | { | ||
804 | struct acpi_device *acpi_dev; | ||
805 | int *lid_present = context; | ||
806 | |||
807 | acpi_dev = NULL; | ||
808 | /* Get the acpi device for device handle */ | ||
809 | if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) { | ||
810 | /* If there is no ACPI device for handle, return */ | ||
811 | return AE_OK; | ||
812 | } | ||
813 | |||
814 | if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7)) | ||
815 | *lid_present = 1; | ||
816 | |||
817 | return AE_OK; | ||
818 | } | ||
819 | |||
820 | /** | ||
821 | * check whether there exists the ACPI LID device by enumerating the ACPI | ||
822 | * device tree. | ||
823 | */ | ||
824 | static int intel_lid_present(void) | ||
825 | { | ||
826 | int lid_present = 0; | ||
827 | |||
828 | if (acpi_disabled) { | ||
829 | /* If ACPI is disabled, there is no ACPI device tree to | ||
830 | * check, so assume the LID device would have been present. | ||
831 | */ | ||
832 | return 1; | ||
833 | } | ||
834 | |||
835 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
836 | ACPI_UINT32_MAX, | ||
837 | check_lid_device, &lid_present, NULL); | ||
838 | |||
839 | return lid_present; | ||
840 | } | ||
841 | #else | ||
842 | static int intel_lid_present(void) | ||
843 | { | ||
844 | /* In the absence of ACPI built in, assume that the LID device would | ||
845 | * have been present. | ||
846 | */ | ||
847 | return 1; | ||
848 | } | ||
849 | #endif | ||
850 | |||
791 | /** | 851 | /** |
792 | * intel_lvds_init - setup LVDS connectors on this device | 852 | * intel_lvds_init - setup LVDS connectors on this device |
793 | * @dev: drm device | 853 | * @dev: drm device |
@@ -811,6 +871,16 @@ void intel_lvds_init(struct drm_device *dev) | |||
811 | if (dmi_check_system(intel_no_lvds)) | 871 | if (dmi_check_system(intel_no_lvds)) |
812 | return; | 872 | return; |
813 | 873 | ||
874 | /* Assume that any device without an ACPI LID device also doesn't | ||
875 | * have an integrated LVDS. We would be better off parsing the BIOS | ||
876 | * to get a reliable indicator, but that code isn't written yet. | ||
877 | * | ||
878 | * In the case of all-in-one desktops using LVDS that we've seen, | ||
879 | * they're using SDVO LVDS. | ||
880 | */ | ||
881 | if (!intel_lid_present()) | ||
882 | return; | ||
883 | |||
814 | if (IS_IGDNG(dev)) { | 884 | if (IS_IGDNG(dev)) { |
815 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) | 885 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) |
816 | return; | 886 | return; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index f03473779feb..4f0c30948bc4 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -68,12 +68,23 @@ struct intel_sdvo_priv { | |||
68 | * This is set if we treat the device as HDMI, instead of DVI. | 68 | * This is set if we treat the device as HDMI, instead of DVI. |
69 | */ | 69 | */ |
70 | bool is_hdmi; | 70 | bool is_hdmi; |
71 | |||
71 | /** | 72 | /** |
72 | * This is set if we detect output of sdvo device as LVDS. | 73 | * This is set if we detect output of sdvo device as LVDS. |
73 | */ | 74 | */ |
74 | bool is_lvds; | 75 | bool is_lvds; |
75 | 76 | ||
76 | /** | 77 | /** |
78 | * This is sdvo flags for input timing. | ||
79 | */ | ||
80 | uint8_t sdvo_flags; | ||
81 | |||
82 | /** | ||
83 | * This is sdvo fixed pannel mode pointer | ||
84 | */ | ||
85 | struct drm_display_mode *sdvo_lvds_fixed_mode; | ||
86 | |||
87 | /** | ||
77 | * Returned SDTV resolutions allowed for the current format, if the | 88 | * Returned SDTV resolutions allowed for the current format, if the |
78 | * device reported it. | 89 | * device reported it. |
79 | */ | 90 | */ |
@@ -592,6 +603,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
592 | uint16_t height) | 603 | uint16_t height) |
593 | { | 604 | { |
594 | struct intel_sdvo_preferred_input_timing_args args; | 605 | struct intel_sdvo_preferred_input_timing_args args; |
606 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | ||
595 | uint8_t status; | 607 | uint8_t status; |
596 | 608 | ||
597 | memset(&args, 0, sizeof(args)); | 609 | memset(&args, 0, sizeof(args)); |
@@ -599,7 +611,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
599 | args.width = width; | 611 | args.width = width; |
600 | args.height = height; | 612 | args.height = height; |
601 | args.interlace = 0; | 613 | args.interlace = 0; |
602 | args.scaled = 0; | 614 | |
615 | if (sdvo_priv->is_lvds && | ||
616 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | ||
617 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | ||
618 | args.scaled = 1; | ||
619 | |||
603 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 620 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
604 | &args, sizeof(args)); | 621 | &args, sizeof(args)); |
605 | status = intel_sdvo_read_response(output, NULL, 0); | 622 | status = intel_sdvo_read_response(output, NULL, 0); |
@@ -944,12 +961,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
944 | struct intel_output *output = enc_to_intel_output(encoder); | 961 | struct intel_output *output = enc_to_intel_output(encoder); |
945 | struct intel_sdvo_priv *dev_priv = output->dev_priv; | 962 | struct intel_sdvo_priv *dev_priv = output->dev_priv; |
946 | 963 | ||
947 | if (!dev_priv->is_tv) { | 964 | if (dev_priv->is_tv) { |
948 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
949 | * SDVO device will be told of the multiplier during mode_set. | ||
950 | */ | ||
951 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
952 | } else { | ||
953 | struct intel_sdvo_dtd output_dtd; | 965 | struct intel_sdvo_dtd output_dtd; |
954 | bool success; | 966 | bool success; |
955 | 967 | ||
@@ -980,6 +992,47 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
980 | intel_sdvo_get_preferred_input_timing(output, | 992 | intel_sdvo_get_preferred_input_timing(output, |
981 | &input_dtd); | 993 | &input_dtd); |
982 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 994 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
995 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
996 | |||
997 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
998 | |||
999 | mode->clock = adjusted_mode->clock; | ||
1000 | |||
1001 | adjusted_mode->clock *= | ||
1002 | intel_sdvo_get_pixel_multiplier(mode); | ||
1003 | } else { | ||
1004 | return false; | ||
1005 | } | ||
1006 | } else if (dev_priv->is_lvds) { | ||
1007 | struct intel_sdvo_dtd output_dtd; | ||
1008 | bool success; | ||
1009 | |||
1010 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
1011 | /* Set output timings */ | ||
1012 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
1013 | dev_priv->sdvo_lvds_fixed_mode); | ||
1014 | |||
1015 | intel_sdvo_set_target_output(output, | ||
1016 | dev_priv->controlled_output); | ||
1017 | intel_sdvo_set_output_timing(output, &output_dtd); | ||
1018 | |||
1019 | /* Set the input timing to the screen. Assume always input 0. */ | ||
1020 | intel_sdvo_set_target_input(output, true, false); | ||
1021 | |||
1022 | |||
1023 | success = intel_sdvo_create_preferred_input_timing( | ||
1024 | output, | ||
1025 | mode->clock / 10, | ||
1026 | mode->hdisplay, | ||
1027 | mode->vdisplay); | ||
1028 | |||
1029 | if (success) { | ||
1030 | struct intel_sdvo_dtd input_dtd; | ||
1031 | |||
1032 | intel_sdvo_get_preferred_input_timing(output, | ||
1033 | &input_dtd); | ||
1034 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1035 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
983 | 1036 | ||
984 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1037 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
985 | 1038 | ||
@@ -990,6 +1043,12 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
990 | } else { | 1043 | } else { |
991 | return false; | 1044 | return false; |
992 | } | 1045 | } |
1046 | |||
1047 | } else { | ||
1048 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
1049 | * SDVO device will be told of the multiplier during mode_set. | ||
1050 | */ | ||
1051 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
993 | } | 1052 | } |
994 | return true; | 1053 | return true; |
995 | } | 1054 | } |
@@ -1033,15 +1092,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1033 | 1092 | ||
1034 | /* We have tried to get input timing in mode_fixup, and filled into | 1093 | /* We have tried to get input timing in mode_fixup, and filled into |
1035 | adjusted_mode */ | 1094 | adjusted_mode */ |
1036 | if (sdvo_priv->is_tv) | 1095 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { |
1037 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1096 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1038 | else | 1097 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; |
1098 | } else | ||
1039 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | 1099 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); |
1040 | 1100 | ||
1041 | /* If it's a TV, we already set the output timing in mode_fixup. | 1101 | /* If it's a TV, we already set the output timing in mode_fixup. |
1042 | * Otherwise, the output timing is equal to the input timing. | 1102 | * Otherwise, the output timing is equal to the input timing. |
1043 | */ | 1103 | */ |
1044 | if (!sdvo_priv->is_tv) { | 1104 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { |
1045 | /* Set the output timing to the screen */ | 1105 | /* Set the output timing to the screen */ |
1046 | intel_sdvo_set_target_output(output, | 1106 | intel_sdvo_set_target_output(output, |
1047 | sdvo_priv->controlled_output); | 1107 | sdvo_priv->controlled_output); |
@@ -1116,6 +1176,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1116 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1176 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1117 | } | 1177 | } |
1118 | 1178 | ||
1179 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | ||
1180 | sdvox |= SDVO_STALL_SELECT; | ||
1119 | intel_sdvo_write_sdvox(output, sdvox); | 1181 | intel_sdvo_write_sdvox(output, sdvox); |
1120 | } | 1182 | } |
1121 | 1183 | ||
@@ -1276,6 +1338,17 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1276 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1338 | if (sdvo_priv->pixel_clock_max < mode->clock) |
1277 | return MODE_CLOCK_HIGH; | 1339 | return MODE_CLOCK_HIGH; |
1278 | 1340 | ||
1341 | if (sdvo_priv->is_lvds == true) { | ||
1342 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | ||
1343 | return MODE_PANEL; | ||
1344 | |||
1345 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | ||
1346 | return MODE_PANEL; | ||
1347 | |||
1348 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | ||
1349 | return MODE_PANEL; | ||
1350 | } | ||
1351 | |||
1279 | return MODE_OK; | 1352 | return MODE_OK; |
1280 | } | 1353 | } |
1281 | 1354 | ||
@@ -1549,6 +1622,8 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1549 | { | 1622 | { |
1550 | struct intel_output *intel_output = to_intel_output(connector); | 1623 | struct intel_output *intel_output = to_intel_output(connector); |
1551 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1624 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1625 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1626 | struct drm_display_mode *newmode; | ||
1552 | 1627 | ||
1553 | /* | 1628 | /* |
1554 | * Attempt to get the mode list from DDC. | 1629 | * Attempt to get the mode list from DDC. |
@@ -1557,11 +1632,10 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1557 | */ | 1632 | */ |
1558 | intel_ddc_get_modes(intel_output); | 1633 | intel_ddc_get_modes(intel_output); |
1559 | if (list_empty(&connector->probed_modes) == false) | 1634 | if (list_empty(&connector->probed_modes) == false) |
1560 | return; | 1635 | goto end; |
1561 | 1636 | ||
1562 | /* Fetch modes from VBT */ | 1637 | /* Fetch modes from VBT */ |
1563 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { | 1638 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { |
1564 | struct drm_display_mode *newmode; | ||
1565 | newmode = drm_mode_duplicate(connector->dev, | 1639 | newmode = drm_mode_duplicate(connector->dev, |
1566 | dev_priv->sdvo_lvds_vbt_mode); | 1640 | dev_priv->sdvo_lvds_vbt_mode); |
1567 | if (newmode != NULL) { | 1641 | if (newmode != NULL) { |
@@ -1571,6 +1645,16 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1571 | drm_mode_probed_add(connector, newmode); | 1645 | drm_mode_probed_add(connector, newmode); |
1572 | } | 1646 | } |
1573 | } | 1647 | } |
1648 | |||
1649 | end: | ||
1650 | list_for_each_entry(newmode, &connector->probed_modes, head) { | ||
1651 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | ||
1652 | sdvo_priv->sdvo_lvds_fixed_mode = | ||
1653 | drm_mode_duplicate(connector->dev, newmode); | ||
1654 | break; | ||
1655 | } | ||
1656 | } | ||
1657 | |||
1574 | } | 1658 | } |
1575 | 1659 | ||
1576 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1660 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
@@ -1593,14 +1677,20 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1593 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1677 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1594 | { | 1678 | { |
1595 | struct intel_output *intel_output = to_intel_output(connector); | 1679 | struct intel_output *intel_output = to_intel_output(connector); |
1680 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1596 | 1681 | ||
1597 | if (intel_output->i2c_bus) | 1682 | if (intel_output->i2c_bus) |
1598 | intel_i2c_destroy(intel_output->i2c_bus); | 1683 | intel_i2c_destroy(intel_output->i2c_bus); |
1599 | if (intel_output->ddc_bus) | 1684 | if (intel_output->ddc_bus) |
1600 | intel_i2c_destroy(intel_output->ddc_bus); | 1685 | intel_i2c_destroy(intel_output->ddc_bus); |
1601 | 1686 | ||
1687 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
1688 | drm_mode_destroy(connector->dev, | ||
1689 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
1690 | |||
1602 | drm_sysfs_connector_remove(connector); | 1691 | drm_sysfs_connector_remove(connector); |
1603 | drm_connector_cleanup(connector); | 1692 | drm_connector_cleanup(connector); |
1693 | |||
1604 | kfree(intel_output); | 1694 | kfree(intel_output); |
1605 | } | 1695 | } |
1606 | 1696 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index 193938b7d7f9..ba5cdf8ae40b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
@@ -715,6 +715,7 @@ struct intel_sdvo_enhancements_arg { | |||
715 | #define SDVO_HBUF_TX_ONCE (2 << 6) | 715 | #define SDVO_HBUF_TX_ONCE (2 << 6) |
716 | #define SDVO_HBUF_TX_VSYNC (3 << 6) | 716 | #define SDVO_HBUF_TX_VSYNC (3 << 6) |
717 | #define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c | 717 | #define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c |
718 | #define SDVO_NEED_TO_STALL (1 << 7) | ||
718 | 719 | ||
719 | struct intel_sdvo_encode{ | 720 | struct intel_sdvo_encode{ |
720 | u8 dvi_rev; | 721 | u8 dvi_rev; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 41c907f6c560..33de7637c0c6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c | |||
@@ -330,7 +330,7 @@ ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp, | |||
330 | goto out_unref; | 330 | goto out_unref; |
331 | 331 | ||
332 | kmap_offset = dev_offset - bo->vm_node->start; | 332 | kmap_offset = dev_offset - bo->vm_node->start; |
333 | if (unlikely(kmap_offset) >= bo->num_pages) { | 333 | if (unlikely(kmap_offset >= bo->num_pages)) { |
334 | ret = -EFBIG; | 334 | ret = -EFBIG; |
335 | goto out_unref; | 335 | goto out_unref; |
336 | } | 336 | } |
@@ -404,7 +404,7 @@ ssize_t ttm_bo_fbdev_io(struct ttm_buffer_object *bo, const char __user *wbuf, | |||
404 | bool dummy; | 404 | bool dummy; |
405 | 405 | ||
406 | kmap_offset = (*f_pos >> PAGE_SHIFT); | 406 | kmap_offset = (*f_pos >> PAGE_SHIFT); |
407 | if (unlikely(kmap_offset) >= bo->num_pages) | 407 | if (unlikely(kmap_offset >= bo->num_pages)) |
408 | return -EFBIG; | 408 | return -EFBIG; |
409 | 409 | ||
410 | page_offset = *f_pos & ~PAGE_MASK; | 410 | page_offset = *f_pos & ~PAGE_MASK; |
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index c248c1d37268..5935b8842e86 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c | |||
@@ -183,7 +183,7 @@ int via_enable_vblank(struct drm_device *dev, int crtc) | |||
183 | } | 183 | } |
184 | 184 | ||
185 | status = VIA_READ(VIA_REG_INTERRUPT); | 185 | status = VIA_READ(VIA_REG_INTERRUPT); |
186 | VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); | 186 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_VBLANK_ENABLE); |
187 | 187 | ||
188 | VIA_WRITE8(0x83d4, 0x11); | 188 | VIA_WRITE8(0x83d4, 0x11); |
189 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | 189 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); |
@@ -194,6 +194,10 @@ int via_enable_vblank(struct drm_device *dev, int crtc) | |||
194 | void via_disable_vblank(struct drm_device *dev, int crtc) | 194 | void via_disable_vblank(struct drm_device *dev, int crtc) |
195 | { | 195 | { |
196 | drm_via_private_t *dev_priv = dev->dev_private; | 196 | drm_via_private_t *dev_priv = dev->dev_private; |
197 | u32 status; | ||
198 | |||
199 | status = VIA_READ(VIA_REG_INTERRUPT); | ||
200 | VIA_WRITE(VIA_REG_INTERRUPT, status & ~VIA_IRQ_VBLANK_ENABLE); | ||
197 | 201 | ||
198 | VIA_WRITE8(0x83d4, 0x11); | 202 | VIA_WRITE8(0x83d4, 0x11); |
199 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); | 203 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f2c21d5d24e8..5eb10c2ce665 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1075,14 +1075,16 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event); | |||
1075 | */ | 1075 | */ |
1076 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) | 1076 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) |
1077 | { | 1077 | { |
1078 | struct hid_report_enum *report_enum = hid->report_enum + type; | 1078 | struct hid_report_enum *report_enum; |
1079 | struct hid_driver *hdrv = hid->driver; | 1079 | struct hid_driver *hdrv; |
1080 | struct hid_report *report; | 1080 | struct hid_report *report; |
1081 | unsigned int i; | 1081 | unsigned int i; |
1082 | int ret; | 1082 | int ret; |
1083 | 1083 | ||
1084 | if (!hid || !hid->driver) | 1084 | if (!hid || !hid->driver) |
1085 | return -ENODEV; | 1085 | return -ENODEV; |
1086 | report_enum = hid->report_enum + type; | ||
1087 | hdrv = hid->driver; | ||
1086 | 1088 | ||
1087 | if (!size) { | 1089 | if (!size) { |
1088 | dbg_hid("empty report\n"); | 1090 | dbg_hid("empty report\n"); |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 76c4bbe9dccb..3c1fcb7640ab 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
27 | #include <asm/unaligned.h> | 26 | #include <asm/unaligned.h> |
28 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 9e9421525fb9..215b2addddbb 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -527,8 +527,10 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, | |||
527 | goto goodreturn; | 527 | goto goodreturn; |
528 | 528 | ||
529 | case HIDIOCGCOLLECTIONINDEX: | 529 | case HIDIOCGCOLLECTIONINDEX: |
530 | i = field->usage[uref->usage_index].collection_index; | ||
531 | unlock_kernel(); | ||
530 | kfree(uref_multi); | 532 | kfree(uref_multi); |
531 | return field->usage[uref->usage_index].collection_index; | 533 | return i; |
532 | case HIDIOCGUSAGES: | 534 | case HIDIOCGUSAGES: |
533 | for (i = 0; i < uref_multi->num_values; i++) | 535 | for (i = 0; i < uref_multi->num_values; i++) |
534 | uref_multi->values[i] = | 536 | uref_multi->values[i] = |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index ad2b3431b725..7d3f15d32fdf 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
@@ -357,7 +357,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
357 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | 357 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, |
358 | { NULL, 0, 0, 0, 0, 0 } } | 358 | { NULL, 0, 0, 0, 0, 0 } } |
359 | }, | 359 | }, |
360 | { 0x0014, NULL /* Abit AB9 Pro, need DMI string */, { | 360 | { 0x0014, "AB9", /* + AB9 Pro */ { |
361 | { "CPU Core", 0, 0, 10, 1, 0 }, | 361 | { "CPU Core", 0, 0, 10, 1, 0 }, |
362 | { "DDR", 1, 0, 10, 1, 0 }, | 362 | { "DDR", 1, 0, 10, 1, 0 }, |
363 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 363 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -455,7 +455,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
455 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, | 455 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, |
456 | { NULL, 0, 0, 0, 0, 0 } } | 456 | { NULL, 0, 0, 0, 0, 0 } } |
457 | }, | 457 | }, |
458 | { 0x0018, NULL /* Unknown, need DMI string */, { | 458 | { 0x0018, "AB9 QuadGT", { |
459 | { "CPU Core", 0, 0, 10, 1, 0 }, | 459 | { "CPU Core", 0, 0, 10, 1, 0 }, |
460 | { "DDR2", 1, 0, 20, 1, 0 }, | 460 | { "DDR2", 1, 0, 20, 1, 0 }, |
461 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 461 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -564,7 +564,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
564 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 564 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
565 | { NULL, 0, 0, 0, 0, 0 } } | 565 | { NULL, 0, 0, 0, 0, 0 } } |
566 | }, | 566 | }, |
567 | { 0x001C, NULL /* Unknown, need DMI string */, { | 567 | { 0x001C, "IX38 QuadGT", { |
568 | { "CPU Core", 0, 0, 10, 1, 0 }, | 568 | { "CPU Core", 0, 0, 10, 1, 0 }, |
569 | { "DDR2", 1, 0, 20, 1, 0 }, | 569 | { "DDR2", 1, 0, 20, 1, 0 }, |
570 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 570 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index bff0103610c1..fe4fa29c9219 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c | |||
@@ -593,7 +593,11 @@ static int atk_add_sensor(struct atk_data *data, union acpi_object *obj) | |||
593 | sensor->data = data; | 593 | sensor->data = data; |
594 | sensor->id = flags->integer.value; | 594 | sensor->id = flags->integer.value; |
595 | sensor->limit1 = limit1->integer.value; | 595 | sensor->limit1 = limit1->integer.value; |
596 | sensor->limit2 = limit2->integer.value; | 596 | if (data->old_interface) |
597 | sensor->limit2 = limit2->integer.value; | ||
598 | else | ||
599 | /* The upper limit is expressed as delta from lower limit */ | ||
600 | sensor->limit2 = sensor->limit1 + limit2->integer.value; | ||
597 | 601 | ||
598 | snprintf(sensor->input_attr_name, ATTR_NAME_SIZE, | 602 | snprintf(sensor->input_attr_name, ATTR_NAME_SIZE, |
599 | "%s%d_input", base_name, start + *num); | 603 | "%s%d_input", base_name, start + *num); |
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 86142a858238..58f66be61b1f 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
@@ -418,6 +418,7 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr, | |||
418 | data->count = 3; | 418 | data->count = 3; |
419 | break; | 419 | break; |
420 | default: | 420 | default: |
421 | mutex_unlock(&data->update_lock); | ||
421 | dev_err(&client->dev, | 422 | dev_err(&client->dev, |
422 | "illegal value for fan divider (%d)\n", div); | 423 | "illegal value for fan divider (%d)\n", div); |
423 | return -EINVAL; | 424 | return -EINVAL; |
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 56cd6004da36..6290a259456e 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c | |||
@@ -257,7 +257,7 @@ static inline int sht15_update_single_val(struct sht15_data *data, | |||
257 | (data->flag == SHT15_READING_NOTHING), | 257 | (data->flag == SHT15_READING_NOTHING), |
258 | msecs_to_jiffies(timeout_msecs)); | 258 | msecs_to_jiffies(timeout_msecs)); |
259 | if (ret == 0) {/* timeout occurred */ | 259 | if (ret == 0) {/* timeout occurred */ |
260 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));; | 260 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); |
261 | sht15_connection_reset(data); | 261 | sht15_connection_reset(data); |
262 | return -ETIME; | 262 | return -ETIME; |
263 | } | 263 | } |
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index a92dbb97ee99..ba75bfcf14ce 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -86,6 +86,7 @@ superio_exit(void) | |||
86 | #define SUPERIO_REG_ACT 0x30 | 86 | #define SUPERIO_REG_ACT 0x30 |
87 | #define SUPERIO_REG_BASE 0x60 | 87 | #define SUPERIO_REG_BASE 0x60 |
88 | #define SUPERIO_REG_DEVID 0x20 | 88 | #define SUPERIO_REG_DEVID 0x20 |
89 | #define SUPERIO_REG_DEVREV 0x21 | ||
89 | 90 | ||
90 | /* Logical device registers */ | 91 | /* Logical device registers */ |
91 | 92 | ||
@@ -429,6 +430,9 @@ static int __init smsc47m1_find(unsigned short *addr, | |||
429 | * The LPC47M292 (device id 0x6B) is somewhat compatible, but it | 430 | * The LPC47M292 (device id 0x6B) is somewhat compatible, but it |
430 | * supports a 3rd fan, and the pin configuration registers are | 431 | * supports a 3rd fan, and the pin configuration registers are |
431 | * unfortunately different. | 432 | * unfortunately different. |
433 | * The LPC47M233 has the same device id (0x6B) but is not compatible. | ||
434 | * We check the high bit of the device revision register to | ||
435 | * differentiate them. | ||
432 | */ | 436 | */ |
433 | switch (val) { | 437 | switch (val) { |
434 | case 0x51: | 438 | case 0x51: |
@@ -448,6 +452,13 @@ static int __init smsc47m1_find(unsigned short *addr, | |||
448 | sio_data->type = smsc47m1; | 452 | sio_data->type = smsc47m1; |
449 | break; | 453 | break; |
450 | case 0x6B: | 454 | case 0x6B: |
455 | if (superio_inb(SUPERIO_REG_DEVREV) & 0x80) { | ||
456 | pr_debug(DRVNAME ": " | ||
457 | "Found SMSC LPC47M233, unsupported\n"); | ||
458 | superio_exit(); | ||
459 | return -ENODEV; | ||
460 | } | ||
461 | |||
451 | pr_info(DRVNAME ": Found SMSC LPC47M292\n"); | 462 | pr_info(DRVNAME ": Found SMSC LPC47M292\n"); |
452 | sio_data->type = smsc47m2; | 463 | sio_data->type = smsc47m2; |
453 | break; | 464 | break; |
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 3fae3a91ce5b..c89687a10835 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -187,6 +187,11 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) | |||
187 | davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); | 187 | davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); |
188 | davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); | 188 | davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); |
189 | 189 | ||
190 | /* Respond at reserved "SMBus Host" slave address" (and zero); | ||
191 | * we seem to have no option to not respond... | ||
192 | */ | ||
193 | davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08); | ||
194 | |||
190 | dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); | 195 | dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); |
191 | dev_dbg(dev->dev, "PSC = %d\n", | 196 | dev_dbg(dev->dev, "PSC = %d\n", |
192 | davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); | 197 | davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); |
@@ -387,7 +392,7 @@ static void terminate_write(struct davinci_i2c_dev *dev) | |||
387 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); | 392 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); |
388 | 393 | ||
389 | if (!dev->terminate) | 394 | if (!dev->terminate) |
390 | dev_err(dev->dev, "TDR IRQ while no data to send\n"); | 395 | dev_dbg(dev->dev, "TDR IRQ while no data to send\n"); |
391 | } | 396 | } |
392 | 397 | ||
393 | /* | 398 | /* |
@@ -473,9 +478,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) | |||
473 | break; | 478 | break; |
474 | 479 | ||
475 | case DAVINCI_I2C_IVR_AAS: | 480 | case DAVINCI_I2C_IVR_AAS: |
476 | dev_warn(dev->dev, "Address as slave interrupt\n"); | 481 | dev_dbg(dev->dev, "Address as slave interrupt\n"); |
477 | }/* switch */ | 482 | break; |
478 | }/* while */ | 483 | |
484 | default: | ||
485 | dev_warn(dev->dev, "Unrecognized irq stat %d\n", stat); | ||
486 | break; | ||
487 | } | ||
488 | } | ||
479 | 489 | ||
480 | return count ? IRQ_HANDLED : IRQ_NONE; | 490 | return count ? IRQ_HANDLED : IRQ_NONE; |
481 | } | 491 | } |
@@ -505,7 +515,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) | |||
505 | return -ENODEV; | 515 | return -ENODEV; |
506 | } | 516 | } |
507 | 517 | ||
508 | ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, | 518 | ioarea = request_mem_region(mem->start, resource_size(mem), |
509 | pdev->name); | 519 | pdev->name); |
510 | if (!ioarea) { | 520 | if (!ioarea) { |
511 | dev_err(&pdev->dev, "I2C region already claimed\n"); | 521 | dev_err(&pdev->dev, "I2C region already claimed\n"); |
@@ -523,7 +533,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) | |||
523 | dev->irq = irq->start; | 533 | dev->irq = irq->start; |
524 | platform_set_drvdata(pdev, dev); | 534 | platform_set_drvdata(pdev, dev); |
525 | 535 | ||
526 | dev->clk = clk_get(&pdev->dev, "I2CCLK"); | 536 | dev->clk = clk_get(&pdev->dev, NULL); |
527 | if (IS_ERR(dev->clk)) { | 537 | if (IS_ERR(dev->clk)) { |
528 | r = -ENODEV; | 538 | r = -ENODEV; |
529 | goto err_free_mem; | 539 | goto err_free_mem; |
@@ -568,7 +578,7 @@ err_free_mem: | |||
568 | put_device(&pdev->dev); | 578 | put_device(&pdev->dev); |
569 | kfree(dev); | 579 | kfree(dev); |
570 | err_release_region: | 580 | err_release_region: |
571 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 581 | release_mem_region(mem->start, resource_size(mem)); |
572 | 582 | ||
573 | return r; | 583 | return r; |
574 | } | 584 | } |
@@ -591,7 +601,7 @@ static int davinci_i2c_remove(struct platform_device *pdev) | |||
591 | kfree(dev); | 601 | kfree(dev); |
592 | 602 | ||
593 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 603 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
594 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 604 | release_mem_region(mem->start, resource_size(mem)); |
595 | return 0; | 605 | return 0; |
596 | } | 606 | } |
597 | 607 | ||
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index ad8d2010c921..fdd83277c8a8 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -806,7 +806,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
806 | return -ENODEV; | 806 | return -ENODEV; |
807 | } | 807 | } |
808 | 808 | ||
809 | ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, | 809 | ioarea = request_mem_region(mem->start, resource_size(mem), |
810 | pdev->name); | 810 | pdev->name); |
811 | if (!ioarea) { | 811 | if (!ioarea) { |
812 | dev_err(&pdev->dev, "I2C region already claimed\n"); | 812 | dev_err(&pdev->dev, "I2C region already claimed\n"); |
@@ -905,7 +905,7 @@ err_free_mem: | |||
905 | platform_set_drvdata(pdev, NULL); | 905 | platform_set_drvdata(pdev, NULL); |
906 | kfree(dev); | 906 | kfree(dev); |
907 | err_release_region: | 907 | err_release_region: |
908 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 908 | release_mem_region(mem->start, resource_size(mem)); |
909 | 909 | ||
910 | return r; | 910 | return r; |
911 | } | 911 | } |
@@ -925,7 +925,7 @@ omap_i2c_remove(struct platform_device *pdev) | |||
925 | iounmap(dev->base); | 925 | iounmap(dev->base); |
926 | kfree(dev); | 926 | kfree(dev); |
927 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 927 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
928 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 928 | release_mem_region(mem->start, resource_size(mem)); |
929 | return 0; | 929 | return 0; |
930 | } | 930 | } |
931 | 931 | ||
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 1c01083b01b5..4f3d99cd1692 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
@@ -563,7 +563,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) | |||
563 | goto err_irq; | 563 | goto err_irq; |
564 | } | 564 | } |
565 | 565 | ||
566 | size = (res->end - res->start) + 1; | 566 | size = resource_size(res); |
567 | 567 | ||
568 | pd->reg = ioremap(res->start, size); | 568 | pd->reg = ioremap(res->start, size); |
569 | if (pd->reg == NULL) { | 569 | if (pd->reg == NULL) { |
diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index 042fda295f3a..6407f47bda82 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c | |||
@@ -92,7 +92,7 @@ static int simtec_i2c_probe(struct platform_device *dev) | |||
92 | goto err; | 92 | goto err; |
93 | } | 93 | } |
94 | 94 | ||
95 | size = (res->end-res->start)+1; | 95 | size = resource_size(res); |
96 | 96 | ||
97 | pd->ioarea = request_mem_region(res->start, size, dev->name); | 97 | pd->ioarea = request_mem_region(res->start, size, dev->name); |
98 | if (pd->ioarea == NULL) { | 98 | if (pd->ioarea == NULL) { |
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c index 1a9cc135219f..b96f3025e588 100644 --- a/drivers/i2c/chips/tsl2550.c +++ b/drivers/i2c/chips/tsl2550.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | 28 | ||
29 | #define TSL2550_DRV_NAME "tsl2550" | 29 | #define TSL2550_DRV_NAME "tsl2550" |
30 | #define DRIVER_VERSION "1.1.1" | 30 | #define DRIVER_VERSION "1.1.2" |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Defines | 33 | * Defines |
@@ -189,13 +189,16 @@ static int tsl2550_calculate_lux(u8 ch0, u8 ch1) | |||
189 | u8 r = 128; | 189 | u8 r = 128; |
190 | 190 | ||
191 | /* Avoid division by 0 and count 1 cannot be greater than count 0 */ | 191 | /* Avoid division by 0 and count 1 cannot be greater than count 0 */ |
192 | if (c0 && (c1 <= c0)) | 192 | if (c1 <= c0) |
193 | r = c1 * 128 / c0; | 193 | if (c0) { |
194 | r = c1 * 128 / c0; | ||
195 | |||
196 | /* Calculate LUX */ | ||
197 | lux = ((c0 - c1) * ratio_lut[r]) / 256; | ||
198 | } else | ||
199 | lux = 0; | ||
194 | else | 200 | else |
195 | return -1; | 201 | return -EAGAIN; |
196 | |||
197 | /* Calculate LUX */ | ||
198 | lux = ((c0 - c1) * ratio_lut[r]) / 256; | ||
199 | 202 | ||
200 | /* LUX range check */ | 203 | /* LUX range check */ |
201 | return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux; | 204 | return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux; |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 695181120cdb..7f878017b736 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -455,6 +455,7 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | |||
455 | 455 | ||
456 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; | 456 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; |
457 | rq->special = cmd; | 457 | rq->special = cmd; |
458 | cmd->rq = rq; | ||
458 | } | 459 | } |
459 | 460 | ||
460 | ide_devset_get(multcount, mult_count); | 461 | ide_devset_get(multcount, mult_count); |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 013dc595fab6..bc5fb12b913c 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -1064,6 +1064,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, | |||
1064 | tape->best_dsc_rw_freq = config.dsc_rw_frequency; | 1064 | tape->best_dsc_rw_freq = config.dsc_rw_frequency; |
1065 | break; | 1065 | break; |
1066 | case 0x0350: | 1066 | case 0x0350: |
1067 | memset(&config, 0, sizeof(config)); | ||
1067 | config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq; | 1068 | config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq; |
1068 | config.nr_stages = 1; | 1069 | config.nr_stages = 1; |
1069 | if (copy_to_user(argp, &config, sizeof(config))) | 1070 | if (copy_to_user(argp, &config, sizeof(config))) |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 114efd8dc8f5..1148140d08a1 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -608,8 +608,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
608 | p, compat_mode); | 608 | p, compat_mode); |
609 | 609 | ||
610 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) | 610 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) |
611 | return str_to_user(dev_name(&evdev->dev), | 611 | return str_to_user(dev->name, _IOC_SIZE(cmd), p); |
612 | _IOC_SIZE(cmd), p); | ||
613 | 612 | ||
614 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) | 613 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) |
615 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); | 614 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 0e12f89276a3..4cfd084fa897 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -536,7 +536,7 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
536 | default: | 536 | default: |
537 | if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) { | 537 | if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) { |
538 | int len; | 538 | int len; |
539 | const char *name = dev_name(&dev->dev); | 539 | const char *name = dev->name; |
540 | 540 | ||
541 | if (!name) | 541 | if (!name) |
542 | return 0; | 542 | return 0; |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index b868b8d5fbb3..f155ad8cdae7 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -470,20 +470,20 @@ static void xpad_irq_out(struct urb *urb) | |||
470 | status = urb->status; | 470 | status = urb->status; |
471 | 471 | ||
472 | switch (status) { | 472 | switch (status) { |
473 | case 0: | 473 | case 0: |
474 | /* success */ | 474 | /* success */ |
475 | break; | 475 | return; |
476 | case -ECONNRESET: | 476 | |
477 | case -ENOENT: | 477 | case -ECONNRESET: |
478 | case -ESHUTDOWN: | 478 | case -ENOENT: |
479 | /* this urb is terminated, clean up */ | 479 | case -ESHUTDOWN: |
480 | dbg("%s - urb shutting down with status: %d", | 480 | /* this urb is terminated, clean up */ |
481 | __func__, status); | 481 | dbg("%s - urb shutting down with status: %d", __func__, status); |
482 | return; | 482 | return; |
483 | default: | 483 | |
484 | dbg("%s - nonzero urb status received: %d", | 484 | default: |
485 | __func__, status); | 485 | dbg("%s - nonzero urb status received: %d", __func__, status); |
486 | goto exit; | 486 | goto exit; |
487 | } | 487 | } |
488 | 488 | ||
489 | exit: | 489 | exit: |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index df3f8aa68115..95fe0452dae4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -895,6 +895,13 @@ static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = { | |||
895 | }; | 895 | }; |
896 | 896 | ||
897 | /* | 897 | /* |
898 | * Amilo Pi 3525 key release for Fn+Volume keys not working | ||
899 | */ | ||
900 | static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = { | ||
901 | 0x20, 0xa0, 0x2e, 0xae, 0x30, 0xb0, -1U | ||
902 | }; | ||
903 | |||
904 | /* | ||
898 | * Amilo Xi 3650 key release for light touch bar not working | 905 | * Amilo Xi 3650 key release for light touch bar not working |
899 | */ | 906 | */ |
900 | static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { | 907 | static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { |
@@ -902,6 +909,13 @@ static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { | |||
902 | }; | 909 | }; |
903 | 910 | ||
904 | /* | 911 | /* |
912 | * Soltech TA12 system with broken key release on volume keys and mute key | ||
913 | */ | ||
914 | static unsigned int atkdb_soltech_ta12_forced_release_keys[] = { | ||
915 | 0xa0, 0xae, 0xb0, -1U | ||
916 | }; | ||
917 | |||
918 | /* | ||
905 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 919 | * atkbd_set_keycode_table() initializes keyboard's keycode table |
906 | * according to the selected scancode set | 920 | * according to the selected scancode set |
907 | */ | 921 | */ |
@@ -1568,6 +1582,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1568 | .driver_data = atkbd_amilo_pa1510_forced_release_keys, | 1582 | .driver_data = atkbd_amilo_pa1510_forced_release_keys, |
1569 | }, | 1583 | }, |
1570 | { | 1584 | { |
1585 | .ident = "Fujitsu Amilo Pi 3525", | ||
1586 | .matches = { | ||
1587 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
1588 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), | ||
1589 | }, | ||
1590 | .callback = atkbd_setup_forced_release, | ||
1591 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, | ||
1592 | }, | ||
1593 | { | ||
1571 | .ident = "Fujitsu Amilo Xi 3650", | 1594 | .ident = "Fujitsu Amilo Xi 3650", |
1572 | .matches = { | 1595 | .matches = { |
1573 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1596 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
@@ -1576,6 +1599,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1576 | .callback = atkbd_setup_forced_release, | 1599 | .callback = atkbd_setup_forced_release, |
1577 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, | 1600 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, |
1578 | }, | 1601 | }, |
1602 | { | ||
1603 | .ident = "Soltech Corporation TA12", | ||
1604 | .matches = { | ||
1605 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), | ||
1606 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), | ||
1607 | }, | ||
1608 | .callback = atkbd_setup_forced_release, | ||
1609 | .driver_data = atkdb_soltech_ta12_forced_release_keys, | ||
1610 | }, | ||
1579 | { } | 1611 | { } |
1580 | }; | 1612 | }; |
1581 | 1613 | ||
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 6d67af5387ad..21cb755a54fb 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c | |||
@@ -114,7 +114,7 @@ static int __devexit pcspkr_remove(struct platform_device *dev) | |||
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | 116 | ||
117 | static int pcspkr_suspend(struct platform_device *dev, pm_message_t state) | 117 | static int pcspkr_suspend(struct device *dev) |
118 | { | 118 | { |
119 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); | 119 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); |
120 | 120 | ||
@@ -127,14 +127,18 @@ static void pcspkr_shutdown(struct platform_device *dev) | |||
127 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); | 127 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); |
128 | } | 128 | } |
129 | 129 | ||
130 | static struct dev_pm_ops pcspkr_pm_ops = { | ||
131 | .suspend = pcspkr_suspend, | ||
132 | }; | ||
133 | |||
130 | static struct platform_driver pcspkr_platform_driver = { | 134 | static struct platform_driver pcspkr_platform_driver = { |
131 | .driver = { | 135 | .driver = { |
132 | .name = "pcspkr", | 136 | .name = "pcspkr", |
133 | .owner = THIS_MODULE, | 137 | .owner = THIS_MODULE, |
138 | .pm = &pcspkr_pm_ops, | ||
134 | }, | 139 | }, |
135 | .probe = pcspkr_probe, | 140 | .probe = pcspkr_probe, |
136 | .remove = __devexit_p(pcspkr_remove), | 141 | .remove = __devexit_p(pcspkr_remove), |
137 | .suspend = pcspkr_suspend, | ||
138 | .shutdown = pcspkr_shutdown, | 142 | .shutdown = pcspkr_shutdown, |
139 | }; | 143 | }; |
140 | 144 | ||
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 7c8957dd22c0..26e17a9a22eb 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -646,6 +646,15 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
646 | }, | 646 | }, |
647 | { | 647 | { |
648 | .callback = dmi_matched, | 648 | .callback = dmi_matched, |
649 | .ident = "Maxdata Pro 7000 DX", | ||
650 | .matches = { | ||
651 | DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), | ||
652 | DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), | ||
653 | }, | ||
654 | .driver_data = keymap_fs_amilo_pro_v2000 | ||
655 | }, | ||
656 | { | ||
657 | .callback = dmi_matched, | ||
649 | .ident = "Fujitsu N3510", | 658 | .ident = "Fujitsu N3510", |
650 | .matches = { | 659 | .matches = { |
651 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 660 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 1ebfcab74662..8ff7e35c7069 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -408,6 +408,8 @@ static int if_write_room(struct tty_struct *tty) | |||
408 | return retval; | 408 | return retval; |
409 | } | 409 | } |
410 | 410 | ||
411 | /* FIXME: This function does not have error returns */ | ||
412 | |||
411 | static int if_chars_in_buffer(struct tty_struct *tty) | 413 | static int if_chars_in_buffer(struct tty_struct *tty) |
412 | { | 414 | { |
413 | struct cardstate *cs; | 415 | struct cardstate *cs; |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index 8df889b0c1a9..9de54202c90c 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/kernel_stat.h> | 37 | #include <linux/kernel_stat.h> |
38 | #include <linux/usb.h> | 38 | #include <linux/usb.h> |
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/sched.h> | 40 | #include <linux/sched.h> |
42 | #include <linux/moduleparam.h> | 41 | #include <linux/moduleparam.h> |
43 | #include "hisax.h" | 42 | #include "hisax.h" |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index b4d4522e5071..2881a66c1aa9 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/isdn.h> | 14 | #include <linux/isdn.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/smp_lock.h> | ||
16 | #include "isdn_common.h" | 17 | #include "isdn_common.h" |
17 | #include "isdn_tty.h" | 18 | #include "isdn_tty.h" |
18 | #ifdef CONFIG_ISDN_AUDIO | 19 | #ifdef CONFIG_ISDN_AUDIO |
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 990e6a7e6674..c3b661a666cb 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c | |||
@@ -731,10 +731,10 @@ l1oip_socket_thread(void *data) | |||
731 | while (!signal_pending(current)) { | 731 | while (!signal_pending(current)) { |
732 | struct kvec iov = { | 732 | struct kvec iov = { |
733 | .iov_base = recvbuf, | 733 | .iov_base = recvbuf, |
734 | .iov_len = sizeof(recvbuf), | 734 | .iov_len = recvbuf_size, |
735 | }; | 735 | }; |
736 | recvlen = kernel_recvmsg(socket, &msg, &iov, 1, | 736 | recvlen = kernel_recvmsg(socket, &msg, &iov, 1, |
737 | sizeof(recvbuf), 0); | 737 | recvbuf_size, 0); |
738 | if (recvlen > 0) { | 738 | if (recvlen > 0) { |
739 | l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen); | 739 | l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen); |
740 | } else { | 740 | } else { |
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index e2f45019ebf0..3e1532a180ff 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/mISDNif.h> | 18 | #include <linux/mISDNif.h> |
19 | #include <linux/kthread.h> | 19 | #include <linux/kthread.h> |
20 | #include <linux/smp_lock.h> | ||
20 | #include "core.h" | 21 | #include "core.h" |
21 | 22 | ||
22 | static u_int *debug; | 23 | static u_int *debug; |
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index 9c3138265f8e..01c591923793 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h | |||
@@ -38,8 +38,6 @@ struct lguest_pages | |||
38 | #define CHANGED_GDT_TLS 4 /* Actually a subset of CHANGED_GDT */ | 38 | #define CHANGED_GDT_TLS 4 /* Actually a subset of CHANGED_GDT */ |
39 | #define CHANGED_ALL 3 | 39 | #define CHANGED_ALL 3 |
40 | 40 | ||
41 | struct lguest; | ||
42 | |||
43 | struct lg_cpu { | 41 | struct lg_cpu { |
44 | unsigned int id; | 42 | unsigned int id; |
45 | struct lguest *lg; | 43 | struct lguest *lg; |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 9933eb861c71..ed1038164019 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -776,7 +776,7 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) | |||
776 | * But don't wait if split was due to the io size restriction | 776 | * But don't wait if split was due to the io size restriction |
777 | */ | 777 | */ |
778 | if (unlikely(out_of_pages)) | 778 | if (unlikely(out_of_pages)) |
779 | congestion_wait(WRITE, HZ/100); | 779 | congestion_wait(BLK_RW_ASYNC, HZ/100); |
780 | 780 | ||
781 | /* | 781 | /* |
782 | * With async crypto it is unsafe to share the crypto context | 782 | * With async crypto it is unsafe to share the crypto context |
@@ -1318,7 +1318,7 @@ static int crypt_iterate_devices(struct dm_target *ti, | |||
1318 | { | 1318 | { |
1319 | struct crypt_config *cc = ti->private; | 1319 | struct crypt_config *cc = ti->private; |
1320 | 1320 | ||
1321 | return fn(ti, cc->dev, cc->start, data); | 1321 | return fn(ti, cc->dev, cc->start, ti->len, data); |
1322 | } | 1322 | } |
1323 | 1323 | ||
1324 | static struct target_type crypt_target = { | 1324 | static struct target_type crypt_target = { |
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c index 4e5b843cd4d7..ebe7381f47c8 100644 --- a/drivers/md/dm-delay.c +++ b/drivers/md/dm-delay.c | |||
@@ -324,12 +324,12 @@ static int delay_iterate_devices(struct dm_target *ti, | |||
324 | struct delay_c *dc = ti->private; | 324 | struct delay_c *dc = ti->private; |
325 | int ret = 0; | 325 | int ret = 0; |
326 | 326 | ||
327 | ret = fn(ti, dc->dev_read, dc->start_read, data); | 327 | ret = fn(ti, dc->dev_read, dc->start_read, ti->len, data); |
328 | if (ret) | 328 | if (ret) |
329 | goto out; | 329 | goto out; |
330 | 330 | ||
331 | if (dc->dev_write) | 331 | if (dc->dev_write) |
332 | ret = fn(ti, dc->dev_write, dc->start_write, data); | 332 | ret = fn(ti, dc->dev_write, dc->start_write, ti->len, data); |
333 | 333 | ||
334 | out: | 334 | out: |
335 | return ret; | 335 | return ret; |
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 9184b6deb868..82f7d6e6b1ea 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c | |||
@@ -139,7 +139,7 @@ static int linear_iterate_devices(struct dm_target *ti, | |||
139 | { | 139 | { |
140 | struct linear_c *lc = ti->private; | 140 | struct linear_c *lc = ti->private; |
141 | 141 | ||
142 | return fn(ti, lc->dev, lc->start, data); | 142 | return fn(ti, lc->dev, lc->start, ti->len, data); |
143 | } | 143 | } |
144 | 144 | ||
145 | static struct target_type linear_target = { | 145 | static struct target_type linear_target = { |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index c70604a20897..6f0d90d4a541 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -1453,7 +1453,7 @@ static int multipath_iterate_devices(struct dm_target *ti, | |||
1453 | 1453 | ||
1454 | list_for_each_entry(pg, &m->priority_groups, list) { | 1454 | list_for_each_entry(pg, &m->priority_groups, list) { |
1455 | list_for_each_entry(p, &pg->pgpaths, list) { | 1455 | list_for_each_entry(p, &pg->pgpaths, list) { |
1456 | ret = fn(ti, p->path.dev, ti->begin, data); | 1456 | ret = fn(ti, p->path.dev, ti->begin, ti->len, data); |
1457 | if (ret) | 1457 | if (ret) |
1458 | goto out; | 1458 | goto out; |
1459 | } | 1459 | } |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index ce8868c768cc..9726577cde49 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -638,6 +638,7 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) | |||
638 | spin_lock_irq(&ms->lock); | 638 | spin_lock_irq(&ms->lock); |
639 | bio_list_merge(&ms->writes, &requeue); | 639 | bio_list_merge(&ms->writes, &requeue); |
640 | spin_unlock_irq(&ms->lock); | 640 | spin_unlock_irq(&ms->lock); |
641 | delayed_wake(ms); | ||
641 | } | 642 | } |
642 | 643 | ||
643 | /* | 644 | /* |
@@ -1292,7 +1293,7 @@ static int mirror_iterate_devices(struct dm_target *ti, | |||
1292 | 1293 | ||
1293 | for (i = 0; !ret && i < ms->nr_mirrors; i++) | 1294 | for (i = 0; !ret && i < ms->nr_mirrors; i++) |
1294 | ret = fn(ti, ms->mirror[i].dev, | 1295 | ret = fn(ti, ms->mirror[i].dev, |
1295 | ms->mirror[i].offset, data); | 1296 | ms->mirror[i].offset, ti->len, data); |
1296 | 1297 | ||
1297 | return ret; | 1298 | return ret; |
1298 | } | 1299 | } |
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index b240e85ae39a..4e0e5937e42a 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c | |||
@@ -320,10 +320,11 @@ static int stripe_iterate_devices(struct dm_target *ti, | |||
320 | int ret = 0; | 320 | int ret = 0; |
321 | unsigned i = 0; | 321 | unsigned i = 0; |
322 | 322 | ||
323 | do | 323 | do { |
324 | ret = fn(ti, sc->stripe[i].dev, | 324 | ret = fn(ti, sc->stripe[i].dev, |
325 | sc->stripe[i].physical_start, data); | 325 | sc->stripe[i].physical_start, |
326 | while (!ret && ++i < sc->stripes); | 326 | sc->stripe_width, data); |
327 | } while (!ret && ++i < sc->stripes); | ||
327 | 328 | ||
328 | return ret; | 329 | return ret; |
329 | } | 330 | } |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 2cba557d9e61..d952b3441913 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -346,7 +346,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) | |||
346 | * If possible, this checks an area of a destination device is valid. | 346 | * If possible, this checks an area of a destination device is valid. |
347 | */ | 347 | */ |
348 | static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, | 348 | static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, |
349 | sector_t start, void *data) | 349 | sector_t start, sector_t len, void *data) |
350 | { | 350 | { |
351 | struct queue_limits *limits = data; | 351 | struct queue_limits *limits = data; |
352 | struct block_device *bdev = dev->bdev; | 352 | struct block_device *bdev = dev->bdev; |
@@ -359,7 +359,7 @@ static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, | |||
359 | if (!dev_size) | 359 | if (!dev_size) |
360 | return 1; | 360 | return 1; |
361 | 361 | ||
362 | if ((start >= dev_size) || (start + ti->len > dev_size)) { | 362 | if ((start >= dev_size) || (start + len > dev_size)) { |
363 | DMWARN("%s: %s too small for target", | 363 | DMWARN("%s: %s too small for target", |
364 | dm_device_name(ti->table->md), bdevname(bdev, b)); | 364 | dm_device_name(ti->table->md), bdevname(bdev, b)); |
365 | return 0; | 365 | return 0; |
@@ -377,11 +377,11 @@ static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, | |||
377 | return 0; | 377 | return 0; |
378 | } | 378 | } |
379 | 379 | ||
380 | if (ti->len & (logical_block_size_sectors - 1)) { | 380 | if (len & (logical_block_size_sectors - 1)) { |
381 | DMWARN("%s: len=%llu not aligned to h/w " | 381 | DMWARN("%s: len=%llu not aligned to h/w " |
382 | "logical block size %hu of %s", | 382 | "logical block size %hu of %s", |
383 | dm_device_name(ti->table->md), | 383 | dm_device_name(ti->table->md), |
384 | (unsigned long long)ti->len, | 384 | (unsigned long long)len, |
385 | limits->logical_block_size, bdevname(bdev, b)); | 385 | limits->logical_block_size, bdevname(bdev, b)); |
386 | return 0; | 386 | return 0; |
387 | } | 387 | } |
@@ -482,7 +482,7 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti, | |||
482 | #define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) | 482 | #define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) |
483 | 483 | ||
484 | int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, | 484 | int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, |
485 | sector_t start, void *data) | 485 | sector_t start, sector_t len, void *data) |
486 | { | 486 | { |
487 | struct queue_limits *limits = data; | 487 | struct queue_limits *limits = data; |
488 | struct block_device *bdev = dev->bdev; | 488 | struct block_device *bdev = dev->bdev; |
@@ -830,11 +830,6 @@ unsigned dm_table_get_type(struct dm_table *t) | |||
830 | return t->type; | 830 | return t->type; |
831 | } | 831 | } |
832 | 832 | ||
833 | bool dm_table_bio_based(struct dm_table *t) | ||
834 | { | ||
835 | return dm_table_get_type(t) == DM_TYPE_BIO_BASED; | ||
836 | } | ||
837 | |||
838 | bool dm_table_request_based(struct dm_table *t) | 833 | bool dm_table_request_based(struct dm_table *t) |
839 | { | 834 | { |
840 | return dm_table_get_type(t) == DM_TYPE_REQUEST_BASED; | 835 | return dm_table_get_type(t) == DM_TYPE_REQUEST_BASED; |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 9acd54a5cffb..8a311ea0d441 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -2203,16 +2203,6 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) | |||
2203 | goto out; | 2203 | goto out; |
2204 | } | 2204 | } |
2205 | 2205 | ||
2206 | /* | ||
2207 | * It is enought that blk_queue_ordered() is called only once when | ||
2208 | * the first bio-based table is bound. | ||
2209 | * | ||
2210 | * This setting should be moved to alloc_dev() when request-based dm | ||
2211 | * supports barrier. | ||
2212 | */ | ||
2213 | if (!md->map && dm_table_bio_based(table)) | ||
2214 | blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN, NULL); | ||
2215 | |||
2216 | __unbind(md); | 2206 | __unbind(md); |
2217 | r = __bind(md, table, &limits); | 2207 | r = __bind(md, table, &limits); |
2218 | 2208 | ||
diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 23278ae80f08..a7663eba17e2 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h | |||
@@ -61,7 +61,6 @@ int dm_table_any_congested(struct dm_table *t, int bdi_bits); | |||
61 | int dm_table_any_busy_target(struct dm_table *t); | 61 | int dm_table_any_busy_target(struct dm_table *t); |
62 | int dm_table_set_type(struct dm_table *t); | 62 | int dm_table_set_type(struct dm_table *t); |
63 | unsigned dm_table_get_type(struct dm_table *t); | 63 | unsigned dm_table_get_type(struct dm_table *t); |
64 | bool dm_table_bio_based(struct dm_table *t); | ||
65 | bool dm_table_request_based(struct dm_table *t); | 64 | bool dm_table_request_based(struct dm_table *t); |
66 | int dm_table_alloc_md_mempools(struct dm_table *t); | 65 | int dm_table_alloc_md_mempools(struct dm_table *t); |
67 | void dm_table_free_md_mempools(struct dm_table *t); | 66 | void dm_table_free_md_mempools(struct dm_table *t); |
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index efb4a6c2b57a..9a6307a347b2 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -20,8 +20,14 @@ | |||
20 | #include "tuner-simple.h" | 20 | #include "tuner-simple.h" |
21 | #include "stv0297.h" | 21 | #include "stv0297.h" |
22 | 22 | ||
23 | |||
24 | /* Can we use the specified front-end? Remember that if we are compiled | ||
25 | * into the kernel we can't call code that's in modules. */ | ||
26 | #define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \ | ||
27 | (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE))) | ||
28 | |||
23 | /* lnb control */ | 29 | /* lnb control */ |
24 | #if defined(CONFIG_DVB_MT312_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) | 30 | #if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299) |
25 | static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 31 | static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
26 | { | 32 | { |
27 | struct flexcop_device *fc = fe->dvb->priv; | 33 | struct flexcop_device *fc = fe->dvb->priv; |
@@ -49,8 +55,7 @@ static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage | |||
49 | } | 55 | } |
50 | #endif | 56 | #endif |
51 | 57 | ||
52 | #if defined(CONFIG_DVB_S5H1420_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) \ | 58 | #if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312) |
53 | || defined(CONFIG_DVB_MT312_MODULE) | ||
54 | static int flexcop_sleep(struct dvb_frontend* fe) | 59 | static int flexcop_sleep(struct dvb_frontend* fe) |
55 | { | 60 | { |
56 | struct flexcop_device *fc = fe->dvb->priv; | 61 | struct flexcop_device *fc = fe->dvb->priv; |
@@ -61,7 +66,7 @@ static int flexcop_sleep(struct dvb_frontend* fe) | |||
61 | #endif | 66 | #endif |
62 | 67 | ||
63 | /* SkyStar2 DVB-S rev 2.3 */ | 68 | /* SkyStar2 DVB-S rev 2.3 */ |
64 | #if defined(CONFIG_DVB_MT312_MODULE) | 69 | #if FE_SUPPORTED(MT312) |
65 | static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | 70 | static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) |
66 | { | 71 | { |
67 | /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ | 72 | /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ |
@@ -193,10 +198,12 @@ static int skystar2_rev23_attach(struct flexcop_device *fc, | |||
193 | } | 198 | } |
194 | return 0; | 199 | return 0; |
195 | } | 200 | } |
201 | #else | ||
202 | #define skystar2_rev23_attach NULL | ||
196 | #endif | 203 | #endif |
197 | 204 | ||
198 | /* SkyStar2 DVB-S rev 2.6 */ | 205 | /* SkyStar2 DVB-S rev 2.6 */ |
199 | #if defined(CONFIG_DVB_STV0299_MODULE) | 206 | #if FE_SUPPORTED(STV0299) |
200 | static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe, | 207 | static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe, |
201 | u32 srate, u32 ratio) | 208 | u32 srate, u32 ratio) |
202 | { | 209 | { |
@@ -321,10 +328,12 @@ static int skystar2_rev26_attach(struct flexcop_device *fc, | |||
321 | } | 328 | } |
322 | return 0; | 329 | return 0; |
323 | } | 330 | } |
331 | #else | ||
332 | #define skystar2_rev26_attach NULL | ||
324 | #endif | 333 | #endif |
325 | 334 | ||
326 | /* SkyStar2 DVB-S rev 2.7 */ | 335 | /* SkyStar2 DVB-S rev 2.7 */ |
327 | #if defined(CONFIG_DVB_S5H1420_MODULE) | 336 | #if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000) |
328 | static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { | 337 | static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { |
329 | .demod_address = 0x53, | 338 | .demod_address = 0x53, |
330 | .invert = 1, | 339 | .invert = 1, |
@@ -385,10 +394,12 @@ fail: | |||
385 | fc->fc_i2c_adap[0].no_base_addr = 0; | 394 | fc->fc_i2c_adap[0].no_base_addr = 0; |
386 | return 0; | 395 | return 0; |
387 | } | 396 | } |
397 | #else | ||
398 | #define skystar2_rev27_attach NULL | ||
388 | #endif | 399 | #endif |
389 | 400 | ||
390 | /* SkyStar2 rev 2.8 */ | 401 | /* SkyStar2 rev 2.8 */ |
391 | #if defined(CONFIG_DVB_CX24123_MODULE) | 402 | #if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113) |
392 | static struct cx24123_config skystar2_rev2_8_cx24123_config = { | 403 | static struct cx24123_config skystar2_rev2_8_cx24123_config = { |
393 | .demod_address = 0x55, | 404 | .demod_address = 0x55, |
394 | .dont_use_pll = 1, | 405 | .dont_use_pll = 1, |
@@ -433,10 +444,12 @@ static int skystar2_rev28_attach(struct flexcop_device *fc, | |||
433 | * IR-receiver (PIC16F818) - but the card has no input for that ??? */ | 444 | * IR-receiver (PIC16F818) - but the card has no input for that ??? */ |
434 | return 1; | 445 | return 1; |
435 | } | 446 | } |
447 | #else | ||
448 | #define skystar2_rev28_attach NULL | ||
436 | #endif | 449 | #endif |
437 | 450 | ||
438 | /* AirStar DVB-T */ | 451 | /* AirStar DVB-T */ |
439 | #if defined(CONFIG_DVB_MT352_MODULE) | 452 | #if FE_SUPPORTED(MT352) |
440 | static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe) | 453 | static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe) |
441 | { | 454 | { |
442 | static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d }; | 455 | static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d }; |
@@ -495,10 +508,12 @@ static int airstar_dvbt_attach(struct flexcop_device *fc, | |||
495 | } | 508 | } |
496 | return 0; | 509 | return 0; |
497 | } | 510 | } |
511 | #else | ||
512 | #define airstar_dvbt_attach NULL | ||
498 | #endif | 513 | #endif |
499 | 514 | ||
500 | /* AirStar ATSC 1st generation */ | 515 | /* AirStar ATSC 1st generation */ |
501 | #if defined(CONFIG_DVB_BCM3510_MODULE) | 516 | #if FE_SUPPORTED(BCM3510) |
502 | static int flexcop_fe_request_firmware(struct dvb_frontend *fe, | 517 | static int flexcop_fe_request_firmware(struct dvb_frontend *fe, |
503 | const struct firmware **fw, char* name) | 518 | const struct firmware **fw, char* name) |
504 | { | 519 | { |
@@ -517,10 +532,12 @@ static int airstar_atsc1_attach(struct flexcop_device *fc, | |||
517 | fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); | 532 | fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); |
518 | return fc->fe != NULL; | 533 | return fc->fe != NULL; |
519 | } | 534 | } |
535 | #else | ||
536 | #define airstar_atsc1_attach NULL | ||
520 | #endif | 537 | #endif |
521 | 538 | ||
522 | /* AirStar ATSC 2nd generation */ | 539 | /* AirStar ATSC 2nd generation */ |
523 | #if defined(CONFIG_DVB_NXT200X_MODULE) | 540 | #if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL) |
524 | static struct nxt200x_config samsung_tbmv_config = { | 541 | static struct nxt200x_config samsung_tbmv_config = { |
525 | .demod_address = 0x0a, | 542 | .demod_address = 0x0a, |
526 | }; | 543 | }; |
@@ -535,10 +552,12 @@ static int airstar_atsc2_attach(struct flexcop_device *fc, | |||
535 | return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, | 552 | return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, |
536 | DVB_PLL_SAMSUNG_TBMV); | 553 | DVB_PLL_SAMSUNG_TBMV); |
537 | } | 554 | } |
555 | #else | ||
556 | #define airstar_atsc2_attach NULL | ||
538 | #endif | 557 | #endif |
539 | 558 | ||
540 | /* AirStar ATSC 3rd generation */ | 559 | /* AirStar ATSC 3rd generation */ |
541 | #if defined(CONFIG_DVB_LGDT330X_MODULE) | 560 | #if FE_SUPPORTED(LGDT330X) |
542 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { | 561 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { |
543 | .demod_address = 0x59, | 562 | .demod_address = 0x59, |
544 | .demod_chip = LGDT3303, | 563 | .demod_chip = LGDT3303, |
@@ -556,10 +575,12 @@ static int airstar_atsc3_attach(struct flexcop_device *fc, | |||
556 | return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, | 575 | return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, |
557 | TUNER_LG_TDVS_H06XF); | 576 | TUNER_LG_TDVS_H06XF); |
558 | } | 577 | } |
578 | #else | ||
579 | #define airstar_atsc3_attach NULL | ||
559 | #endif | 580 | #endif |
560 | 581 | ||
561 | /* CableStar2 DVB-C */ | 582 | /* CableStar2 DVB-C */ |
562 | #if defined(CONFIG_DVB_STV0297_MODULE) | 583 | #if FE_SUPPORTED(STV0297) |
563 | static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, | 584 | static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, |
564 | struct dvb_frontend_parameters *fep) | 585 | struct dvb_frontend_parameters *fep) |
565 | { | 586 | { |
@@ -698,39 +719,23 @@ static int cablestar2_attach(struct flexcop_device *fc, | |||
698 | fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; | 719 | fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; |
699 | return 1; | 720 | return 1; |
700 | } | 721 | } |
722 | #else | ||
723 | #define cablestar2_attach NULL | ||
701 | #endif | 724 | #endif |
702 | 725 | ||
703 | static struct { | 726 | static struct { |
704 | flexcop_device_type_t type; | 727 | flexcop_device_type_t type; |
705 | int (*attach)(struct flexcop_device *, struct i2c_adapter *); | 728 | int (*attach)(struct flexcop_device *, struct i2c_adapter *); |
706 | } flexcop_frontends[] = { | 729 | } flexcop_frontends[] = { |
707 | #if defined(CONFIG_DVB_S5H1420_MODULE) | ||
708 | { FC_SKY_REV27, skystar2_rev27_attach }, | 730 | { FC_SKY_REV27, skystar2_rev27_attach }, |
709 | #endif | ||
710 | #if defined(CONFIG_DVB_CX24123_MODULE) | ||
711 | { FC_SKY_REV28, skystar2_rev28_attach }, | 731 | { FC_SKY_REV28, skystar2_rev28_attach }, |
712 | #endif | ||
713 | #if defined(CONFIG_DVB_STV0299_MODULE) | ||
714 | { FC_SKY_REV26, skystar2_rev26_attach }, | 732 | { FC_SKY_REV26, skystar2_rev26_attach }, |
715 | #endif | ||
716 | #if defined(CONFIG_DVB_MT352_MODULE) | ||
717 | { FC_AIR_DVBT, airstar_dvbt_attach }, | 733 | { FC_AIR_DVBT, airstar_dvbt_attach }, |
718 | #endif | ||
719 | #if defined(CONFIG_DVB_NXT200X_MODULE) | ||
720 | { FC_AIR_ATSC2, airstar_atsc2_attach }, | 734 | { FC_AIR_ATSC2, airstar_atsc2_attach }, |
721 | #endif | ||
722 | #if defined(CONFIG_DVB_LGDT330X_MODULE) | ||
723 | { FC_AIR_ATSC3, airstar_atsc3_attach }, | 735 | { FC_AIR_ATSC3, airstar_atsc3_attach }, |
724 | #endif | ||
725 | #if defined(CONFIG_DVB_BCM3510_MODULE) | ||
726 | { FC_AIR_ATSC1, airstar_atsc1_attach }, | 736 | { FC_AIR_ATSC1, airstar_atsc1_attach }, |
727 | #endif | ||
728 | #if defined(CONFIG_DVB_STV0297_MODULE) | ||
729 | { FC_CABLE, cablestar2_attach }, | 737 | { FC_CABLE, cablestar2_attach }, |
730 | #endif | ||
731 | #if defined(CONFIG_DVB_MT312_MODULE) | ||
732 | { FC_SKY_REV23, skystar2_rev23_attach }, | 738 | { FC_SKY_REV23, skystar2_rev23_attach }, |
733 | #endif | ||
734 | }; | 739 | }; |
735 | 740 | ||
736 | /* try to figure out the frontend */ | 741 | /* try to figure out the frontend */ |
@@ -738,6 +743,8 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
738 | { | 743 | { |
739 | int i; | 744 | int i; |
740 | for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) { | 745 | for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) { |
746 | if (!flexcop_frontends[i].attach) | ||
747 | continue; | ||
741 | /* type needs to be set before, because of some workarounds | 748 | /* type needs to be set before, because of some workarounds |
742 | * done based on the probed card type */ | 749 | * done based on the probed card type */ |
743 | fc->dev_type = flexcop_frontends[i].type; | 750 | fc->dev_type = flexcop_frontends[i].type; |
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index 4601b059b2b2..0e246eaad05a 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/smp_lock.h> | ||
24 | #include <linux/string.h> | 25 | #include <linux/string.h> |
25 | #include <linux/dvb/ca.h> | 26 | #include <linux/dvb/ca.h> |
26 | #include "dvbdev.h" | 27 | #include "dvbdev.h" |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 79927305e84d..487919bea7ae 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/poll.h> | 27 | #include <linux/poll.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/list.h> | 29 | #include <linux/list.h> |
30 | #include <linux/smp_lock.h> | ||
31 | 30 | ||
32 | #define DVB_MAJOR 212 | 31 | #define DVB_MAJOR 212 |
33 | 32 | ||
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 136c5863d81b..12e018b4107d 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c | |||
@@ -527,6 +527,10 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
527 | u8 i, buf[3] = {0, 0, 0}; | 527 | u8 i, buf[3] = {0, 0, 0}; |
528 | *auto_mode = 0; /* set if parameters are requested to auto set */ | 528 | *auto_mode = 0; /* set if parameters are requested to auto set */ |
529 | 529 | ||
530 | /* Try auto-detect transmission parameters in case of AUTO requested or | ||
531 | garbage parameters given by application for compatibility. | ||
532 | MPlayer seems to provide garbage parameters currently. */ | ||
533 | |||
530 | switch (params->transmission_mode) { | 534 | switch (params->transmission_mode) { |
531 | case TRANSMISSION_MODE_AUTO: | 535 | case TRANSMISSION_MODE_AUTO: |
532 | *auto_mode = 1; | 536 | *auto_mode = 1; |
@@ -536,7 +540,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
536 | buf[0] |= (1 << 0); | 540 | buf[0] |= (1 << 0); |
537 | break; | 541 | break; |
538 | default: | 542 | default: |
539 | return -EINVAL; | 543 | deb_info("%s: invalid transmission_mode\n", __func__); |
544 | *auto_mode = 1; | ||
540 | } | 545 | } |
541 | 546 | ||
542 | switch (params->guard_interval) { | 547 | switch (params->guard_interval) { |
@@ -554,7 +559,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
554 | buf[0] |= (3 << 2); | 559 | buf[0] |= (3 << 2); |
555 | break; | 560 | break; |
556 | default: | 561 | default: |
557 | return -EINVAL; | 562 | deb_info("%s: invalid guard_interval\n", __func__); |
563 | *auto_mode = 1; | ||
558 | } | 564 | } |
559 | 565 | ||
560 | switch (params->hierarchy_information) { | 566 | switch (params->hierarchy_information) { |
@@ -572,7 +578,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
572 | buf[0] |= (3 << 4); | 578 | buf[0] |= (3 << 4); |
573 | break; | 579 | break; |
574 | default: | 580 | default: |
575 | return -EINVAL; | 581 | deb_info("%s: invalid hierarchy_information\n", __func__); |
582 | *auto_mode = 1; | ||
576 | }; | 583 | }; |
577 | 584 | ||
578 | switch (params->constellation) { | 585 | switch (params->constellation) { |
@@ -587,7 +594,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
587 | buf[1] |= (2 << 6); | 594 | buf[1] |= (2 << 6); |
588 | break; | 595 | break; |
589 | default: | 596 | default: |
590 | return -EINVAL; | 597 | deb_info("%s: invalid constellation\n", __func__); |
598 | *auto_mode = 1; | ||
591 | } | 599 | } |
592 | 600 | ||
593 | /* Use HP. How and which case we can switch to LP? */ | 601 | /* Use HP. How and which case we can switch to LP? */ |
@@ -611,7 +619,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
611 | buf[2] |= (4 << 0); | 619 | buf[2] |= (4 << 0); |
612 | break; | 620 | break; |
613 | default: | 621 | default: |
614 | return -EINVAL; | 622 | deb_info("%s: invalid code_rate_HP\n", __func__); |
623 | *auto_mode = 1; | ||
615 | } | 624 | } |
616 | 625 | ||
617 | switch (params->code_rate_LP) { | 626 | switch (params->code_rate_LP) { |
@@ -638,7 +647,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
638 | if (params->hierarchy_information == HIERARCHY_AUTO) | 647 | if (params->hierarchy_information == HIERARCHY_AUTO) |
639 | break; | 648 | break; |
640 | default: | 649 | default: |
641 | return -EINVAL; | 650 | deb_info("%s: invalid code_rate_LP\n", __func__); |
651 | *auto_mode = 1; | ||
642 | } | 652 | } |
643 | 653 | ||
644 | switch (params->bandwidth) { | 654 | switch (params->bandwidth) { |
@@ -651,7 +661,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
651 | buf[1] |= (2 << 2); | 661 | buf[1] |= (2 << 2); |
652 | break; | 662 | break; |
653 | default: | 663 | default: |
654 | return -EINVAL; | 664 | deb_info("%s: invalid bandwidth\n", __func__); |
665 | buf[1] |= (2 << 2); /* cannot auto-detect BW, try 8 MHz */ | ||
655 | } | 666 | } |
656 | 667 | ||
657 | /* program */ | 668 | /* program */ |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index d1d959ed37b7..8d65c652ba50 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/timer.h> | 37 | #include <linux/timer.h> |
38 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
39 | #include <linux/smp_lock.h> | ||
40 | 39 | ||
41 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
42 | #include <linux/sched.h> | 41 | #include <linux/sched.h> |
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 837467f93805..575bf9d89419 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/module.h> | 58 | #include <linux/module.h> |
59 | #include <linux/init.h> | 59 | #include <linux/init.h> |
60 | #include <linux/slab.h> | 60 | #include <linux/slab.h> |
61 | #include <linux/smp_lock.h> | ||
61 | #include <linux/input.h> | 62 | #include <linux/input.h> |
62 | #include <linux/videodev2.h> | 63 | #include <linux/videodev2.h> |
63 | #include <media/v4l2-device.h> | 64 | #include <media/v4l2-device.h> |
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 46d216329611..e85f318b4d2b 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
@@ -127,6 +127,7 @@ | |||
127 | #include <linux/module.h> | 127 | #include <linux/module.h> |
128 | #include <linux/init.h> | 128 | #include <linux/init.h> |
129 | #include <linux/slab.h> | 129 | #include <linux/slab.h> |
130 | #include <linux/smp_lock.h> | ||
130 | #include <linux/input.h> | 131 | #include <linux/input.h> |
131 | #include <linux/usb.h> | 132 | #include <linux/usb.h> |
132 | #include <linux/hid.h> | 133 | #include <linux/hid.h> |
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index fdb4adff3d28..ca6558c394be 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -3324,8 +3324,6 @@ void __devinit bttv_init_card1(struct bttv *btv) | |||
3324 | /* initialization part two -- after registering i2c bus */ | 3324 | /* initialization part two -- after registering i2c bus */ |
3325 | void __devinit bttv_init_card2(struct bttv *btv) | 3325 | void __devinit bttv_init_card2(struct bttv *btv) |
3326 | { | 3326 | { |
3327 | int addr=ADDR_UNSET; | ||
3328 | |||
3329 | btv->tuner_type = UNSET; | 3327 | btv->tuner_type = UNSET; |
3330 | 3328 | ||
3331 | if (BTTV_BOARD_UNKNOWN == btv->c.type) { | 3329 | if (BTTV_BOARD_UNKNOWN == btv->c.type) { |
@@ -3470,9 +3468,6 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3470 | btv->pll.pll_current = -1; | 3468 | btv->pll.pll_current = -1; |
3471 | 3469 | ||
3472 | /* tuner configuration (from card list / autodetect / insmod option) */ | 3470 | /* tuner configuration (from card list / autodetect / insmod option) */ |
3473 | if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr) | ||
3474 | addr = bttv_tvcards[btv->c.type].tuner_addr; | ||
3475 | |||
3476 | if (UNSET != bttv_tvcards[btv->c.type].tuner_type) | 3471 | if (UNSET != bttv_tvcards[btv->c.type].tuner_type) |
3477 | if (UNSET == btv->tuner_type) | 3472 | if (UNSET == btv->tuner_type) |
3478 | btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; | 3473 | btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; |
@@ -3496,40 +3491,6 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3496 | if (UNSET == btv->tuner_type) | 3491 | if (UNSET == btv->tuner_type) |
3497 | btv->tuner_type = TUNER_ABSENT; | 3492 | btv->tuner_type = TUNER_ABSENT; |
3498 | 3493 | ||
3499 | if (btv->tuner_type != TUNER_ABSENT) { | ||
3500 | struct tuner_setup tun_setup; | ||
3501 | |||
3502 | /* Load tuner module before issuing tuner config call! */ | ||
3503 | if (bttv_tvcards[btv->c.type].has_radio) | ||
3504 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
3505 | &btv->c.i2c_adap, "tuner", "tuner", | ||
3506 | v4l2_i2c_tuner_addrs(ADDRS_RADIO)); | ||
3507 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
3508 | &btv->c.i2c_adap, "tuner", "tuner", | ||
3509 | v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | ||
3510 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
3511 | &btv->c.i2c_adap, "tuner", "tuner", | ||
3512 | v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); | ||
3513 | |||
3514 | tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; | ||
3515 | tun_setup.type = btv->tuner_type; | ||
3516 | tun_setup.addr = addr; | ||
3517 | |||
3518 | if (bttv_tvcards[btv->c.type].has_radio) | ||
3519 | tun_setup.mode_mask |= T_RADIO; | ||
3520 | |||
3521 | bttv_call_all(btv, tuner, s_type_addr, &tun_setup); | ||
3522 | } | ||
3523 | |||
3524 | if (btv->tda9887_conf) { | ||
3525 | struct v4l2_priv_tun_config tda9887_cfg; | ||
3526 | |||
3527 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
3528 | tda9887_cfg.priv = &btv->tda9887_conf; | ||
3529 | |||
3530 | bttv_call_all(btv, tuner, s_config, &tda9887_cfg); | ||
3531 | } | ||
3532 | |||
3533 | btv->dig = bttv_tvcards[btv->c.type].has_dig_in ? | 3494 | btv->dig = bttv_tvcards[btv->c.type].has_dig_in ? |
3534 | bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET; | 3495 | bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET; |
3535 | btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ? | 3496 | btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ? |
@@ -3540,15 +3501,15 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3540 | btv->has_remote = remote[btv->c.nr]; | 3501 | btv->has_remote = remote[btv->c.nr]; |
3541 | 3502 | ||
3542 | if (bttv_tvcards[btv->c.type].has_radio) | 3503 | if (bttv_tvcards[btv->c.type].has_radio) |
3543 | btv->has_radio=1; | 3504 | btv->has_radio = 1; |
3544 | if (bttv_tvcards[btv->c.type].has_remote) | 3505 | if (bttv_tvcards[btv->c.type].has_remote) |
3545 | btv->has_remote=1; | 3506 | btv->has_remote = 1; |
3546 | if (!bttv_tvcards[btv->c.type].no_gpioirq) | 3507 | if (!bttv_tvcards[btv->c.type].no_gpioirq) |
3547 | btv->gpioirq=1; | 3508 | btv->gpioirq = 1; |
3548 | if (bttv_tvcards[btv->c.type].volume_gpio) | 3509 | if (bttv_tvcards[btv->c.type].volume_gpio) |
3549 | btv->volume_gpio=bttv_tvcards[btv->c.type].volume_gpio; | 3510 | btv->volume_gpio = bttv_tvcards[btv->c.type].volume_gpio; |
3550 | if (bttv_tvcards[btv->c.type].audio_mode_gpio) | 3511 | if (bttv_tvcards[btv->c.type].audio_mode_gpio) |
3551 | btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio; | 3512 | btv->audio_mode_gpio = bttv_tvcards[btv->c.type].audio_mode_gpio; |
3552 | 3513 | ||
3553 | if (btv->tuner_type == TUNER_ABSENT) | 3514 | if (btv->tuner_type == TUNER_ABSENT) |
3554 | return; /* no tuner or related drivers to load */ | 3515 | return; /* no tuner or related drivers to load */ |
@@ -3666,6 +3627,49 @@ no_audio: | |||
3666 | } | 3627 | } |
3667 | 3628 | ||
3668 | 3629 | ||
3630 | /* initialize the tuner */ | ||
3631 | void __devinit bttv_init_tuner(struct bttv *btv) | ||
3632 | { | ||
3633 | int addr = ADDR_UNSET; | ||
3634 | |||
3635 | if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr) | ||
3636 | addr = bttv_tvcards[btv->c.type].tuner_addr; | ||
3637 | |||
3638 | if (btv->tuner_type != TUNER_ABSENT) { | ||
3639 | struct tuner_setup tun_setup; | ||
3640 | |||
3641 | /* Load tuner module before issuing tuner config call! */ | ||
3642 | if (bttv_tvcards[btv->c.type].has_radio) | ||
3643 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
3644 | &btv->c.i2c_adap, "tuner", "tuner", | ||
3645 | v4l2_i2c_tuner_addrs(ADDRS_RADIO)); | ||
3646 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
3647 | &btv->c.i2c_adap, "tuner", "tuner", | ||
3648 | v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | ||
3649 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
3650 | &btv->c.i2c_adap, "tuner", "tuner", | ||
3651 | v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); | ||
3652 | |||
3653 | tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; | ||
3654 | tun_setup.type = btv->tuner_type; | ||
3655 | tun_setup.addr = addr; | ||
3656 | |||
3657 | if (bttv_tvcards[btv->c.type].has_radio) | ||
3658 | tun_setup.mode_mask |= T_RADIO; | ||
3659 | |||
3660 | bttv_call_all(btv, tuner, s_type_addr, &tun_setup); | ||
3661 | } | ||
3662 | |||
3663 | if (btv->tda9887_conf) { | ||
3664 | struct v4l2_priv_tun_config tda9887_cfg; | ||
3665 | |||
3666 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
3667 | tda9887_cfg.priv = &btv->tda9887_conf; | ||
3668 | |||
3669 | bttv_call_all(btv, tuner, s_config, &tda9887_cfg); | ||
3670 | } | ||
3671 | } | ||
3672 | |||
3669 | /* ----------------------------------------------------------------------- */ | 3673 | /* ----------------------------------------------------------------------- */ |
3670 | 3674 | ||
3671 | static void modtec_eeprom(struct bttv *btv) | 3675 | static void modtec_eeprom(struct bttv *btv) |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 5eb1464af670..8cc6dd28d6a7 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/fs.h> | 41 | #include <linux/fs.h> |
42 | #include <linux/kernel.h> | 42 | #include <linux/kernel.h> |
43 | #include <linux/sched.h> | 43 | #include <linux/sched.h> |
44 | #include <linux/smp_lock.h> | ||
44 | #include <linux/interrupt.h> | 45 | #include <linux/interrupt.h> |
45 | #include <linux/kdev_t.h> | 46 | #include <linux/kdev_t.h> |
46 | #include "bttvp.h" | 47 | #include "bttvp.h" |
@@ -4418,6 +4419,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4418 | 4419 | ||
4419 | /* some card-specific stuff (needs working i2c) */ | 4420 | /* some card-specific stuff (needs working i2c) */ |
4420 | bttv_init_card2(btv); | 4421 | bttv_init_card2(btv); |
4422 | bttv_init_tuner(btv); | ||
4421 | init_irqreg(btv); | 4423 | init_irqreg(btv); |
4422 | 4424 | ||
4423 | /* register video4linux + input */ | 4425 | /* register video4linux + input */ |
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index 3d36daf206f3..3ec2402c6b4a 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
@@ -283,6 +283,7 @@ extern struct tvcard bttv_tvcards[]; | |||
283 | extern void bttv_idcard(struct bttv *btv); | 283 | extern void bttv_idcard(struct bttv *btv); |
284 | extern void bttv_init_card1(struct bttv *btv); | 284 | extern void bttv_init_card1(struct bttv *btv); |
285 | extern void bttv_init_card2(struct bttv *btv); | 285 | extern void bttv_init_card2(struct bttv *btv); |
286 | extern void bttv_init_tuner(struct bttv *btv); | ||
286 | 287 | ||
287 | /* card-specific funtions */ | 288 | /* card-specific funtions */ |
288 | extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); | 289 | extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); |
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 2943bfd32a94..e0cf21e0b1bf 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/device.h> | 32 | #include <linux/device.h> |
33 | #include <linux/firmware.h> | 33 | #include <linux/firmware.h> |
34 | #include <linux/smp_lock.h> | ||
34 | #include <media/v4l2-common.h> | 35 | #include <media/v4l2-common.h> |
35 | #include <media/v4l2-ioctl.h> | 36 | #include <media/v4l2-ioctl.h> |
36 | #include <media/cx2341x.h> | 37 | #include <media/cx2341x.h> |
@@ -57,7 +58,8 @@ MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); | |||
57 | 58 | ||
58 | #define dprintk(level, fmt, arg...)\ | 59 | #define dprintk(level, fmt, arg...)\ |
59 | do { if (v4l_debug >= level) \ | 60 | do { if (v4l_debug >= level) \ |
60 | printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg);\ | 61 | printk(KERN_DEBUG "%s: " fmt, \ |
62 | (dev) ? dev->name : "cx23885[?]", ## arg); \ | ||
61 | } while (0) | 63 | } while (0) |
62 | 64 | ||
63 | static struct cx23885_tvnorm cx23885_tvnorms[] = { | 65 | static struct cx23885_tvnorm cx23885_tvnorms[] = { |
@@ -1676,6 +1678,7 @@ static struct v4l2_file_operations mpeg_fops = { | |||
1676 | .read = mpeg_read, | 1678 | .read = mpeg_read, |
1677 | .poll = mpeg_poll, | 1679 | .poll = mpeg_poll, |
1678 | .mmap = mpeg_mmap, | 1680 | .mmap = mpeg_mmap, |
1681 | .ioctl = video_ioctl2, | ||
1679 | }; | 1682 | }; |
1680 | 1683 | ||
1681 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { | 1684 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 70836af3ab48..5d6093336300 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kmod.h> | 26 | #include <linux/kmod.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
30 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
31 | #include <linux/kthread.h> | 32 | #include <linux/kthread.h> |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 44eacfb0d0d6..356d6896da3f 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/device.h> | 33 | #include <linux/device.h> |
34 | #include <linux/firmware.h> | 34 | #include <linux/firmware.h> |
35 | #include <linux/smp_lock.h> | ||
35 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
36 | #include <media/v4l2-ioctl.h> | 37 | #include <media/v4l2-ioctl.h> |
37 | #include <media/cx2341x.h> | 38 | #include <media/cx2341x.h> |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index b12770848c00..2bb54c3ef5cd 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kmod.h> | 31 | #include <linux/kmod.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/smp_lock.h> | ||
34 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
35 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
36 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c index ec2f45dde164..0664d111085f 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/media/video/dabusb.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/list.h> | 32 | #include <linux/list.h> |
33 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/smp_lock.h> | ||
35 | #include <linux/init.h> | 36 | #include <linux/init.h> |
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
37 | #include <asm/atomic.h> | 38 | #include <asm/atomic.h> |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ebd24a25fb85..320f1f60276e 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -58,8 +58,6 @@ static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | |||
58 | module_param_array(card, int, NULL, 0444); | 58 | module_param_array(card, int, NULL, 0444); |
59 | MODULE_PARM_DESC(card, "card type"); | 59 | MODULE_PARM_DESC(card, "card type"); |
60 | 60 | ||
61 | #define MT9V011_VERSION 0x8243 | ||
62 | |||
63 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ | 61 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ |
64 | static unsigned long em28xx_devused; | 62 | static unsigned long em28xx_devused; |
65 | 63 | ||
@@ -159,6 +157,20 @@ static struct em28xx_reg_seq evga_indtube_digital[] = { | |||
159 | { -1, -1, -1, -1}, | 157 | { -1, -1, -1, -1}, |
160 | }; | 158 | }; |
161 | 159 | ||
160 | /* Pinnacle Hybrid Pro eb1a:2881 */ | ||
161 | static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = { | ||
162 | {EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10}, | ||
163 | { -1, -1, -1, -1}, | ||
164 | }; | ||
165 | |||
166 | static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { | ||
167 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
168 | {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */ | ||
169 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, | ||
170 | { -1, -1, -1, -1}, | ||
171 | }; | ||
172 | |||
173 | |||
162 | /* Callback for the most boards */ | 174 | /* Callback for the most boards */ |
163 | static struct em28xx_reg_seq default_tuner_gpio[] = { | 175 | static struct em28xx_reg_seq default_tuner_gpio[] = { |
164 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | 176 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, |
@@ -205,13 +217,15 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = { | |||
205 | */ | 217 | */ |
206 | struct em28xx_board em28xx_boards[] = { | 218 | struct em28xx_board em28xx_boards[] = { |
207 | [EM2750_BOARD_UNKNOWN] = { | 219 | [EM2750_BOARD_UNKNOWN] = { |
208 | .name = "Unknown EM2750/EM2751 webcam grabber", | 220 | .name = "EM2710/EM2750/EM2751 webcam grabber", |
209 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, | 221 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, |
210 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | 222 | .tuner_type = TUNER_ABSENT, |
223 | .is_webcam = 1, | ||
211 | .input = { { | 224 | .input = { { |
212 | .type = EM28XX_VMUX_COMPOSITE1, | 225 | .type = EM28XX_VMUX_COMPOSITE1, |
213 | .vmux = 0, | 226 | .vmux = 0, |
214 | .amux = EM28XX_AMUX_VIDEO, | 227 | .amux = EM28XX_AMUX_VIDEO, |
228 | .gpio = silvercrest_reg_seq, | ||
215 | } }, | 229 | } }, |
216 | }, | 230 | }, |
217 | [EM2800_BOARD_UNKNOWN] = { | 231 | [EM2800_BOARD_UNKNOWN] = { |
@@ -233,13 +247,15 @@ struct em28xx_board em28xx_boards[] = { | |||
233 | [EM2820_BOARD_UNKNOWN] = { | 247 | [EM2820_BOARD_UNKNOWN] = { |
234 | .name = "Unknown EM2750/28xx video grabber", | 248 | .name = "Unknown EM2750/28xx video grabber", |
235 | .tuner_type = TUNER_ABSENT, | 249 | .tuner_type = TUNER_ABSENT, |
250 | .is_webcam = 1, /* To enable sensor probe */ | ||
236 | }, | 251 | }, |
237 | [EM2750_BOARD_DLCW_130] = { | 252 | [EM2750_BOARD_DLCW_130] = { |
238 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | 253 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ |
239 | .name = "Huaqi DLCW-130", | 254 | .name = "Huaqi DLCW-130", |
240 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 255 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
241 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, | 256 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, |
242 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | 257 | .tuner_type = TUNER_ABSENT, |
258 | .is_webcam = 1, | ||
243 | .input = { { | 259 | .input = { { |
244 | .type = EM28XX_VMUX_COMPOSITE1, | 260 | .type = EM28XX_VMUX_COMPOSITE1, |
245 | .vmux = 0, | 261 | .vmux = 0, |
@@ -440,7 +456,8 @@ struct em28xx_board em28xx_boards[] = { | |||
440 | [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { | 456 | [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { |
441 | .name = "Videology 20K14XUSB USB2.0", | 457 | .name = "Videology 20K14XUSB USB2.0", |
442 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 458 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
443 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | 459 | .tuner_type = TUNER_ABSENT, |
460 | .is_webcam = 1, | ||
444 | .input = { { | 461 | .input = { { |
445 | .type = EM28XX_VMUX_COMPOSITE1, | 462 | .type = EM28XX_VMUX_COMPOSITE1, |
446 | .vmux = 0, | 463 | .vmux = 0, |
@@ -450,8 +467,7 @@ struct em28xx_board em28xx_boards[] = { | |||
450 | [EM2820_BOARD_SILVERCREST_WEBCAM] = { | 467 | [EM2820_BOARD_SILVERCREST_WEBCAM] = { |
451 | .name = "Silvercrest Webcam 1.3mpix", | 468 | .name = "Silvercrest Webcam 1.3mpix", |
452 | .tuner_type = TUNER_ABSENT, | 469 | .tuner_type = TUNER_ABSENT, |
453 | .is_27xx = 1, | 470 | .is_webcam = 1, |
454 | .decoder = EM28XX_MT9V011, | ||
455 | .input = { { | 471 | .input = { { |
456 | .type = EM28XX_VMUX_COMPOSITE1, | 472 | .type = EM28XX_VMUX_COMPOSITE1, |
457 | .vmux = 0, | 473 | .vmux = 0, |
@@ -500,7 +516,8 @@ struct em28xx_board em28xx_boards[] = { | |||
500 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | 516 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ |
501 | .name = "NetGMBH Cam", | 517 | .name = "NetGMBH Cam", |
502 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 518 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
503 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | 519 | .tuner_type = TUNER_ABSENT, |
520 | .is_webcam = 1, | ||
504 | .input = { { | 521 | .input = { { |
505 | .type = EM28XX_VMUX_COMPOSITE1, | 522 | .type = EM28XX_VMUX_COMPOSITE1, |
506 | .vmux = 0, | 523 | .vmux = 0, |
@@ -1250,25 +1267,26 @@ struct em28xx_board em28xx_boards[] = { | |||
1250 | }, | 1267 | }, |
1251 | [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { | 1268 | [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { |
1252 | .name = "Pinnacle Hybrid Pro", | 1269 | .name = "Pinnacle Hybrid Pro", |
1253 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1254 | .tuner_type = TUNER_XC2028, | 1270 | .tuner_type = TUNER_XC2028, |
1255 | .tuner_gpio = default_tuner_gpio, | 1271 | .tuner_gpio = default_tuner_gpio, |
1256 | .decoder = EM28XX_TVP5150, | 1272 | .decoder = EM28XX_TVP5150, |
1273 | .has_dvb = 1, | ||
1274 | .dvb_gpio = pinnacle_hybrid_pro_digital, | ||
1257 | .input = { { | 1275 | .input = { { |
1258 | .type = EM28XX_VMUX_TELEVISION, | 1276 | .type = EM28XX_VMUX_TELEVISION, |
1259 | .vmux = TVP5150_COMPOSITE0, | 1277 | .vmux = TVP5150_COMPOSITE0, |
1260 | .amux = EM28XX_AMUX_VIDEO, | 1278 | .amux = EM28XX_AMUX_VIDEO, |
1261 | .gpio = default_analog, | 1279 | .gpio = pinnacle_hybrid_pro_analog, |
1262 | }, { | 1280 | }, { |
1263 | .type = EM28XX_VMUX_COMPOSITE1, | 1281 | .type = EM28XX_VMUX_COMPOSITE1, |
1264 | .vmux = TVP5150_COMPOSITE1, | 1282 | .vmux = TVP5150_COMPOSITE1, |
1265 | .amux = EM28XX_AMUX_LINE_IN, | 1283 | .amux = EM28XX_AMUX_LINE_IN, |
1266 | .gpio = default_analog, | 1284 | .gpio = pinnacle_hybrid_pro_analog, |
1267 | }, { | 1285 | }, { |
1268 | .type = EM28XX_VMUX_SVIDEO, | 1286 | .type = EM28XX_VMUX_SVIDEO, |
1269 | .vmux = TVP5150_SVIDEO, | 1287 | .vmux = TVP5150_SVIDEO, |
1270 | .amux = EM28XX_AMUX_LINE_IN, | 1288 | .amux = EM28XX_AMUX_LINE_IN, |
1271 | .gpio = default_analog, | 1289 | .gpio = pinnacle_hybrid_pro_analog, |
1272 | } }, | 1290 | } }, |
1273 | }, | 1291 | }, |
1274 | [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { | 1292 | [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { |
@@ -1638,6 +1656,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = { | |||
1638 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, | 1656 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, |
1639 | {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, | 1657 | {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, |
1640 | {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, | 1658 | {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, |
1659 | {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, | ||
1641 | }; | 1660 | }; |
1642 | 1661 | ||
1643 | /* I2C devicelist hash table for devices with generic USB IDs */ | 1662 | /* I2C devicelist hash table for devices with generic USB IDs */ |
@@ -1704,6 +1723,32 @@ static inline void em28xx_set_model(struct em28xx *dev) | |||
1704 | EM28XX_I2C_FREQ_100_KHZ; | 1723 | EM28XX_I2C_FREQ_100_KHZ; |
1705 | } | 1724 | } |
1706 | 1725 | ||
1726 | /* FIXME: Should be replaced by a proper mt9m001 driver */ | ||
1727 | static int em28xx_initialize_mt9m001(struct em28xx *dev) | ||
1728 | { | ||
1729 | int i; | ||
1730 | unsigned char regs[][3] = { | ||
1731 | { 0x0d, 0x00, 0x01, }, | ||
1732 | { 0x0d, 0x00, 0x00, }, | ||
1733 | { 0x04, 0x05, 0x00, }, /* hres = 1280 */ | ||
1734 | { 0x03, 0x04, 0x00, }, /* vres = 1024 */ | ||
1735 | { 0x20, 0x11, 0x00, }, | ||
1736 | { 0x06, 0x00, 0x10, }, | ||
1737 | { 0x2b, 0x00, 0x24, }, | ||
1738 | { 0x2e, 0x00, 0x24, }, | ||
1739 | { 0x35, 0x00, 0x24, }, | ||
1740 | { 0x2d, 0x00, 0x20, }, | ||
1741 | { 0x2c, 0x00, 0x20, }, | ||
1742 | { 0x09, 0x0a, 0xd4, }, | ||
1743 | { 0x35, 0x00, 0x57, }, | ||
1744 | }; | ||
1745 | |||
1746 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
1747 | i2c_master_send(&dev->i2c_client, ®s[i][0], 3); | ||
1748 | |||
1749 | return 0; | ||
1750 | } | ||
1751 | |||
1707 | /* HINT method: webcam I2C chips | 1752 | /* HINT method: webcam I2C chips |
1708 | * | 1753 | * |
1709 | * This method work for webcams with Micron sensors | 1754 | * This method work for webcams with Micron sensors |
@@ -1716,9 +1761,6 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
1716 | __be16 version_be; | 1761 | __be16 version_be; |
1717 | u16 version; | 1762 | u16 version; |
1718 | 1763 | ||
1719 | if (dev->model != EM2820_BOARD_UNKNOWN) | ||
1720 | return 0; | ||
1721 | |||
1722 | dev->i2c_client.addr = 0xba >> 1; | 1764 | dev->i2c_client.addr = 0xba >> 1; |
1723 | cmd = 0; | 1765 | cmd = 0; |
1724 | i2c_master_send(&dev->i2c_client, &cmd, 1); | 1766 | i2c_master_send(&dev->i2c_client, &cmd, 1); |
@@ -1729,16 +1771,38 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
1729 | version = be16_to_cpu(version_be); | 1771 | version = be16_to_cpu(version_be); |
1730 | 1772 | ||
1731 | switch (version) { | 1773 | switch (version) { |
1732 | case MT9V011_VERSION: | 1774 | case 0x8243: /* mt9v011 640x480 1.3 Mpix sensor */ |
1733 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; | 1775 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; |
1734 | sensor_name = "mt9v011"; | 1776 | sensor_name = "mt9v011"; |
1777 | dev->em28xx_sensor = EM28XX_MT9V011; | ||
1778 | dev->sensor_xres = 640; | ||
1779 | dev->sensor_yres = 480; | ||
1780 | dev->sensor_xtal = 6300000; | ||
1781 | |||
1782 | /* probably means GRGB 16 bit bayer */ | ||
1783 | dev->vinmode = 0x0d; | ||
1784 | dev->vinctl = 0x00; | ||
1785 | |||
1786 | break; | ||
1787 | case 0x8431: | ||
1788 | dev->model = EM2750_BOARD_UNKNOWN; | ||
1789 | sensor_name = "mt9m001"; | ||
1790 | dev->em28xx_sensor = EM28XX_MT9M001; | ||
1791 | em28xx_initialize_mt9m001(dev); | ||
1792 | dev->sensor_xres = 1280; | ||
1793 | dev->sensor_yres = 1024; | ||
1794 | |||
1795 | /* probably means BGGR 16 bit bayer */ | ||
1796 | dev->vinmode = 0x0c; | ||
1797 | dev->vinctl = 0x00; | ||
1798 | |||
1735 | break; | 1799 | break; |
1736 | default: | 1800 | default: |
1737 | printk("Unknown Sensor 0x%04x\n", be16_to_cpu(version)); | 1801 | printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version)); |
1738 | return -EINVAL; | 1802 | return -EINVAL; |
1739 | } | 1803 | } |
1740 | 1804 | ||
1741 | em28xx_errdev("Sensor is %s, assuming that webcam is %s\n", | 1805 | em28xx_errdev("Sensor is %s, using model %s entry.\n", |
1742 | sensor_name, em28xx_boards[dev->model].name); | 1806 | sensor_name, em28xx_boards[dev->model].name); |
1743 | 1807 | ||
1744 | return 0; | 1808 | return 0; |
@@ -1772,10 +1836,7 @@ void em28xx_pre_card_setup(struct em28xx *dev) | |||
1772 | em28xx_info("chip ID is em2750\n"); | 1836 | em28xx_info("chip ID is em2750\n"); |
1773 | break; | 1837 | break; |
1774 | case CHIP_ID_EM2820: | 1838 | case CHIP_ID_EM2820: |
1775 | if (dev->board.is_27xx) | 1839 | em28xx_info("chip ID is em2710 or em2820\n"); |
1776 | em28xx_info("chip is em2710\n"); | ||
1777 | else | ||
1778 | em28xx_info("chip ID is em2820\n"); | ||
1779 | break; | 1840 | break; |
1780 | case CHIP_ID_EM2840: | 1841 | case CHIP_ID_EM2840: |
1781 | em28xx_info("chip ID is em2840\n"); | 1842 | em28xx_info("chip ID is em2840\n"); |
@@ -1929,6 +1990,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | |||
1929 | ctl->demod = XC3028_FE_ZARLINK456; | 1990 | ctl->demod = XC3028_FE_ZARLINK456; |
1930 | break; | 1991 | break; |
1931 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 1992 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
1993 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
1932 | ctl->demod = XC3028_FE_ZARLINK456; | 1994 | ctl->demod = XC3028_FE_ZARLINK456; |
1933 | break; | 1995 | break; |
1934 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | 1996 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: |
@@ -2225,6 +2287,7 @@ void em28xx_card_setup(struct em28xx *dev) | |||
2225 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, | 2287 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, |
2226 | so make the call now so the analog GPIOs are set properly | 2288 | so make the call now so the analog GPIOs are set properly |
2227 | before probing the i2c bus. */ | 2289 | before probing the i2c bus. */ |
2290 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
2228 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | 2291 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); |
2229 | break; | 2292 | break; |
2230 | case EM2820_BOARD_SILVERCREST_WEBCAM: | 2293 | case EM2820_BOARD_SILVERCREST_WEBCAM: |
@@ -2262,9 +2325,14 @@ void em28xx_card_setup(struct em28xx *dev) | |||
2262 | v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2325 | v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
2263 | "tvp5150", "tvp5150", tvp5150_addrs); | 2326 | "tvp5150", "tvp5150", tvp5150_addrs); |
2264 | 2327 | ||
2265 | if (dev->board.decoder == EM28XX_MT9V011) | 2328 | if (dev->em28xx_sensor == EM28XX_MT9V011) { |
2266 | v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2329 | struct v4l2_subdev *sd; |
2267 | "mt9v011", "mt9v011", mt9v011_addrs); | 2330 | |
2331 | sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, | ||
2332 | &dev->i2c_adap, "mt9v011", "mt9v011", mt9v011_addrs); | ||
2333 | v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); | ||
2334 | } | ||
2335 | |||
2268 | 2336 | ||
2269 | if (dev->board.adecoder == EM28XX_TVAUDIO) | 2337 | if (dev->board.adecoder == EM28XX_TVAUDIO) |
2270 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2338 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
@@ -2410,7 +2478,19 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2410 | return errCode; | 2478 | return errCode; |
2411 | } | 2479 | } |
2412 | 2480 | ||
2413 | em28xx_hint_sensor(dev); | 2481 | /* |
2482 | * Default format, used for tvp5150 or saa711x output formats | ||
2483 | */ | ||
2484 | dev->vinmode = 0x10; | ||
2485 | dev->vinctl = 0x11; | ||
2486 | |||
2487 | /* | ||
2488 | * If the device can be a webcam, seek for a sensor. | ||
2489 | * If sensor is not found, then it isn't a webcam. | ||
2490 | */ | ||
2491 | if (dev->board.is_webcam) | ||
2492 | if (em28xx_hint_sensor(dev) < 0) | ||
2493 | dev->board.is_webcam = 0; | ||
2414 | 2494 | ||
2415 | /* Do board specific init and eeprom reading */ | 2495 | /* Do board specific init and eeprom reading */ |
2416 | em28xx_card_setup(dev); | 2496 | em28xx_card_setup(dev); |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 079ab4d563a6..5b78e199abd1 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -648,28 +648,17 @@ int em28xx_capture_start(struct em28xx *dev, int start) | |||
648 | int em28xx_set_outfmt(struct em28xx *dev) | 648 | int em28xx_set_outfmt(struct em28xx *dev) |
649 | { | 649 | { |
650 | int ret; | 650 | int ret; |
651 | int vinmode, vinctl, outfmt; | ||
652 | |||
653 | outfmt = dev->format->reg; | ||
654 | |||
655 | if (dev->board.is_27xx) { | ||
656 | vinmode = 0x0d; | ||
657 | vinctl = 0x00; | ||
658 | } else { | ||
659 | vinmode = 0x10; | ||
660 | vinctl = 0x11; | ||
661 | } | ||
662 | 651 | ||
663 | ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, | 652 | ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, |
664 | outfmt | 0x20, 0xff); | 653 | dev->format->reg | 0x20, 0xff); |
665 | if (ret < 0) | 654 | if (ret < 0) |
666 | return ret; | 655 | return ret; |
667 | 656 | ||
668 | ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, vinmode); | 657 | ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode); |
669 | if (ret < 0) | 658 | if (ret < 0) |
670 | return ret; | 659 | return ret; |
671 | 660 | ||
672 | return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctl); | 661 | return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, dev->vinctl); |
673 | } | 662 | } |
674 | 663 | ||
675 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, | 664 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, |
@@ -707,10 +696,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | |||
707 | u8 mode; | 696 | u8 mode; |
708 | /* the em2800 scaler only supports scaling down to 50% */ | 697 | /* the em2800 scaler only supports scaling down to 50% */ |
709 | 698 | ||
710 | if (dev->board.is_27xx) { | 699 | if (dev->board.is_em2800) { |
711 | /* FIXME: Don't use the scaler yet */ | ||
712 | mode = 0; | ||
713 | } else if (dev->board.is_em2800) { | ||
714 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); | 700 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); |
715 | } else { | 701 | } else { |
716 | u8 buf[2]; | 702 | u8 buf[2]; |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 3da97c32b8fa..cf0ac7f2a30d 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "lgdt330x.h" | 31 | #include "lgdt330x.h" |
32 | #include "zl10353.h" | 32 | #include "zl10353.h" |
33 | #include "s5h1409.h" | 33 | #include "s5h1409.h" |
34 | #include "mt352.h" | ||
35 | #include "mt352_priv.h" /* FIXME */ | ||
34 | 36 | ||
35 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); | 37 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); |
36 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 38 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); |
@@ -243,7 +245,7 @@ static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { | |||
243 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | 245 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK |
244 | }; | 246 | }; |
245 | 247 | ||
246 | static struct zl10353_config em28xx_terratec_xs_zl10353_xc3028 = { | 248 | static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = { |
247 | .demod_address = (0x1e >> 1), | 249 | .demod_address = (0x1e >> 1), |
248 | .no_tuner = 1, | 250 | .no_tuner = 1, |
249 | .disable_i2c_gate_ctrl = 1, | 251 | .disable_i2c_gate_ctrl = 1, |
@@ -258,6 +260,41 @@ static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { | |||
258 | }; | 260 | }; |
259 | #endif | 261 | #endif |
260 | 262 | ||
263 | static int mt352_terratec_xs_init(struct dvb_frontend *fe) | ||
264 | { | ||
265 | /* Values extracted from a USB trace of the Terratec Windows driver */ | ||
266 | static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x2c }; | ||
267 | static u8 reset[] = { RESET, 0x80 }; | ||
268 | static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; | ||
269 | static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0xa0 }; | ||
270 | static u8 input_freq_cfg[] = { INPUT_FREQ_1, 0x31, 0xb8 }; | ||
271 | static u8 rs_err_cfg[] = { RS_ERR_PER_1, 0x00, 0x4d }; | ||
272 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | ||
273 | static u8 trl_nom_cfg[] = { TRL_NOMINAL_RATE_1, 0x64, 0x00 }; | ||
274 | static u8 tps_given_cfg[] = { TPS_GIVEN_1, 0x40, 0x80, 0x50 }; | ||
275 | static u8 tuner_go[] = { TUNER_GO, 0x01}; | ||
276 | |||
277 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
278 | udelay(200); | ||
279 | mt352_write(fe, reset, sizeof(reset)); | ||
280 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
281 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
282 | mt352_write(fe, input_freq_cfg, sizeof(input_freq_cfg)); | ||
283 | mt352_write(fe, rs_err_cfg, sizeof(rs_err_cfg)); | ||
284 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
285 | mt352_write(fe, trl_nom_cfg, sizeof(trl_nom_cfg)); | ||
286 | mt352_write(fe, tps_given_cfg, sizeof(tps_given_cfg)); | ||
287 | mt352_write(fe, tuner_go, sizeof(tuner_go)); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static struct mt352_config terratec_xs_mt352_cfg = { | ||
292 | .demod_address = (0x1e >> 1), | ||
293 | .no_tuner = 1, | ||
294 | .if2 = 45600, | ||
295 | .demod_init = mt352_terratec_xs_init, | ||
296 | }; | ||
297 | |||
261 | /* ------------------------------------------------------------------ */ | 298 | /* ------------------------------------------------------------------ */ |
262 | 299 | ||
263 | static int attach_xc3028(u8 addr, struct em28xx *dev) | 300 | static int attach_xc3028(u8 addr, struct em28xx *dev) |
@@ -440,7 +477,6 @@ static int dvb_init(struct em28xx *dev) | |||
440 | goto out_free; | 477 | goto out_free; |
441 | } | 478 | } |
442 | break; | 479 | break; |
443 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
444 | case EM2880_BOARD_KWORLD_DVB_310U: | 480 | case EM2880_BOARD_KWORLD_DVB_310U: |
445 | case EM2880_BOARD_EMPIRE_DUAL_TV: | 481 | case EM2880_BOARD_EMPIRE_DUAL_TV: |
446 | dvb->frontend = dvb_attach(zl10353_attach, | 482 | dvb->frontend = dvb_attach(zl10353_attach, |
@@ -451,20 +487,28 @@ static int dvb_init(struct em28xx *dev) | |||
451 | goto out_free; | 487 | goto out_free; |
452 | } | 488 | } |
453 | break; | 489 | break; |
490 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
491 | dvb->frontend = dvb_attach(zl10353_attach, | ||
492 | &em28xx_zl10353_xc3028_no_i2c_gate, | ||
493 | &dev->i2c_adap); | ||
494 | if (attach_xc3028(0x61, dev) < 0) { | ||
495 | result = -EINVAL; | ||
496 | goto out_free; | ||
497 | } | ||
498 | break; | ||
454 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 499 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
500 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
455 | dvb->frontend = dvb_attach(zl10353_attach, | 501 | dvb->frontend = dvb_attach(zl10353_attach, |
456 | &em28xx_terratec_xs_zl10353_xc3028, | 502 | &em28xx_zl10353_xc3028_no_i2c_gate, |
457 | &dev->i2c_adap); | 503 | &dev->i2c_adap); |
458 | if (dvb->frontend == NULL) { | 504 | if (dvb->frontend == NULL) { |
459 | /* This board could have either a zl10353 or a mt352. | 505 | /* This board could have either a zl10353 or a mt352. |
460 | If the chip id isn't for zl10353, try mt352 */ | 506 | If the chip id isn't for zl10353, try mt352 */ |
461 | 507 | dvb->frontend = dvb_attach(mt352_attach, | |
462 | /* FIXME: make support for mt352 work */ | 508 | &terratec_xs_mt352_cfg, |
463 | printk(KERN_ERR "version of this board with mt352 not " | 509 | &dev->i2c_adap); |
464 | "currently supported\n"); | ||
465 | result = -EINVAL; | ||
466 | goto out_free; | ||
467 | } | 510 | } |
511 | |||
468 | if (attach_xc3028(0x61, dev) < 0) { | 512 | if (attach_xc3028(0x61, dev) < 0) { |
469 | result = -EINVAL; | 513 | result = -EINVAL; |
470 | goto out_free; | 514 | goto out_free; |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 14316c912179..ff37b4c15f44 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -657,8 +657,8 @@ static void get_scale(struct em28xx *dev, | |||
657 | unsigned int width, unsigned int height, | 657 | unsigned int width, unsigned int height, |
658 | unsigned int *hscale, unsigned int *vscale) | 658 | unsigned int *hscale, unsigned int *vscale) |
659 | { | 659 | { |
660 | unsigned int maxw = norm_maxw(dev); | 660 | unsigned int maxw = norm_maxw(dev); |
661 | unsigned int maxh = norm_maxh(dev); | 661 | unsigned int maxh = norm_maxh(dev); |
662 | 662 | ||
663 | *hscale = (((unsigned long)maxw) << 12) / width - 4096L; | 663 | *hscale = (((unsigned long)maxw) << 12) / width - 4096L; |
664 | if (*hscale >= 0x4000) | 664 | if (*hscale >= 0x4000) |
@@ -726,11 +726,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
726 | return -EINVAL; | 726 | return -EINVAL; |
727 | } | 727 | } |
728 | 728 | ||
729 | if (dev->board.is_27xx) { | 729 | if (dev->board.is_em2800) { |
730 | /* FIXME: This is the only supported fmt */ | ||
731 | width = 640; | ||
732 | height = 480; | ||
733 | } else if (dev->board.is_em2800) { | ||
734 | /* the em2800 can only scale down to 50% */ | 730 | /* the em2800 can only scale down to 50% */ |
735 | height = height > (3 * maxh / 4) ? maxh : maxh / 2; | 731 | height = height > (3 * maxh / 4) ? maxh : maxh / 2; |
736 | width = width > (3 * maxw / 4) ? maxw : maxw / 2; | 732 | width = width > (3 * maxw / 4) ? maxw : maxw / 2; |
@@ -767,12 +763,6 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, | |||
767 | { | 763 | { |
768 | struct em28xx_fmt *fmt; | 764 | struct em28xx_fmt *fmt; |
769 | 765 | ||
770 | /* FIXME: This is the only supported fmt */ | ||
771 | if (dev->board.is_27xx) { | ||
772 | width = 640; | ||
773 | height = 480; | ||
774 | } | ||
775 | |||
776 | fmt = format_by_fourcc(fourcc); | 766 | fmt = format_by_fourcc(fourcc); |
777 | if (!fmt) | 767 | if (!fmt) |
778 | return -EINVAL; | 768 | return -EINVAL; |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index d90fef463764..45bd513f62dc 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -358,10 +358,15 @@ struct em28xx_input { | |||
358 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) | 358 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) |
359 | 359 | ||
360 | enum em28xx_decoder { | 360 | enum em28xx_decoder { |
361 | EM28XX_NODECODER, | 361 | EM28XX_NODECODER = 0, |
362 | EM28XX_TVP5150, | 362 | EM28XX_TVP5150, |
363 | EM28XX_SAA711X, | 363 | EM28XX_SAA711X, |
364 | }; | ||
365 | |||
366 | enum em28xx_sensor { | ||
367 | EM28XX_NOSENSOR = 0, | ||
364 | EM28XX_MT9V011, | 368 | EM28XX_MT9V011, |
369 | EM28XX_MT9M001, | ||
365 | }; | 370 | }; |
366 | 371 | ||
367 | enum em28xx_adecoder { | 372 | enum em28xx_adecoder { |
@@ -390,7 +395,7 @@ struct em28xx_board { | |||
390 | unsigned int max_range_640_480:1; | 395 | unsigned int max_range_640_480:1; |
391 | unsigned int has_dvb:1; | 396 | unsigned int has_dvb:1; |
392 | unsigned int has_snapshot_button:1; | 397 | unsigned int has_snapshot_button:1; |
393 | unsigned int is_27xx:1; | 398 | unsigned int is_webcam:1; |
394 | unsigned int valid:1; | 399 | unsigned int valid:1; |
395 | 400 | ||
396 | unsigned char xclk, i2c_speed; | 401 | unsigned char xclk, i2c_speed; |
@@ -474,6 +479,14 @@ struct em28xx { | |||
474 | struct v4l2_device v4l2_dev; | 479 | struct v4l2_device v4l2_dev; |
475 | struct em28xx_board board; | 480 | struct em28xx_board board; |
476 | 481 | ||
482 | /* Webcam specific fields */ | ||
483 | enum em28xx_sensor em28xx_sensor; | ||
484 | int sensor_xres, sensor_yres; | ||
485 | int sensor_xtal; | ||
486 | |||
487 | /* Vinmode/Vinctl used at the driver */ | ||
488 | int vinmode, vinctl; | ||
489 | |||
477 | unsigned int stream_on:1; /* Locks streams */ | 490 | unsigned int stream_on:1; /* Locks streams */ |
478 | unsigned int has_audio_class:1; | 491 | unsigned int has_audio_class:1; |
479 | unsigned int has_alsa_audio:1; | 492 | unsigned int has_alsa_audio:1; |
@@ -754,17 +767,23 @@ static inline int em28xx_gamma_set(struct em28xx *dev, s32 val) | |||
754 | /*FIXME: maxw should be dependent of alt mode */ | 767 | /*FIXME: maxw should be dependent of alt mode */ |
755 | static inline unsigned int norm_maxw(struct em28xx *dev) | 768 | static inline unsigned int norm_maxw(struct em28xx *dev) |
756 | { | 769 | { |
770 | if (dev->board.is_webcam) | ||
771 | return dev->sensor_xres; | ||
772 | |||
757 | if (dev->board.max_range_640_480) | 773 | if (dev->board.max_range_640_480) |
758 | return 640; | 774 | return 640; |
759 | else | 775 | |
760 | return 720; | 776 | return 720; |
761 | } | 777 | } |
762 | 778 | ||
763 | static inline unsigned int norm_maxh(struct em28xx *dev) | 779 | static inline unsigned int norm_maxh(struct em28xx *dev) |
764 | { | 780 | { |
781 | if (dev->board.is_webcam) | ||
782 | return dev->sensor_yres; | ||
783 | |||
765 | if (dev->board.max_range_640_480) | 784 | if (dev->board.max_range_640_480) |
766 | return 480; | 785 | return 480; |
767 | else | 786 | |
768 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; | 787 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; |
769 | } | 788 | } |
770 | #endif | 789 | #endif |
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index 578dc4ffc965..34f46f2bc040 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig | |||
@@ -102,6 +102,22 @@ config USB_GSPCA_PAC7311 | |||
102 | To compile this driver as a module, choose M here: the | 102 | To compile this driver as a module, choose M here: the |
103 | module will be called gspca_pac7311. | 103 | module will be called gspca_pac7311. |
104 | 104 | ||
105 | config USB_GSPCA_SN9C20X | ||
106 | tristate "SN9C20X USB Camera Driver" | ||
107 | depends on VIDEO_V4L2 && USB_GSPCA | ||
108 | help | ||
109 | Say Y here if you want support for cameras based on the | ||
110 | sn9c20x chips (SN9C201 and SN9C202). | ||
111 | |||
112 | To compile this driver as a module, choose M here: the | ||
113 | module will be called gspca_sn9c20x. | ||
114 | |||
115 | config USB_GSPCA_SN9C20X_EVDEV | ||
116 | bool "Enable evdev support" | ||
117 | depends on USB_GSPCA_SN9C20X | ||
118 | ---help--- | ||
119 | Say Y here in order to enable evdev support for sn9c20x webcam button. | ||
120 | |||
105 | config USB_GSPCA_SONIXB | 121 | config USB_GSPCA_SONIXB |
106 | tristate "SONIX Bayer USB Camera Driver" | 122 | tristate "SONIX Bayer USB Camera Driver" |
107 | depends on VIDEO_V4L2 && USB_GSPCA | 123 | depends on VIDEO_V4L2 && USB_GSPCA |
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index 8a6643e8eb96..f6d3b86e9ad5 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o | |||
8 | obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o | 8 | obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o |
9 | obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o | 9 | obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o |
10 | obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o | 10 | obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o |
11 | obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o | ||
11 | obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o | 12 | obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o |
12 | obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o | 13 | obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o |
13 | obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o | 14 | obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o |
@@ -35,6 +36,7 @@ gspca_ov519-objs := ov519.o | |||
35 | gspca_ov534-objs := ov534.o | 36 | gspca_ov534-objs := ov534.o |
36 | gspca_pac207-objs := pac207.o | 37 | gspca_pac207-objs := pac207.o |
37 | gspca_pac7311-objs := pac7311.o | 38 | gspca_pac7311-objs := pac7311.o |
39 | gspca_sn9c20x-objs := sn9c20x.o | ||
38 | gspca_sonixb-objs := sonixb.o | 40 | gspca_sonixb-objs := sonixb.o |
39 | gspca_sonixj-objs := sonixj.o | 41 | gspca_sonixj-objs := sonixj.o |
40 | gspca_spca500-objs := spca500.o | 42 | gspca_spca500-objs := spca500.o |
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 219cfa6fb877..8d48ea1742c2 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c | |||
@@ -846,6 +846,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
846 | 846 | ||
847 | /* create the JPEG header */ | 847 | /* create the JPEG header */ |
848 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 848 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
849 | if (!sd->jpeg_hdr) | ||
850 | return -ENOMEM; | ||
849 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 851 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
850 | 0x22); /* JPEG 411 */ | 852 | 0x22); /* JPEG 411 */ |
851 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 853 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 1e89600986c8..b8561dfb6c8c 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -727,6 +727,74 @@ static int gspca_get_mode(struct gspca_dev *gspca_dev, | |||
727 | return -EINVAL; | 727 | return -EINVAL; |
728 | } | 728 | } |
729 | 729 | ||
730 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
731 | static int vidioc_g_register(struct file *file, void *priv, | ||
732 | struct v4l2_dbg_register *reg) | ||
733 | { | ||
734 | int ret; | ||
735 | struct gspca_dev *gspca_dev = priv; | ||
736 | |||
737 | if (!gspca_dev->sd_desc->get_chip_ident) | ||
738 | return -EINVAL; | ||
739 | |||
740 | if (!gspca_dev->sd_desc->get_register) | ||
741 | return -EINVAL; | ||
742 | |||
743 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | ||
744 | return -ERESTARTSYS; | ||
745 | if (gspca_dev->present) | ||
746 | ret = gspca_dev->sd_desc->get_register(gspca_dev, reg); | ||
747 | else | ||
748 | ret = -ENODEV; | ||
749 | mutex_unlock(&gspca_dev->usb_lock); | ||
750 | |||
751 | return ret; | ||
752 | } | ||
753 | |||
754 | static int vidioc_s_register(struct file *file, void *priv, | ||
755 | struct v4l2_dbg_register *reg) | ||
756 | { | ||
757 | int ret; | ||
758 | struct gspca_dev *gspca_dev = priv; | ||
759 | |||
760 | if (!gspca_dev->sd_desc->get_chip_ident) | ||
761 | return -EINVAL; | ||
762 | |||
763 | if (!gspca_dev->sd_desc->set_register) | ||
764 | return -EINVAL; | ||
765 | |||
766 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | ||
767 | return -ERESTARTSYS; | ||
768 | if (gspca_dev->present) | ||
769 | ret = gspca_dev->sd_desc->set_register(gspca_dev, reg); | ||
770 | else | ||
771 | ret = -ENODEV; | ||
772 | mutex_unlock(&gspca_dev->usb_lock); | ||
773 | |||
774 | return ret; | ||
775 | } | ||
776 | #endif | ||
777 | |||
778 | static int vidioc_g_chip_ident(struct file *file, void *priv, | ||
779 | struct v4l2_dbg_chip_ident *chip) | ||
780 | { | ||
781 | int ret; | ||
782 | struct gspca_dev *gspca_dev = priv; | ||
783 | |||
784 | if (!gspca_dev->sd_desc->get_chip_ident) | ||
785 | return -EINVAL; | ||
786 | |||
787 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | ||
788 | return -ERESTARTSYS; | ||
789 | if (gspca_dev->present) | ||
790 | ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); | ||
791 | else | ||
792 | ret = -ENODEV; | ||
793 | mutex_unlock(&gspca_dev->usb_lock); | ||
794 | |||
795 | return ret; | ||
796 | } | ||
797 | |||
730 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | 798 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
731 | struct v4l2_fmtdesc *fmtdesc) | 799 | struct v4l2_fmtdesc *fmtdesc) |
732 | { | 800 | { |
@@ -1883,6 +1951,11 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { | |||
1883 | .vidioc_s_parm = vidioc_s_parm, | 1951 | .vidioc_s_parm = vidioc_s_parm, |
1884 | .vidioc_s_std = vidioc_s_std, | 1952 | .vidioc_s_std = vidioc_s_std, |
1885 | .vidioc_enum_framesizes = vidioc_enum_framesizes, | 1953 | .vidioc_enum_framesizes = vidioc_enum_framesizes, |
1954 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1955 | .vidioc_g_register = vidioc_g_register, | ||
1956 | .vidioc_s_register = vidioc_s_register, | ||
1957 | #endif | ||
1958 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | ||
1886 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1959 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1887 | .vidiocgmbuf = vidiocgmbuf, | 1960 | .vidiocgmbuf = vidiocgmbuf, |
1888 | #endif | 1961 | #endif |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index bd1faff88644..46c4effdfcd5 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -69,6 +69,10 @@ typedef void (*cam_v_op) (struct gspca_dev *); | |||
69 | typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); | 69 | typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); |
70 | typedef int (*cam_jpg_op) (struct gspca_dev *, | 70 | typedef int (*cam_jpg_op) (struct gspca_dev *, |
71 | struct v4l2_jpegcompression *); | 71 | struct v4l2_jpegcompression *); |
72 | typedef int (*cam_reg_op) (struct gspca_dev *, | ||
73 | struct v4l2_dbg_register *); | ||
74 | typedef int (*cam_ident_op) (struct gspca_dev *, | ||
75 | struct v4l2_dbg_chip_ident *); | ||
72 | typedef int (*cam_streamparm_op) (struct gspca_dev *, | 76 | typedef int (*cam_streamparm_op) (struct gspca_dev *, |
73 | struct v4l2_streamparm *); | 77 | struct v4l2_streamparm *); |
74 | typedef int (*cam_qmnu_op) (struct gspca_dev *, | 78 | typedef int (*cam_qmnu_op) (struct gspca_dev *, |
@@ -105,6 +109,11 @@ struct sd_desc { | |||
105 | cam_qmnu_op querymenu; | 109 | cam_qmnu_op querymenu; |
106 | cam_streamparm_op get_streamparm; | 110 | cam_streamparm_op get_streamparm; |
107 | cam_streamparm_op set_streamparm; | 111 | cam_streamparm_op set_streamparm; |
112 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
113 | cam_reg_op set_register; | ||
114 | cam_reg_op get_register; | ||
115 | #endif | ||
116 | cam_ident_op get_chip_ident; | ||
108 | }; | 117 | }; |
109 | 118 | ||
110 | /* packet types when moving from iso buf to frame buf */ | 119 | /* packet types when moving from iso buf to frame buf */ |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 191bcd718979..0163903d1c0f 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
@@ -476,9 +476,6 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
476 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 476 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
477 | if (err < 0) | 477 | if (err < 0) |
478 | return err; | 478 | return err; |
479 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
480 | if (err < 0) | ||
481 | return err; | ||
482 | 479 | ||
483 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 480 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
484 | if (err < 0) | 481 | if (err < 0) |
@@ -524,9 +521,6 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
524 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 521 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
525 | if (err < 0) | 522 | if (err < 0) |
526 | return err; | 523 | return err; |
527 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
528 | if (err < 0) | ||
529 | return err; | ||
530 | 524 | ||
531 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 525 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
532 | if (err < 0) | 526 | if (err < 0) |
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 75e8d14e4ac7..de769caf013d 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c | |||
@@ -201,6 +201,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
201 | 201 | ||
202 | /* create the JPEG header */ | 202 | /* create the JPEG header */ |
203 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 203 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
204 | if (!sd->jpeg_hdr) | ||
205 | return -ENOMEM; | ||
204 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 206 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
205 | 0x21); /* JPEG 422 */ | 207 | 0x21); /* JPEG 422 */ |
206 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 208 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c new file mode 100644 index 000000000000..fcfbbd329b4c --- /dev/null +++ b/drivers/media/video/gspca/sn9c20x.c | |||
@@ -0,0 +1,2434 @@ | |||
1 | /* | ||
2 | * Sonix sn9c201 sn9c202 library | ||
3 | * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com> | ||
4 | * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | ||
22 | #include <linux/kthread.h> | ||
23 | #include <linux/freezer.h> | ||
24 | #include <linux/usb/input.h> | ||
25 | #include <linux/input.h> | ||
26 | #endif | ||
27 | |||
28 | #include "gspca.h" | ||
29 | #include "jpeg.h" | ||
30 | |||
31 | #include <media/v4l2-chip-ident.h> | ||
32 | |||
33 | MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, " | ||
34 | "microdia project <microdia@googlegroups.com>"); | ||
35 | MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); | ||
36 | MODULE_LICENSE("GPL"); | ||
37 | |||
38 | #define MODULE_NAME "sn9c20x" | ||
39 | |||
40 | #define MODE_RAW 0x10 | ||
41 | #define MODE_JPEG 0x20 | ||
42 | #define MODE_SXGA 0x80 | ||
43 | |||
44 | #define SENSOR_OV9650 0 | ||
45 | #define SENSOR_OV9655 1 | ||
46 | #define SENSOR_SOI968 2 | ||
47 | #define SENSOR_OV7660 3 | ||
48 | #define SENSOR_OV7670 4 | ||
49 | #define SENSOR_MT9V011 5 | ||
50 | #define SENSOR_MT9V111 6 | ||
51 | #define SENSOR_MT9V112 7 | ||
52 | #define SENSOR_MT9M001 8 | ||
53 | #define SENSOR_MT9M111 9 | ||
54 | #define SENSOR_HV7131R 10 | ||
55 | #define SENSOR_MT9VPRB 20 | ||
56 | |||
57 | /* specific webcam descriptor */ | ||
58 | struct sd { | ||
59 | struct gspca_dev gspca_dev; | ||
60 | |||
61 | #define MIN_AVG_LUM 80 | ||
62 | #define MAX_AVG_LUM 130 | ||
63 | atomic_t avg_lum; | ||
64 | u8 old_step; | ||
65 | u8 older_step; | ||
66 | u8 exposure_step; | ||
67 | |||
68 | u8 brightness; | ||
69 | u8 contrast; | ||
70 | u8 saturation; | ||
71 | s16 hue; | ||
72 | u8 gamma; | ||
73 | u8 red; | ||
74 | u8 blue; | ||
75 | |||
76 | u8 hflip; | ||
77 | u8 vflip; | ||
78 | u8 gain; | ||
79 | u16 exposure; | ||
80 | u8 auto_exposure; | ||
81 | |||
82 | u8 i2c_addr; | ||
83 | u8 sensor; | ||
84 | u8 hstart; | ||
85 | u8 vstart; | ||
86 | |||
87 | u8 *jpeg_hdr; | ||
88 | u8 quality; | ||
89 | |||
90 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | ||
91 | struct input_dev *input_dev; | ||
92 | u8 input_gpio; | ||
93 | struct task_struct *input_task; | ||
94 | #endif | ||
95 | }; | ||
96 | |||
97 | static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val); | ||
98 | static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val); | ||
99 | static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val); | ||
100 | static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val); | ||
101 | static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val); | ||
102 | static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val); | ||
103 | static int sd_sethue(struct gspca_dev *gspca_dev, s32 val); | ||
104 | static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val); | ||
105 | static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val); | ||
106 | static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val); | ||
107 | static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val); | ||
108 | static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val); | ||
109 | static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val); | ||
110 | static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val); | ||
111 | static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val); | ||
112 | static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val); | ||
113 | static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val); | ||
114 | static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val); | ||
115 | static int sd_setgain(struct gspca_dev *gspca_dev, s32 val); | ||
116 | static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val); | ||
117 | static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val); | ||
118 | static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val); | ||
119 | static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); | ||
120 | static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); | ||
121 | |||
122 | static struct ctrl sd_ctrls[] = { | ||
123 | { | ||
124 | #define BRIGHTNESS_IDX 0 | ||
125 | { | ||
126 | .id = V4L2_CID_BRIGHTNESS, | ||
127 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
128 | .name = "Brightness", | ||
129 | .minimum = 0, | ||
130 | .maximum = 0xff, | ||
131 | .step = 1, | ||
132 | #define BRIGHTNESS_DEFAULT 0x7f | ||
133 | .default_value = BRIGHTNESS_DEFAULT, | ||
134 | }, | ||
135 | .set = sd_setbrightness, | ||
136 | .get = sd_getbrightness, | ||
137 | }, | ||
138 | { | ||
139 | #define CONTRAST_IDX 1 | ||
140 | { | ||
141 | .id = V4L2_CID_CONTRAST, | ||
142 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
143 | .name = "Contrast", | ||
144 | .minimum = 0, | ||
145 | .maximum = 0xff, | ||
146 | .step = 1, | ||
147 | #define CONTRAST_DEFAULT 0x7f | ||
148 | .default_value = CONTRAST_DEFAULT, | ||
149 | }, | ||
150 | .set = sd_setcontrast, | ||
151 | .get = sd_getcontrast, | ||
152 | }, | ||
153 | { | ||
154 | #define SATURATION_IDX 2 | ||
155 | { | ||
156 | .id = V4L2_CID_SATURATION, | ||
157 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
158 | .name = "Saturation", | ||
159 | .minimum = 0, | ||
160 | .maximum = 0xff, | ||
161 | .step = 1, | ||
162 | #define SATURATION_DEFAULT 0x7f | ||
163 | .default_value = SATURATION_DEFAULT, | ||
164 | }, | ||
165 | .set = sd_setsaturation, | ||
166 | .get = sd_getsaturation, | ||
167 | }, | ||
168 | { | ||
169 | #define HUE_IDX 3 | ||
170 | { | ||
171 | .id = V4L2_CID_HUE, | ||
172 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
173 | .name = "Hue", | ||
174 | .minimum = -180, | ||
175 | .maximum = 180, | ||
176 | .step = 1, | ||
177 | #define HUE_DEFAULT 0 | ||
178 | .default_value = HUE_DEFAULT, | ||
179 | }, | ||
180 | .set = sd_sethue, | ||
181 | .get = sd_gethue, | ||
182 | }, | ||
183 | { | ||
184 | #define GAMMA_IDX 4 | ||
185 | { | ||
186 | .id = V4L2_CID_GAMMA, | ||
187 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
188 | .name = "Gamma", | ||
189 | .minimum = 0, | ||
190 | .maximum = 0xff, | ||
191 | .step = 1, | ||
192 | #define GAMMA_DEFAULT 0x10 | ||
193 | .default_value = GAMMA_DEFAULT, | ||
194 | }, | ||
195 | .set = sd_setgamma, | ||
196 | .get = sd_getgamma, | ||
197 | }, | ||
198 | { | ||
199 | #define BLUE_IDX 5 | ||
200 | { | ||
201 | .id = V4L2_CID_BLUE_BALANCE, | ||
202 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
203 | .name = "Blue Balance", | ||
204 | .minimum = 0, | ||
205 | .maximum = 0x7f, | ||
206 | .step = 1, | ||
207 | #define BLUE_DEFAULT 0x28 | ||
208 | .default_value = BLUE_DEFAULT, | ||
209 | }, | ||
210 | .set = sd_setbluebalance, | ||
211 | .get = sd_getbluebalance, | ||
212 | }, | ||
213 | { | ||
214 | #define RED_IDX 6 | ||
215 | { | ||
216 | .id = V4L2_CID_RED_BALANCE, | ||
217 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
218 | .name = "Red Balance", | ||
219 | .minimum = 0, | ||
220 | .maximum = 0x7f, | ||
221 | .step = 1, | ||
222 | #define RED_DEFAULT 0x28 | ||
223 | .default_value = RED_DEFAULT, | ||
224 | }, | ||
225 | .set = sd_setredbalance, | ||
226 | .get = sd_getredbalance, | ||
227 | }, | ||
228 | { | ||
229 | #define HFLIP_IDX 7 | ||
230 | { | ||
231 | .id = V4L2_CID_HFLIP, | ||
232 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
233 | .name = "Horizontal Flip", | ||
234 | .minimum = 0, | ||
235 | .maximum = 1, | ||
236 | .step = 1, | ||
237 | #define HFLIP_DEFAULT 0 | ||
238 | .default_value = HFLIP_DEFAULT, | ||
239 | }, | ||
240 | .set = sd_sethflip, | ||
241 | .get = sd_gethflip, | ||
242 | }, | ||
243 | { | ||
244 | #define VFLIP_IDX 8 | ||
245 | { | ||
246 | .id = V4L2_CID_VFLIP, | ||
247 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
248 | .name = "Vertical Flip", | ||
249 | .minimum = 0, | ||
250 | .maximum = 1, | ||
251 | .step = 1, | ||
252 | #define VFLIP_DEFAULT 0 | ||
253 | .default_value = VFLIP_DEFAULT, | ||
254 | }, | ||
255 | .set = sd_setvflip, | ||
256 | .get = sd_getvflip, | ||
257 | }, | ||
258 | { | ||
259 | #define EXPOSURE_IDX 9 | ||
260 | { | ||
261 | .id = V4L2_CID_EXPOSURE, | ||
262 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
263 | .name = "Exposure", | ||
264 | .minimum = 0, | ||
265 | .maximum = 0x1780, | ||
266 | .step = 1, | ||
267 | #define EXPOSURE_DEFAULT 0x33 | ||
268 | .default_value = EXPOSURE_DEFAULT, | ||
269 | }, | ||
270 | .set = sd_setexposure, | ||
271 | .get = sd_getexposure, | ||
272 | }, | ||
273 | { | ||
274 | #define GAIN_IDX 10 | ||
275 | { | ||
276 | .id = V4L2_CID_GAIN, | ||
277 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
278 | .name = "Gain", | ||
279 | .minimum = 0, | ||
280 | .maximum = 28, | ||
281 | .step = 1, | ||
282 | #define GAIN_DEFAULT 0x00 | ||
283 | .default_value = GAIN_DEFAULT, | ||
284 | }, | ||
285 | .set = sd_setgain, | ||
286 | .get = sd_getgain, | ||
287 | }, | ||
288 | { | ||
289 | #define AUTOGAIN_IDX 11 | ||
290 | { | ||
291 | .id = V4L2_CID_AUTOGAIN, | ||
292 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
293 | .name = "Auto Exposure", | ||
294 | .minimum = 0, | ||
295 | .maximum = 1, | ||
296 | .step = 1, | ||
297 | #define AUTO_EXPOSURE_DEFAULT 1 | ||
298 | .default_value = AUTO_EXPOSURE_DEFAULT, | ||
299 | }, | ||
300 | .set = sd_setautoexposure, | ||
301 | .get = sd_getautoexposure, | ||
302 | }, | ||
303 | }; | ||
304 | |||
305 | static const struct v4l2_pix_format vga_mode[] = { | ||
306 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
307 | .bytesperline = 240, | ||
308 | .sizeimage = 240 * 120, | ||
309 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
310 | .priv = 0 | MODE_JPEG}, | ||
311 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
312 | .bytesperline = 160, | ||
313 | .sizeimage = 160 * 120, | ||
314 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
315 | .priv = 0 | MODE_RAW}, | ||
316 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | ||
317 | .bytesperline = 240, | ||
318 | .sizeimage = 240 * 120, | ||
319 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
320 | .priv = 0}, | ||
321 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
322 | .bytesperline = 480, | ||
323 | .sizeimage = 480 * 240 , | ||
324 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
325 | .priv = 1 | MODE_JPEG}, | ||
326 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
327 | .bytesperline = 320, | ||
328 | .sizeimage = 320 * 240 , | ||
329 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
330 | .priv = 1 | MODE_RAW}, | ||
331 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | ||
332 | .bytesperline = 480, | ||
333 | .sizeimage = 480 * 240 , | ||
334 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
335 | .priv = 1}, | ||
336 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
337 | .bytesperline = 960, | ||
338 | .sizeimage = 960 * 480, | ||
339 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
340 | .priv = 2 | MODE_JPEG}, | ||
341 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
342 | .bytesperline = 640, | ||
343 | .sizeimage = 640 * 480, | ||
344 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
345 | .priv = 2 | MODE_RAW}, | ||
346 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | ||
347 | .bytesperline = 960, | ||
348 | .sizeimage = 960 * 480, | ||
349 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
350 | .priv = 2}, | ||
351 | }; | ||
352 | |||
353 | static const struct v4l2_pix_format sxga_mode[] = { | ||
354 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
355 | .bytesperline = 240, | ||
356 | .sizeimage = 240 * 120, | ||
357 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
358 | .priv = 0 | MODE_JPEG}, | ||
359 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
360 | .bytesperline = 160, | ||
361 | .sizeimage = 160 * 120, | ||
362 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
363 | .priv = 0 | MODE_RAW}, | ||
364 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | ||
365 | .bytesperline = 240, | ||
366 | .sizeimage = 240 * 120, | ||
367 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
368 | .priv = 0}, | ||
369 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
370 | .bytesperline = 480, | ||
371 | .sizeimage = 480 * 240 , | ||
372 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
373 | .priv = 1 | MODE_JPEG}, | ||
374 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
375 | .bytesperline = 320, | ||
376 | .sizeimage = 320 * 240 , | ||
377 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
378 | .priv = 1 | MODE_RAW}, | ||
379 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | ||
380 | .bytesperline = 480, | ||
381 | .sizeimage = 480 * 240 , | ||
382 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
383 | .priv = 1}, | ||
384 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
385 | .bytesperline = 960, | ||
386 | .sizeimage = 960 * 480, | ||
387 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
388 | .priv = 2 | MODE_JPEG}, | ||
389 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
390 | .bytesperline = 640, | ||
391 | .sizeimage = 640 * 480, | ||
392 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
393 | .priv = 2 | MODE_RAW}, | ||
394 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | ||
395 | .bytesperline = 960, | ||
396 | .sizeimage = 960 * 480, | ||
397 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
398 | .priv = 2}, | ||
399 | {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
400 | .bytesperline = 1280, | ||
401 | .sizeimage = (1280 * 1024) + 64, | ||
402 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
403 | .priv = 3 | MODE_RAW | MODE_SXGA}, | ||
404 | }; | ||
405 | |||
406 | static const int hsv_red_x[] = { | ||
407 | 41, 44, 46, 48, 50, 52, 54, 56, | ||
408 | 58, 60, 62, 64, 66, 68, 70, 72, | ||
409 | 74, 76, 78, 80, 81, 83, 85, 87, | ||
410 | 88, 90, 92, 93, 95, 97, 98, 100, | ||
411 | 101, 102, 104, 105, 107, 108, 109, 110, | ||
412 | 112, 113, 114, 115, 116, 117, 118, 119, | ||
413 | 120, 121, 122, 123, 123, 124, 125, 125, | ||
414 | 126, 127, 127, 128, 128, 129, 129, 129, | ||
415 | 130, 130, 130, 130, 131, 131, 131, 131, | ||
416 | 131, 131, 131, 131, 130, 130, 130, 130, | ||
417 | 129, 129, 129, 128, 128, 127, 127, 126, | ||
418 | 125, 125, 124, 123, 122, 122, 121, 120, | ||
419 | 119, 118, 117, 116, 115, 114, 112, 111, | ||
420 | 110, 109, 107, 106, 105, 103, 102, 101, | ||
421 | 99, 98, 96, 94, 93, 91, 90, 88, | ||
422 | 86, 84, 83, 81, 79, 77, 75, 74, | ||
423 | 72, 70, 68, 66, 64, 62, 60, 58, | ||
424 | 56, 54, 52, 49, 47, 45, 43, 41, | ||
425 | 39, 36, 34, 32, 30, 28, 25, 23, | ||
426 | 21, 19, 16, 14, 12, 9, 7, 5, | ||
427 | 3, 0, -1, -3, -6, -8, -10, -12, | ||
428 | -15, -17, -19, -22, -24, -26, -28, -30, | ||
429 | -33, -35, -37, -39, -41, -44, -46, -48, | ||
430 | -50, -52, -54, -56, -58, -60, -62, -64, | ||
431 | -66, -68, -70, -72, -74, -76, -78, -80, | ||
432 | -81, -83, -85, -87, -88, -90, -92, -93, | ||
433 | -95, -97, -98, -100, -101, -102, -104, -105, | ||
434 | -107, -108, -109, -110, -112, -113, -114, -115, | ||
435 | -116, -117, -118, -119, -120, -121, -122, -123, | ||
436 | -123, -124, -125, -125, -126, -127, -127, -128, | ||
437 | -128, -128, -128, -128, -128, -128, -128, -128, | ||
438 | -128, -128, -128, -128, -128, -128, -128, -128, | ||
439 | -128, -128, -128, -128, -128, -128, -128, -128, | ||
440 | -128, -127, -127, -126, -125, -125, -124, -123, | ||
441 | -122, -122, -121, -120, -119, -118, -117, -116, | ||
442 | -115, -114, -112, -111, -110, -109, -107, -106, | ||
443 | -105, -103, -102, -101, -99, -98, -96, -94, | ||
444 | -93, -91, -90, -88, -86, -84, -83, -81, | ||
445 | -79, -77, -75, -74, -72, -70, -68, -66, | ||
446 | -64, -62, -60, -58, -56, -54, -52, -49, | ||
447 | -47, -45, -43, -41, -39, -36, -34, -32, | ||
448 | -30, -28, -25, -23, -21, -19, -16, -14, | ||
449 | -12, -9, -7, -5, -3, 0, 1, 3, | ||
450 | 6, 8, 10, 12, 15, 17, 19, 22, | ||
451 | 24, 26, 28, 30, 33, 35, 37, 39, 41 | ||
452 | }; | ||
453 | |||
454 | static const int hsv_red_y[] = { | ||
455 | 82, 80, 78, 76, 74, 73, 71, 69, | ||
456 | 67, 65, 63, 61, 58, 56, 54, 52, | ||
457 | 50, 48, 46, 44, 41, 39, 37, 35, | ||
458 | 32, 30, 28, 26, 23, 21, 19, 16, | ||
459 | 14, 12, 10, 7, 5, 3, 0, -1, | ||
460 | -3, -6, -8, -10, -13, -15, -17, -19, | ||
461 | -22, -24, -26, -29, -31, -33, -35, -38, | ||
462 | -40, -42, -44, -46, -48, -51, -53, -55, | ||
463 | -57, -59, -61, -63, -65, -67, -69, -71, | ||
464 | -73, -75, -77, -79, -81, -82, -84, -86, | ||
465 | -88, -89, -91, -93, -94, -96, -98, -99, | ||
466 | -101, -102, -104, -105, -106, -108, -109, -110, | ||
467 | -112, -113, -114, -115, -116, -117, -119, -120, | ||
468 | -120, -121, -122, -123, -124, -125, -126, -126, | ||
469 | -127, -128, -128, -128, -128, -128, -128, -128, | ||
470 | -128, -128, -128, -128, -128, -128, -128, -128, | ||
471 | -128, -128, -128, -128, -128, -128, -128, -128, | ||
472 | -128, -128, -128, -128, -128, -128, -128, -128, | ||
473 | -127, -127, -126, -125, -125, -124, -123, -122, | ||
474 | -121, -120, -119, -118, -117, -116, -115, -114, | ||
475 | -113, -111, -110, -109, -107, -106, -105, -103, | ||
476 | -102, -100, -99, -97, -96, -94, -92, -91, | ||
477 | -89, -87, -85, -84, -82, -80, -78, -76, | ||
478 | -74, -73, -71, -69, -67, -65, -63, -61, | ||
479 | -58, -56, -54, -52, -50, -48, -46, -44, | ||
480 | -41, -39, -37, -35, -32, -30, -28, -26, | ||
481 | -23, -21, -19, -16, -14, -12, -10, -7, | ||
482 | -5, -3, 0, 1, 3, 6, 8, 10, | ||
483 | 13, 15, 17, 19, 22, 24, 26, 29, | ||
484 | 31, 33, 35, 38, 40, 42, 44, 46, | ||
485 | 48, 51, 53, 55, 57, 59, 61, 63, | ||
486 | 65, 67, 69, 71, 73, 75, 77, 79, | ||
487 | 81, 82, 84, 86, 88, 89, 91, 93, | ||
488 | 94, 96, 98, 99, 101, 102, 104, 105, | ||
489 | 106, 108, 109, 110, 112, 113, 114, 115, | ||
490 | 116, 117, 119, 120, 120, 121, 122, 123, | ||
491 | 124, 125, 126, 126, 127, 128, 128, 129, | ||
492 | 129, 130, 130, 131, 131, 131, 131, 132, | ||
493 | 132, 132, 132, 132, 132, 132, 132, 132, | ||
494 | 132, 132, 132, 131, 131, 131, 130, 130, | ||
495 | 130, 129, 129, 128, 127, 127, 126, 125, | ||
496 | 125, 124, 123, 122, 121, 120, 119, 118, | ||
497 | 117, 116, 115, 114, 113, 111, 110, 109, | ||
498 | 107, 106, 105, 103, 102, 100, 99, 97, | ||
499 | 96, 94, 92, 91, 89, 87, 85, 84, 82 | ||
500 | }; | ||
501 | |||
502 | static const int hsv_green_x[] = { | ||
503 | -124, -124, -125, -125, -125, -125, -125, -125, | ||
504 | -125, -126, -126, -125, -125, -125, -125, -125, | ||
505 | -125, -124, -124, -124, -123, -123, -122, -122, | ||
506 | -121, -121, -120, -120, -119, -118, -117, -117, | ||
507 | -116, -115, -114, -113, -112, -111, -110, -109, | ||
508 | -108, -107, -105, -104, -103, -102, -100, -99, | ||
509 | -98, -96, -95, -93, -92, -91, -89, -87, | ||
510 | -86, -84, -83, -81, -79, -77, -76, -74, | ||
511 | -72, -70, -69, -67, -65, -63, -61, -59, | ||
512 | -57, -55, -53, -51, -49, -47, -45, -43, | ||
513 | -41, -39, -37, -35, -33, -30, -28, -26, | ||
514 | -24, -22, -20, -18, -15, -13, -11, -9, | ||
515 | -7, -4, -2, 0, 1, 3, 6, 8, | ||
516 | 10, 12, 14, 17, 19, 21, 23, 25, | ||
517 | 27, 29, 32, 34, 36, 38, 40, 42, | ||
518 | 44, 46, 48, 50, 52, 54, 56, 58, | ||
519 | 60, 62, 64, 66, 68, 70, 71, 73, | ||
520 | 75, 77, 78, 80, 82, 83, 85, 87, | ||
521 | 88, 90, 91, 93, 94, 96, 97, 98, | ||
522 | 100, 101, 102, 104, 105, 106, 107, 108, | ||
523 | 109, 111, 112, 113, 113, 114, 115, 116, | ||
524 | 117, 118, 118, 119, 120, 120, 121, 122, | ||
525 | 122, 123, 123, 124, 124, 124, 125, 125, | ||
526 | 125, 125, 125, 125, 125, 126, 126, 125, | ||
527 | 125, 125, 125, 125, 125, 124, 124, 124, | ||
528 | 123, 123, 122, 122, 121, 121, 120, 120, | ||
529 | 119, 118, 117, 117, 116, 115, 114, 113, | ||
530 | 112, 111, 110, 109, 108, 107, 105, 104, | ||
531 | 103, 102, 100, 99, 98, 96, 95, 93, | ||
532 | 92, 91, 89, 87, 86, 84, 83, 81, | ||
533 | 79, 77, 76, 74, 72, 70, 69, 67, | ||
534 | 65, 63, 61, 59, 57, 55, 53, 51, | ||
535 | 49, 47, 45, 43, 41, 39, 37, 35, | ||
536 | 33, 30, 28, 26, 24, 22, 20, 18, | ||
537 | 15, 13, 11, 9, 7, 4, 2, 0, | ||
538 | -1, -3, -6, -8, -10, -12, -14, -17, | ||
539 | -19, -21, -23, -25, -27, -29, -32, -34, | ||
540 | -36, -38, -40, -42, -44, -46, -48, -50, | ||
541 | -52, -54, -56, -58, -60, -62, -64, -66, | ||
542 | -68, -70, -71, -73, -75, -77, -78, -80, | ||
543 | -82, -83, -85, -87, -88, -90, -91, -93, | ||
544 | -94, -96, -97, -98, -100, -101, -102, -104, | ||
545 | -105, -106, -107, -108, -109, -111, -112, -113, | ||
546 | -113, -114, -115, -116, -117, -118, -118, -119, | ||
547 | -120, -120, -121, -122, -122, -123, -123, -124, -124 | ||
548 | }; | ||
549 | |||
550 | static const int hsv_green_y[] = { | ||
551 | -100, -99, -98, -97, -95, -94, -93, -91, | ||
552 | -90, -89, -87, -86, -84, -83, -81, -80, | ||
553 | -78, -76, -75, -73, -71, -70, -68, -66, | ||
554 | -64, -63, -61, -59, -57, -55, -53, -51, | ||
555 | -49, -48, -46, -44, -42, -40, -38, -36, | ||
556 | -34, -32, -30, -27, -25, -23, -21, -19, | ||
557 | -17, -15, -13, -11, -9, -7, -4, -2, | ||
558 | 0, 1, 3, 5, 7, 9, 11, 14, | ||
559 | 16, 18, 20, 22, 24, 26, 28, 30, | ||
560 | 32, 34, 36, 38, 40, 42, 44, 46, | ||
561 | 48, 50, 52, 54, 56, 58, 59, 61, | ||
562 | 63, 65, 67, 68, 70, 72, 74, 75, | ||
563 | 77, 78, 80, 82, 83, 85, 86, 88, | ||
564 | 89, 90, 92, 93, 95, 96, 97, 98, | ||
565 | 100, 101, 102, 103, 104, 105, 106, 107, | ||
566 | 108, 109, 110, 111, 112, 112, 113, 114, | ||
567 | 115, 115, 116, 116, 117, 117, 118, 118, | ||
568 | 119, 119, 119, 120, 120, 120, 120, 120, | ||
569 | 121, 121, 121, 121, 121, 121, 120, 120, | ||
570 | 120, 120, 120, 119, 119, 119, 118, 118, | ||
571 | 117, 117, 116, 116, 115, 114, 114, 113, | ||
572 | 112, 111, 111, 110, 109, 108, 107, 106, | ||
573 | 105, 104, 103, 102, 100, 99, 98, 97, | ||
574 | 95, 94, 93, 91, 90, 89, 87, 86, | ||
575 | 84, 83, 81, 80, 78, 76, 75, 73, | ||
576 | 71, 70, 68, 66, 64, 63, 61, 59, | ||
577 | 57, 55, 53, 51, 49, 48, 46, 44, | ||
578 | 42, 40, 38, 36, 34, 32, 30, 27, | ||
579 | 25, 23, 21, 19, 17, 15, 13, 11, | ||
580 | 9, 7, 4, 2, 0, -1, -3, -5, | ||
581 | -7, -9, -11, -14, -16, -18, -20, -22, | ||
582 | -24, -26, -28, -30, -32, -34, -36, -38, | ||
583 | -40, -42, -44, -46, -48, -50, -52, -54, | ||
584 | -56, -58, -59, -61, -63, -65, -67, -68, | ||
585 | -70, -72, -74, -75, -77, -78, -80, -82, | ||
586 | -83, -85, -86, -88, -89, -90, -92, -93, | ||
587 | -95, -96, -97, -98, -100, -101, -102, -103, | ||
588 | -104, -105, -106, -107, -108, -109, -110, -111, | ||
589 | -112, -112, -113, -114, -115, -115, -116, -116, | ||
590 | -117, -117, -118, -118, -119, -119, -119, -120, | ||
591 | -120, -120, -120, -120, -121, -121, -121, -121, | ||
592 | -121, -121, -120, -120, -120, -120, -120, -119, | ||
593 | -119, -119, -118, -118, -117, -117, -116, -116, | ||
594 | -115, -114, -114, -113, -112, -111, -111, -110, | ||
595 | -109, -108, -107, -106, -105, -104, -103, -102, -100 | ||
596 | }; | ||
597 | |||
598 | static const int hsv_blue_x[] = { | ||
599 | 112, 113, 114, 114, 115, 116, 117, 117, | ||
600 | 118, 118, 119, 119, 120, 120, 120, 121, | ||
601 | 121, 121, 122, 122, 122, 122, 122, 122, | ||
602 | 122, 122, 122, 122, 122, 122, 121, 121, | ||
603 | 121, 120, 120, 120, 119, 119, 118, 118, | ||
604 | 117, 116, 116, 115, 114, 113, 113, 112, | ||
605 | 111, 110, 109, 108, 107, 106, 105, 104, | ||
606 | 103, 102, 100, 99, 98, 97, 95, 94, | ||
607 | 93, 91, 90, 88, 87, 85, 84, 82, | ||
608 | 80, 79, 77, 76, 74, 72, 70, 69, | ||
609 | 67, 65, 63, 61, 60, 58, 56, 54, | ||
610 | 52, 50, 48, 46, 44, 42, 40, 38, | ||
611 | 36, 34, 32, 30, 28, 26, 24, 22, | ||
612 | 19, 17, 15, 13, 11, 9, 7, 5, | ||
613 | 2, 0, -1, -3, -5, -7, -9, -12, | ||
614 | -14, -16, -18, -20, -22, -24, -26, -28, | ||
615 | -31, -33, -35, -37, -39, -41, -43, -45, | ||
616 | -47, -49, -51, -53, -54, -56, -58, -60, | ||
617 | -62, -64, -66, -67, -69, -71, -73, -74, | ||
618 | -76, -78, -79, -81, -83, -84, -86, -87, | ||
619 | -89, -90, -92, -93, -94, -96, -97, -98, | ||
620 | -99, -101, -102, -103, -104, -105, -106, -107, | ||
621 | -108, -109, -110, -111, -112, -113, -114, -114, | ||
622 | -115, -116, -117, -117, -118, -118, -119, -119, | ||
623 | -120, -120, -120, -121, -121, -121, -122, -122, | ||
624 | -122, -122, -122, -122, -122, -122, -122, -122, | ||
625 | -122, -122, -121, -121, -121, -120, -120, -120, | ||
626 | -119, -119, -118, -118, -117, -116, -116, -115, | ||
627 | -114, -113, -113, -112, -111, -110, -109, -108, | ||
628 | -107, -106, -105, -104, -103, -102, -100, -99, | ||
629 | -98, -97, -95, -94, -93, -91, -90, -88, | ||
630 | -87, -85, -84, -82, -80, -79, -77, -76, | ||
631 | -74, -72, -70, -69, -67, -65, -63, -61, | ||
632 | -60, -58, -56, -54, -52, -50, -48, -46, | ||
633 | -44, -42, -40, -38, -36, -34, -32, -30, | ||
634 | -28, -26, -24, -22, -19, -17, -15, -13, | ||
635 | -11, -9, -7, -5, -2, 0, 1, 3, | ||
636 | 5, 7, 9, 12, 14, 16, 18, 20, | ||
637 | 22, 24, 26, 28, 31, 33, 35, 37, | ||
638 | 39, 41, 43, 45, 47, 49, 51, 53, | ||
639 | 54, 56, 58, 60, 62, 64, 66, 67, | ||
640 | 69, 71, 73, 74, 76, 78, 79, 81, | ||
641 | 83, 84, 86, 87, 89, 90, 92, 93, | ||
642 | 94, 96, 97, 98, 99, 101, 102, 103, | ||
643 | 104, 105, 106, 107, 108, 109, 110, 111, 112 | ||
644 | }; | ||
645 | |||
646 | static const int hsv_blue_y[] = { | ||
647 | -11, -13, -15, -17, -19, -21, -23, -25, | ||
648 | -27, -29, -31, -33, -35, -37, -39, -41, | ||
649 | -43, -45, -46, -48, -50, -52, -54, -55, | ||
650 | -57, -59, -61, -62, -64, -66, -67, -69, | ||
651 | -71, -72, -74, -75, -77, -78, -80, -81, | ||
652 | -83, -84, -86, -87, -88, -90, -91, -92, | ||
653 | -93, -95, -96, -97, -98, -99, -100, -101, | ||
654 | -102, -103, -104, -105, -106, -106, -107, -108, | ||
655 | -109, -109, -110, -111, -111, -112, -112, -113, | ||
656 | -113, -114, -114, -114, -115, -115, -115, -115, | ||
657 | -116, -116, -116, -116, -116, -116, -116, -116, | ||
658 | -116, -115, -115, -115, -115, -114, -114, -114, | ||
659 | -113, -113, -112, -112, -111, -111, -110, -110, | ||
660 | -109, -108, -108, -107, -106, -105, -104, -103, | ||
661 | -102, -101, -100, -99, -98, -97, -96, -95, | ||
662 | -94, -93, -91, -90, -89, -88, -86, -85, | ||
663 | -84, -82, -81, -79, -78, -76, -75, -73, | ||
664 | -71, -70, -68, -67, -65, -63, -62, -60, | ||
665 | -58, -56, -55, -53, -51, -49, -47, -45, | ||
666 | -44, -42, -40, -38, -36, -34, -32, -30, | ||
667 | -28, -26, -24, -22, -20, -18, -16, -14, | ||
668 | -12, -10, -8, -6, -4, -2, 0, 1, | ||
669 | 3, 5, 7, 9, 11, 13, 15, 17, | ||
670 | 19, 21, 23, 25, 27, 29, 31, 33, | ||
671 | 35, 37, 39, 41, 43, 45, 46, 48, | ||
672 | 50, 52, 54, 55, 57, 59, 61, 62, | ||
673 | 64, 66, 67, 69, 71, 72, 74, 75, | ||
674 | 77, 78, 80, 81, 83, 84, 86, 87, | ||
675 | 88, 90, 91, 92, 93, 95, 96, 97, | ||
676 | 98, 99, 100, 101, 102, 103, 104, 105, | ||
677 | 106, 106, 107, 108, 109, 109, 110, 111, | ||
678 | 111, 112, 112, 113, 113, 114, 114, 114, | ||
679 | 115, 115, 115, 115, 116, 116, 116, 116, | ||
680 | 116, 116, 116, 116, 116, 115, 115, 115, | ||
681 | 115, 114, 114, 114, 113, 113, 112, 112, | ||
682 | 111, 111, 110, 110, 109, 108, 108, 107, | ||
683 | 106, 105, 104, 103, 102, 101, 100, 99, | ||
684 | 98, 97, 96, 95, 94, 93, 91, 90, | ||
685 | 89, 88, 86, 85, 84, 82, 81, 79, | ||
686 | 78, 76, 75, 73, 71, 70, 68, 67, | ||
687 | 65, 63, 62, 60, 58, 56, 55, 53, | ||
688 | 51, 49, 47, 45, 44, 42, 40, 38, | ||
689 | 36, 34, 32, 30, 28, 26, 24, 22, | ||
690 | 20, 18, 16, 14, 12, 10, 8, 6, | ||
691 | 4, 2, 0, -1, -3, -5, -7, -9, -11 | ||
692 | }; | ||
693 | |||
694 | static u16 i2c_ident[] = { | ||
695 | V4L2_IDENT_OV9650, | ||
696 | V4L2_IDENT_OV9655, | ||
697 | V4L2_IDENT_SOI968, | ||
698 | V4L2_IDENT_OV7660, | ||
699 | V4L2_IDENT_OV7670, | ||
700 | V4L2_IDENT_MT9V011, | ||
701 | V4L2_IDENT_MT9V111, | ||
702 | V4L2_IDENT_MT9V112, | ||
703 | V4L2_IDENT_MT9M001C12ST, | ||
704 | V4L2_IDENT_MT9M111, | ||
705 | V4L2_IDENT_HV7131R, | ||
706 | }; | ||
707 | |||
708 | static u16 bridge_init[][2] = { | ||
709 | {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c}, | ||
710 | {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40}, | ||
711 | {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10}, | ||
712 | {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00}, | ||
713 | {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50}, | ||
714 | {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50}, | ||
715 | {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04}, | ||
716 | {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05}, | ||
717 | {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00}, | ||
718 | {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d}, | ||
719 | {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04}, | ||
720 | {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8}, | ||
721 | {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32}, | ||
722 | {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd}, | ||
723 | {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01}, | ||
724 | {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f}, | ||
725 | {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f}, | ||
726 | {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01}, | ||
727 | {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80} | ||
728 | }; | ||
729 | |||
730 | /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */ | ||
731 | static u8 ov_gain[] = { | ||
732 | 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */, | ||
733 | 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */, | ||
734 | 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */, | ||
735 | 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */, | ||
736 | 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */, | ||
737 | 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */, | ||
738 | 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */, | ||
739 | 0x70 /* 8x */ | ||
740 | }; | ||
741 | |||
742 | /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */ | ||
743 | static u16 micron1_gain[] = { | ||
744 | /* 1x 1.25x 1.5x 1.75x */ | ||
745 | 0x0020, 0x0028, 0x0030, 0x0038, | ||
746 | /* 2x 2.25x 2.5x 2.75x */ | ||
747 | 0x00a0, 0x00a4, 0x00a8, 0x00ac, | ||
748 | /* 3x 3.25x 3.5x 3.75x */ | ||
749 | 0x00b0, 0x00b4, 0x00b8, 0x00bc, | ||
750 | /* 4x 4.25x 4.5x 4.75x */ | ||
751 | 0x00c0, 0x00c4, 0x00c8, 0x00cc, | ||
752 | /* 5x 5.25x 5.5x 5.75x */ | ||
753 | 0x00d0, 0x00d4, 0x00d8, 0x00dc, | ||
754 | /* 6x 6.25x 6.5x 6.75x */ | ||
755 | 0x00e0, 0x00e4, 0x00e8, 0x00ec, | ||
756 | /* 7x 7.25x 7.5x 7.75x */ | ||
757 | 0x00f0, 0x00f4, 0x00f8, 0x00fc, | ||
758 | /* 8x */ | ||
759 | 0x01c0 | ||
760 | }; | ||
761 | |||
762 | /* mt9m001 sensor uses a different gain formula then other micron sensors */ | ||
763 | /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */ | ||
764 | static u16 micron2_gain[] = { | ||
765 | /* 1x 1.25x 1.5x 1.75x */ | ||
766 | 0x0008, 0x000a, 0x000c, 0x000e, | ||
767 | /* 2x 2.25x 2.5x 2.75x */ | ||
768 | 0x0010, 0x0012, 0x0014, 0x0016, | ||
769 | /* 3x 3.25x 3.5x 3.75x */ | ||
770 | 0x0018, 0x001a, 0x001c, 0x001e, | ||
771 | /* 4x 4.25x 4.5x 4.75x */ | ||
772 | 0x0020, 0x0051, 0x0052, 0x0053, | ||
773 | /* 5x 5.25x 5.5x 5.75x */ | ||
774 | 0x0054, 0x0055, 0x0056, 0x0057, | ||
775 | /* 6x 6.25x 6.5x 6.75x */ | ||
776 | 0x0058, 0x0059, 0x005a, 0x005b, | ||
777 | /* 7x 7.25x 7.5x 7.75x */ | ||
778 | 0x005c, 0x005d, 0x005e, 0x005f, | ||
779 | /* 8x */ | ||
780 | 0x0060 | ||
781 | }; | ||
782 | |||
783 | /* Gain = .5 + bit[7:0] / 16 */ | ||
784 | static u8 hv7131r_gain[] = { | ||
785 | 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */, | ||
786 | 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */, | ||
787 | 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */, | ||
788 | 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */, | ||
789 | 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */, | ||
790 | 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */, | ||
791 | 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */, | ||
792 | 0x78 /* 8x */ | ||
793 | }; | ||
794 | |||
795 | static u8 soi968_init[][2] = { | ||
796 | {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f}, | ||
797 | {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, | ||
798 | {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, | ||
799 | {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, | ||
800 | {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20}, | ||
801 | {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e}, | ||
802 | {0x13, 0x8a}, {0x12, 0x40}, {0x17, 0x13}, | ||
803 | {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79}, | ||
804 | {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40}, | ||
805 | {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32}, | ||
806 | {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80}, | ||
807 | }; | ||
808 | |||
809 | static u8 ov7660_init[][2] = { | ||
810 | {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3}, | ||
811 | {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40}, | ||
812 | {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a}, | ||
813 | {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43}, | ||
814 | {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6}, | ||
815 | {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50}, | ||
816 | }; | ||
817 | |||
818 | static u8 ov7670_init[][2] = { | ||
819 | {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, | ||
820 | {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, | ||
821 | {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, | ||
822 | {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00}, | ||
823 | {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07}, | ||
824 | {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75}, | ||
825 | {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8}, | ||
826 | {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5}, | ||
827 | {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27}, | ||
828 | {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b}, | ||
829 | {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a}, | ||
830 | {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00}, | ||
831 | {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00}, | ||
832 | {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80}, | ||
833 | {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82}, | ||
834 | {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20}, | ||
835 | {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c}, | ||
836 | {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66}, | ||
837 | {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11}, | ||
838 | {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40}, | ||
839 | {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02}, | ||
840 | {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a}, | ||
841 | {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08}, | ||
842 | {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04}, | ||
843 | {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30}, | ||
844 | {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88}, | ||
845 | {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30}, | ||
846 | {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99}, | ||
847 | {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0}, | ||
848 | {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e}, | ||
849 | {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01}, | ||
850 | {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20}, | ||
851 | {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0}, | ||
852 | {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30}, | ||
853 | {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06}, | ||
854 | {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a}, | ||
855 | {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a}, | ||
856 | {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84}, | ||
857 | {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d}, | ||
858 | {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d}, | ||
859 | {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00}, | ||
860 | {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, | ||
861 | {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60}, | ||
862 | {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, | ||
863 | {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e}, | ||
864 | {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56}, | ||
865 | {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03}, | ||
866 | {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47}, | ||
867 | {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74}, | ||
868 | {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2}, | ||
869 | {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00}, | ||
870 | {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a}, | ||
871 | {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00}, | ||
872 | {0x93, 0x00}, | ||
873 | }; | ||
874 | |||
875 | static u8 ov9650_init[][2] = { | ||
876 | {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78}, | ||
877 | {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, | ||
878 | {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, | ||
879 | {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00}, | ||
880 | {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c}, | ||
881 | {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2}, | ||
882 | {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07}, | ||
883 | {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00}, | ||
884 | {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04}, | ||
885 | {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68}, | ||
886 | {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80}, | ||
887 | {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00}, | ||
888 | {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00}, | ||
889 | {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30}, | ||
890 | {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf}, | ||
891 | {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00}, | ||
892 | {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01}, | ||
893 | {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19}, | ||
894 | {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1}, | ||
895 | {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80}, | ||
896 | {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00}, | ||
897 | {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20}, | ||
898 | {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf}, | ||
899 | {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88}, | ||
900 | {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00}, | ||
901 | {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8}, | ||
902 | {0xaa, 0x92}, {0xab, 0x0a}, | ||
903 | }; | ||
904 | |||
905 | static u8 ov9655_init[][2] = { | ||
906 | {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61}, | ||
907 | {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24}, | ||
908 | {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08}, | ||
909 | {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x32, 0xbf}, | ||
910 | {0x34, 0x3d}, {0x35, 0x00}, {0x36, 0xf8}, {0x38, 0x12}, | ||
911 | {0x39, 0x57}, {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, | ||
912 | {0x3d, 0x19}, {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, | ||
913 | {0x42, 0x80}, {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, | ||
914 | {0x48, 0x3c}, {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, | ||
915 | {0x4d, 0xdc}, {0x4e, 0xdc}, {0x69, 0x02}, {0x6c, 0x04}, | ||
916 | {0x6f, 0x9e}, {0x70, 0x05}, {0x71, 0x78}, {0x77, 0x02}, | ||
917 | {0x8a, 0x23}, {0x8c, 0x0d}, {0x90, 0x7e}, {0x91, 0x7c}, | ||
918 | {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, {0xa6, 0x60}, | ||
919 | {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, {0xab, 0x04}, | ||
920 | {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, {0xaf, 0x80}, | ||
921 | {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, {0xb6, 0xaf}, | ||
922 | {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, {0xbe, 0x3b}, | ||
923 | {0xbf, 0x3a}, {0xc0, 0xe2}, {0xc1, 0xc8}, {0xc2, 0x01}, | ||
924 | {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0}, | ||
925 | {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x12, 0x61}, | ||
926 | {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a}, | ||
927 | {0x03, 0x12}, {0x17, 0x14}, {0x18, 0x00}, {0x19, 0x01}, | ||
928 | {0x1a, 0x3d}, {0x32, 0xbf}, {0x11, 0x80}, {0x2a, 0x10}, | ||
929 | {0x2b, 0x0a}, {0x92, 0x00}, {0x93, 0x00}, {0x1e, 0x04}, | ||
930 | {0x1e, 0x04}, {0x10, 0x7c}, {0x04, 0x03}, {0xa1, 0x00}, | ||
931 | {0x2d, 0x00}, {0x2e, 0x00}, {0x00, 0x00}, {0x01, 0x80}, | ||
932 | {0x02, 0x80}, {0x12, 0x61}, {0x36, 0xfa}, {0x8c, 0x8d}, | ||
933 | {0xc0, 0xaa}, {0x69, 0x0a}, {0x03, 0x12}, {0x17, 0x14}, | ||
934 | {0x18, 0x00}, {0x19, 0x01}, {0x1a, 0x3d}, {0x32, 0xbf}, | ||
935 | {0x11, 0x80}, {0x2a, 0x10}, {0x2b, 0x0a}, {0x92, 0x00}, | ||
936 | {0x93, 0x00}, {0x04, 0x01}, {0x10, 0x1f}, {0xa1, 0x00}, | ||
937 | {0x00, 0x0a}, {0xa1, 0x00}, {0x10, 0x5d}, {0x04, 0x03}, | ||
938 | {0x00, 0x01}, {0xa1, 0x00}, {0x10, 0x7c}, {0x04, 0x03}, | ||
939 | {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13}, | ||
940 | }; | ||
941 | |||
942 | static u16 mt9v112_init[][2] = { | ||
943 | {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020}, | ||
944 | {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b}, | ||
945 | {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001}, | ||
946 | {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a}, | ||
947 | {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58}, | ||
948 | {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001}, | ||
949 | {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020}, | ||
950 | {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020}, | ||
951 | {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020}, | ||
952 | {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, | ||
953 | {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2}, | ||
954 | {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, | ||
955 | {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020}, | ||
956 | {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, | ||
957 | {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae}, | ||
958 | {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae}, | ||
959 | }; | ||
960 | |||
961 | static u16 mt9v111_init[][2] = { | ||
962 | {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000}, | ||
963 | {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1}, | ||
964 | {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002}, | ||
965 | {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03}, | ||
966 | {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c}, | ||
967 | {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064}, | ||
968 | {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480}, | ||
969 | {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6}, | ||
970 | {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000}, | ||
971 | {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000}, | ||
972 | {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000}, | ||
973 | {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0}, | ||
974 | {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000}, | ||
975 | {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000}, | ||
976 | {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000}, | ||
977 | {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000}, | ||
978 | {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016}, | ||
979 | {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004}, | ||
980 | {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d}, | ||
981 | {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0}, | ||
982 | {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0}, | ||
983 | {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281}, | ||
984 | {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002}, | ||
985 | {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004}, | ||
986 | }; | ||
987 | |||
988 | static u16 mt9v011_init[][2] = { | ||
989 | {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000}, | ||
990 | {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1}, | ||
991 | {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006}, | ||
992 | {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000}, | ||
993 | {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000}, | ||
994 | {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000}, | ||
995 | {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000}, | ||
996 | {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000}, | ||
997 | {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000}, | ||
998 | {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000}, | ||
999 | {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000}, | ||
1000 | {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000}, | ||
1001 | {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024}, | ||
1002 | {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000}, | ||
1003 | {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100}, | ||
1004 | {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1}, | ||
1005 | {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000}, | ||
1006 | {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000}, | ||
1007 | {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000}, | ||
1008 | {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101}, | ||
1009 | {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003}, | ||
1010 | {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, | ||
1011 | {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000}, | ||
1012 | {0x06, 0x0029}, {0x05, 0x0009}, | ||
1013 | }; | ||
1014 | |||
1015 | static u16 mt9m001_init[][2] = { | ||
1016 | {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e}, | ||
1017 | {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501}, | ||
1018 | {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002}, | ||
1019 | {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000}, | ||
1020 | {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000}, | ||
1021 | {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000}, | ||
1022 | {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2}, | ||
1023 | {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003}, | ||
1024 | {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a}, | ||
1025 | {0x2e, 0x0029}, {0x07, 0x0002}, | ||
1026 | }; | ||
1027 | |||
1028 | static u16 mt9m111_init[][2] = { | ||
1029 | {0xf0, 0x0000}, {0x0d, 0x0008}, {0x0d, 0x0009}, | ||
1030 | {0x0d, 0x0008}, {0xf0, 0x0001}, {0x3a, 0x4300}, | ||
1031 | {0x9b, 0x4300}, {0xa1, 0x0280}, {0xa4, 0x0200}, | ||
1032 | {0x06, 0x308e}, {0xf0, 0x0000}, | ||
1033 | }; | ||
1034 | |||
1035 | static u8 hv7131r_init[][2] = { | ||
1036 | {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08}, | ||
1037 | {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0}, | ||
1038 | {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08}, | ||
1039 | {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07}, | ||
1040 | {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62}, | ||
1041 | {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10}, | ||
1042 | {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00}, | ||
1043 | {0x23, 0x09}, {0x01, 0x08}, | ||
1044 | }; | ||
1045 | |||
1046 | int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) | ||
1047 | { | ||
1048 | struct usb_device *dev = gspca_dev->dev; | ||
1049 | int result; | ||
1050 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
1051 | 0x00, | ||
1052 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
1053 | reg, | ||
1054 | 0x00, | ||
1055 | gspca_dev->usb_buf, | ||
1056 | length, | ||
1057 | 500); | ||
1058 | if (unlikely(result < 0 || result != length)) { | ||
1059 | err("Read register failed 0x%02X", reg); | ||
1060 | return -EIO; | ||
1061 | } | ||
1062 | return 0; | ||
1063 | } | ||
1064 | |||
1065 | int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length) | ||
1066 | { | ||
1067 | struct usb_device *dev = gspca_dev->dev; | ||
1068 | int result; | ||
1069 | memcpy(gspca_dev->usb_buf, buffer, length); | ||
1070 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
1071 | 0x08, | ||
1072 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
1073 | reg, | ||
1074 | 0x00, | ||
1075 | gspca_dev->usb_buf, | ||
1076 | length, | ||
1077 | 500); | ||
1078 | if (unlikely(result < 0 || result != length)) { | ||
1079 | err("Write register failed index 0x%02X", reg); | ||
1080 | return -EIO; | ||
1081 | } | ||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) | ||
1086 | { | ||
1087 | u8 data[1] = {value}; | ||
1088 | return reg_w(gspca_dev, reg, data, 1); | ||
1089 | } | ||
1090 | |||
1091 | int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) | ||
1092 | { | ||
1093 | int i; | ||
1094 | reg_w(gspca_dev, 0x10c0, buffer, 8); | ||
1095 | for (i = 0; i < 5; i++) { | ||
1096 | reg_r(gspca_dev, 0x10c0, 1); | ||
1097 | if (gspca_dev->usb_buf[0] & 0x04) { | ||
1098 | if (gspca_dev->usb_buf[0] & 0x08) | ||
1099 | return -1; | ||
1100 | return 0; | ||
1101 | } | ||
1102 | msleep(1); | ||
1103 | } | ||
1104 | return -1; | ||
1105 | } | ||
1106 | |||
1107 | int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) | ||
1108 | { | ||
1109 | struct sd *sd = (struct sd *) gspca_dev; | ||
1110 | |||
1111 | u8 row[8]; | ||
1112 | |||
1113 | /* | ||
1114 | * from the point of view of the bridge, the length | ||
1115 | * includes the address | ||
1116 | */ | ||
1117 | row[0] = 0x81 | (2 << 4); | ||
1118 | row[1] = sd->i2c_addr; | ||
1119 | row[2] = reg; | ||
1120 | row[3] = val; | ||
1121 | row[4] = 0x00; | ||
1122 | row[5] = 0x00; | ||
1123 | row[6] = 0x00; | ||
1124 | row[7] = 0x10; | ||
1125 | |||
1126 | return i2c_w(gspca_dev, row); | ||
1127 | } | ||
1128 | |||
1129 | int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) | ||
1130 | { | ||
1131 | struct sd *sd = (struct sd *) gspca_dev; | ||
1132 | u8 row[8]; | ||
1133 | |||
1134 | /* | ||
1135 | * from the point of view of the bridge, the length | ||
1136 | * includes the address | ||
1137 | */ | ||
1138 | row[0] = 0x81 | (3 << 4); | ||
1139 | row[1] = sd->i2c_addr; | ||
1140 | row[2] = reg; | ||
1141 | row[3] = (val >> 8) & 0xff; | ||
1142 | row[4] = val & 0xff; | ||
1143 | row[5] = 0x00; | ||
1144 | row[6] = 0x00; | ||
1145 | row[7] = 0x10; | ||
1146 | |||
1147 | return i2c_w(gspca_dev, row); | ||
1148 | } | ||
1149 | |||
1150 | int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) | ||
1151 | { | ||
1152 | struct sd *sd = (struct sd *) gspca_dev; | ||
1153 | u8 row[8]; | ||
1154 | |||
1155 | row[0] = 0x81 | 0x10; | ||
1156 | row[1] = sd->i2c_addr; | ||
1157 | row[2] = reg; | ||
1158 | row[3] = 0; | ||
1159 | row[4] = 0; | ||
1160 | row[5] = 0; | ||
1161 | row[6] = 0; | ||
1162 | row[7] = 0x10; | ||
1163 | reg_w(gspca_dev, 0x10c0, row, 8); | ||
1164 | msleep(1); | ||
1165 | row[0] = 0x81 | (2 << 4) | 0x02; | ||
1166 | row[2] = 0; | ||
1167 | reg_w(gspca_dev, 0x10c0, row, 8); | ||
1168 | msleep(1); | ||
1169 | reg_r(gspca_dev, 0x10c2, 5); | ||
1170 | *val = gspca_dev->usb_buf[3]; | ||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1174 | int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) | ||
1175 | { | ||
1176 | struct sd *sd = (struct sd *) gspca_dev; | ||
1177 | u8 row[8]; | ||
1178 | |||
1179 | row[0] = 0x81 | 0x10; | ||
1180 | row[1] = sd->i2c_addr; | ||
1181 | row[2] = reg; | ||
1182 | row[3] = 0; | ||
1183 | row[4] = 0; | ||
1184 | row[5] = 0; | ||
1185 | row[6] = 0; | ||
1186 | row[7] = 0x10; | ||
1187 | reg_w(gspca_dev, 0x10c0, row, 8); | ||
1188 | msleep(1); | ||
1189 | row[0] = 0x81 | (3 << 4) | 0x02; | ||
1190 | row[2] = 0; | ||
1191 | reg_w(gspca_dev, 0x10c0, row, 8); | ||
1192 | msleep(1); | ||
1193 | reg_r(gspca_dev, 0x10c2, 5); | ||
1194 | *val = (gspca_dev->usb_buf[2] << 8) | gspca_dev->usb_buf[3]; | ||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | static int ov9650_init_sensor(struct gspca_dev *gspca_dev) | ||
1199 | { | ||
1200 | int i; | ||
1201 | struct sd *sd = (struct sd *) gspca_dev; | ||
1202 | |||
1203 | for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) { | ||
1204 | if (i2c_w1(gspca_dev, ov9650_init[i][0], | ||
1205 | ov9650_init[i][1]) < 0) { | ||
1206 | err("OV9650 sensor initialization failed"); | ||
1207 | return -ENODEV; | ||
1208 | } | ||
1209 | } | ||
1210 | sd->hstart = 1; | ||
1211 | sd->vstart = 7; | ||
1212 | return 0; | ||
1213 | } | ||
1214 | |||
1215 | static int ov9655_init_sensor(struct gspca_dev *gspca_dev) | ||
1216 | { | ||
1217 | int i; | ||
1218 | struct sd *sd = (struct sd *) gspca_dev; | ||
1219 | |||
1220 | for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) { | ||
1221 | if (i2c_w1(gspca_dev, ov9655_init[i][0], | ||
1222 | ov9655_init[i][1]) < 0) { | ||
1223 | err("OV9655 sensor initialization failed"); | ||
1224 | return -ENODEV; | ||
1225 | } | ||
1226 | } | ||
1227 | /* disable hflip and vflip */ | ||
1228 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); | ||
1229 | sd->hstart = 0; | ||
1230 | sd->vstart = 7; | ||
1231 | return 0; | ||
1232 | } | ||
1233 | |||
1234 | static int soi968_init_sensor(struct gspca_dev *gspca_dev) | ||
1235 | { | ||
1236 | int i; | ||
1237 | struct sd *sd = (struct sd *) gspca_dev; | ||
1238 | |||
1239 | for (i = 0; i < ARRAY_SIZE(soi968_init); i++) { | ||
1240 | if (i2c_w1(gspca_dev, soi968_init[i][0], | ||
1241 | soi968_init[i][1]) < 0) { | ||
1242 | err("SOI968 sensor initialization failed"); | ||
1243 | return -ENODEV; | ||
1244 | } | ||
1245 | } | ||
1246 | /* disable hflip and vflip */ | ||
1247 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); | ||
1248 | sd->hstart = 60; | ||
1249 | sd->vstart = 11; | ||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1253 | static int ov7660_init_sensor(struct gspca_dev *gspca_dev) | ||
1254 | { | ||
1255 | int i; | ||
1256 | struct sd *sd = (struct sd *) gspca_dev; | ||
1257 | |||
1258 | for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) { | ||
1259 | if (i2c_w1(gspca_dev, ov7660_init[i][0], | ||
1260 | ov7660_init[i][1]) < 0) { | ||
1261 | err("OV7660 sensor initialization failed"); | ||
1262 | return -ENODEV; | ||
1263 | } | ||
1264 | } | ||
1265 | /* disable hflip and vflip */ | ||
1266 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); | ||
1267 | sd->hstart = 1; | ||
1268 | sd->vstart = 1; | ||
1269 | return 0; | ||
1270 | } | ||
1271 | |||
1272 | static int ov7670_init_sensor(struct gspca_dev *gspca_dev) | ||
1273 | { | ||
1274 | int i; | ||
1275 | struct sd *sd = (struct sd *) gspca_dev; | ||
1276 | |||
1277 | for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) { | ||
1278 | if (i2c_w1(gspca_dev, ov7670_init[i][0], | ||
1279 | ov7670_init[i][1]) < 0) { | ||
1280 | err("OV7670 sensor initialization failed"); | ||
1281 | return -ENODEV; | ||
1282 | } | ||
1283 | } | ||
1284 | /* disable hflip and vflip */ | ||
1285 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); | ||
1286 | sd->hstart = 0; | ||
1287 | sd->vstart = 1; | ||
1288 | return 0; | ||
1289 | } | ||
1290 | |||
1291 | static int mt9v_init_sensor(struct gspca_dev *gspca_dev) | ||
1292 | { | ||
1293 | struct sd *sd = (struct sd *) gspca_dev; | ||
1294 | int i; | ||
1295 | u16 value; | ||
1296 | int ret; | ||
1297 | |||
1298 | sd->i2c_addr = 0x5d; | ||
1299 | ret = i2c_r2(gspca_dev, 0xff, &value); | ||
1300 | if ((ret == 0) && (value == 0x8243)) { | ||
1301 | for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) { | ||
1302 | if (i2c_w2(gspca_dev, mt9v011_init[i][0], | ||
1303 | mt9v011_init[i][1]) < 0) { | ||
1304 | err("MT9V011 sensor initialization failed"); | ||
1305 | return -ENODEV; | ||
1306 | } | ||
1307 | } | ||
1308 | sd->hstart = 2; | ||
1309 | sd->vstart = 2; | ||
1310 | sd->sensor = SENSOR_MT9V011; | ||
1311 | info("MT9V011 sensor detected"); | ||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1315 | sd->i2c_addr = 0x5c; | ||
1316 | i2c_w2(gspca_dev, 0x01, 0x0004); | ||
1317 | ret = i2c_r2(gspca_dev, 0xff, &value); | ||
1318 | if ((ret == 0) && (value == 0x823a)) { | ||
1319 | for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) { | ||
1320 | if (i2c_w2(gspca_dev, mt9v111_init[i][0], | ||
1321 | mt9v111_init[i][1]) < 0) { | ||
1322 | err("MT9V111 sensor initialization failed"); | ||
1323 | return -ENODEV; | ||
1324 | } | ||
1325 | } | ||
1326 | sd->hstart = 2; | ||
1327 | sd->vstart = 2; | ||
1328 | sd->sensor = SENSOR_MT9V111; | ||
1329 | info("MT9V111 sensor detected"); | ||
1330 | return 0; | ||
1331 | } | ||
1332 | |||
1333 | sd->i2c_addr = 0x5d; | ||
1334 | ret = i2c_w2(gspca_dev, 0xf0, 0x0000); | ||
1335 | if (ret < 0) { | ||
1336 | sd->i2c_addr = 0x48; | ||
1337 | i2c_w2(gspca_dev, 0xf0, 0x0000); | ||
1338 | } | ||
1339 | ret = i2c_r2(gspca_dev, 0x00, &value); | ||
1340 | if ((ret == 0) && (value == 0x1229)) { | ||
1341 | for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) { | ||
1342 | if (i2c_w2(gspca_dev, mt9v112_init[i][0], | ||
1343 | mt9v112_init[i][1]) < 0) { | ||
1344 | err("MT9V112 sensor initialization failed"); | ||
1345 | return -ENODEV; | ||
1346 | } | ||
1347 | } | ||
1348 | sd->hstart = 6; | ||
1349 | sd->vstart = 2; | ||
1350 | sd->sensor = SENSOR_MT9V112; | ||
1351 | info("MT9V112 sensor detected"); | ||
1352 | return 0; | ||
1353 | } | ||
1354 | |||
1355 | return -ENODEV; | ||
1356 | } | ||
1357 | |||
1358 | static int mt9m111_init_sensor(struct gspca_dev *gspca_dev) | ||
1359 | { | ||
1360 | struct sd *sd = (struct sd *) gspca_dev; | ||
1361 | int i; | ||
1362 | for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) { | ||
1363 | if (i2c_w2(gspca_dev, mt9m111_init[i][0], | ||
1364 | mt9m111_init[i][1]) < 0) { | ||
1365 | err("MT9M111 sensor initialization failed"); | ||
1366 | return -ENODEV; | ||
1367 | } | ||
1368 | } | ||
1369 | sd->hstart = 0; | ||
1370 | sd->vstart = 2; | ||
1371 | return 0; | ||
1372 | } | ||
1373 | |||
1374 | static int mt9m001_init_sensor(struct gspca_dev *gspca_dev) | ||
1375 | { | ||
1376 | struct sd *sd = (struct sd *) gspca_dev; | ||
1377 | int i; | ||
1378 | for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) { | ||
1379 | if (i2c_w2(gspca_dev, mt9m001_init[i][0], | ||
1380 | mt9m001_init[i][1]) < 0) { | ||
1381 | err("MT9M001 sensor initialization failed"); | ||
1382 | return -ENODEV; | ||
1383 | } | ||
1384 | } | ||
1385 | /* disable hflip and vflip */ | ||
1386 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); | ||
1387 | sd->hstart = 2; | ||
1388 | sd->vstart = 2; | ||
1389 | return 0; | ||
1390 | } | ||
1391 | |||
1392 | static int hv7131r_init_sensor(struct gspca_dev *gspca_dev) | ||
1393 | { | ||
1394 | int i; | ||
1395 | struct sd *sd = (struct sd *) gspca_dev; | ||
1396 | |||
1397 | for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) { | ||
1398 | if (i2c_w1(gspca_dev, hv7131r_init[i][0], | ||
1399 | hv7131r_init[i][1]) < 0) { | ||
1400 | err("HV7131R Sensor initialization failed"); | ||
1401 | return -ENODEV; | ||
1402 | } | ||
1403 | } | ||
1404 | sd->hstart = 0; | ||
1405 | sd->vstart = 1; | ||
1406 | return 0; | ||
1407 | } | ||
1408 | |||
1409 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | ||
1410 | static int input_kthread(void *data) | ||
1411 | { | ||
1412 | struct gspca_dev *gspca_dev = (struct gspca_dev *)data; | ||
1413 | struct sd *sd = (struct sd *) gspca_dev; | ||
1414 | |||
1415 | DECLARE_WAIT_QUEUE_HEAD(wait); | ||
1416 | set_freezable(); | ||
1417 | for (;;) { | ||
1418 | if (kthread_should_stop()) | ||
1419 | break; | ||
1420 | |||
1421 | if (reg_r(gspca_dev, 0x1005, 1) < 0) | ||
1422 | continue; | ||
1423 | |||
1424 | input_report_key(sd->input_dev, | ||
1425 | KEY_CAMERA, | ||
1426 | gspca_dev->usb_buf[0] & sd->input_gpio); | ||
1427 | input_sync(sd->input_dev); | ||
1428 | |||
1429 | wait_event_freezable_timeout(wait, | ||
1430 | kthread_should_stop(), | ||
1431 | msecs_to_jiffies(100)); | ||
1432 | } | ||
1433 | return 0; | ||
1434 | } | ||
1435 | |||
1436 | |||
1437 | static int sn9c20x_input_init(struct gspca_dev *gspca_dev) | ||
1438 | { | ||
1439 | struct sd *sd = (struct sd *) gspca_dev; | ||
1440 | if (sd->input_gpio == 0) | ||
1441 | return 0; | ||
1442 | |||
1443 | sd->input_dev = input_allocate_device(); | ||
1444 | if (!sd->input_dev) | ||
1445 | return -ENOMEM; | ||
1446 | |||
1447 | sd->input_dev->name = "SN9C20X Webcam"; | ||
1448 | |||
1449 | sd->input_dev->phys = kasprintf(GFP_KERNEL, "usb-%s-%s", | ||
1450 | gspca_dev->dev->bus->bus_name, | ||
1451 | gspca_dev->dev->devpath); | ||
1452 | |||
1453 | if (!sd->input_dev->phys) | ||
1454 | return -ENOMEM; | ||
1455 | |||
1456 | usb_to_input_id(gspca_dev->dev, &sd->input_dev->id); | ||
1457 | sd->input_dev->dev.parent = &gspca_dev->dev->dev; | ||
1458 | |||
1459 | set_bit(EV_KEY, sd->input_dev->evbit); | ||
1460 | set_bit(KEY_CAMERA, sd->input_dev->keybit); | ||
1461 | |||
1462 | if (input_register_device(sd->input_dev)) | ||
1463 | return -EINVAL; | ||
1464 | |||
1465 | sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%d", | ||
1466 | gspca_dev->vdev.minor); | ||
1467 | |||
1468 | if (IS_ERR(sd->input_task)) | ||
1469 | return -EINVAL; | ||
1470 | |||
1471 | return 0; | ||
1472 | } | ||
1473 | |||
1474 | static void sn9c20x_input_cleanup(struct gspca_dev *gspca_dev) | ||
1475 | { | ||
1476 | struct sd *sd = (struct sd *) gspca_dev; | ||
1477 | if (sd->input_task != NULL && !IS_ERR(sd->input_task)) | ||
1478 | kthread_stop(sd->input_task); | ||
1479 | |||
1480 | if (sd->input_dev != NULL) { | ||
1481 | input_unregister_device(sd->input_dev); | ||
1482 | kfree(sd->input_dev->phys); | ||
1483 | input_free_device(sd->input_dev); | ||
1484 | sd->input_dev = NULL; | ||
1485 | } | ||
1486 | } | ||
1487 | #endif | ||
1488 | |||
1489 | static int set_cmatrix(struct gspca_dev *gspca_dev) | ||
1490 | { | ||
1491 | struct sd *sd = (struct sd *) gspca_dev; | ||
1492 | s32 hue_coord, hue_index = 180 + sd->hue; | ||
1493 | u8 cmatrix[21]; | ||
1494 | memset(cmatrix, 0, 21); | ||
1495 | |||
1496 | cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26; | ||
1497 | cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; | ||
1498 | cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; | ||
1499 | cmatrix[18] = sd->brightness - 0x80; | ||
1500 | |||
1501 | hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8; | ||
1502 | cmatrix[6] = (unsigned char)(hue_coord & 0xff); | ||
1503 | cmatrix[7] = (unsigned char)((hue_coord >> 8) & 0x0f); | ||
1504 | |||
1505 | hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8; | ||
1506 | cmatrix[8] = (unsigned char)(hue_coord & 0xff); | ||
1507 | cmatrix[9] = (unsigned char)((hue_coord >> 8) & 0x0f); | ||
1508 | |||
1509 | hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8; | ||
1510 | cmatrix[10] = (unsigned char)(hue_coord & 0xff); | ||
1511 | cmatrix[11] = (unsigned char)((hue_coord >> 8) & 0x0f); | ||
1512 | |||
1513 | hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8; | ||
1514 | cmatrix[12] = (unsigned char)(hue_coord & 0xff); | ||
1515 | cmatrix[13] = (unsigned char)((hue_coord >> 8) & 0x0f); | ||
1516 | |||
1517 | hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8; | ||
1518 | cmatrix[14] = (unsigned char)(hue_coord & 0xff); | ||
1519 | cmatrix[15] = (unsigned char)((hue_coord >> 8) & 0x0f); | ||
1520 | |||
1521 | hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8; | ||
1522 | cmatrix[16] = (unsigned char)(hue_coord & 0xff); | ||
1523 | cmatrix[17] = (unsigned char)((hue_coord >> 8) & 0x0f); | ||
1524 | |||
1525 | return reg_w(gspca_dev, 0x10e1, cmatrix, 21); | ||
1526 | } | ||
1527 | |||
1528 | static int set_gamma(struct gspca_dev *gspca_dev) | ||
1529 | { | ||
1530 | struct sd *sd = (struct sd *) gspca_dev; | ||
1531 | u8 gamma[17]; | ||
1532 | u8 gval = sd->gamma * 0xb8 / 0x100; | ||
1533 | |||
1534 | |||
1535 | gamma[0] = 0x0a; | ||
1536 | gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); | ||
1537 | gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8); | ||
1538 | gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8); | ||
1539 | gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8); | ||
1540 | gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8); | ||
1541 | gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8); | ||
1542 | gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8); | ||
1543 | gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8); | ||
1544 | gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8); | ||
1545 | gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8); | ||
1546 | gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8); | ||
1547 | gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8); | ||
1548 | gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8); | ||
1549 | gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8); | ||
1550 | gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8); | ||
1551 | gamma[16] = 0xf5; | ||
1552 | |||
1553 | return reg_w(gspca_dev, 0x1190, gamma, 17); | ||
1554 | } | ||
1555 | |||
1556 | static int set_redblue(struct gspca_dev *gspca_dev) | ||
1557 | { | ||
1558 | struct sd *sd = (struct sd *) gspca_dev; | ||
1559 | reg_w1(gspca_dev, 0x118c, sd->red); | ||
1560 | reg_w1(gspca_dev, 0x118f, sd->blue); | ||
1561 | return 0; | ||
1562 | } | ||
1563 | |||
1564 | static int set_hvflip(struct gspca_dev *gspca_dev) | ||
1565 | { | ||
1566 | u8 value, tslb; | ||
1567 | u16 value2; | ||
1568 | struct sd *sd = (struct sd *) gspca_dev; | ||
1569 | switch (sd->sensor) { | ||
1570 | case SENSOR_OV9650: | ||
1571 | i2c_r1(gspca_dev, 0x1e, &value); | ||
1572 | value &= ~0x30; | ||
1573 | tslb = 0x01; | ||
1574 | if (sd->hflip) | ||
1575 | value |= 0x20; | ||
1576 | if (sd->vflip) { | ||
1577 | value |= 0x10; | ||
1578 | tslb = 0x49; | ||
1579 | } | ||
1580 | i2c_w1(gspca_dev, 0x1e, value); | ||
1581 | i2c_w1(gspca_dev, 0x3a, tslb); | ||
1582 | break; | ||
1583 | case SENSOR_MT9V111: | ||
1584 | case SENSOR_MT9V011: | ||
1585 | i2c_r2(gspca_dev, 0x20, &value2); | ||
1586 | value2 &= ~0xc0a0; | ||
1587 | if (sd->hflip) | ||
1588 | value2 |= 0x8080; | ||
1589 | if (sd->vflip) | ||
1590 | value2 |= 0x4020; | ||
1591 | i2c_w2(gspca_dev, 0x20, value2); | ||
1592 | break; | ||
1593 | case SENSOR_MT9M111: | ||
1594 | case SENSOR_MT9V112: | ||
1595 | i2c_r2(gspca_dev, 0x20, &value2); | ||
1596 | value2 &= ~0x0003; | ||
1597 | if (sd->hflip) | ||
1598 | value2 |= 0x0002; | ||
1599 | if (sd->vflip) | ||
1600 | value2 |= 0x0001; | ||
1601 | i2c_w2(gspca_dev, 0x20, value2); | ||
1602 | break; | ||
1603 | case SENSOR_HV7131R: | ||
1604 | i2c_r1(gspca_dev, 0x01, &value); | ||
1605 | value &= ~0x03; | ||
1606 | if (sd->vflip) | ||
1607 | value |= 0x01; | ||
1608 | if (sd->hflip) | ||
1609 | value |= 0x02; | ||
1610 | i2c_w1(gspca_dev, 0x01, value); | ||
1611 | break; | ||
1612 | } | ||
1613 | return 0; | ||
1614 | } | ||
1615 | |||
1616 | static int set_exposure(struct gspca_dev *gspca_dev) | ||
1617 | { | ||
1618 | struct sd *sd = (struct sd *) gspca_dev; | ||
1619 | u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e}; | ||
1620 | switch (sd->sensor) { | ||
1621 | case SENSOR_OV7660: | ||
1622 | case SENSOR_OV7670: | ||
1623 | case SENSOR_SOI968: | ||
1624 | case SENSOR_OV9655: | ||
1625 | case SENSOR_OV9650: | ||
1626 | exp[0] |= (3 << 4); | ||
1627 | exp[2] = 0x2d; | ||
1628 | exp[3] = sd->exposure & 0xff; | ||
1629 | exp[4] = sd->exposure >> 8; | ||
1630 | break; | ||
1631 | case SENSOR_MT9M001: | ||
1632 | case SENSOR_MT9M111: | ||
1633 | case SENSOR_MT9V112: | ||
1634 | case SENSOR_MT9V111: | ||
1635 | case SENSOR_MT9V011: | ||
1636 | exp[0] |= (3 << 4); | ||
1637 | exp[2] = 0x09; | ||
1638 | exp[3] = sd->exposure >> 8; | ||
1639 | exp[4] = sd->exposure & 0xff; | ||
1640 | break; | ||
1641 | case SENSOR_HV7131R: | ||
1642 | exp[0] |= (4 << 4); | ||
1643 | exp[2] = 0x25; | ||
1644 | exp[3] = ((sd->exposure * 0xffffff) / 0xffff) >> 16; | ||
1645 | exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8; | ||
1646 | exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff; | ||
1647 | break; | ||
1648 | } | ||
1649 | i2c_w(gspca_dev, exp); | ||
1650 | return 0; | ||
1651 | } | ||
1652 | |||
1653 | static int set_gain(struct gspca_dev *gspca_dev) | ||
1654 | { | ||
1655 | struct sd *sd = (struct sd *) gspca_dev; | ||
1656 | u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d}; | ||
1657 | switch (sd->sensor) { | ||
1658 | case SENSOR_OV7660: | ||
1659 | case SENSOR_OV7670: | ||
1660 | case SENSOR_SOI968: | ||
1661 | case SENSOR_OV9655: | ||
1662 | case SENSOR_OV9650: | ||
1663 | gain[0] |= (2 << 4); | ||
1664 | gain[3] = ov_gain[sd->gain]; | ||
1665 | break; | ||
1666 | case SENSOR_MT9V011: | ||
1667 | case SENSOR_MT9V111: | ||
1668 | gain[0] |= (3 << 4); | ||
1669 | gain[2] = 0x35; | ||
1670 | gain[3] = micron1_gain[sd->gain] >> 8; | ||
1671 | gain[4] = micron1_gain[sd->gain] & 0xff; | ||
1672 | break; | ||
1673 | case SENSOR_MT9V112: | ||
1674 | case SENSOR_MT9M111: | ||
1675 | gain[0] |= (3 << 4); | ||
1676 | gain[2] = 0x2f; | ||
1677 | gain[3] = micron1_gain[sd->gain] >> 8; | ||
1678 | gain[4] = micron1_gain[sd->gain] & 0xff; | ||
1679 | break; | ||
1680 | case SENSOR_MT9M001: | ||
1681 | gain[0] |= (3 << 4); | ||
1682 | gain[2] = 0x2f; | ||
1683 | gain[3] = micron2_gain[sd->gain] >> 8; | ||
1684 | gain[4] = micron2_gain[sd->gain] & 0xff; | ||
1685 | break; | ||
1686 | case SENSOR_HV7131R: | ||
1687 | gain[0] |= (2 << 4); | ||
1688 | gain[2] = 0x30; | ||
1689 | gain[3] = hv7131r_gain[sd->gain]; | ||
1690 | break; | ||
1691 | } | ||
1692 | i2c_w(gspca_dev, gain); | ||
1693 | return 0; | ||
1694 | } | ||
1695 | |||
1696 | static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val) | ||
1697 | { | ||
1698 | struct sd *sd = (struct sd *) gspca_dev; | ||
1699 | |||
1700 | sd->brightness = val; | ||
1701 | if (gspca_dev->streaming) | ||
1702 | return set_cmatrix(gspca_dev); | ||
1703 | return 0; | ||
1704 | } | ||
1705 | |||
1706 | static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val) | ||
1707 | { | ||
1708 | struct sd *sd = (struct sd *) gspca_dev; | ||
1709 | *val = sd->brightness; | ||
1710 | return 0; | ||
1711 | } | ||
1712 | |||
1713 | |||
1714 | static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val) | ||
1715 | { | ||
1716 | struct sd *sd = (struct sd *) gspca_dev; | ||
1717 | |||
1718 | sd->contrast = val; | ||
1719 | if (gspca_dev->streaming) | ||
1720 | return set_cmatrix(gspca_dev); | ||
1721 | return 0; | ||
1722 | } | ||
1723 | |||
1724 | static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val) | ||
1725 | { | ||
1726 | struct sd *sd = (struct sd *) gspca_dev; | ||
1727 | *val = sd->contrast; | ||
1728 | return 0; | ||
1729 | } | ||
1730 | |||
1731 | static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val) | ||
1732 | { | ||
1733 | struct sd *sd = (struct sd *) gspca_dev; | ||
1734 | |||
1735 | sd->saturation = val; | ||
1736 | if (gspca_dev->streaming) | ||
1737 | return set_cmatrix(gspca_dev); | ||
1738 | return 0; | ||
1739 | } | ||
1740 | |||
1741 | static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val) | ||
1742 | { | ||
1743 | struct sd *sd = (struct sd *) gspca_dev; | ||
1744 | *val = sd->saturation; | ||
1745 | return 0; | ||
1746 | } | ||
1747 | |||
1748 | static int sd_sethue(struct gspca_dev *gspca_dev, s32 val) | ||
1749 | { | ||
1750 | struct sd *sd = (struct sd *) gspca_dev; | ||
1751 | |||
1752 | sd->hue = val; | ||
1753 | if (gspca_dev->streaming) | ||
1754 | return set_cmatrix(gspca_dev); | ||
1755 | return 0; | ||
1756 | } | ||
1757 | |||
1758 | static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val) | ||
1759 | { | ||
1760 | struct sd *sd = (struct sd *) gspca_dev; | ||
1761 | *val = sd->hue; | ||
1762 | return 0; | ||
1763 | } | ||
1764 | |||
1765 | static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val) | ||
1766 | { | ||
1767 | struct sd *sd = (struct sd *) gspca_dev; | ||
1768 | |||
1769 | sd->gamma = val; | ||
1770 | if (gspca_dev->streaming) | ||
1771 | return set_gamma(gspca_dev); | ||
1772 | return 0; | ||
1773 | } | ||
1774 | |||
1775 | static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val) | ||
1776 | { | ||
1777 | struct sd *sd = (struct sd *) gspca_dev; | ||
1778 | *val = sd->gamma; | ||
1779 | return 0; | ||
1780 | } | ||
1781 | |||
1782 | static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val) | ||
1783 | { | ||
1784 | struct sd *sd = (struct sd *) gspca_dev; | ||
1785 | |||
1786 | sd->red = val; | ||
1787 | if (gspca_dev->streaming) | ||
1788 | return set_redblue(gspca_dev); | ||
1789 | return 0; | ||
1790 | } | ||
1791 | |||
1792 | static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val) | ||
1793 | { | ||
1794 | struct sd *sd = (struct sd *) gspca_dev; | ||
1795 | *val = sd->red; | ||
1796 | return 0; | ||
1797 | } | ||
1798 | |||
1799 | static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val) | ||
1800 | { | ||
1801 | struct sd *sd = (struct sd *) gspca_dev; | ||
1802 | |||
1803 | sd->blue = val; | ||
1804 | if (gspca_dev->streaming) | ||
1805 | return set_redblue(gspca_dev); | ||
1806 | return 0; | ||
1807 | } | ||
1808 | |||
1809 | static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val) | ||
1810 | { | ||
1811 | struct sd *sd = (struct sd *) gspca_dev; | ||
1812 | *val = sd->blue; | ||
1813 | return 0; | ||
1814 | } | ||
1815 | |||
1816 | static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val) | ||
1817 | { | ||
1818 | struct sd *sd = (struct sd *) gspca_dev; | ||
1819 | |||
1820 | sd->hflip = val; | ||
1821 | if (gspca_dev->streaming) | ||
1822 | return set_hvflip(gspca_dev); | ||
1823 | return 0; | ||
1824 | } | ||
1825 | |||
1826 | static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val) | ||
1827 | { | ||
1828 | struct sd *sd = (struct sd *) gspca_dev; | ||
1829 | *val = sd->hflip; | ||
1830 | return 0; | ||
1831 | } | ||
1832 | |||
1833 | static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val) | ||
1834 | { | ||
1835 | struct sd *sd = (struct sd *) gspca_dev; | ||
1836 | |||
1837 | sd->vflip = val; | ||
1838 | if (gspca_dev->streaming) | ||
1839 | return set_hvflip(gspca_dev); | ||
1840 | return 0; | ||
1841 | } | ||
1842 | |||
1843 | static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val) | ||
1844 | { | ||
1845 | struct sd *sd = (struct sd *) gspca_dev; | ||
1846 | *val = sd->vflip; | ||
1847 | return 0; | ||
1848 | } | ||
1849 | |||
1850 | static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val) | ||
1851 | { | ||
1852 | struct sd *sd = (struct sd *) gspca_dev; | ||
1853 | |||
1854 | sd->exposure = val; | ||
1855 | if (gspca_dev->streaming) | ||
1856 | return set_exposure(gspca_dev); | ||
1857 | return 0; | ||
1858 | } | ||
1859 | |||
1860 | static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val) | ||
1861 | { | ||
1862 | struct sd *sd = (struct sd *) gspca_dev; | ||
1863 | *val = sd->exposure; | ||
1864 | return 0; | ||
1865 | } | ||
1866 | |||
1867 | static int sd_setgain(struct gspca_dev *gspca_dev, s32 val) | ||
1868 | { | ||
1869 | struct sd *sd = (struct sd *) gspca_dev; | ||
1870 | |||
1871 | sd->gain = val; | ||
1872 | if (gspca_dev->streaming) | ||
1873 | return set_gain(gspca_dev); | ||
1874 | return 0; | ||
1875 | } | ||
1876 | |||
1877 | static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val) | ||
1878 | { | ||
1879 | struct sd *sd = (struct sd *) gspca_dev; | ||
1880 | *val = sd->gain; | ||
1881 | return 0; | ||
1882 | } | ||
1883 | |||
1884 | static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val) | ||
1885 | { | ||
1886 | struct sd *sd = (struct sd *) gspca_dev; | ||
1887 | sd->auto_exposure = val; | ||
1888 | return 0; | ||
1889 | } | ||
1890 | |||
1891 | static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val) | ||
1892 | { | ||
1893 | struct sd *sd = (struct sd *) gspca_dev; | ||
1894 | *val = sd->auto_exposure; | ||
1895 | return 0; | ||
1896 | } | ||
1897 | |||
1898 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1899 | static int sd_dbg_g_register(struct gspca_dev *gspca_dev, | ||
1900 | struct v4l2_dbg_register *reg) | ||
1901 | { | ||
1902 | struct sd *sd = (struct sd *) gspca_dev; | ||
1903 | switch (reg->match.type) { | ||
1904 | case V4L2_CHIP_MATCH_HOST: | ||
1905 | if (reg->match.addr != 0) | ||
1906 | return -EINVAL; | ||
1907 | if (reg->reg < 0x1000 || reg->reg > 0x11ff) | ||
1908 | return -EINVAL; | ||
1909 | if (reg_r(gspca_dev, reg->reg, 1) < 0) | ||
1910 | return -EINVAL; | ||
1911 | reg->val = gspca_dev->usb_buf[0]; | ||
1912 | return 0; | ||
1913 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1914 | if (reg->match.addr != sd->i2c_addr) | ||
1915 | return -EINVAL; | ||
1916 | if (sd->sensor >= SENSOR_MT9V011 && | ||
1917 | sd->sensor <= SENSOR_MT9M111) { | ||
1918 | if (i2c_r2(gspca_dev, reg->reg, (u16 *)®->val) < 0) | ||
1919 | return -EINVAL; | ||
1920 | } else { | ||
1921 | if (i2c_r1(gspca_dev, reg->reg, (u8 *)®->val) < 0) | ||
1922 | return -EINVAL; | ||
1923 | } | ||
1924 | return 0; | ||
1925 | } | ||
1926 | return -EINVAL; | ||
1927 | } | ||
1928 | |||
1929 | static int sd_dbg_s_register(struct gspca_dev *gspca_dev, | ||
1930 | struct v4l2_dbg_register *reg) | ||
1931 | { | ||
1932 | struct sd *sd = (struct sd *) gspca_dev; | ||
1933 | switch (reg->match.type) { | ||
1934 | case V4L2_CHIP_MATCH_HOST: | ||
1935 | if (reg->match.addr != 0) | ||
1936 | return -EINVAL; | ||
1937 | if (reg->reg < 0x1000 || reg->reg > 0x11ff) | ||
1938 | return -EINVAL; | ||
1939 | if (reg_w1(gspca_dev, reg->reg, reg->val) < 0) | ||
1940 | return -EINVAL; | ||
1941 | return 0; | ||
1942 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1943 | if (reg->match.addr != sd->i2c_addr) | ||
1944 | return -EINVAL; | ||
1945 | if (sd->sensor >= SENSOR_MT9V011 && | ||
1946 | sd->sensor <= SENSOR_MT9M111) { | ||
1947 | if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0) | ||
1948 | return -EINVAL; | ||
1949 | } else { | ||
1950 | if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0) | ||
1951 | return -EINVAL; | ||
1952 | } | ||
1953 | return 0; | ||
1954 | } | ||
1955 | return -EINVAL; | ||
1956 | } | ||
1957 | #endif | ||
1958 | |||
1959 | static int sd_chip_ident(struct gspca_dev *gspca_dev, | ||
1960 | struct v4l2_dbg_chip_ident *chip) | ||
1961 | { | ||
1962 | struct sd *sd = (struct sd *) gspca_dev; | ||
1963 | |||
1964 | switch (chip->match.type) { | ||
1965 | case V4L2_CHIP_MATCH_HOST: | ||
1966 | if (chip->match.addr != 0) | ||
1967 | return -EINVAL; | ||
1968 | chip->revision = 0; | ||
1969 | chip->ident = V4L2_IDENT_SN9C20X; | ||
1970 | return 0; | ||
1971 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1972 | if (chip->match.addr != sd->i2c_addr) | ||
1973 | return -EINVAL; | ||
1974 | chip->revision = 0; | ||
1975 | chip->ident = i2c_ident[sd->sensor]; | ||
1976 | return 0; | ||
1977 | } | ||
1978 | return -EINVAL; | ||
1979 | } | ||
1980 | |||
1981 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1982 | const struct usb_device_id *id) | ||
1983 | { | ||
1984 | struct sd *sd = (struct sd *) gspca_dev; | ||
1985 | struct cam *cam; | ||
1986 | |||
1987 | cam = &gspca_dev->cam; | ||
1988 | |||
1989 | sd->sensor = (id->driver_info >> 8) & 0xff; | ||
1990 | sd->i2c_addr = id->driver_info & 0xff; | ||
1991 | |||
1992 | switch (sd->sensor) { | ||
1993 | case SENSOR_OV9650: | ||
1994 | cam->cam_mode = sxga_mode; | ||
1995 | cam->nmodes = ARRAY_SIZE(sxga_mode); | ||
1996 | break; | ||
1997 | default: | ||
1998 | cam->cam_mode = vga_mode; | ||
1999 | cam->nmodes = ARRAY_SIZE(vga_mode); | ||
2000 | } | ||
2001 | |||
2002 | sd->old_step = 0; | ||
2003 | sd->older_step = 0; | ||
2004 | sd->exposure_step = 16; | ||
2005 | |||
2006 | sd->brightness = BRIGHTNESS_DEFAULT; | ||
2007 | sd->contrast = CONTRAST_DEFAULT; | ||
2008 | sd->saturation = SATURATION_DEFAULT; | ||
2009 | sd->hue = HUE_DEFAULT; | ||
2010 | sd->gamma = GAMMA_DEFAULT; | ||
2011 | sd->red = RED_DEFAULT; | ||
2012 | sd->blue = BLUE_DEFAULT; | ||
2013 | |||
2014 | sd->hflip = HFLIP_DEFAULT; | ||
2015 | sd->vflip = VFLIP_DEFAULT; | ||
2016 | sd->exposure = EXPOSURE_DEFAULT; | ||
2017 | sd->gain = GAIN_DEFAULT; | ||
2018 | sd->auto_exposure = AUTO_EXPOSURE_DEFAULT; | ||
2019 | |||
2020 | sd->quality = 95; | ||
2021 | |||
2022 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | ||
2023 | sd->input_gpio = (id->driver_info >> 16) & 0xff; | ||
2024 | if (sn9c20x_input_init(gspca_dev) < 0) | ||
2025 | return -ENODEV; | ||
2026 | #endif | ||
2027 | return 0; | ||
2028 | } | ||
2029 | |||
2030 | static int sd_init(struct gspca_dev *gspca_dev) | ||
2031 | { | ||
2032 | struct sd *sd = (struct sd *) gspca_dev; | ||
2033 | int i; | ||
2034 | u8 value; | ||
2035 | u8 i2c_init[9] = | ||
2036 | {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}; | ||
2037 | |||
2038 | for (i = 0; i < ARRAY_SIZE(bridge_init); i++) { | ||
2039 | value = bridge_init[i][1]; | ||
2040 | if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) { | ||
2041 | err("Device initialization failed"); | ||
2042 | return -ENODEV; | ||
2043 | } | ||
2044 | } | ||
2045 | |||
2046 | if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) { | ||
2047 | err("Device initialization failed"); | ||
2048 | return -ENODEV; | ||
2049 | } | ||
2050 | |||
2051 | switch (sd->sensor) { | ||
2052 | case SENSOR_OV9650: | ||
2053 | if (ov9650_init_sensor(gspca_dev) < 0) | ||
2054 | return -ENODEV; | ||
2055 | info("OV9650 sensor detected"); | ||
2056 | break; | ||
2057 | case SENSOR_OV9655: | ||
2058 | if (ov9655_init_sensor(gspca_dev) < 0) | ||
2059 | return -ENODEV; | ||
2060 | info("OV9655 sensor detected"); | ||
2061 | break; | ||
2062 | case SENSOR_SOI968: | ||
2063 | if (soi968_init_sensor(gspca_dev) < 0) | ||
2064 | return -ENODEV; | ||
2065 | info("SOI968 sensor detected"); | ||
2066 | break; | ||
2067 | case SENSOR_OV7660: | ||
2068 | if (ov7660_init_sensor(gspca_dev) < 0) | ||
2069 | return -ENODEV; | ||
2070 | info("OV7660 sensor detected"); | ||
2071 | break; | ||
2072 | case SENSOR_OV7670: | ||
2073 | if (ov7670_init_sensor(gspca_dev) < 0) | ||
2074 | return -ENODEV; | ||
2075 | info("OV7670 sensor detected"); | ||
2076 | break; | ||
2077 | case SENSOR_MT9VPRB: | ||
2078 | if (mt9v_init_sensor(gspca_dev) < 0) | ||
2079 | return -ENODEV; | ||
2080 | break; | ||
2081 | case SENSOR_MT9M111: | ||
2082 | if (mt9m111_init_sensor(gspca_dev) < 0) | ||
2083 | return -ENODEV; | ||
2084 | info("MT9M111 sensor detected"); | ||
2085 | break; | ||
2086 | case SENSOR_MT9M001: | ||
2087 | if (mt9m001_init_sensor(gspca_dev) < 0) | ||
2088 | return -ENODEV; | ||
2089 | info("MT9M001 sensor detected"); | ||
2090 | break; | ||
2091 | case SENSOR_HV7131R: | ||
2092 | if (hv7131r_init_sensor(gspca_dev) < 0) | ||
2093 | return -ENODEV; | ||
2094 | info("HV7131R sensor detected"); | ||
2095 | break; | ||
2096 | default: | ||
2097 | info("Unsupported Sensor"); | ||
2098 | return -ENODEV; | ||
2099 | } | ||
2100 | |||
2101 | return 0; | ||
2102 | } | ||
2103 | |||
2104 | static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) | ||
2105 | { | ||
2106 | struct sd *sd = (struct sd *) gspca_dev; | ||
2107 | u8 value; | ||
2108 | switch (sd->sensor) { | ||
2109 | case SENSOR_OV9650: | ||
2110 | if (mode & MODE_SXGA) { | ||
2111 | i2c_w1(gspca_dev, 0x17, 0x1b); | ||
2112 | i2c_w1(gspca_dev, 0x18, 0xbc); | ||
2113 | i2c_w1(gspca_dev, 0x19, 0x01); | ||
2114 | i2c_w1(gspca_dev, 0x1a, 0x82); | ||
2115 | i2c_r1(gspca_dev, 0x12, &value); | ||
2116 | i2c_w1(gspca_dev, 0x12, value & 0x07); | ||
2117 | } else { | ||
2118 | i2c_w1(gspca_dev, 0x17, 0x24); | ||
2119 | i2c_w1(gspca_dev, 0x18, 0xc5); | ||
2120 | i2c_w1(gspca_dev, 0x19, 0x00); | ||
2121 | i2c_w1(gspca_dev, 0x1a, 0x3c); | ||
2122 | i2c_r1(gspca_dev, 0x12, &value); | ||
2123 | i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40); | ||
2124 | } | ||
2125 | break; | ||
2126 | } | ||
2127 | } | ||
2128 | |||
2129 | #define HW_WIN(mode, hstart, vstart) \ | ||
2130 | ((const u8 []){hstart & 0xff, hstart >> 8, \ | ||
2131 | vstart & 0xff, vstart >> 8, \ | ||
2132 | (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \ | ||
2133 | (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)}) | ||
2134 | |||
2135 | #define CLR_WIN(width, height) \ | ||
2136 | ((const u8 [])\ | ||
2137 | {0, width >> 2, 0, height >> 1,\ | ||
2138 | ((width >> 10) & 0x01) | ((height >> 8) & 0x6)}) | ||
2139 | |||
2140 | static int sd_start(struct gspca_dev *gspca_dev) | ||
2141 | { | ||
2142 | struct sd *sd = (struct sd *) gspca_dev; | ||
2143 | int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
2144 | int width = gspca_dev->width; | ||
2145 | int height = gspca_dev->height; | ||
2146 | u8 fmt, scale = 0; | ||
2147 | |||
2148 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | ||
2149 | if (sd->jpeg_hdr == NULL) | ||
2150 | return -ENOMEM; | ||
2151 | |||
2152 | jpeg_define(sd->jpeg_hdr, height, width, | ||
2153 | 0x21); | ||
2154 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | ||
2155 | |||
2156 | if (mode & MODE_RAW) | ||
2157 | fmt = 0x2d; | ||
2158 | else if (mode & MODE_JPEG) | ||
2159 | fmt = 0x2c; | ||
2160 | else | ||
2161 | fmt = 0x2f; | ||
2162 | |||
2163 | switch (mode & 0x0f) { | ||
2164 | case 3: | ||
2165 | scale = 0xc0; | ||
2166 | info("Set 1280x1024"); | ||
2167 | break; | ||
2168 | case 2: | ||
2169 | scale = 0x80; | ||
2170 | info("Set 640x480"); | ||
2171 | break; | ||
2172 | case 1: | ||
2173 | scale = 0x90; | ||
2174 | info("Set 320x240"); | ||
2175 | break; | ||
2176 | case 0: | ||
2177 | scale = 0xa0; | ||
2178 | info("Set 160x120"); | ||
2179 | break; | ||
2180 | } | ||
2181 | |||
2182 | configure_sensor_output(gspca_dev, mode); | ||
2183 | reg_w(gspca_dev, 0x1100, sd->jpeg_hdr + JPEG_QT0_OFFSET, 64); | ||
2184 | reg_w(gspca_dev, 0x1140, sd->jpeg_hdr + JPEG_QT1_OFFSET, 64); | ||
2185 | reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5); | ||
2186 | reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6); | ||
2187 | reg_w1(gspca_dev, 0x1189, scale); | ||
2188 | reg_w1(gspca_dev, 0x10e0, fmt); | ||
2189 | |||
2190 | set_cmatrix(gspca_dev); | ||
2191 | set_gamma(gspca_dev); | ||
2192 | set_redblue(gspca_dev); | ||
2193 | set_gain(gspca_dev); | ||
2194 | set_exposure(gspca_dev); | ||
2195 | set_hvflip(gspca_dev); | ||
2196 | |||
2197 | reg_r(gspca_dev, 0x1061, 1); | ||
2198 | reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02); | ||
2199 | return 0; | ||
2200 | } | ||
2201 | |||
2202 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
2203 | { | ||
2204 | reg_r(gspca_dev, 0x1061, 1); | ||
2205 | reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02); | ||
2206 | } | ||
2207 | |||
2208 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
2209 | { | ||
2210 | struct sd *sd = (struct sd *) gspca_dev; | ||
2211 | kfree(sd->jpeg_hdr); | ||
2212 | } | ||
2213 | |||
2214 | static void do_autoexposure(struct gspca_dev *gspca_dev) | ||
2215 | { | ||
2216 | struct sd *sd = (struct sd *) gspca_dev; | ||
2217 | int avg_lum, new_exp; | ||
2218 | |||
2219 | if (!sd->auto_exposure) | ||
2220 | return; | ||
2221 | |||
2222 | avg_lum = atomic_read(&sd->avg_lum); | ||
2223 | |||
2224 | /* | ||
2225 | * some hardcoded values are present | ||
2226 | * like those for maximal/minimal exposure | ||
2227 | * and exposure steps | ||
2228 | */ | ||
2229 | if (avg_lum < MIN_AVG_LUM) { | ||
2230 | if (sd->exposure > 0x1770) | ||
2231 | return; | ||
2232 | |||
2233 | new_exp = sd->exposure + sd->exposure_step; | ||
2234 | if (new_exp > 0x1770) | ||
2235 | new_exp = 0x1770; | ||
2236 | if (new_exp < 0x10) | ||
2237 | new_exp = 0x10; | ||
2238 | sd->exposure = new_exp; | ||
2239 | set_exposure(gspca_dev); | ||
2240 | |||
2241 | sd->older_step = sd->old_step; | ||
2242 | sd->old_step = 1; | ||
2243 | |||
2244 | if (sd->old_step ^ sd->older_step) | ||
2245 | sd->exposure_step /= 2; | ||
2246 | else | ||
2247 | sd->exposure_step += 2; | ||
2248 | } | ||
2249 | if (avg_lum > MAX_AVG_LUM) { | ||
2250 | if (sd->exposure < 0x10) | ||
2251 | return; | ||
2252 | new_exp = sd->exposure - sd->exposure_step; | ||
2253 | if (new_exp > 0x1700) | ||
2254 | new_exp = 0x1770; | ||
2255 | if (new_exp < 0x10) | ||
2256 | new_exp = 0x10; | ||
2257 | sd->exposure = new_exp; | ||
2258 | set_exposure(gspca_dev); | ||
2259 | sd->older_step = sd->old_step; | ||
2260 | sd->old_step = 0; | ||
2261 | |||
2262 | if (sd->old_step ^ sd->older_step) | ||
2263 | sd->exposure_step /= 2; | ||
2264 | else | ||
2265 | sd->exposure_step += 2; | ||
2266 | } | ||
2267 | } | ||
2268 | |||
2269 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
2270 | struct gspca_frame *frame, /* target */ | ||
2271 | u8 *data, /* isoc packet */ | ||
2272 | int len) /* iso packet length */ | ||
2273 | { | ||
2274 | struct sd *sd = (struct sd *) gspca_dev; | ||
2275 | int avg_lum; | ||
2276 | static unsigned char frame_header[] = | ||
2277 | {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; | ||
2278 | if (len == 64 && memcmp(data, frame_header, 6) == 0) { | ||
2279 | avg_lum = ((data[35] >> 2) & 3) | | ||
2280 | (data[20] << 2) | | ||
2281 | (data[19] << 10); | ||
2282 | avg_lum += ((data[35] >> 4) & 3) | | ||
2283 | (data[22] << 2) | | ||
2284 | (data[21] << 10); | ||
2285 | avg_lum += ((data[35] >> 6) & 3) | | ||
2286 | (data[24] << 2) | | ||
2287 | (data[23] << 10); | ||
2288 | avg_lum += (data[36] & 3) | | ||
2289 | (data[26] << 2) | | ||
2290 | (data[25] << 10); | ||
2291 | avg_lum += ((data[36] >> 2) & 3) | | ||
2292 | (data[28] << 2) | | ||
2293 | (data[27] << 10); | ||
2294 | avg_lum += ((data[36] >> 4) & 3) | | ||
2295 | (data[30] << 2) | | ||
2296 | (data[29] << 10); | ||
2297 | avg_lum += ((data[36] >> 6) & 3) | | ||
2298 | (data[32] << 2) | | ||
2299 | (data[31] << 10); | ||
2300 | avg_lum += ((data[44] >> 4) & 3) | | ||
2301 | (data[34] << 2) | | ||
2302 | (data[33] << 10); | ||
2303 | avg_lum >>= 9; | ||
2304 | atomic_set(&sd->avg_lum, avg_lum); | ||
2305 | gspca_frame_add(gspca_dev, LAST_PACKET, | ||
2306 | frame, data, len); | ||
2307 | return; | ||
2308 | } | ||
2309 | if (gspca_dev->last_packet_type == LAST_PACKET) { | ||
2310 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv | ||
2311 | & MODE_JPEG) { | ||
2312 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
2313 | sd->jpeg_hdr, JPEG_HDR_SZ); | ||
2314 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
2315 | data, len); | ||
2316 | } else { | ||
2317 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
2318 | data, len); | ||
2319 | } | ||
2320 | } else { | ||
2321 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
2322 | } | ||
2323 | } | ||
2324 | |||
2325 | /* sub-driver description */ | ||
2326 | static const struct sd_desc sd_desc = { | ||
2327 | .name = MODULE_NAME, | ||
2328 | .ctrls = sd_ctrls, | ||
2329 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
2330 | .config = sd_config, | ||
2331 | .init = sd_init, | ||
2332 | .start = sd_start, | ||
2333 | .stopN = sd_stopN, | ||
2334 | .stop0 = sd_stop0, | ||
2335 | .pkt_scan = sd_pkt_scan, | ||
2336 | .dq_callback = do_autoexposure, | ||
2337 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
2338 | .set_register = sd_dbg_s_register, | ||
2339 | .get_register = sd_dbg_g_register, | ||
2340 | #endif | ||
2341 | .get_chip_ident = sd_chip_ident, | ||
2342 | }; | ||
2343 | |||
2344 | #define SN9C20X(sensor, i2c_addr, button_mask) \ | ||
2345 | .driver_info = (button_mask << 16) \ | ||
2346 | | (SENSOR_ ## sensor << 8) \ | ||
2347 | | (i2c_addr) | ||
2348 | |||
2349 | static const __devinitdata struct usb_device_id device_table[] = { | ||
2350 | {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, | ||
2351 | {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)}, | ||
2352 | {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, | ||
2353 | {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, 0x10)}, | ||
2354 | {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)}, | ||
2355 | {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, | ||
2356 | {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, | ||
2357 | {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)}, | ||
2358 | {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)}, | ||
2359 | {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)}, | ||
2360 | {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)}, | ||
2361 | {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, | ||
2362 | {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, | ||
2363 | {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)}, | ||
2364 | {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)}, | ||
2365 | {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)}, | ||
2366 | {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)}, | ||
2367 | {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, | ||
2368 | {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, | ||
2369 | {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)}, | ||
2370 | {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)}, | ||
2371 | {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, | ||
2372 | {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, | ||
2373 | {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, | ||
2374 | {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)}, | ||
2375 | {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)}, | ||
2376 | {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)}, | ||
2377 | {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)}, | ||
2378 | {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)}, | ||
2379 | {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)}, | ||
2380 | {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)}, | ||
2381 | {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)}, | ||
2382 | {} | ||
2383 | }; | ||
2384 | MODULE_DEVICE_TABLE(usb, device_table); | ||
2385 | |||
2386 | /* -- device connect -- */ | ||
2387 | static int sd_probe(struct usb_interface *intf, | ||
2388 | const struct usb_device_id *id) | ||
2389 | { | ||
2390 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
2391 | THIS_MODULE); | ||
2392 | } | ||
2393 | |||
2394 | static void sd_disconnect(struct usb_interface *intf) | ||
2395 | { | ||
2396 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | ||
2397 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | ||
2398 | |||
2399 | sn9c20x_input_cleanup(gspca_dev); | ||
2400 | #endif | ||
2401 | |||
2402 | gspca_disconnect(intf); | ||
2403 | } | ||
2404 | |||
2405 | static struct usb_driver sd_driver = { | ||
2406 | .name = MODULE_NAME, | ||
2407 | .id_table = device_table, | ||
2408 | .probe = sd_probe, | ||
2409 | .disconnect = sd_disconnect, | ||
2410 | #ifdef CONFIG_PM | ||
2411 | .suspend = gspca_suspend, | ||
2412 | .resume = gspca_resume, | ||
2413 | .reset_resume = gspca_resume, | ||
2414 | #endif | ||
2415 | }; | ||
2416 | |||
2417 | /* -- module insert / remove -- */ | ||
2418 | static int __init sd_mod_init(void) | ||
2419 | { | ||
2420 | int ret; | ||
2421 | ret = usb_register(&sd_driver); | ||
2422 | if (ret < 0) | ||
2423 | return ret; | ||
2424 | info("registered"); | ||
2425 | return 0; | ||
2426 | } | ||
2427 | static void __exit sd_mod_exit(void) | ||
2428 | { | ||
2429 | usb_deregister(&sd_driver); | ||
2430 | info("deregistered"); | ||
2431 | } | ||
2432 | |||
2433 | module_init(sd_mod_init); | ||
2434 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 0d02f41fa7d0..d6332ab80669 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -1634,6 +1634,8 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
1634 | { | 1634 | { |
1635 | struct sd *sd = (struct sd *) gspca_dev; | 1635 | struct sd *sd = (struct sd *) gspca_dev; |
1636 | 1636 | ||
1637 | if (gspca_dev->ctrl_dis & (1 << FREQ_IDX)) | ||
1638 | return; | ||
1637 | if (sd->sensor == SENSOR_OV7660) { | 1639 | if (sd->sensor == SENSOR_OV7660) { |
1638 | switch (sd->freq) { | 1640 | switch (sd->freq) { |
1639 | case 0: /* Banding filter disabled */ | 1641 | case 0: /* Banding filter disabled */ |
@@ -1735,6 +1737,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1735 | 1737 | ||
1736 | /* create the JPEG header */ | 1738 | /* create the JPEG header */ |
1737 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 1739 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
1740 | if (!sd->jpeg_hdr) | ||
1741 | return -ENOMEM; | ||
1738 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 1742 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
1739 | 0x21); /* JPEG 422 */ | 1743 | 0x21); /* JPEG 422 */ |
1740 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 1744 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 8806b2ff82be..fab7ef85a6c1 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c | |||
@@ -670,6 +670,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
670 | 670 | ||
671 | /* create the JPEG header */ | 671 | /* create the JPEG header */ |
672 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 672 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
673 | if (!sd->jpeg_hdr) | ||
674 | return -ENOMEM; | ||
673 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 675 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
674 | 0x22); /* JPEG 411 */ | 676 | 0x22); /* JPEG 411 */ |
675 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 677 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index f25be20cf1a6..47628964801e 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c | |||
@@ -333,6 +333,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
333 | 333 | ||
334 | /* create the JPEG header */ | 334 | /* create the JPEG header */ |
335 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 335 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
336 | if (!sd->jpeg_hdr) | ||
337 | return -ENOMEM; | ||
336 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 338 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
337 | 0x22); /* JPEG 411 */ | 339 | 0x22); /* JPEG 411 */ |
338 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 340 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c index 3039ec208f3a..e5024c8496ef 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c | |||
@@ -64,7 +64,7 @@ static struct v4l2_pix_format hdcs1x00_mode[] = { | |||
64 | { | 64 | { |
65 | HDCS_1X00_DEF_WIDTH, | 65 | HDCS_1X00_DEF_WIDTH, |
66 | HDCS_1X00_DEF_HEIGHT, | 66 | HDCS_1X00_DEF_HEIGHT, |
67 | V4L2_PIX_FMT_SBGGR8, | 67 | V4L2_PIX_FMT_SGRBG8, |
68 | V4L2_FIELD_NONE, | 68 | V4L2_FIELD_NONE, |
69 | .sizeimage = | 69 | .sizeimage = |
70 | HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, | 70 | HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, |
@@ -80,7 +80,7 @@ static struct v4l2_pix_format hdcs1020_mode[] = { | |||
80 | { | 80 | { |
81 | HDCS_1020_DEF_WIDTH, | 81 | HDCS_1020_DEF_WIDTH, |
82 | HDCS_1020_DEF_HEIGHT, | 82 | HDCS_1020_DEF_HEIGHT, |
83 | V4L2_PIX_FMT_SBGGR8, | 83 | V4L2_PIX_FMT_SGRBG8, |
84 | V4L2_FIELD_NONE, | 84 | V4L2_FIELD_NONE, |
85 | .sizeimage = | 85 | .sizeimage = |
86 | HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, | 86 | HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, |
@@ -131,9 +131,11 @@ static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) | |||
131 | (reg + len > 0xff))) | 131 | (reg + len > 0xff))) |
132 | return -EINVAL; | 132 | return -EINVAL; |
133 | 133 | ||
134 | for (i = 0; i < len; i++, reg++) { | 134 | for (i = 0; i < len; i++) { |
135 | regs[2*i] = reg; | 135 | regs[2 * i] = reg; |
136 | regs[2*i+1] = vals[i]; | 136 | regs[2 * i + 1] = vals[i]; |
137 | /* All addresses are shifted left one bit as bit 0 toggles r/w */ | ||
138 | reg += 2; | ||
137 | } | 139 | } |
138 | 140 | ||
139 | return stv06xx_write_sensor_bytes(sd, regs, len); | 141 | return stv06xx_write_sensor_bytes(sd, regs, len); |
@@ -174,7 +176,9 @@ static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state) | |||
174 | } | 176 | } |
175 | 177 | ||
176 | ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); | 178 | ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); |
177 | if (ret < 0) | 179 | |
180 | /* Update the state if the write succeeded */ | ||
181 | if (!ret) | ||
178 | hdcs->state = state; | 182 | hdcs->state = state; |
179 | 183 | ||
180 | return ret; | 184 | return ret; |
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 9623f294bdac..5127bbf9dd26 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -973,6 +973,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
973 | 973 | ||
974 | /* create the JPEG header */ | 974 | /* create the JPEG header */ |
975 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 975 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
976 | if (!sd->jpeg_hdr) | ||
977 | return -ENOMEM; | ||
976 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 978 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
977 | 0x22); /* JPEG 411 */ | 979 | 0x22); /* JPEG 411 */ |
978 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 980 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 08422d315e68..3d2756f7874a 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -7243,6 +7243,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
7243 | 7243 | ||
7244 | /* create the JPEG header */ | 7244 | /* create the JPEG header */ |
7245 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 7245 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
7246 | if (!sd->jpeg_hdr) | ||
7247 | return -ENOMEM; | ||
7246 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 7248 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
7247 | 0x21); /* JPEG 422 */ | 7249 | 0x21); /* JPEG 422 */ |
7248 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 7250 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c index 1fe8fc9183a7..b2260de645f0 100644 --- a/drivers/media/video/mt9v011.c +++ b/drivers/media/video/mt9v011.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/i2c.h> | 8 | #include <linux/i2c.h> |
9 | #include <linux/videodev2.h> | 9 | #include <linux/videodev2.h> |
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <asm/div64.h> | ||
11 | #include <media/v4l2-device.h> | 12 | #include <media/v4l2-device.h> |
12 | #include "mt9v011.h" | 13 | #include "mt9v011.h" |
13 | #include <media/v4l2-i2c-drv.h> | 14 | #include <media/v4l2-i2c-drv.h> |
@@ -57,6 +58,7 @@ static struct v4l2_queryctrl mt9v011_qctrl[] = { | |||
57 | struct mt9v011 { | 58 | struct mt9v011 { |
58 | struct v4l2_subdev sd; | 59 | struct v4l2_subdev sd; |
59 | unsigned width, height; | 60 | unsigned width, height; |
61 | unsigned xtal; | ||
60 | 62 | ||
61 | u16 global_gain, red_bal, blue_bal; | 63 | u16 global_gain, red_bal, blue_bal; |
62 | }; | 64 | }; |
@@ -131,7 +133,7 @@ static const struct i2c_reg_value mt9v011_init_default[] = { | |||
131 | { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 }, | 133 | { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 }, |
132 | { R20_MT9V011_READ_MODE, 0x1000 }, | 134 | { R20_MT9V011_READ_MODE, 0x1000 }, |
133 | 135 | ||
134 | { R07_MT9V011_OUT_CTRL, 0x000a }, /* chip enable */ | 136 | { R07_MT9V011_OUT_CTRL, 0x0002 }, /* chip enable */ |
135 | }; | 137 | }; |
136 | 138 | ||
137 | static void set_balance(struct v4l2_subdev *sd) | 139 | static void set_balance(struct v4l2_subdev *sd) |
@@ -154,6 +156,31 @@ static void set_balance(struct v4l2_subdev *sd) | |||
154 | mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); | 156 | mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); |
155 | } | 157 | } |
156 | 158 | ||
159 | static void calc_fps(struct v4l2_subdev *sd) | ||
160 | { | ||
161 | struct mt9v011 *core = to_mt9v011(sd); | ||
162 | unsigned height, width, hblank, vblank, speed; | ||
163 | unsigned row_time, t_time; | ||
164 | u64 frames_per_ms; | ||
165 | unsigned tmp; | ||
166 | |||
167 | height = mt9v011_read(sd, R03_MT9V011_HEIGHT); | ||
168 | width = mt9v011_read(sd, R04_MT9V011_WIDTH); | ||
169 | hblank = mt9v011_read(sd, R05_MT9V011_HBLANK); | ||
170 | vblank = mt9v011_read(sd, R06_MT9V011_VBLANK); | ||
171 | speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED); | ||
172 | |||
173 | row_time = (width + 113 + hblank) * (speed + 2); | ||
174 | t_time = row_time * (height + vblank + 1); | ||
175 | |||
176 | frames_per_ms = core->xtal * 1000l; | ||
177 | do_div(frames_per_ms, t_time); | ||
178 | tmp = frames_per_ms; | ||
179 | |||
180 | v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n", | ||
181 | tmp / 1000, tmp % 1000, t_time); | ||
182 | } | ||
183 | |||
157 | static void set_res(struct v4l2_subdev *sd) | 184 | static void set_res(struct v4l2_subdev *sd) |
158 | { | 185 | { |
159 | struct mt9v011 *core = to_mt9v011(sd); | 186 | struct mt9v011 *core = to_mt9v011(sd); |
@@ -175,10 +202,12 @@ static void set_res(struct v4l2_subdev *sd) | |||
175 | mt9v011_write(sd, R04_MT9V011_WIDTH, core->width); | 202 | mt9v011_write(sd, R04_MT9V011_WIDTH, core->width); |
176 | mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width); | 203 | mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width); |
177 | 204 | ||
178 | vstart = 8 + (640 - core->height) / 2; | 205 | vstart = 8 + (480 - core->height) / 2; |
179 | mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart); | 206 | mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart); |
180 | mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height); | 207 | mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height); |
181 | mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height); | 208 | mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height); |
209 | |||
210 | calc_fps(sd); | ||
182 | }; | 211 | }; |
183 | 212 | ||
184 | static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) | 213 | static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) |
@@ -215,6 +244,23 @@ static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
215 | return -EINVAL; | 244 | return -EINVAL; |
216 | } | 245 | } |
217 | 246 | ||
247 | static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | ||
248 | { | ||
249 | int i; | ||
250 | |||
251 | v4l2_dbg(1, debug, sd, "queryctrl called\n"); | ||
252 | |||
253 | for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++) | ||
254 | if (qc->id && qc->id == mt9v011_qctrl[i].id) { | ||
255 | memcpy(qc, &(mt9v011_qctrl[i]), | ||
256 | sizeof(*qc)); | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | return -EINVAL; | ||
261 | } | ||
262 | |||
263 | |||
218 | static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 264 | static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
219 | { | 265 | { |
220 | struct mt9v011 *core = to_mt9v011(sd); | 266 | struct mt9v011 *core = to_mt9v011(sd); |
@@ -294,6 +340,22 @@ static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |||
294 | return 0; | 340 | return 0; |
295 | } | 341 | } |
296 | 342 | ||
343 | static int mt9v011_s_config(struct v4l2_subdev *sd, int dumb, void *data) | ||
344 | { | ||
345 | struct mt9v011 *core = to_mt9v011(sd); | ||
346 | unsigned *xtal = data; | ||
347 | |||
348 | v4l2_dbg(1, debug, sd, "s_config called\n"); | ||
349 | |||
350 | if (xtal) { | ||
351 | core->xtal = *xtal; | ||
352 | v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n", | ||
353 | *xtal / 1000000, (*xtal / 1000) % 1000); | ||
354 | } | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
297 | 359 | ||
298 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 360 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
299 | static int mt9v011_g_register(struct v4l2_subdev *sd, | 361 | static int mt9v011_g_register(struct v4l2_subdev *sd, |
@@ -338,9 +400,11 @@ static int mt9v011_g_chip_ident(struct v4l2_subdev *sd, | |||
338 | } | 400 | } |
339 | 401 | ||
340 | static const struct v4l2_subdev_core_ops mt9v011_core_ops = { | 402 | static const struct v4l2_subdev_core_ops mt9v011_core_ops = { |
403 | .queryctrl = mt9v011_queryctrl, | ||
341 | .g_ctrl = mt9v011_g_ctrl, | 404 | .g_ctrl = mt9v011_g_ctrl, |
342 | .s_ctrl = mt9v011_s_ctrl, | 405 | .s_ctrl = mt9v011_s_ctrl, |
343 | .reset = mt9v011_reset, | 406 | .reset = mt9v011_reset, |
407 | .s_config = mt9v011_s_config, | ||
344 | .g_chip_ident = mt9v011_g_chip_ident, | 408 | .g_chip_ident = mt9v011_g_chip_ident, |
345 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 409 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
346 | .g_register = mt9v011_g_register, | 410 | .g_register = mt9v011_g_register, |
@@ -395,6 +459,7 @@ static int mt9v011_probe(struct i2c_client *c, | |||
395 | core->global_gain = 0x0024; | 459 | core->global_gain = 0x0024; |
396 | core->width = 640; | 460 | core->width = 640; |
397 | core->height = 480; | 461 | core->height = 480; |
462 | core->xtal = 27000000; /* Hz */ | ||
398 | 463 | ||
399 | v4l_info(c, "chip found @ 0x%02x (%s)\n", | 464 | v4l_info(c, "chip found @ 0x%02x (%s)\n", |
400 | c->addr << 1, c->adapter->name); | 465 | c->addr << 1, c->adapter->name); |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index db25c3034c11..8d17cf613306 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/module.h> | 62 | #include <linux/module.h> |
63 | #include <linux/poll.h> | 63 | #include <linux/poll.h> |
64 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
65 | #include <linux/smp_lock.h> | ||
65 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 66 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
66 | #include <linux/usb/input.h> | 67 | #include <linux/usb/input.h> |
67 | #endif | 68 | #endif |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 0be6f814f539..0b658dee05a4 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/usb.h> | 29 | #include <linux/usb.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/version.h> | 32 | #include <linux/version.h> |
34 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
35 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 6be845ccc7d7..9e3262c0ba37 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/videodev2.h> | 48 | #include <linux/videodev2.h> |
49 | #include <linux/version.h> | 49 | #include <linux/version.h> |
50 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
51 | #include <linux/smp_lock.h> | ||
51 | #include <media/videobuf-vmalloc.h> | 52 | #include <media/videobuf-vmalloc.h> |
52 | #include <media/v4l2-common.h> | 53 | #include <media/v4l2-common.h> |
53 | #include <media/v4l2-ioctl.h> | 54 | #include <media/v4l2-ioctl.h> |
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index 155804b061e9..b624a4c01fdc 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/mm.h> | 43 | #include <linux/mm.h> |
44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/i2c.h> | 45 | #include <linux/i2c.h> |
46 | #include <linux/smp_lock.h> | ||
47 | #include <linux/mutex.h> | 46 | #include <linux/mutex.h> |
48 | #include <linux/videotext.h> | 47 | #include <linux/videotext.h> |
49 | #include <linux/videodev2.h> | 48 | #include <linux/videodev2.h> |
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 271d6e931b75..12835fb82c95 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/mm.h> | 46 | #include <linux/mm.h> |
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/i2c.h> | 48 | #include <linux/i2c.h> |
49 | #include <linux/smp_lock.h> | ||
50 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
51 | #include <linux/delay.h> | 50 | #include <linux/delay.h> |
52 | #include <linux/videotext.h> | 51 | #include <linux/videotext.h> |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index add1757f8930..296788c3bf0e 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/smp_lock.h> | ||
25 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
26 | 27 | ||
27 | #include "saa7134-reg.h" | 28 | #include "saa7134-reg.h" |
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index c8f05297d0f0..85ffc2cba039 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c | |||
@@ -31,6 +31,7 @@ static const char version[] = "0.24"; | |||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/vmalloc.h> | 32 | #include <linux/vmalloc.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/smp_lock.h> | ||
34 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
35 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
36 | #include "se401.h" | 37 | #include "se401.h" |
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 2e5937047278..4d6785e63455 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/smp_lock.h> | ||
30 | 31 | ||
31 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
32 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 0eb313082c97..eaada39c76fd 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/major.h> | 27 | #include <linux/major.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
29 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
31 | #include <linux/poll.h> | 32 | #include <linux/poll.h> |
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index 75f286f7a2e9..8b4e7dafce7b 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/init.h> | 62 | #include <linux/init.h> |
63 | #include <linux/vmalloc.h> | 63 | #include <linux/vmalloc.h> |
64 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
65 | #include <linux/smp_lock.h> | ||
65 | #include <linux/pagemap.h> | 66 | #include <linux/pagemap.h> |
66 | #include <linux/errno.h> | 67 | #include <linux/errno.h> |
67 | #include <linux/videodev.h> | 68 | #include <linux/videodev.h> |
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 8d73979596f9..45fce39ec9ad 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/vmalloc.h> | 43 | #include <linux/vmalloc.h> |
44 | #include <linux/mm.h> | 44 | #include <linux/mm.h> |
45 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
46 | #include <linux/smp_lock.h> | ||
46 | #include <linux/mutex.h> | 47 | #include <linux/mutex.h> |
47 | #include <linux/firmware.h> | 48 | #include <linux/firmware.h> |
48 | #include <linux/ihex.h> | 49 | #include <linux/ihex.h> |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 90b58914f984..90d9b5c0e9a7 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/list.h> | 50 | #include <linux/list.h> |
51 | #include <linux/timer.h> | 51 | #include <linux/timer.h> |
52 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
53 | #include <linux/smp_lock.h> | ||
53 | #include <linux/mm.h> | 54 | #include <linux/mm.h> |
54 | #include <linux/utsname.h> | 55 | #include <linux/utsname.h> |
55 | #include <linux/highmem.h> | 56 | #include <linux/highmem.h> |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 31eac66411d7..a7f1b69a7dab 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/kmod.h> | 26 | #include <linux/kmod.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
30 | #include <asm/system.h> | 29 | #include <asm/system.h> |
31 | 30 | ||
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 3d7df32a3d87..bcdefb1bcb3d 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/module.h> | 49 | #include <linux/module.h> |
50 | #include <linux/delay.h> | 50 | #include <linux/delay.h> |
51 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
52 | #include <linux/smp_lock.h> | ||
52 | #include <linux/pci.h> | 53 | #include <linux/pci.h> |
53 | #include <linux/vmalloc.h> | 54 | #include <linux/vmalloc.h> |
54 | #include <linux/wait.h> | 55 | #include <linux/wait.h> |
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index fa2d93a9fb8d..aed609832bc2 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
34 | #include <linux/device.h> | 33 | #include <linux/device.h> |
35 | #include <linux/miscdevice.h> | 34 | #include <linux/miscdevice.h> |
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index eedbf9c32760..79689b10f937 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
27 | #include <linux/smp_lock.h> | ||
28 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
29 | #include <linux/device.h> | 28 | #include <linux/device.h> |
30 | #include <linux/miscdevice.h> | 29 | #include <linux/miscdevice.h> |
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index b56d72ff06e9..34e23489811a 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c | |||
@@ -384,7 +384,7 @@ static irqreturn_t mvsd_irq(int irq, void *dev) | |||
384 | u16 val[2] = {0, 0}; | 384 | u16 val[2] = {0, 0}; |
385 | val[0] = mvsd_read(MVSD_FIFO); | 385 | val[0] = mvsd_read(MVSD_FIFO); |
386 | val[1] = mvsd_read(MVSD_FIFO); | 386 | val[1] = mvsd_read(MVSD_FIFO); |
387 | memcpy(p, &val, s); | 387 | memcpy(p, ((void *)&val) + 4 - s, s); |
388 | s = 0; | 388 | s = 0; |
389 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 389 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
390 | } | 390 | } |
@@ -423,7 +423,7 @@ static irqreturn_t mvsd_irq(int irq, void *dev) | |||
423 | if (s < 4) { | 423 | if (s < 4) { |
424 | if (s && (intr_status & MVSD_NOR_TX_AVAIL)) { | 424 | if (s && (intr_status & MVSD_NOR_TX_AVAIL)) { |
425 | u16 val[2] = {0, 0}; | 425 | u16 val[2] = {0, 0}; |
426 | memcpy(&val, p, s); | 426 | memcpy(((void *)&val) + 4 - s, p, s); |
427 | mvsd_write(MVSD_FIFO, val[0]); | 427 | mvsd_write(MVSD_FIFO, val[0]); |
428 | mvsd_write(MVSD_FIFO, val[1]); | 428 | mvsd_write(MVSD_FIFO, val[1]); |
429 | s = 0; | 429 | s = 0; |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index d7d7109ef47e..e55ac792d68c 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -168,12 +168,12 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) | |||
168 | 168 | ||
169 | if (data->flags & MMC_DATA_READ) { | 169 | if (data->flags & MMC_DATA_READ) { |
170 | host->dma_dir = DMA_FROM_DEVICE; | 170 | host->dma_dir = DMA_FROM_DEVICE; |
171 | dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG; | 171 | dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; |
172 | DRCMR(host->dma_drcmrtx) = 0; | 172 | DRCMR(host->dma_drcmrtx) = 0; |
173 | DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD; | 173 | DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD; |
174 | } else { | 174 | } else { |
175 | host->dma_dir = DMA_TO_DEVICE; | 175 | host->dma_dir = DMA_TO_DEVICE; |
176 | dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC; | 176 | dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; |
177 | DRCMR(host->dma_drcmrrx) = 0; | 177 | DRCMR(host->dma_drcmrrx) = 0; |
178 | DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD; | 178 | DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD; |
179 | } | 179 | } |
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 286ed594e5a0..e1f7d0a78b9d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -657,6 +657,11 @@ static int io_init(struct ubi_device *ubi) | |||
657 | if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) | 657 | if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) |
658 | ubi->bad_allowed = 1; | 658 | ubi->bad_allowed = 1; |
659 | 659 | ||
660 | if (ubi->mtd->type == MTD_NORFLASH) { | ||
661 | ubi_assert(ubi->mtd->writesize == 1); | ||
662 | ubi->nor_flash = 1; | ||
663 | } | ||
664 | |||
660 | ubi->min_io_size = ubi->mtd->writesize; | 665 | ubi->min_io_size = ubi->mtd->writesize; |
661 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; | 666 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; |
662 | 667 | ||
@@ -996,6 +1001,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
996 | ubi_msg("number of PEBs reserved for bad PEB handling: %d", | 1001 | ubi_msg("number of PEBs reserved for bad PEB handling: %d", |
997 | ubi->beb_rsvd_pebs); | 1002 | ubi->beb_rsvd_pebs); |
998 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); | 1003 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); |
1004 | ubi_msg("image sequence number: %d", ubi->image_seq); | ||
999 | 1005 | ||
1000 | /* | 1006 | /* |
1001 | * The below lock makes sure we do not race with 'ubi_thread()' which | 1007 | * The below lock makes sure we do not race with 'ubi_thread()' which |
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index c0ed60e8ade9..54b0186915fb 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c | |||
@@ -44,6 +44,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) | |||
44 | be32_to_cpu(ec_hdr->vid_hdr_offset)); | 44 | be32_to_cpu(ec_hdr->vid_hdr_offset)); |
45 | printk(KERN_DEBUG "\tdata_offset %d\n", | 45 | printk(KERN_DEBUG "\tdata_offset %d\n", |
46 | be32_to_cpu(ec_hdr->data_offset)); | 46 | be32_to_cpu(ec_hdr->data_offset)); |
47 | printk(KERN_DEBUG "\timage_seq %d\n", | ||
48 | be32_to_cpu(ec_hdr->image_seq)); | ||
47 | printk(KERN_DEBUG "\thdr_crc %#08x\n", | 49 | printk(KERN_DEBUG "\thdr_crc %#08x\n", |
48 | be32_to_cpu(ec_hdr->hdr_crc)); | 50 | be32_to_cpu(ec_hdr->hdr_crc)); |
49 | printk(KERN_DEBUG "erase counter header hexdump:\n"); | 51 | printk(KERN_DEBUG "erase counter header hexdump:\n"); |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 13777e5beac9..a4da7a09b949 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h | |||
@@ -93,6 +93,12 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); | |||
93 | #define UBI_IO_DEBUG 0 | 93 | #define UBI_IO_DEBUG 0 |
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | ||
97 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); | ||
98 | #else | ||
99 | #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 | ||
100 | #endif | ||
101 | |||
96 | #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT | 102 | #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT |
97 | #define DBG_DISABLE_BGT 1 | 103 | #define DBG_DISABLE_BGT 1 |
98 | #else | 104 | #else |
@@ -167,6 +173,7 @@ static inline int ubi_dbg_is_erase_failure(void) | |||
167 | #define ubi_dbg_is_bitflip() 0 | 173 | #define ubi_dbg_is_bitflip() 0 |
168 | #define ubi_dbg_is_write_failure() 0 | 174 | #define ubi_dbg_is_write_failure() 0 |
169 | #define ubi_dbg_is_erase_failure() 0 | 175 | #define ubi_dbg_is_erase_failure() 0 |
176 | #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 | ||
170 | 177 | ||
171 | #endif /* !CONFIG_MTD_UBI_DEBUG */ | 178 | #endif /* !CONFIG_MTD_UBI_DEBUG */ |
172 | #endif /* !__UBI_DEBUG_H__ */ | 179 | #endif /* !__UBI_DEBUG_H__ */ |
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 95aaac03f938..b5e478fa2661 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c | |||
@@ -332,6 +332,7 @@ static int gluebi_create(struct ubi_device_info *di, | |||
332 | } | 332 | } |
333 | 333 | ||
334 | gluebi->vol_id = vi->vol_id; | 334 | gluebi->vol_id = vi->vol_id; |
335 | gluebi->ubi_num = vi->ubi_num; | ||
335 | mtd->type = MTD_UBIVOLUME; | 336 | mtd->type = MTD_UBIVOLUME; |
336 | if (!di->ro_mode) | 337 | if (!di->ro_mode) |
337 | mtd->flags = MTD_WRITEABLE; | 338 | mtd->flags = MTD_WRITEABLE; |
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index effaff28bab1..4cb69925d8d9 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -98,17 +98,12 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
98 | static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); | 98 | static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); |
99 | static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, | 99 | static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, |
100 | const struct ubi_vid_hdr *vid_hdr); | 100 | const struct ubi_vid_hdr *vid_hdr); |
101 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, | ||
102 | int len); | ||
103 | static int paranoid_check_empty(struct ubi_device *ubi, int pnum); | ||
104 | #else | 101 | #else |
105 | #define paranoid_check_not_bad(ubi, pnum) 0 | 102 | #define paranoid_check_not_bad(ubi, pnum) 0 |
106 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 | 103 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 |
107 | #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 | 104 | #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 |
108 | #define paranoid_check_peb_vid_hdr(ubi, pnum) 0 | 105 | #define paranoid_check_peb_vid_hdr(ubi, pnum) 0 |
109 | #define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 | 106 | #define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 |
110 | #define paranoid_check_all_ff(ubi, pnum, offset, len) 0 | ||
111 | #define paranoid_check_empty(ubi, pnum) 0 | ||
112 | #endif | 107 | #endif |
113 | 108 | ||
114 | /** | 109 | /** |
@@ -244,7 +239,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, | |||
244 | return err > 0 ? -EINVAL : err; | 239 | return err > 0 ? -EINVAL : err; |
245 | 240 | ||
246 | /* The area we are writing to has to contain all 0xFF bytes */ | 241 | /* The area we are writing to has to contain all 0xFF bytes */ |
247 | err = paranoid_check_all_ff(ubi, pnum, offset, len); | 242 | err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); |
248 | if (err) | 243 | if (err) |
249 | return err > 0 ? -EINVAL : err; | 244 | return err > 0 ? -EINVAL : err; |
250 | 245 | ||
@@ -271,8 +266,8 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, | |||
271 | addr = (loff_t)pnum * ubi->peb_size + offset; | 266 | addr = (loff_t)pnum * ubi->peb_size + offset; |
272 | err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); | 267 | err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); |
273 | if (err) { | 268 | if (err) { |
274 | ubi_err("error %d while writing %d bytes to PEB %d:%d, written" | 269 | ubi_err("error %d while writing %d bytes to PEB %d:%d, written " |
275 | " %zd bytes", err, len, pnum, offset, written); | 270 | "%zd bytes", err, len, pnum, offset, written); |
276 | ubi_dbg_dump_stack(); | 271 | ubi_dbg_dump_stack(); |
277 | } else | 272 | } else |
278 | ubi_assert(written == len); | 273 | ubi_assert(written == len); |
@@ -350,7 +345,7 @@ retry: | |||
350 | return -EIO; | 345 | return -EIO; |
351 | } | 346 | } |
352 | 347 | ||
353 | err = paranoid_check_all_ff(ubi, pnum, 0, ubi->peb_size); | 348 | err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size); |
354 | if (err) | 349 | if (err) |
355 | return err > 0 ? -EINVAL : err; | 350 | return err > 0 ? -EINVAL : err; |
356 | 351 | ||
@@ -459,6 +454,54 @@ out: | |||
459 | } | 454 | } |
460 | 455 | ||
461 | /** | 456 | /** |
457 | * nor_erase_prepare - prepare a NOR flash PEB for erasure. | ||
458 | * @ubi: UBI device description object | ||
459 | * @pnum: physical eraseblock number to prepare | ||
460 | * | ||
461 | * NOR flash, or at least some of them, have peculiar embedded PEB erasure | ||
462 | * algorithm: the PEB is first filled with zeroes, then it is erased. And | ||
463 | * filling with zeroes starts from the end of the PEB. This was observed with | ||
464 | * Spansion S29GL512N NOR flash. | ||
465 | * | ||
466 | * This means that in case of a power cut we may end up with intact data at the | ||
467 | * beginning of the PEB, and all zeroes at the end of PEB. In other words, the | ||
468 | * EC and VID headers are OK, but a large chunk of data at the end of PEB is | ||
469 | * zeroed. This makes UBI mistakenly treat this PEB as used and associate it | ||
470 | * with an LEB, which leads to subsequent failures (e.g., UBIFS fails). | ||
471 | * | ||
472 | * This function is called before erasing NOR PEBs and it zeroes out EC and VID | ||
473 | * magic numbers in order to invalidate them and prevent the failures. Returns | ||
474 | * zero in case of success and a negative error code in case of failure. | ||
475 | */ | ||
476 | static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | ||
477 | { | ||
478 | int err; | ||
479 | size_t written; | ||
480 | loff_t addr; | ||
481 | uint32_t data = 0; | ||
482 | |||
483 | addr = (loff_t)pnum * ubi->peb_size; | ||
484 | err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); | ||
485 | if (err) { | ||
486 | ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " | ||
487 | "%zd bytes", err, pnum, 0, written); | ||
488 | ubi_dbg_dump_stack(); | ||
489 | return err; | ||
490 | } | ||
491 | |||
492 | addr += ubi->vid_hdr_aloffset; | ||
493 | err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); | ||
494 | if (err) { | ||
495 | ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " | ||
496 | "%zd bytes", err, pnum, ubi->vid_hdr_aloffset, written); | ||
497 | ubi_dbg_dump_stack(); | ||
498 | return err; | ||
499 | } | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | /** | ||
462 | * ubi_io_sync_erase - synchronously erase a physical eraseblock. | 505 | * ubi_io_sync_erase - synchronously erase a physical eraseblock. |
463 | * @ubi: UBI device description object | 506 | * @ubi: UBI device description object |
464 | * @pnum: physical eraseblock number to erase | 507 | * @pnum: physical eraseblock number to erase |
@@ -489,6 +532,12 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) | |||
489 | return -EROFS; | 532 | return -EROFS; |
490 | } | 533 | } |
491 | 534 | ||
535 | if (ubi->nor_flash) { | ||
536 | err = nor_erase_prepare(ubi, pnum); | ||
537 | if (err) | ||
538 | return err; | ||
539 | } | ||
540 | |||
492 | if (torture) { | 541 | if (torture) { |
493 | ret = torture_peb(ubi, pnum); | 542 | ret = torture_peb(ubi, pnum); |
494 | if (ret < 0) | 543 | if (ret < 0) |
@@ -672,11 +721,6 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
672 | if (read_err != -EBADMSG && | 721 | if (read_err != -EBADMSG && |
673 | check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { | 722 | check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { |
674 | /* The physical eraseblock is supposedly empty */ | 723 | /* The physical eraseblock is supposedly empty */ |
675 | err = paranoid_check_all_ff(ubi, pnum, 0, | ||
676 | ubi->peb_size); | ||
677 | if (err) | ||
678 | return err > 0 ? UBI_IO_BAD_EC_HDR : err; | ||
679 | |||
680 | if (verbose) | 724 | if (verbose) |
681 | ubi_warn("no EC header found at PEB %d, " | 725 | ubi_warn("no EC header found at PEB %d, " |
682 | "only 0xFF bytes", pnum); | 726 | "only 0xFF bytes", pnum); |
@@ -752,6 +796,7 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, | |||
752 | ec_hdr->version = UBI_VERSION; | 796 | ec_hdr->version = UBI_VERSION; |
753 | ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); | 797 | ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); |
754 | ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); | 798 | ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); |
799 | ec_hdr->image_seq = cpu_to_be32(ubi->image_seq); | ||
755 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); | 800 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); |
756 | ec_hdr->hdr_crc = cpu_to_be32(crc); | 801 | ec_hdr->hdr_crc = cpu_to_be32(crc); |
757 | 802 | ||
@@ -947,15 +992,6 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
947 | if (read_err != -EBADMSG && | 992 | if (read_err != -EBADMSG && |
948 | check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { | 993 | check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { |
949 | /* The physical eraseblock is supposedly free */ | 994 | /* The physical eraseblock is supposedly free */ |
950 | |||
951 | /* | ||
952 | * The below is just a paranoid check, it has to be | ||
953 | * compiled out if paranoid checks are disabled. | ||
954 | */ | ||
955 | err = paranoid_check_empty(ubi, pnum); | ||
956 | if (err) | ||
957 | return err > 0 ? UBI_IO_BAD_VID_HDR : err; | ||
958 | |||
959 | if (verbose) | 995 | if (verbose) |
960 | ubi_warn("no VID header found at PEB %d, " | 996 | ubi_warn("no VID header found at PEB %d, " |
961 | "only 0xFF bytes", pnum); | 997 | "only 0xFF bytes", pnum); |
@@ -1229,7 +1265,7 @@ exit: | |||
1229 | } | 1265 | } |
1230 | 1266 | ||
1231 | /** | 1267 | /** |
1232 | * paranoid_check_all_ff - check that a region of flash is empty. | 1268 | * ubi_dbg_check_all_ff - check that a region of flash is empty. |
1233 | * @ubi: UBI device description object | 1269 | * @ubi: UBI device description object |
1234 | * @pnum: the physical eraseblock number to check | 1270 | * @pnum: the physical eraseblock number to check |
1235 | * @offset: the starting offset within the physical eraseblock to check | 1271 | * @offset: the starting offset within the physical eraseblock to check |
@@ -1239,8 +1275,7 @@ exit: | |||
1239 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error | 1275 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error |
1240 | * code if an error occurred. | 1276 | * code if an error occurred. |
1241 | */ | 1277 | */ |
1242 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, | 1278 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) |
1243 | int len) | ||
1244 | { | 1279 | { |
1245 | size_t read; | 1280 | size_t read; |
1246 | int err; | 1281 | int err; |
@@ -1276,74 +1311,4 @@ error: | |||
1276 | return err; | 1311 | return err; |
1277 | } | 1312 | } |
1278 | 1313 | ||
1279 | /** | ||
1280 | * paranoid_check_empty - whether a PEB is empty. | ||
1281 | * @ubi: UBI device description object | ||
1282 | * @pnum: the physical eraseblock number to check | ||
1283 | * | ||
1284 | * This function makes sure PEB @pnum is empty, which means it contains only | ||
1285 | * %0xFF data bytes. Returns zero if the PEB is empty, %1 if not, and a | ||
1286 | * negative error code in case of failure. | ||
1287 | * | ||
1288 | * Empty PEBs have the EC header, and do not have the VID header. The caller of | ||
1289 | * this function should have already made sure the PEB does not have the VID | ||
1290 | * header. However, this function re-checks that, because it is possible that | ||
1291 | * the header and data has already been written to the PEB. | ||
1292 | * | ||
1293 | * Let's consider a possible scenario. Suppose there are 2 tasks - A and B. | ||
1294 | * Task A is in 'wear_leveling_worker()'. It is reading VID header of PEB X to | ||
1295 | * find which LEB it corresponds to. PEB X is currently unmapped, and has no | ||
1296 | * VID header. Task B is trying to write to PEB X. | ||
1297 | * | ||
1298 | * Task A: in 'ubi_io_read_vid_hdr()': reads the VID header from PEB X. The | ||
1299 | * read data contain all 0xFF bytes; | ||
1300 | * Task B: writes VID header and some data to PEB X; | ||
1301 | * Task A: assumes PEB X is empty, calls 'paranoid_check_empty()'. And if we | ||
1302 | * do not re-read the VID header, and do not cancel the checking if it | ||
1303 | * is there, we fail. | ||
1304 | */ | ||
1305 | static int paranoid_check_empty(struct ubi_device *ubi, int pnum) | ||
1306 | { | ||
1307 | int err, offs = ubi->vid_hdr_aloffset, len = ubi->vid_hdr_alsize; | ||
1308 | size_t read; | ||
1309 | uint32_t magic; | ||
1310 | const struct ubi_vid_hdr *vid_hdr; | ||
1311 | |||
1312 | mutex_lock(&ubi->dbg_buf_mutex); | ||
1313 | err = ubi->mtd->read(ubi->mtd, offs, len, &read, ubi->dbg_peb_buf); | ||
1314 | if (err && err != -EUCLEAN) { | ||
1315 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " | ||
1316 | "read %zd bytes", err, len, pnum, offs, read); | ||
1317 | goto error; | ||
1318 | } | ||
1319 | |||
1320 | vid_hdr = ubi->dbg_peb_buf; | ||
1321 | magic = be32_to_cpu(vid_hdr->magic); | ||
1322 | if (magic == UBI_VID_HDR_MAGIC) | ||
1323 | /* The PEB contains VID header, so it is not empty */ | ||
1324 | goto out; | ||
1325 | |||
1326 | err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); | ||
1327 | if (err == 0) { | ||
1328 | ubi_err("flash region at PEB %d:%d, length %d does not " | ||
1329 | "contain all 0xFF bytes", pnum, offs, len); | ||
1330 | goto fail; | ||
1331 | } | ||
1332 | |||
1333 | out: | ||
1334 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1335 | return 0; | ||
1336 | |||
1337 | fail: | ||
1338 | ubi_err("paranoid check failed for PEB %d", pnum); | ||
1339 | ubi_msg("hex dump of the %d-%d region", offs, offs + len); | ||
1340 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, | ||
1341 | ubi->dbg_peb_buf, len, 1); | ||
1342 | err = 1; | ||
1343 | error: | ||
1344 | ubi_dbg_dump_stack(); | ||
1345 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1346 | return err; | ||
1347 | } | ||
1348 | |||
1349 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 1314 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index c3d653ba5ca0..a423131b6171 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -757,6 +757,8 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
757 | si->is_empty = 0; | 757 | si->is_empty = 0; |
758 | 758 | ||
759 | if (!ec_corr) { | 759 | if (!ec_corr) { |
760 | int image_seq; | ||
761 | |||
760 | /* Make sure UBI version is OK */ | 762 | /* Make sure UBI version is OK */ |
761 | if (ech->version != UBI_VERSION) { | 763 | if (ech->version != UBI_VERSION) { |
762 | ubi_err("this UBI version is %d, image version is %d", | 764 | ubi_err("this UBI version is %d, image version is %d", |
@@ -778,6 +780,18 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
778 | ubi_dbg_dump_ec_hdr(ech); | 780 | ubi_dbg_dump_ec_hdr(ech); |
779 | return -EINVAL; | 781 | return -EINVAL; |
780 | } | 782 | } |
783 | |||
784 | image_seq = be32_to_cpu(ech->image_seq); | ||
785 | if (!si->image_seq_set) { | ||
786 | ubi->image_seq = image_seq; | ||
787 | si->image_seq_set = 1; | ||
788 | } else if (ubi->image_seq != image_seq) { | ||
789 | ubi_err("bad image sequence number %d in PEB %d, " | ||
790 | "expected %d", image_seq, pnum, ubi->image_seq); | ||
791 | ubi_dbg_dump_ec_hdr(ech); | ||
792 | return -EINVAL; | ||
793 | } | ||
794 | |||
781 | } | 795 | } |
782 | 796 | ||
783 | /* OK, we've done with the EC header, let's look at the VID header */ | 797 | /* OK, we've done with the EC header, let's look at the VID header */ |
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 61df208e2f20..1017cf12def5 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h | |||
@@ -102,6 +102,7 @@ struct ubi_scan_volume { | |||
102 | * @mean_ec: mean erase counter value | 102 | * @mean_ec: mean erase counter value |
103 | * @ec_sum: a temporary variable used when calculating @mean_ec | 103 | * @ec_sum: a temporary variable used when calculating @mean_ec |
104 | * @ec_count: a temporary variable used when calculating @mean_ec | 104 | * @ec_count: a temporary variable used when calculating @mean_ec |
105 | * @image_seq_set: indicates @ubi->image_seq is known | ||
105 | * | 106 | * |
106 | * This data structure contains the result of scanning and may be used by other | 107 | * This data structure contains the result of scanning and may be used by other |
107 | * UBI sub-systems to build final UBI data structures, further error-recovery | 108 | * UBI sub-systems to build final UBI data structures, further error-recovery |
@@ -124,6 +125,7 @@ struct ubi_scan_info { | |||
124 | int mean_ec; | 125 | int mean_ec; |
125 | uint64_t ec_sum; | 126 | uint64_t ec_sum; |
126 | int ec_count; | 127 | int ec_count; |
128 | int image_seq_set; | ||
127 | }; | 129 | }; |
128 | 130 | ||
129 | struct ubi_device; | 131 | struct ubi_device; |
diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h index 8419fdccc79c..503ea9b27309 100644 --- a/drivers/mtd/ubi/ubi-media.h +++ b/drivers/mtd/ubi/ubi-media.h | |||
@@ -129,6 +129,7 @@ enum { | |||
129 | * @ec: the erase counter | 129 | * @ec: the erase counter |
130 | * @vid_hdr_offset: where the VID header starts | 130 | * @vid_hdr_offset: where the VID header starts |
131 | * @data_offset: where the user data start | 131 | * @data_offset: where the user data start |
132 | * @image_seq: image sequence number | ||
132 | * @padding2: reserved for future, zeroes | 133 | * @padding2: reserved for future, zeroes |
133 | * @hdr_crc: erase counter header CRC checksum | 134 | * @hdr_crc: erase counter header CRC checksum |
134 | * | 135 | * |
@@ -144,6 +145,14 @@ enum { | |||
144 | * volume identifier header and user data, relative to the beginning of the | 145 | * volume identifier header and user data, relative to the beginning of the |
145 | * physical eraseblock. These values have to be the same for all physical | 146 | * physical eraseblock. These values have to be the same for all physical |
146 | * eraseblocks. | 147 | * eraseblocks. |
148 | * | ||
149 | * The @image_seq field is used to validate a UBI image that has been prepared | ||
150 | * for a UBI device. The @image_seq value can be any value, but it must be the | ||
151 | * same on all eraseblocks. UBI will ensure that all new erase counter headers | ||
152 | * also contain this value, and will check the value when scanning at start-up. | ||
153 | * One way to make use of @image_seq is to increase its value by one every time | ||
154 | * an image is flashed over an existing image, then, if the flashing does not | ||
155 | * complete, UBI will detect the error when scanning. | ||
147 | */ | 156 | */ |
148 | struct ubi_ec_hdr { | 157 | struct ubi_ec_hdr { |
149 | __be32 magic; | 158 | __be32 magic; |
@@ -152,7 +161,8 @@ struct ubi_ec_hdr { | |||
152 | __be64 ec; /* Warning: the current limit is 31-bit anyway! */ | 161 | __be64 ec; /* Warning: the current limit is 31-bit anyway! */ |
153 | __be32 vid_hdr_offset; | 162 | __be32 vid_hdr_offset; |
154 | __be32 data_offset; | 163 | __be32 data_offset; |
155 | __u8 padding2[36]; | 164 | __be32 image_seq; |
165 | __u8 padding2[32]; | ||
156 | __be32 hdr_crc; | 166 | __be32 hdr_crc; |
157 | } __attribute__ ((packed)); | 167 | } __attribute__ ((packed)); |
158 | 168 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 28acd133c997..6a5fe9633783 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -301,6 +301,7 @@ struct ubi_wl_entry; | |||
301 | * @vol->readers, @vol->writers, @vol->exclusive, | 301 | * @vol->readers, @vol->writers, @vol->exclusive, |
302 | * @vol->ref_count, @vol->mapping and @vol->eba_tbl. | 302 | * @vol->ref_count, @vol->mapping and @vol->eba_tbl. |
303 | * @ref_count: count of references on the UBI device | 303 | * @ref_count: count of references on the UBI device |
304 | * @image_seq: image sequence number recorded on EC headers | ||
304 | * | 305 | * |
305 | * @rsvd_pebs: count of reserved physical eraseblocks | 306 | * @rsvd_pebs: count of reserved physical eraseblocks |
306 | * @avail_pebs: count of available physical eraseblocks | 307 | * @avail_pebs: count of available physical eraseblocks |
@@ -372,6 +373,7 @@ struct ubi_wl_entry; | |||
372 | * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset | 373 | * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset |
373 | * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or | 374 | * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or |
374 | * not | 375 | * not |
376 | * @nor_flash: non-zero if working on top of NOR flash | ||
375 | * @mtd: MTD device descriptor | 377 | * @mtd: MTD device descriptor |
376 | * | 378 | * |
377 | * @peb_buf1: a buffer of PEB size used for different purposes | 379 | * @peb_buf1: a buffer of PEB size used for different purposes |
@@ -390,6 +392,7 @@ struct ubi_device { | |||
390 | struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT]; | 392 | struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT]; |
391 | spinlock_t volumes_lock; | 393 | spinlock_t volumes_lock; |
392 | int ref_count; | 394 | int ref_count; |
395 | int image_seq; | ||
393 | 396 | ||
394 | int rsvd_pebs; | 397 | int rsvd_pebs; |
395 | int avail_pebs; | 398 | int avail_pebs; |
@@ -452,7 +455,8 @@ struct ubi_device { | |||
452 | int vid_hdr_offset; | 455 | int vid_hdr_offset; |
453 | int vid_hdr_aloffset; | 456 | int vid_hdr_aloffset; |
454 | int vid_hdr_shift; | 457 | int vid_hdr_shift; |
455 | int bad_allowed; | 458 | unsigned int bad_allowed:1; |
459 | unsigned int nor_flash:1; | ||
456 | struct mtd_info *mtd; | 460 | struct mtd_info *mtd; |
457 | 461 | ||
458 | void *peb_buf1; | 462 | void *peb_buf1; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 2b2472300610..600c7229d5cf 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -459,6 +459,14 @@ retry: | |||
459 | dbg_wl("PEB %d EC %d", e->pnum, e->ec); | 459 | dbg_wl("PEB %d EC %d", e->pnum, e->ec); |
460 | prot_queue_add(ubi, e); | 460 | prot_queue_add(ubi, e); |
461 | spin_unlock(&ubi->wl_lock); | 461 | spin_unlock(&ubi->wl_lock); |
462 | |||
463 | err = ubi_dbg_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, | ||
464 | ubi->peb_size - ubi->vid_hdr_aloffset); | ||
465 | if (err) { | ||
466 | ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); | ||
467 | return err > 0 ? -EINVAL : err; | ||
468 | } | ||
469 | |||
462 | return e->pnum; | 470 | return e->pnum; |
463 | } | 471 | } |
464 | 472 | ||
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 8ae72ec14456..0e2ba21d4441 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -908,6 +908,7 @@ static const struct net_device_ops rtl8139_netdev_ops = { | |||
908 | .ndo_open = rtl8139_open, | 908 | .ndo_open = rtl8139_open, |
909 | .ndo_stop = rtl8139_close, | 909 | .ndo_stop = rtl8139_close, |
910 | .ndo_get_stats = rtl8139_get_stats, | 910 | .ndo_get_stats = rtl8139_get_stats, |
911 | .ndo_change_mtu = eth_change_mtu, | ||
911 | .ndo_validate_addr = eth_validate_addr, | 912 | .ndo_validate_addr = eth_validate_addr, |
912 | .ndo_set_mac_address = rtl8139_set_mac_address, | 913 | .ndo_set_mac_address = rtl8139_set_mac_address, |
913 | .ndo_start_xmit = rtl8139_start_xmit, | 914 | .ndo_start_xmit = rtl8139_start_xmit, |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c155bd3ec9f1..5f6509a5f640 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -1729,6 +1729,13 @@ config KS8842 | |||
1729 | help | 1729 | help |
1730 | This platform driver is for Micrel KSZ8842 chip. | 1730 | This platform driver is for Micrel KSZ8842 chip. |
1731 | 1731 | ||
1732 | config KS8851 | ||
1733 | tristate "Micrel KS8851 SPI" | ||
1734 | depends on SPI | ||
1735 | select MII | ||
1736 | help | ||
1737 | SPI driver for Micrel KS8851 SPI attached network chip. | ||
1738 | |||
1732 | config VIA_RHINE | 1739 | config VIA_RHINE |
1733 | tristate "VIA Rhine support" | 1740 | tristate "VIA Rhine support" |
1734 | depends on NET_PCI && PCI | 1741 | depends on NET_PCI && PCI |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 4b58a59f211b..ead8cab3cfe1 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -88,6 +88,7 @@ obj-$(CONFIG_SKGE) += skge.o | |||
88 | obj-$(CONFIG_SKY2) += sky2.o | 88 | obj-$(CONFIG_SKY2) += sky2.o |
89 | obj-$(CONFIG_SKFP) += skfp/ | 89 | obj-$(CONFIG_SKFP) += skfp/ |
90 | obj-$(CONFIG_KS8842) += ks8842.o | 90 | obj-$(CONFIG_KS8842) += ks8842.o |
91 | obj-$(CONFIG_KS8851) += ks8851.o | ||
91 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o | 92 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o |
92 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o | 93 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o |
93 | obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o | 94 | obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o |
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index 2895db13bfa4..c37ee9e6b67b 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig | |||
@@ -63,3 +63,11 @@ config IXP4XX_ETH | |||
63 | help | 63 | help |
64 | Say Y here if you want to use built-in Ethernet ports | 64 | Say Y here if you want to use built-in Ethernet ports |
65 | on IXP4xx processor. | 65 | on IXP4xx processor. |
66 | |||
67 | config W90P910_ETH | ||
68 | tristate "Nuvoton w90p910 Ethernet support" | ||
69 | depends on ARM && ARCH_W90X900 | ||
70 | select PHYLIB | ||
71 | help | ||
72 | Say Y here if you want to use built-in Ethernet ports | ||
73 | on w90p910 processor. | ||
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile index 811a3ccd14c1..303171f589e6 100644 --- a/drivers/net/arm/Makefile +++ b/drivers/net/arm/Makefile | |||
@@ -11,3 +11,4 @@ obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o | |||
11 | obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o | 11 | obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o |
12 | obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o | 12 | obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o |
13 | obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o | 13 | obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o |
14 | obj-$(CONFIG_W90P910_ETH) += w90p910_ether.o | ||
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 2e7419a61191..5041d10bae9d 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c | |||
@@ -1228,7 +1228,6 @@ static int at91ether_resume(struct platform_device *pdev) | |||
1228 | #endif | 1228 | #endif |
1229 | 1229 | ||
1230 | static struct platform_driver at91ether_driver = { | 1230 | static struct platform_driver at91ether_driver = { |
1231 | .probe = at91ether_probe, | ||
1232 | .remove = __devexit_p(at91ether_remove), | 1231 | .remove = __devexit_p(at91ether_remove), |
1233 | .suspend = at91ether_suspend, | 1232 | .suspend = at91ether_suspend, |
1234 | .resume = at91ether_resume, | 1233 | .resume = at91ether_resume, |
@@ -1240,7 +1239,7 @@ static struct platform_driver at91ether_driver = { | |||
1240 | 1239 | ||
1241 | static int __init at91ether_init(void) | 1240 | static int __init at91ether_init(void) |
1242 | { | 1241 | { |
1243 | return platform_driver_register(&at91ether_driver); | 1242 | return platform_driver_probe(&at91ether_driver, at91ether_probe); |
1244 | } | 1243 | } |
1245 | 1244 | ||
1246 | static void __exit at91ether_exit(void) | 1245 | static void __exit at91ether_exit(void) |
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 6f42ad728915..3fe09876e76d 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c | |||
@@ -1142,7 +1142,9 @@ static const struct net_device_ops ixp4xx_netdev_ops = { | |||
1142 | .ndo_start_xmit = eth_xmit, | 1142 | .ndo_start_xmit = eth_xmit, |
1143 | .ndo_set_multicast_list = eth_set_mcast_list, | 1143 | .ndo_set_multicast_list = eth_set_mcast_list, |
1144 | .ndo_do_ioctl = eth_ioctl, | 1144 | .ndo_do_ioctl = eth_ioctl, |
1145 | 1145 | .ndo_change_mtu = eth_change_mtu, | |
1146 | .ndo_set_mac_address = eth_mac_addr, | ||
1147 | .ndo_validate_addr = eth_validate_addr, | ||
1146 | }; | 1148 | }; |
1147 | 1149 | ||
1148 | static int __devinit eth_init_one(struct platform_device *pdev) | 1150 | static int __devinit eth_init_one(struct platform_device *pdev) |
diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c new file mode 100644 index 000000000000..616fb7985a34 --- /dev/null +++ b/drivers/net/arm/w90p910_ether.c | |||
@@ -0,0 +1,1105 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Nuvoton technology corporation. | ||
3 | * | ||
4 | * Wan ZongShun <mcuos.com@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation;version 2 of the License. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/mii.h> | ||
15 | #include <linux/netdevice.h> | ||
16 | #include <linux/etherdevice.h> | ||
17 | #include <linux/skbuff.h> | ||
18 | #include <linux/ethtool.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/clk.h> | ||
21 | |||
22 | #define DRV_MODULE_NAME "w90p910-emc" | ||
23 | #define DRV_MODULE_VERSION "0.1" | ||
24 | |||
25 | /* Ethernet MAC Registers */ | ||
26 | #define REG_CAMCMR 0x00 | ||
27 | #define REG_CAMEN 0x04 | ||
28 | #define REG_CAMM_BASE 0x08 | ||
29 | #define REG_CAML_BASE 0x0c | ||
30 | #define REG_TXDLSA 0x88 | ||
31 | #define REG_RXDLSA 0x8C | ||
32 | #define REG_MCMDR 0x90 | ||
33 | #define REG_MIID 0x94 | ||
34 | #define REG_MIIDA 0x98 | ||
35 | #define REG_FFTCR 0x9C | ||
36 | #define REG_TSDR 0xa0 | ||
37 | #define REG_RSDR 0xa4 | ||
38 | #define REG_DMARFC 0xa8 | ||
39 | #define REG_MIEN 0xac | ||
40 | #define REG_MISTA 0xb0 | ||
41 | #define REG_CTXDSA 0xcc | ||
42 | #define REG_CTXBSA 0xd0 | ||
43 | #define REG_CRXDSA 0xd4 | ||
44 | #define REG_CRXBSA 0xd8 | ||
45 | |||
46 | /* mac controller bit */ | ||
47 | #define MCMDR_RXON 0x01 | ||
48 | #define MCMDR_ACP (0x01 << 3) | ||
49 | #define MCMDR_SPCRC (0x01 << 5) | ||
50 | #define MCMDR_TXON (0x01 << 8) | ||
51 | #define MCMDR_FDUP (0x01 << 18) | ||
52 | #define MCMDR_ENMDC (0x01 << 19) | ||
53 | #define MCMDR_OPMOD (0x01 << 20) | ||
54 | #define SWR (0x01 << 24) | ||
55 | |||
56 | /* cam command regiser */ | ||
57 | #define CAMCMR_AUP 0x01 | ||
58 | #define CAMCMR_AMP (0x01 << 1) | ||
59 | #define CAMCMR_ABP (0x01 << 2) | ||
60 | #define CAMCMR_CCAM (0x01 << 3) | ||
61 | #define CAMCMR_ECMP (0x01 << 4) | ||
62 | #define CAM0EN 0x01 | ||
63 | |||
64 | /* mac mii controller bit */ | ||
65 | #define MDCCR (0x0a << 20) | ||
66 | #define PHYAD (0x01 << 8) | ||
67 | #define PHYWR (0x01 << 16) | ||
68 | #define PHYBUSY (0x01 << 17) | ||
69 | #define PHYPRESP (0x01 << 18) | ||
70 | #define CAM_ENTRY_SIZE 0x08 | ||
71 | |||
72 | /* rx and tx status */ | ||
73 | #define TXDS_TXCP (0x01 << 19) | ||
74 | #define RXDS_CRCE (0x01 << 17) | ||
75 | #define RXDS_PTLE (0x01 << 19) | ||
76 | #define RXDS_RXGD (0x01 << 20) | ||
77 | #define RXDS_ALIE (0x01 << 21) | ||
78 | #define RXDS_RP (0x01 << 22) | ||
79 | |||
80 | /* mac interrupt status*/ | ||
81 | #define MISTA_EXDEF (0x01 << 19) | ||
82 | #define MISTA_TXBERR (0x01 << 24) | ||
83 | #define MISTA_TDU (0x01 << 23) | ||
84 | #define MISTA_RDU (0x01 << 10) | ||
85 | #define MISTA_RXBERR (0x01 << 11) | ||
86 | |||
87 | #define ENSTART 0x01 | ||
88 | #define ENRXINTR 0x01 | ||
89 | #define ENRXGD (0x01 << 4) | ||
90 | #define ENRXBERR (0x01 << 11) | ||
91 | #define ENTXINTR (0x01 << 16) | ||
92 | #define ENTXCP (0x01 << 18) | ||
93 | #define ENTXABT (0x01 << 21) | ||
94 | #define ENTXBERR (0x01 << 24) | ||
95 | #define ENMDC (0x01 << 19) | ||
96 | #define PHYBUSY (0x01 << 17) | ||
97 | #define MDCCR_VAL 0xa00000 | ||
98 | |||
99 | /* rx and tx owner bit */ | ||
100 | #define RX_OWEN_DMA (0x01 << 31) | ||
101 | #define RX_OWEN_CPU (~(0x03 << 30)) | ||
102 | #define TX_OWEN_DMA (0x01 << 31) | ||
103 | #define TX_OWEN_CPU (~(0x01 << 31)) | ||
104 | |||
105 | /* tx frame desc controller bit */ | ||
106 | #define MACTXINTEN 0x04 | ||
107 | #define CRCMODE 0x02 | ||
108 | #define PADDINGMODE 0x01 | ||
109 | |||
110 | /* fftcr controller bit */ | ||
111 | #define TXTHD (0x03 << 8) | ||
112 | #define BLENGTH (0x01 << 20) | ||
113 | |||
114 | /* global setting for driver */ | ||
115 | #define RX_DESC_SIZE 50 | ||
116 | #define TX_DESC_SIZE 10 | ||
117 | #define MAX_RBUFF_SZ 0x600 | ||
118 | #define MAX_TBUFF_SZ 0x600 | ||
119 | #define TX_TIMEOUT 50 | ||
120 | #define DELAY 1000 | ||
121 | #define CAM0 0x0 | ||
122 | |||
123 | static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg); | ||
124 | |||
125 | struct w90p910_rxbd { | ||
126 | unsigned int sl; | ||
127 | unsigned int buffer; | ||
128 | unsigned int reserved; | ||
129 | unsigned int next; | ||
130 | }; | ||
131 | |||
132 | struct w90p910_txbd { | ||
133 | unsigned int mode; | ||
134 | unsigned int buffer; | ||
135 | unsigned int sl; | ||
136 | unsigned int next; | ||
137 | }; | ||
138 | |||
139 | struct recv_pdesc { | ||
140 | struct w90p910_rxbd desclist[RX_DESC_SIZE]; | ||
141 | char recv_buf[RX_DESC_SIZE][MAX_RBUFF_SZ]; | ||
142 | }; | ||
143 | |||
144 | struct tran_pdesc { | ||
145 | struct w90p910_txbd desclist[TX_DESC_SIZE]; | ||
146 | char tran_buf[RX_DESC_SIZE][MAX_TBUFF_SZ]; | ||
147 | }; | ||
148 | |||
149 | struct w90p910_ether { | ||
150 | struct recv_pdesc *rdesc; | ||
151 | struct recv_pdesc *rdesc_phys; | ||
152 | struct tran_pdesc *tdesc; | ||
153 | struct tran_pdesc *tdesc_phys; | ||
154 | struct net_device_stats stats; | ||
155 | struct platform_device *pdev; | ||
156 | struct sk_buff *skb; | ||
157 | struct clk *clk; | ||
158 | struct clk *rmiiclk; | ||
159 | struct mii_if_info mii; | ||
160 | struct timer_list check_timer; | ||
161 | void __iomem *reg; | ||
162 | unsigned int rxirq; | ||
163 | unsigned int txirq; | ||
164 | unsigned int cur_tx; | ||
165 | unsigned int cur_rx; | ||
166 | unsigned int finish_tx; | ||
167 | unsigned int rx_packets; | ||
168 | unsigned int rx_bytes; | ||
169 | unsigned int start_tx_ptr; | ||
170 | unsigned int start_rx_ptr; | ||
171 | unsigned int linkflag; | ||
172 | spinlock_t lock; | ||
173 | }; | ||
174 | |||
175 | static void update_linkspeed_register(struct net_device *dev, | ||
176 | unsigned int speed, unsigned int duplex) | ||
177 | { | ||
178 | struct w90p910_ether *ether = netdev_priv(dev); | ||
179 | unsigned int val; | ||
180 | |||
181 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
182 | |||
183 | if (speed == SPEED_100) { | ||
184 | /* 100 full/half duplex */ | ||
185 | if (duplex == DUPLEX_FULL) { | ||
186 | val |= (MCMDR_OPMOD | MCMDR_FDUP); | ||
187 | } else { | ||
188 | val |= MCMDR_OPMOD; | ||
189 | val &= ~MCMDR_FDUP; | ||
190 | } | ||
191 | } else { | ||
192 | /* 10 full/half duplex */ | ||
193 | if (duplex == DUPLEX_FULL) { | ||
194 | val |= MCMDR_FDUP; | ||
195 | val &= ~MCMDR_OPMOD; | ||
196 | } else { | ||
197 | val &= ~(MCMDR_FDUP | MCMDR_OPMOD); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
202 | } | ||
203 | |||
204 | static void update_linkspeed(struct net_device *dev) | ||
205 | { | ||
206 | struct w90p910_ether *ether = netdev_priv(dev); | ||
207 | struct platform_device *pdev; | ||
208 | unsigned int bmsr, bmcr, lpa, speed, duplex; | ||
209 | |||
210 | pdev = ether->pdev; | ||
211 | |||
212 | if (!mii_link_ok(ðer->mii)) { | ||
213 | ether->linkflag = 0x0; | ||
214 | netif_carrier_off(dev); | ||
215 | dev_warn(&pdev->dev, "%s: Link down.\n", dev->name); | ||
216 | return; | ||
217 | } | ||
218 | |||
219 | if (ether->linkflag == 1) | ||
220 | return; | ||
221 | |||
222 | bmsr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMSR); | ||
223 | bmcr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMCR); | ||
224 | |||
225 | if (bmcr & BMCR_ANENABLE) { | ||
226 | if (!(bmsr & BMSR_ANEGCOMPLETE)) | ||
227 | return; | ||
228 | |||
229 | lpa = w90p910_mdio_read(dev, ether->mii.phy_id, MII_LPA); | ||
230 | |||
231 | if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) | ||
232 | speed = SPEED_100; | ||
233 | else | ||
234 | speed = SPEED_10; | ||
235 | |||
236 | if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) | ||
237 | duplex = DUPLEX_FULL; | ||
238 | else | ||
239 | duplex = DUPLEX_HALF; | ||
240 | |||
241 | } else { | ||
242 | speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10; | ||
243 | duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; | ||
244 | } | ||
245 | |||
246 | update_linkspeed_register(dev, speed, duplex); | ||
247 | |||
248 | dev_info(&pdev->dev, "%s: Link now %i-%s\n", dev->name, speed, | ||
249 | (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); | ||
250 | ether->linkflag = 0x01; | ||
251 | |||
252 | netif_carrier_on(dev); | ||
253 | } | ||
254 | |||
255 | static void w90p910_check_link(unsigned long dev_id) | ||
256 | { | ||
257 | struct net_device *dev = (struct net_device *) dev_id; | ||
258 | struct w90p910_ether *ether = netdev_priv(dev); | ||
259 | |||
260 | update_linkspeed(dev); | ||
261 | mod_timer(ðer->check_timer, jiffies + msecs_to_jiffies(1000)); | ||
262 | } | ||
263 | |||
264 | static void w90p910_write_cam(struct net_device *dev, | ||
265 | unsigned int x, unsigned char *pval) | ||
266 | { | ||
267 | struct w90p910_ether *ether = netdev_priv(dev); | ||
268 | unsigned int msw, lsw; | ||
269 | |||
270 | msw = (pval[0] << 24) | (pval[1] << 16) | (pval[2] << 8) | pval[3]; | ||
271 | |||
272 | lsw = (pval[4] << 24) | (pval[5] << 16); | ||
273 | |||
274 | __raw_writel(lsw, ether->reg + REG_CAML_BASE + x * CAM_ENTRY_SIZE); | ||
275 | __raw_writel(msw, ether->reg + REG_CAMM_BASE + x * CAM_ENTRY_SIZE); | ||
276 | } | ||
277 | |||
278 | static void w90p910_init_desc(struct net_device *dev) | ||
279 | { | ||
280 | struct w90p910_ether *ether; | ||
281 | struct w90p910_txbd *tdesc, *tdesc_phys; | ||
282 | struct w90p910_rxbd *rdesc, *rdesc_phys; | ||
283 | unsigned int i, j; | ||
284 | |||
285 | ether = netdev_priv(dev); | ||
286 | |||
287 | ether->tdesc = (struct tran_pdesc *) | ||
288 | dma_alloc_coherent(NULL, sizeof(struct tran_pdesc), | ||
289 | (dma_addr_t *) ðer->tdesc_phys, GFP_KERNEL); | ||
290 | |||
291 | ether->rdesc = (struct recv_pdesc *) | ||
292 | dma_alloc_coherent(NULL, sizeof(struct recv_pdesc), | ||
293 | (dma_addr_t *) ðer->rdesc_phys, GFP_KERNEL); | ||
294 | |||
295 | for (i = 0; i < TX_DESC_SIZE; i++) { | ||
296 | tdesc = &(ether->tdesc->desclist[i]); | ||
297 | |||
298 | j = ((i + 1) / TX_DESC_SIZE); | ||
299 | |||
300 | if (j != 0) { | ||
301 | tdesc_phys = &(ether->tdesc_phys->desclist[0]); | ||
302 | ether->start_tx_ptr = (unsigned int)tdesc_phys; | ||
303 | tdesc->next = (unsigned int)ether->start_tx_ptr; | ||
304 | } else { | ||
305 | tdesc_phys = &(ether->tdesc_phys->desclist[i+1]); | ||
306 | tdesc->next = (unsigned int)tdesc_phys; | ||
307 | } | ||
308 | |||
309 | tdesc->buffer = (unsigned int)ether->tdesc_phys->tran_buf[i]; | ||
310 | tdesc->sl = 0; | ||
311 | tdesc->mode = 0; | ||
312 | } | ||
313 | |||
314 | for (i = 0; i < RX_DESC_SIZE; i++) { | ||
315 | rdesc = &(ether->rdesc->desclist[i]); | ||
316 | |||
317 | j = ((i + 1) / RX_DESC_SIZE); | ||
318 | |||
319 | if (j != 0) { | ||
320 | rdesc_phys = &(ether->rdesc_phys->desclist[0]); | ||
321 | ether->start_rx_ptr = (unsigned int)rdesc_phys; | ||
322 | rdesc->next = (unsigned int)ether->start_rx_ptr; | ||
323 | } else { | ||
324 | rdesc_phys = &(ether->rdesc_phys->desclist[i+1]); | ||
325 | rdesc->next = (unsigned int)rdesc_phys; | ||
326 | } | ||
327 | |||
328 | rdesc->sl = RX_OWEN_DMA; | ||
329 | rdesc->buffer = (unsigned int)ether->rdesc_phys->recv_buf[i]; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | static void w90p910_set_fifo_threshold(struct net_device *dev) | ||
334 | { | ||
335 | struct w90p910_ether *ether = netdev_priv(dev); | ||
336 | unsigned int val; | ||
337 | |||
338 | val = TXTHD | BLENGTH; | ||
339 | __raw_writel(val, ether->reg + REG_FFTCR); | ||
340 | } | ||
341 | |||
342 | static void w90p910_return_default_idle(struct net_device *dev) | ||
343 | { | ||
344 | struct w90p910_ether *ether = netdev_priv(dev); | ||
345 | unsigned int val; | ||
346 | |||
347 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
348 | val |= SWR; | ||
349 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
350 | } | ||
351 | |||
352 | static void w90p910_trigger_rx(struct net_device *dev) | ||
353 | { | ||
354 | struct w90p910_ether *ether = netdev_priv(dev); | ||
355 | |||
356 | __raw_writel(ENSTART, ether->reg + REG_RSDR); | ||
357 | } | ||
358 | |||
359 | static void w90p910_trigger_tx(struct net_device *dev) | ||
360 | { | ||
361 | struct w90p910_ether *ether = netdev_priv(dev); | ||
362 | |||
363 | __raw_writel(ENSTART, ether->reg + REG_TSDR); | ||
364 | } | ||
365 | |||
366 | static void w90p910_enable_mac_interrupt(struct net_device *dev) | ||
367 | { | ||
368 | struct w90p910_ether *ether = netdev_priv(dev); | ||
369 | unsigned int val; | ||
370 | |||
371 | val = ENTXINTR | ENRXINTR | ENRXGD | ENTXCP; | ||
372 | val |= ENTXBERR | ENRXBERR | ENTXABT; | ||
373 | |||
374 | __raw_writel(val, ether->reg + REG_MIEN); | ||
375 | } | ||
376 | |||
377 | static void w90p910_get_and_clear_int(struct net_device *dev, | ||
378 | unsigned int *val) | ||
379 | { | ||
380 | struct w90p910_ether *ether = netdev_priv(dev); | ||
381 | |||
382 | *val = __raw_readl(ether->reg + REG_MISTA); | ||
383 | __raw_writel(*val, ether->reg + REG_MISTA); | ||
384 | } | ||
385 | |||
386 | static void w90p910_set_global_maccmd(struct net_device *dev) | ||
387 | { | ||
388 | struct w90p910_ether *ether = netdev_priv(dev); | ||
389 | unsigned int val; | ||
390 | |||
391 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
392 | val |= MCMDR_SPCRC | MCMDR_ENMDC | MCMDR_ACP | ENMDC; | ||
393 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
394 | } | ||
395 | |||
396 | static void w90p910_enable_cam(struct net_device *dev) | ||
397 | { | ||
398 | struct w90p910_ether *ether = netdev_priv(dev); | ||
399 | unsigned int val; | ||
400 | |||
401 | w90p910_write_cam(dev, CAM0, dev->dev_addr); | ||
402 | |||
403 | val = __raw_readl(ether->reg + REG_CAMEN); | ||
404 | val |= CAM0EN; | ||
405 | __raw_writel(val, ether->reg + REG_CAMEN); | ||
406 | } | ||
407 | |||
408 | static void w90p910_enable_cam_command(struct net_device *dev) | ||
409 | { | ||
410 | struct w90p910_ether *ether = netdev_priv(dev); | ||
411 | unsigned int val; | ||
412 | |||
413 | val = CAMCMR_ECMP | CAMCMR_ABP | CAMCMR_AMP; | ||
414 | __raw_writel(val, ether->reg + REG_CAMCMR); | ||
415 | } | ||
416 | |||
417 | static void w90p910_enable_tx(struct net_device *dev, unsigned int enable) | ||
418 | { | ||
419 | struct w90p910_ether *ether = netdev_priv(dev); | ||
420 | unsigned int val; | ||
421 | |||
422 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
423 | |||
424 | if (enable) | ||
425 | val |= MCMDR_TXON; | ||
426 | else | ||
427 | val &= ~MCMDR_TXON; | ||
428 | |||
429 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
430 | } | ||
431 | |||
432 | static void w90p910_enable_rx(struct net_device *dev, unsigned int enable) | ||
433 | { | ||
434 | struct w90p910_ether *ether = netdev_priv(dev); | ||
435 | unsigned int val; | ||
436 | |||
437 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
438 | |||
439 | if (enable) | ||
440 | val |= MCMDR_RXON; | ||
441 | else | ||
442 | val &= ~MCMDR_RXON; | ||
443 | |||
444 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
445 | } | ||
446 | |||
447 | static void w90p910_set_curdest(struct net_device *dev) | ||
448 | { | ||
449 | struct w90p910_ether *ether = netdev_priv(dev); | ||
450 | |||
451 | __raw_writel(ether->start_rx_ptr, ether->reg + REG_RXDLSA); | ||
452 | __raw_writel(ether->start_tx_ptr, ether->reg + REG_TXDLSA); | ||
453 | } | ||
454 | |||
455 | static void w90p910_reset_mac(struct net_device *dev) | ||
456 | { | ||
457 | struct w90p910_ether *ether = netdev_priv(dev); | ||
458 | |||
459 | spin_lock(ðer->lock); | ||
460 | |||
461 | w90p910_enable_tx(dev, 0); | ||
462 | w90p910_enable_rx(dev, 0); | ||
463 | w90p910_set_fifo_threshold(dev); | ||
464 | w90p910_return_default_idle(dev); | ||
465 | |||
466 | if (!netif_queue_stopped(dev)) | ||
467 | netif_stop_queue(dev); | ||
468 | |||
469 | w90p910_init_desc(dev); | ||
470 | |||
471 | dev->trans_start = jiffies; | ||
472 | ether->cur_tx = 0x0; | ||
473 | ether->finish_tx = 0x0; | ||
474 | ether->cur_rx = 0x0; | ||
475 | |||
476 | w90p910_set_curdest(dev); | ||
477 | w90p910_enable_cam(dev); | ||
478 | w90p910_enable_cam_command(dev); | ||
479 | w90p910_enable_mac_interrupt(dev); | ||
480 | w90p910_enable_tx(dev, 1); | ||
481 | w90p910_enable_rx(dev, 1); | ||
482 | w90p910_trigger_tx(dev); | ||
483 | w90p910_trigger_rx(dev); | ||
484 | |||
485 | dev->trans_start = jiffies; | ||
486 | |||
487 | if (netif_queue_stopped(dev)) | ||
488 | netif_wake_queue(dev); | ||
489 | |||
490 | spin_unlock(ðer->lock); | ||
491 | } | ||
492 | |||
493 | static void w90p910_mdio_write(struct net_device *dev, | ||
494 | int phy_id, int reg, int data) | ||
495 | { | ||
496 | struct w90p910_ether *ether = netdev_priv(dev); | ||
497 | struct platform_device *pdev; | ||
498 | unsigned int val, i; | ||
499 | |||
500 | pdev = ether->pdev; | ||
501 | |||
502 | __raw_writel(data, ether->reg + REG_MIID); | ||
503 | |||
504 | val = (phy_id << 0x08) | reg; | ||
505 | val |= PHYBUSY | PHYWR | MDCCR_VAL; | ||
506 | __raw_writel(val, ether->reg + REG_MIIDA); | ||
507 | |||
508 | for (i = 0; i < DELAY; i++) { | ||
509 | if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0) | ||
510 | break; | ||
511 | } | ||
512 | |||
513 | if (i == DELAY) | ||
514 | dev_warn(&pdev->dev, "mdio write timed out\n"); | ||
515 | } | ||
516 | |||
517 | static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg) | ||
518 | { | ||
519 | struct w90p910_ether *ether = netdev_priv(dev); | ||
520 | struct platform_device *pdev; | ||
521 | unsigned int val, i, data; | ||
522 | |||
523 | pdev = ether->pdev; | ||
524 | |||
525 | val = (phy_id << 0x08) | reg; | ||
526 | val |= PHYBUSY | MDCCR_VAL; | ||
527 | __raw_writel(val, ether->reg + REG_MIIDA); | ||
528 | |||
529 | for (i = 0; i < DELAY; i++) { | ||
530 | if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0) | ||
531 | break; | ||
532 | } | ||
533 | |||
534 | if (i == DELAY) { | ||
535 | dev_warn(&pdev->dev, "mdio read timed out\n"); | ||
536 | data = 0xffff; | ||
537 | } else { | ||
538 | data = __raw_readl(ether->reg + REG_MIID); | ||
539 | } | ||
540 | |||
541 | return data; | ||
542 | } | ||
543 | |||
544 | static int set_mac_address(struct net_device *dev, void *addr) | ||
545 | { | ||
546 | struct sockaddr *address = addr; | ||
547 | |||
548 | if (!is_valid_ether_addr(address->sa_data)) | ||
549 | return -EADDRNOTAVAIL; | ||
550 | |||
551 | memcpy(dev->dev_addr, address->sa_data, dev->addr_len); | ||
552 | w90p910_write_cam(dev, CAM0, dev->dev_addr); | ||
553 | |||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | static int w90p910_ether_close(struct net_device *dev) | ||
558 | { | ||
559 | struct w90p910_ether *ether = netdev_priv(dev); | ||
560 | |||
561 | dma_free_writecombine(NULL, sizeof(struct w90p910_rxbd), | ||
562 | ether->rdesc, (dma_addr_t)ether->rdesc_phys); | ||
563 | dma_free_writecombine(NULL, sizeof(struct w90p910_txbd), | ||
564 | ether->tdesc, (dma_addr_t)ether->tdesc_phys); | ||
565 | |||
566 | netif_stop_queue(dev); | ||
567 | |||
568 | del_timer_sync(ðer->check_timer); | ||
569 | clk_disable(ether->rmiiclk); | ||
570 | clk_disable(ether->clk); | ||
571 | |||
572 | free_irq(ether->txirq, dev); | ||
573 | free_irq(ether->rxirq, dev); | ||
574 | |||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | static struct net_device_stats *w90p910_ether_stats(struct net_device *dev) | ||
579 | { | ||
580 | struct w90p910_ether *ether; | ||
581 | |||
582 | ether = netdev_priv(dev); | ||
583 | |||
584 | return ðer->stats; | ||
585 | } | ||
586 | |||
587 | static int w90p910_send_frame(struct net_device *dev, | ||
588 | unsigned char *data, int length) | ||
589 | { | ||
590 | struct w90p910_ether *ether; | ||
591 | struct w90p910_txbd *txbd; | ||
592 | struct platform_device *pdev; | ||
593 | unsigned char *buffer; | ||
594 | |||
595 | ether = netdev_priv(dev); | ||
596 | pdev = ether->pdev; | ||
597 | |||
598 | txbd = ðer->tdesc->desclist[ether->cur_tx]; | ||
599 | buffer = ether->tdesc->tran_buf[ether->cur_tx]; | ||
600 | if (length > 1514) { | ||
601 | dev_err(&pdev->dev, "send data %d bytes, check it\n", length); | ||
602 | length = 1514; | ||
603 | } | ||
604 | |||
605 | txbd->sl = length & 0xFFFF; | ||
606 | |||
607 | memcpy(buffer, data, length); | ||
608 | |||
609 | txbd->mode = TX_OWEN_DMA | PADDINGMODE | CRCMODE | MACTXINTEN; | ||
610 | |||
611 | w90p910_enable_tx(dev, 1); | ||
612 | |||
613 | w90p910_trigger_tx(dev); | ||
614 | |||
615 | ether->cur_tx = (ether->cur_tx+1) % TX_DESC_SIZE; | ||
616 | txbd = ðer->tdesc->desclist[ether->cur_tx]; | ||
617 | |||
618 | dev->trans_start = jiffies; | ||
619 | |||
620 | if (txbd->mode & TX_OWEN_DMA) | ||
621 | netif_stop_queue(dev); | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static int w90p910_ether_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
627 | { | ||
628 | struct w90p910_ether *ether = netdev_priv(dev); | ||
629 | |||
630 | if (!(w90p910_send_frame(dev, skb->data, skb->len))) { | ||
631 | ether->skb = skb; | ||
632 | dev_kfree_skb_irq(skb); | ||
633 | return 0; | ||
634 | } | ||
635 | return -1; | ||
636 | } | ||
637 | |||
638 | static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id) | ||
639 | { | ||
640 | struct w90p910_ether *ether; | ||
641 | struct w90p910_txbd *txbd; | ||
642 | struct platform_device *pdev; | ||
643 | struct tran_pdesc *tran_pdesc; | ||
644 | struct net_device *dev; | ||
645 | unsigned int cur_entry, entry, status; | ||
646 | |||
647 | dev = (struct net_device *)dev_id; | ||
648 | ether = netdev_priv(dev); | ||
649 | pdev = ether->pdev; | ||
650 | |||
651 | spin_lock(ðer->lock); | ||
652 | |||
653 | w90p910_get_and_clear_int(dev, &status); | ||
654 | |||
655 | cur_entry = __raw_readl(ether->reg + REG_CTXDSA); | ||
656 | |||
657 | tran_pdesc = ether->tdesc_phys; | ||
658 | entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]); | ||
659 | |||
660 | while (entry != cur_entry) { | ||
661 | txbd = ðer->tdesc->desclist[ether->finish_tx]; | ||
662 | |||
663 | ether->finish_tx = (ether->finish_tx + 1) % TX_DESC_SIZE; | ||
664 | |||
665 | if (txbd->sl & TXDS_TXCP) { | ||
666 | ether->stats.tx_packets++; | ||
667 | ether->stats.tx_bytes += txbd->sl & 0xFFFF; | ||
668 | } else { | ||
669 | ether->stats.tx_errors++; | ||
670 | } | ||
671 | |||
672 | txbd->sl = 0x0; | ||
673 | txbd->mode = 0x0; | ||
674 | |||
675 | if (netif_queue_stopped(dev)) | ||
676 | netif_wake_queue(dev); | ||
677 | |||
678 | entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]); | ||
679 | } | ||
680 | |||
681 | if (status & MISTA_EXDEF) { | ||
682 | dev_err(&pdev->dev, "emc defer exceed interrupt\n"); | ||
683 | } else if (status & MISTA_TXBERR) { | ||
684 | dev_err(&pdev->dev, "emc bus error interrupt\n"); | ||
685 | w90p910_reset_mac(dev); | ||
686 | } else if (status & MISTA_TDU) { | ||
687 | if (netif_queue_stopped(dev)) | ||
688 | netif_wake_queue(dev); | ||
689 | } | ||
690 | |||
691 | spin_unlock(ðer->lock); | ||
692 | |||
693 | return IRQ_HANDLED; | ||
694 | } | ||
695 | |||
696 | static void netdev_rx(struct net_device *dev) | ||
697 | { | ||
698 | struct w90p910_ether *ether; | ||
699 | struct w90p910_rxbd *rxbd; | ||
700 | struct platform_device *pdev; | ||
701 | struct recv_pdesc *rdesc_phys; | ||
702 | struct sk_buff *skb; | ||
703 | unsigned char *data; | ||
704 | unsigned int length, status, val, entry; | ||
705 | |||
706 | ether = netdev_priv(dev); | ||
707 | pdev = ether->pdev; | ||
708 | rdesc_phys = ether->rdesc_phys; | ||
709 | |||
710 | rxbd = ðer->rdesc->desclist[ether->cur_rx]; | ||
711 | |||
712 | do { | ||
713 | val = __raw_readl(ether->reg + REG_CRXDSA); | ||
714 | entry = (unsigned int)&rdesc_phys->desclist[ether->cur_rx]; | ||
715 | |||
716 | if (val == entry) | ||
717 | break; | ||
718 | |||
719 | status = rxbd->sl; | ||
720 | length = status & 0xFFFF; | ||
721 | |||
722 | if (status & RXDS_RXGD) { | ||
723 | data = ether->rdesc->recv_buf[ether->cur_rx]; | ||
724 | skb = dev_alloc_skb(length+2); | ||
725 | if (!skb) { | ||
726 | dev_err(&pdev->dev, "get skb buffer error\n"); | ||
727 | ether->stats.rx_dropped++; | ||
728 | return; | ||
729 | } | ||
730 | |||
731 | skb->dev = dev; | ||
732 | skb_reserve(skb, 2); | ||
733 | skb_put(skb, length); | ||
734 | skb_copy_to_linear_data(skb, data, length); | ||
735 | skb->protocol = eth_type_trans(skb, dev); | ||
736 | ether->stats.rx_packets++; | ||
737 | ether->stats.rx_bytes += length; | ||
738 | netif_rx(skb); | ||
739 | } else { | ||
740 | ether->stats.rx_errors++; | ||
741 | |||
742 | if (status & RXDS_RP) { | ||
743 | dev_err(&pdev->dev, "rx runt err\n"); | ||
744 | ether->stats.rx_length_errors++; | ||
745 | } else if (status & RXDS_CRCE) { | ||
746 | dev_err(&pdev->dev, "rx crc err\n"); | ||
747 | ether->stats.rx_crc_errors++; | ||
748 | } | ||
749 | |||
750 | if (status & RXDS_ALIE) { | ||
751 | dev_err(&pdev->dev, "rx aligment err\n"); | ||
752 | ether->stats.rx_frame_errors++; | ||
753 | } else if (status & RXDS_PTLE) { | ||
754 | dev_err(&pdev->dev, "rx longer err\n"); | ||
755 | ether->stats.rx_over_errors++; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | rxbd->sl = RX_OWEN_DMA; | ||
760 | rxbd->reserved = 0x0; | ||
761 | ether->cur_rx = (ether->cur_rx+1) % RX_DESC_SIZE; | ||
762 | rxbd = ðer->rdesc->desclist[ether->cur_rx]; | ||
763 | |||
764 | dev->last_rx = jiffies; | ||
765 | } while (1); | ||
766 | } | ||
767 | |||
768 | static irqreturn_t w90p910_rx_interrupt(int irq, void *dev_id) | ||
769 | { | ||
770 | struct net_device *dev; | ||
771 | struct w90p910_ether *ether; | ||
772 | struct platform_device *pdev; | ||
773 | unsigned int status; | ||
774 | |||
775 | dev = (struct net_device *)dev_id; | ||
776 | ether = netdev_priv(dev); | ||
777 | pdev = ether->pdev; | ||
778 | |||
779 | spin_lock(ðer->lock); | ||
780 | |||
781 | w90p910_get_and_clear_int(dev, &status); | ||
782 | |||
783 | if (status & MISTA_RDU) { | ||
784 | netdev_rx(dev); | ||
785 | |||
786 | w90p910_trigger_rx(dev); | ||
787 | |||
788 | spin_unlock(ðer->lock); | ||
789 | return IRQ_HANDLED; | ||
790 | } else if (status & MISTA_RXBERR) { | ||
791 | dev_err(&pdev->dev, "emc rx bus error\n"); | ||
792 | w90p910_reset_mac(dev); | ||
793 | } | ||
794 | |||
795 | netdev_rx(dev); | ||
796 | spin_unlock(ðer->lock); | ||
797 | return IRQ_HANDLED; | ||
798 | } | ||
799 | |||
800 | static int w90p910_ether_open(struct net_device *dev) | ||
801 | { | ||
802 | struct w90p910_ether *ether; | ||
803 | struct platform_device *pdev; | ||
804 | |||
805 | ether = netdev_priv(dev); | ||
806 | pdev = ether->pdev; | ||
807 | |||
808 | w90p910_reset_mac(dev); | ||
809 | w90p910_set_fifo_threshold(dev); | ||
810 | w90p910_set_curdest(dev); | ||
811 | w90p910_enable_cam(dev); | ||
812 | w90p910_enable_cam_command(dev); | ||
813 | w90p910_enable_mac_interrupt(dev); | ||
814 | w90p910_set_global_maccmd(dev); | ||
815 | w90p910_enable_rx(dev, 1); | ||
816 | |||
817 | ether->rx_packets = 0x0; | ||
818 | ether->rx_bytes = 0x0; | ||
819 | |||
820 | if (request_irq(ether->txirq, w90p910_tx_interrupt, | ||
821 | 0x0, pdev->name, dev)) { | ||
822 | dev_err(&pdev->dev, "register irq tx failed\n"); | ||
823 | return -EAGAIN; | ||
824 | } | ||
825 | |||
826 | if (request_irq(ether->rxirq, w90p910_rx_interrupt, | ||
827 | 0x0, pdev->name, dev)) { | ||
828 | dev_err(&pdev->dev, "register irq rx failed\n"); | ||
829 | return -EAGAIN; | ||
830 | } | ||
831 | |||
832 | mod_timer(ðer->check_timer, jiffies + msecs_to_jiffies(1000)); | ||
833 | netif_start_queue(dev); | ||
834 | w90p910_trigger_rx(dev); | ||
835 | |||
836 | dev_info(&pdev->dev, "%s is OPENED\n", dev->name); | ||
837 | |||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | static void w90p910_ether_set_multicast_list(struct net_device *dev) | ||
842 | { | ||
843 | struct w90p910_ether *ether; | ||
844 | unsigned int rx_mode; | ||
845 | |||
846 | ether = netdev_priv(dev); | ||
847 | |||
848 | if (dev->flags & IFF_PROMISC) | ||
849 | rx_mode = CAMCMR_AUP | CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP; | ||
850 | else if ((dev->flags & IFF_ALLMULTI) || dev->mc_list) | ||
851 | rx_mode = CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP; | ||
852 | else | ||
853 | rx_mode = CAMCMR_ECMP | CAMCMR_ABP; | ||
854 | __raw_writel(rx_mode, ether->reg + REG_CAMCMR); | ||
855 | } | ||
856 | |||
857 | static int w90p910_ether_ioctl(struct net_device *dev, | ||
858 | struct ifreq *ifr, int cmd) | ||
859 | { | ||
860 | struct w90p910_ether *ether = netdev_priv(dev); | ||
861 | struct mii_ioctl_data *data = if_mii(ifr); | ||
862 | |||
863 | return generic_mii_ioctl(ðer->mii, data, cmd, NULL); | ||
864 | } | ||
865 | |||
866 | static void w90p910_get_drvinfo(struct net_device *dev, | ||
867 | struct ethtool_drvinfo *info) | ||
868 | { | ||
869 | strcpy(info->driver, DRV_MODULE_NAME); | ||
870 | strcpy(info->version, DRV_MODULE_VERSION); | ||
871 | } | ||
872 | |||
873 | static int w90p910_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
874 | { | ||
875 | struct w90p910_ether *ether = netdev_priv(dev); | ||
876 | return mii_ethtool_gset(ðer->mii, cmd); | ||
877 | } | ||
878 | |||
879 | static int w90p910_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
880 | { | ||
881 | struct w90p910_ether *ether = netdev_priv(dev); | ||
882 | return mii_ethtool_sset(ðer->mii, cmd); | ||
883 | } | ||
884 | |||
885 | static int w90p910_nway_reset(struct net_device *dev) | ||
886 | { | ||
887 | struct w90p910_ether *ether = netdev_priv(dev); | ||
888 | return mii_nway_restart(ðer->mii); | ||
889 | } | ||
890 | |||
891 | static u32 w90p910_get_link(struct net_device *dev) | ||
892 | { | ||
893 | struct w90p910_ether *ether = netdev_priv(dev); | ||
894 | return mii_link_ok(ðer->mii); | ||
895 | } | ||
896 | |||
897 | static const struct ethtool_ops w90p910_ether_ethtool_ops = { | ||
898 | .get_settings = w90p910_get_settings, | ||
899 | .set_settings = w90p910_set_settings, | ||
900 | .get_drvinfo = w90p910_get_drvinfo, | ||
901 | .nway_reset = w90p910_nway_reset, | ||
902 | .get_link = w90p910_get_link, | ||
903 | }; | ||
904 | |||
905 | static const struct net_device_ops w90p910_ether_netdev_ops = { | ||
906 | .ndo_open = w90p910_ether_open, | ||
907 | .ndo_stop = w90p910_ether_close, | ||
908 | .ndo_start_xmit = w90p910_ether_start_xmit, | ||
909 | .ndo_get_stats = w90p910_ether_stats, | ||
910 | .ndo_set_multicast_list = w90p910_ether_set_multicast_list, | ||
911 | .ndo_set_mac_address = set_mac_address, | ||
912 | .ndo_do_ioctl = w90p910_ether_ioctl, | ||
913 | .ndo_validate_addr = eth_validate_addr, | ||
914 | .ndo_change_mtu = eth_change_mtu, | ||
915 | }; | ||
916 | |||
917 | static void __init get_mac_address(struct net_device *dev) | ||
918 | { | ||
919 | struct w90p910_ether *ether = netdev_priv(dev); | ||
920 | struct platform_device *pdev; | ||
921 | char addr[6]; | ||
922 | |||
923 | pdev = ether->pdev; | ||
924 | |||
925 | addr[0] = 0x00; | ||
926 | addr[1] = 0x02; | ||
927 | addr[2] = 0xac; | ||
928 | addr[3] = 0x55; | ||
929 | addr[4] = 0x88; | ||
930 | addr[5] = 0xa8; | ||
931 | |||
932 | if (is_valid_ether_addr(addr)) | ||
933 | memcpy(dev->dev_addr, &addr, 0x06); | ||
934 | else | ||
935 | dev_err(&pdev->dev, "invalid mac address\n"); | ||
936 | } | ||
937 | |||
938 | static int w90p910_ether_setup(struct net_device *dev) | ||
939 | { | ||
940 | struct w90p910_ether *ether = netdev_priv(dev); | ||
941 | |||
942 | ether_setup(dev); | ||
943 | dev->netdev_ops = &w90p910_ether_netdev_ops; | ||
944 | dev->ethtool_ops = &w90p910_ether_ethtool_ops; | ||
945 | |||
946 | dev->tx_queue_len = 16; | ||
947 | dev->dma = 0x0; | ||
948 | dev->watchdog_timeo = TX_TIMEOUT; | ||
949 | |||
950 | get_mac_address(dev); | ||
951 | |||
952 | spin_lock_init(ðer->lock); | ||
953 | |||
954 | ether->cur_tx = 0x0; | ||
955 | ether->cur_rx = 0x0; | ||
956 | ether->finish_tx = 0x0; | ||
957 | ether->linkflag = 0x0; | ||
958 | ether->mii.phy_id = 0x01; | ||
959 | ether->mii.phy_id_mask = 0x1f; | ||
960 | ether->mii.reg_num_mask = 0x1f; | ||
961 | ether->mii.dev = dev; | ||
962 | ether->mii.mdio_read = w90p910_mdio_read; | ||
963 | ether->mii.mdio_write = w90p910_mdio_write; | ||
964 | |||
965 | setup_timer(ðer->check_timer, w90p910_check_link, | ||
966 | (unsigned long)dev); | ||
967 | |||
968 | return 0; | ||
969 | } | ||
970 | |||
971 | static int __devinit w90p910_ether_probe(struct platform_device *pdev) | ||
972 | { | ||
973 | struct w90p910_ether *ether; | ||
974 | struct net_device *dev; | ||
975 | struct resource *res; | ||
976 | int error; | ||
977 | |||
978 | dev = alloc_etherdev(sizeof(struct w90p910_ether)); | ||
979 | if (!dev) | ||
980 | return -ENOMEM; | ||
981 | |||
982 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
983 | if (res == NULL) { | ||
984 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
985 | error = -ENXIO; | ||
986 | goto failed_free; | ||
987 | } | ||
988 | |||
989 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
990 | if (res == NULL) { | ||
991 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
992 | error = -EBUSY; | ||
993 | goto failed_free; | ||
994 | } | ||
995 | |||
996 | ether = netdev_priv(dev); | ||
997 | |||
998 | ether->reg = ioremap(res->start, resource_size(res)); | ||
999 | if (ether->reg == NULL) { | ||
1000 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
1001 | error = -ENXIO; | ||
1002 | goto failed_free_mem; | ||
1003 | } | ||
1004 | |||
1005 | ether->txirq = platform_get_irq(pdev, 0); | ||
1006 | if (ether->txirq < 0) { | ||
1007 | dev_err(&pdev->dev, "failed to get ether tx irq\n"); | ||
1008 | error = -ENXIO; | ||
1009 | goto failed_free_io; | ||
1010 | } | ||
1011 | |||
1012 | ether->rxirq = platform_get_irq(pdev, 1); | ||
1013 | if (ether->rxirq < 0) { | ||
1014 | dev_err(&pdev->dev, "failed to get ether rx irq\n"); | ||
1015 | error = -ENXIO; | ||
1016 | goto failed_free_txirq; | ||
1017 | } | ||
1018 | |||
1019 | platform_set_drvdata(pdev, dev); | ||
1020 | |||
1021 | ether->clk = clk_get(&pdev->dev, NULL); | ||
1022 | if (IS_ERR(ether->clk)) { | ||
1023 | dev_err(&pdev->dev, "failed to get ether clock\n"); | ||
1024 | error = PTR_ERR(ether->clk); | ||
1025 | goto failed_free_rxirq; | ||
1026 | } | ||
1027 | |||
1028 | ether->rmiiclk = clk_get(&pdev->dev, "RMII"); | ||
1029 | if (IS_ERR(ether->rmiiclk)) { | ||
1030 | dev_err(&pdev->dev, "failed to get ether clock\n"); | ||
1031 | error = PTR_ERR(ether->rmiiclk); | ||
1032 | goto failed_put_clk; | ||
1033 | } | ||
1034 | |||
1035 | ether->pdev = pdev; | ||
1036 | |||
1037 | w90p910_ether_setup(dev); | ||
1038 | |||
1039 | error = register_netdev(dev); | ||
1040 | if (error != 0) { | ||
1041 | dev_err(&pdev->dev, "Regiter EMC w90p910 FAILED\n"); | ||
1042 | error = -ENODEV; | ||
1043 | goto failed_put_rmiiclk; | ||
1044 | } | ||
1045 | |||
1046 | return 0; | ||
1047 | failed_put_rmiiclk: | ||
1048 | clk_put(ether->rmiiclk); | ||
1049 | failed_put_clk: | ||
1050 | clk_put(ether->clk); | ||
1051 | failed_free_rxirq: | ||
1052 | free_irq(ether->rxirq, pdev); | ||
1053 | platform_set_drvdata(pdev, NULL); | ||
1054 | failed_free_txirq: | ||
1055 | free_irq(ether->txirq, pdev); | ||
1056 | failed_free_io: | ||
1057 | iounmap(ether->reg); | ||
1058 | failed_free_mem: | ||
1059 | release_mem_region(res->start, resource_size(res)); | ||
1060 | failed_free: | ||
1061 | free_netdev(dev); | ||
1062 | return error; | ||
1063 | } | ||
1064 | |||
1065 | static int __devexit w90p910_ether_remove(struct platform_device *pdev) | ||
1066 | { | ||
1067 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1068 | struct w90p910_ether *ether = netdev_priv(dev); | ||
1069 | |||
1070 | unregister_netdev(dev); | ||
1071 | clk_put(ether->rmiiclk); | ||
1072 | clk_put(ether->clk); | ||
1073 | del_timer_sync(ðer->check_timer); | ||
1074 | platform_set_drvdata(pdev, NULL); | ||
1075 | free_netdev(dev); | ||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | static struct platform_driver w90p910_ether_driver = { | ||
1080 | .probe = w90p910_ether_probe, | ||
1081 | .remove = __devexit_p(w90p910_ether_remove), | ||
1082 | .driver = { | ||
1083 | .name = "w90p910-emc", | ||
1084 | .owner = THIS_MODULE, | ||
1085 | }, | ||
1086 | }; | ||
1087 | |||
1088 | static int __init w90p910_ether_init(void) | ||
1089 | { | ||
1090 | return platform_driver_register(&w90p910_ether_driver); | ||
1091 | } | ||
1092 | |||
1093 | static void __exit w90p910_ether_exit(void) | ||
1094 | { | ||
1095 | platform_driver_unregister(&w90p910_ether_driver); | ||
1096 | } | ||
1097 | |||
1098 | module_init(w90p910_ether_init); | ||
1099 | module_exit(w90p910_ether_exit); | ||
1100 | |||
1101 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | ||
1102 | MODULE_DESCRIPTION("w90p910 MAC driver!"); | ||
1103 | MODULE_LICENSE("GPL"); | ||
1104 | MODULE_ALIAS("platform:w90p910-emc"); | ||
1105 | |||
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index 18b566ad4fd1..cf30e278f182 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c | |||
@@ -318,7 +318,7 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr) | |||
318 | pos3 = mca_read_stored_pos( slot, 3 ); | 318 | pos3 = mca_read_stored_pos( slot, 3 ); |
319 | pos4 = mca_read_stored_pos( slot, 4 ); | 319 | pos4 = mca_read_stored_pos( slot, 4 ); |
320 | 320 | ||
321 | for (l_i = 0; l_i < 0x09; l_i++) | 321 | for (l_i = 0; l_i < 8; l_i++) |
322 | if (( pos3 & 0x07) == at1700_ioaddr_pattern[l_i]) | 322 | if (( pos3 & 0x07) == at1700_ioaddr_pattern[l_i]) |
323 | break; | 323 | break; |
324 | ioaddr = at1700_mca_probe_list[l_i]; | 324 | ioaddr = at1700_mca_probe_list[l_i]; |
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index e1658ef3fcdf..2a1120ad2e74 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h | |||
@@ -188,14 +188,14 @@ struct atl1c_tpd_ext_desc { | |||
188 | #define RRS_HDS_TYPE_DATA 2 | 188 | #define RRS_HDS_TYPE_DATA 2 |
189 | 189 | ||
190 | #define RRS_IS_NO_HDS_TYPE(flag) \ | 190 | #define RRS_IS_NO_HDS_TYPE(flag) \ |
191 | (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == 0) | 191 | ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == 0) |
192 | 192 | ||
193 | #define RRS_IS_HDS_HEAD(flag) \ | 193 | #define RRS_IS_HDS_HEAD(flag) \ |
194 | (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \ | 194 | ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \ |
195 | RRS_HDS_TYPE_HEAD) | 195 | RRS_HDS_TYPE_HEAD) |
196 | 196 | ||
197 | #define RRS_IS_HDS_DATA(flag) \ | 197 | #define RRS_IS_HDS_DATA(flag) \ |
198 | (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \ | 198 | ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \ |
199 | RRS_HDS_TYPE_DATA) | 199 | RRS_HDS_TYPE_DATA) |
200 | 200 | ||
201 | /* rrs word 3 bit 0:31 */ | 201 | /* rrs word 3 bit 0:31 */ |
@@ -245,7 +245,7 @@ struct atl1c_tpd_ext_desc { | |||
245 | #define RRS_PACKET_TYPE_802_3 1 | 245 | #define RRS_PACKET_TYPE_802_3 1 |
246 | #define RRS_PACKET_TYPE_ETH 0 | 246 | #define RRS_PACKET_TYPE_ETH 0 |
247 | #define RRS_PACKET_IS_ETH(word) \ | 247 | #define RRS_PACKET_IS_ETH(word) \ |
248 | (((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK == \ | 248 | ((((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK) == \ |
249 | RRS_PACKET_TYPE_ETH) | 249 | RRS_PACKET_TYPE_ETH) |
250 | #define RRS_RXD_IS_VALID(word) \ | 250 | #define RRS_RXD_IS_VALID(word) \ |
251 | ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1) | 251 | ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1) |
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index cd547a205fb9..a383122679de 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c | |||
@@ -1689,7 +1689,7 @@ static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que, | |||
1689 | if (likely(RRS_RXD_IS_VALID(rrs->word3))) { | 1689 | if (likely(RRS_RXD_IS_VALID(rrs->word3))) { |
1690 | rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) & | 1690 | rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) & |
1691 | RRS_RX_RFD_CNT_MASK; | 1691 | RRS_RX_RFD_CNT_MASK; |
1692 | if (unlikely(rfd_num) != 1) | 1692 | if (unlikely(rfd_num != 1)) |
1693 | /* TODO support mul rfd*/ | 1693 | /* TODO support mul rfd*/ |
1694 | if (netif_msg_rx_err(adapter)) | 1694 | if (netif_msg_rx_err(adapter)) |
1695 | dev_warn(&pdev->dev, | 1695 | dev_warn(&pdev->dev, |
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index c734b1983ec1..204db961029e 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c | |||
@@ -2071,7 +2071,7 @@ static int atl2_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
2071 | if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)) | 2071 | if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)) |
2072 | return -EOPNOTSUPP; | 2072 | return -EOPNOTSUPP; |
2073 | 2073 | ||
2074 | if (wol->wolopts & (WAKE_MCAST|WAKE_BCAST|WAKE_MCAST)) | 2074 | if (wol->wolopts & (WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)) |
2075 | return -EOPNOTSUPP; | 2075 | return -EOPNOTSUPP; |
2076 | 2076 | ||
2077 | /* these settings will always override what we currently have */ | 2077 | /* these settings will always override what we currently have */ |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index c43f6a119295..dea3155688bb 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -667,7 +667,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
667 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 667 | struct be_queue_info *rxq = &adapter->rx_obj.q; |
668 | struct be_rx_page_info *page_info; | 668 | struct be_rx_page_info *page_info; |
669 | u16 rxq_idx, i, num_rcvd, j; | 669 | u16 rxq_idx, i, num_rcvd, j; |
670 | u32 pktsize, hdr_len, curr_frag_len; | 670 | u32 pktsize, hdr_len, curr_frag_len, size; |
671 | u8 *start; | 671 | u8 *start; |
672 | 672 | ||
673 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | 673 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); |
@@ -708,12 +708,13 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
708 | } | 708 | } |
709 | 709 | ||
710 | /* More frags present for this completion */ | 710 | /* More frags present for this completion */ |
711 | pktsize -= curr_frag_len; /* account for above copied frag */ | 711 | size = pktsize; |
712 | for (i = 1, j = 0; i < num_rcvd; i++) { | 712 | for (i = 1, j = 0; i < num_rcvd; i++) { |
713 | size -= curr_frag_len; | ||
713 | index_inc(&rxq_idx, rxq->len); | 714 | index_inc(&rxq_idx, rxq->len); |
714 | page_info = get_rx_page_info(adapter, rxq_idx); | 715 | page_info = get_rx_page_info(adapter, rxq_idx); |
715 | 716 | ||
716 | curr_frag_len = min(pktsize, rx_frag_size); | 717 | curr_frag_len = min(size, rx_frag_size); |
717 | 718 | ||
718 | /* Coalesce all frags from the same physical page in one slot */ | 719 | /* Coalesce all frags from the same physical page in one slot */ |
719 | if (page_info->page_offset == 0) { | 720 | if (page_info->page_offset == 0) { |
@@ -731,7 +732,6 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
731 | skb_shinfo(skb)->frags[j].size += curr_frag_len; | 732 | skb_shinfo(skb)->frags[j].size += curr_frag_len; |
732 | skb->len += curr_frag_len; | 733 | skb->len += curr_frag_len; |
733 | skb->data_len += curr_frag_len; | 734 | skb->data_len += curr_frag_len; |
734 | pktsize -= curr_frag_len; | ||
735 | 735 | ||
736 | memset(page_info, 0, sizeof(*page_info)); | 736 | memset(page_info, 0, sizeof(*page_info)); |
737 | } | 737 | } |
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index a76315dc7767..206144f2470f 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c | |||
@@ -431,7 +431,7 @@ bmac_init_phy(struct net_device *dev) | |||
431 | printk(KERN_DEBUG); | 431 | printk(KERN_DEBUG); |
432 | printk(KERN_CONT " %.4x", bmac_mif_read(dev, addr)); | 432 | printk(KERN_CONT " %.4x", bmac_mif_read(dev, addr)); |
433 | } | 433 | } |
434 | print(KERN_CONT "\n"); | 434 | printk(KERN_CONT "\n"); |
435 | 435 | ||
436 | if (bp->is_bmac_plus) { | 436 | if (bp->is_bmac_plus) { |
437 | unsigned int capable, ctrl; | 437 | unsigned int capable, ctrl; |
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index ed648acef7cf..2ee581a2cdec 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c | |||
@@ -4212,13 +4212,14 @@ static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port) | |||
4212 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, | 4212 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, |
4213 | u8 *version, u16 len) | 4213 | u8 *version, u16 len) |
4214 | { | 4214 | { |
4215 | struct bnx2x *bp = params->bp; | 4215 | struct bnx2x *bp; |
4216 | u32 ext_phy_type = 0; | 4216 | u32 ext_phy_type = 0; |
4217 | u32 spirom_ver = 0; | 4217 | u32 spirom_ver = 0; |
4218 | u8 status = 0 ; | 4218 | u8 status = 0 ; |
4219 | 4219 | ||
4220 | if (version == NULL || params == NULL) | 4220 | if (version == NULL || params == NULL) |
4221 | return -EINVAL; | 4221 | return -EINVAL; |
4222 | bp = params->bp; | ||
4222 | 4223 | ||
4223 | spirom_ver = REG_RD(bp, params->shmem_base + | 4224 | spirom_ver = REG_RD(bp, params->shmem_base + |
4224 | offsetof(struct shmem_region, | 4225 | offsetof(struct shmem_region, |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d927f71af8a3..aa1be1feceed 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1459,8 +1459,16 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1459 | * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond | 1459 | * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond |
1460 | */ | 1460 | */ |
1461 | if (bond->slave_cnt == 0) { | 1461 | if (bond->slave_cnt == 0) { |
1462 | if (slave_dev->type != ARPHRD_ETHER) | 1462 | if (bond_dev->type != slave_dev->type) { |
1463 | bond_setup_by_slave(bond_dev, slave_dev); | 1463 | dev_close(bond_dev); |
1464 | pr_debug("%s: change device type from %d to %d\n", | ||
1465 | bond_dev->name, bond_dev->type, slave_dev->type); | ||
1466 | if (slave_dev->type != ARPHRD_ETHER) | ||
1467 | bond_setup_by_slave(bond_dev, slave_dev); | ||
1468 | else | ||
1469 | ether_setup(bond_dev); | ||
1470 | dev_open(bond_dev); | ||
1471 | } | ||
1464 | } else if (bond_dev->type != slave_dev->type) { | 1472 | } else if (bond_dev->type != slave_dev->type) { |
1465 | pr_err(DRV_NAME ": %s ether type (%d) is different " | 1473 | pr_err(DRV_NAME ": %s ether type (%d) is different " |
1466 | "from other slaves (%d), can not enslave it.\n", | 1474 | "from other slaves (%d), can not enslave it.\n", |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 574daddc21bf..9e4283aff828 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -346,7 +346,7 @@ void can_restart(unsigned long data) | |||
346 | skb = dev_alloc_skb(sizeof(struct can_frame)); | 346 | skb = dev_alloc_skb(sizeof(struct can_frame)); |
347 | if (skb == NULL) { | 347 | if (skb == NULL) { |
348 | err = -ENOMEM; | 348 | err = -ENOMEM; |
349 | goto out; | 349 | goto restart; |
350 | } | 350 | } |
351 | skb->dev = dev; | 351 | skb->dev = dev; |
352 | skb->protocol = htons(ETH_P_CAN); | 352 | skb->protocol = htons(ETH_P_CAN); |
@@ -361,13 +361,13 @@ void can_restart(unsigned long data) | |||
361 | stats->rx_packets++; | 361 | stats->rx_packets++; |
362 | stats->rx_bytes += cf->can_dlc; | 362 | stats->rx_bytes += cf->can_dlc; |
363 | 363 | ||
364 | restart: | ||
364 | dev_dbg(dev->dev.parent, "restarted\n"); | 365 | dev_dbg(dev->dev.parent, "restarted\n"); |
365 | priv->can_stats.restarts++; | 366 | priv->can_stats.restarts++; |
366 | 367 | ||
367 | /* Now restart the device */ | 368 | /* Now restart the device */ |
368 | err = priv->do_set_mode(dev, CAN_MODE_START); | 369 | err = priv->do_set_mode(dev, CAN_MODE_START); |
369 | 370 | ||
370 | out: | ||
371 | netif_carrier_on(dev); | 371 | netif_carrier_on(dev); |
372 | if (err) | 372 | if (err) |
373 | dev_err(dev->dev.parent, "Error %d during restart", err); | 373 | dev_err(dev->dev.parent, "Error %d during restart", err); |
@@ -473,6 +473,10 @@ int open_candev(struct net_device *dev) | |||
473 | return -EINVAL; | 473 | return -EINVAL; |
474 | } | 474 | } |
475 | 475 | ||
476 | /* Switch carrier on if device was stopped while in bus-off state */ | ||
477 | if (!netif_carrier_ok(dev)) | ||
478 | netif_carrier_on(dev); | ||
479 | |||
476 | setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev); | 480 | setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev); |
477 | 481 | ||
478 | return 0; | 482 | return 0; |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 571f133a8fec..08ebee79d8a6 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
@@ -63,7 +63,6 @@ | |||
63 | #include <linux/can.h> | 63 | #include <linux/can.h> |
64 | #include <linux/can/dev.h> | 64 | #include <linux/can/dev.h> |
65 | #include <linux/can/error.h> | 65 | #include <linux/can/error.h> |
66 | #include <linux/can/dev.h> | ||
67 | 66 | ||
68 | #include "sja1000.h" | 67 | #include "sja1000.h" |
69 | 68 | ||
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 4d1515f45ba2..4869d77cbe91 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c | |||
@@ -227,7 +227,7 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, | |||
227 | } | 227 | } |
228 | 228 | ||
229 | rcu_read_lock(); | 229 | rcu_read_lock(); |
230 | ulp_ops = rcu_dereference(cp->ulp_ops[CNIC_ULP_ISCSI]); | 230 | ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]); |
231 | if (ulp_ops) | 231 | if (ulp_ops) |
232 | ulp_ops->iscsi_nl_send_msg(cp->dev, msg_type, buf, len); | 232 | ulp_ops->iscsi_nl_send_msg(cp->dev, msg_type, buf, len); |
233 | rcu_read_unlock(); | 233 | rcu_read_unlock(); |
@@ -319,6 +319,20 @@ static int cnic_abort_prep(struct cnic_sock *csk) | |||
319 | return 0; | 319 | return 0; |
320 | } | 320 | } |
321 | 321 | ||
322 | static void cnic_uio_stop(void) | ||
323 | { | ||
324 | struct cnic_dev *dev; | ||
325 | |||
326 | read_lock(&cnic_dev_lock); | ||
327 | list_for_each_entry(dev, &cnic_dev_list, list) { | ||
328 | struct cnic_local *cp = dev->cnic_priv; | ||
329 | |||
330 | if (cp->cnic_uinfo) | ||
331 | cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); | ||
332 | } | ||
333 | read_unlock(&cnic_dev_lock); | ||
334 | } | ||
335 | |||
322 | int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops) | 336 | int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops) |
323 | { | 337 | { |
324 | struct cnic_dev *dev; | 338 | struct cnic_dev *dev; |
@@ -390,6 +404,9 @@ int cnic_unregister_driver(int ulp_type) | |||
390 | } | 404 | } |
391 | read_unlock(&cnic_dev_lock); | 405 | read_unlock(&cnic_dev_lock); |
392 | 406 | ||
407 | if (ulp_type == CNIC_ULP_ISCSI) | ||
408 | cnic_uio_stop(); | ||
409 | |||
393 | rcu_assign_pointer(cnic_ulp_tbl[ulp_type], NULL); | 410 | rcu_assign_pointer(cnic_ulp_tbl[ulp_type], NULL); |
394 | 411 | ||
395 | mutex_unlock(&cnic_lock); | 412 | mutex_unlock(&cnic_lock); |
@@ -632,7 +649,6 @@ static void cnic_free_resc(struct cnic_dev *dev) | |||
632 | int i = 0; | 649 | int i = 0; |
633 | 650 | ||
634 | if (cp->cnic_uinfo) { | 651 | if (cp->cnic_uinfo) { |
635 | cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); | ||
636 | while (cp->uio_dev != -1 && i < 15) { | 652 | while (cp->uio_dev != -1 && i < 15) { |
637 | msleep(100); | 653 | msleep(100); |
638 | i++; | 654 | i++; |
@@ -1057,6 +1073,9 @@ static void cnic_ulp_stop(struct cnic_dev *dev) | |||
1057 | struct cnic_local *cp = dev->cnic_priv; | 1073 | struct cnic_local *cp = dev->cnic_priv; |
1058 | int if_type; | 1074 | int if_type; |
1059 | 1075 | ||
1076 | if (cp->cnic_uinfo) | ||
1077 | cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); | ||
1078 | |||
1060 | rcu_read_lock(); | 1079 | rcu_read_lock(); |
1061 | for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { | 1080 | for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { |
1062 | struct cnic_ulp_ops *ulp_ops; | 1081 | struct cnic_ulp_ops *ulp_ops; |
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 3eee666a9cd2..55445f980f9c 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c | |||
@@ -1524,6 +1524,7 @@ static void net_timeout(struct net_device *dev) | |||
1524 | static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | 1524 | static int net_send_packet(struct sk_buff *skb, struct net_device *dev) |
1525 | { | 1525 | { |
1526 | struct net_local *lp = netdev_priv(dev); | 1526 | struct net_local *lp = netdev_priv(dev); |
1527 | unsigned long flags; | ||
1527 | 1528 | ||
1528 | if (net_debug > 3) { | 1529 | if (net_debug > 3) { |
1529 | printk("%s: sent %d byte packet of type %x\n", | 1530 | printk("%s: sent %d byte packet of type %x\n", |
@@ -1535,7 +1536,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
1535 | ask the chip to start transmitting before the | 1536 | ask the chip to start transmitting before the |
1536 | whole packet has been completely uploaded. */ | 1537 | whole packet has been completely uploaded. */ |
1537 | 1538 | ||
1538 | spin_lock_irq(&lp->lock); | 1539 | spin_lock_irqsave(&lp->lock, flags); |
1539 | netif_stop_queue(dev); | 1540 | netif_stop_queue(dev); |
1540 | 1541 | ||
1541 | /* initiate a transmit sequence */ | 1542 | /* initiate a transmit sequence */ |
@@ -1549,13 +1550,13 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
1549 | * we're waiting for TxOk, so return 1 and requeue this packet. | 1550 | * we're waiting for TxOk, so return 1 and requeue this packet. |
1550 | */ | 1551 | */ |
1551 | 1552 | ||
1552 | spin_unlock_irq(&lp->lock); | 1553 | spin_unlock_irqrestore(&lp->lock, flags); |
1553 | if (net_debug) printk("cs89x0: Tx buffer not free!\n"); | 1554 | if (net_debug) printk("cs89x0: Tx buffer not free!\n"); |
1554 | return NETDEV_TX_BUSY; | 1555 | return NETDEV_TX_BUSY; |
1555 | } | 1556 | } |
1556 | /* Write the contents of the packet */ | 1557 | /* Write the contents of the packet */ |
1557 | writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1); | 1558 | writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1); |
1558 | spin_unlock_irq(&lp->lock); | 1559 | spin_unlock_irqrestore(&lp->lock, flags); |
1559 | lp->stats.tx_bytes += skb->len; | 1560 | lp->stats.tx_bytes += skb->len; |
1560 | dev->trans_start = jiffies; | 1561 | dev->trans_start = jiffies; |
1561 | dev_kfree_skb (skb); | 1562 | dev_kfree_skb (skb); |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 538dda4422dc..fb5df5c6203e 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -642,8 +642,7 @@ static int setup_sge_qsets(struct adapter *adap) | |||
642 | struct port_info *pi = netdev_priv(dev); | 642 | struct port_info *pi = netdev_priv(dev); |
643 | 643 | ||
644 | pi->qs = &adap->sge.qs[pi->first_qset]; | 644 | pi->qs = &adap->sge.qs[pi->first_qset]; |
645 | for (j = pi->first_qset; j < pi->first_qset + pi->nqsets; | 645 | for (j = 0; j < pi->nqsets; ++j, ++qset_idx) { |
646 | ++j, ++qset_idx) { | ||
647 | set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO); | 646 | set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO); |
648 | err = t3_sge_alloc_qset(adap, qset_idx, 1, | 647 | err = t3_sge_alloc_qset(adap, qset_idx, 1, |
649 | (adap->flags & USING_MSIX) ? qset_idx + 1 : | 648 | (adap->flags & USING_MSIX) ? qset_idx + 1 : |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 2df8fb0af701..12fd446f9895 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -1820,11 +1820,19 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr) | |||
1820 | struct device *emac_dev = &priv->ndev->dev; | 1820 | struct device *emac_dev = &priv->ndev->dev; |
1821 | struct sockaddr *sa = addr; | 1821 | struct sockaddr *sa = addr; |
1822 | 1822 | ||
1823 | if (!is_valid_ether_addr(sa->sa_data)) | ||
1824 | return -EINVAL; | ||
1825 | |||
1823 | /* Store mac addr in priv and rx channel and set it in EMAC hw */ | 1826 | /* Store mac addr in priv and rx channel and set it in EMAC hw */ |
1824 | memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len); | 1827 | memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len); |
1825 | memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len); | ||
1826 | memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len); | 1828 | memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len); |
1827 | emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr); | 1829 | |
1830 | /* If the interface is down - rxch is NULL. */ | ||
1831 | /* MAC address is configured only after the interface is enabled. */ | ||
1832 | if (netif_running(ndev)) { | ||
1833 | memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len); | ||
1834 | emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr); | ||
1835 | } | ||
1828 | 1836 | ||
1829 | if (netif_msg_drv(priv)) | 1837 | if (netif_msg_drv(priv)) |
1830 | dev_notice(emac_dev, "DaVinci EMAC: emac_dev_setmac_addr %pM\n", | 1838 | dev_notice(emac_dev, "DaVinci EMAC: emac_dev_setmac_addr %pM\n", |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index efa680f4b8dd..41b648a67fec 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -1897,6 +1897,9 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, | |||
1897 | 1897 | ||
1898 | if (ioread8(&nic->csr->scb.status) & rus_no_res) | 1898 | if (ioread8(&nic->csr->scb.status) & rus_no_res) |
1899 | nic->ru_running = RU_SUSPENDED; | 1899 | nic->ru_running = RU_SUSPENDED; |
1900 | pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, | ||
1901 | sizeof(struct rfd), | ||
1902 | PCI_DMA_BIDIRECTIONAL); | ||
1900 | return -ENODATA; | 1903 | return -ENODATA; |
1901 | } | 1904 | } |
1902 | 1905 | ||
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index cc2ab6412c73..4f7003485348 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c | |||
@@ -1784,7 +1784,7 @@ int __init init_module(void) | |||
1784 | printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n"); | 1784 | printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n"); |
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | for (i = 0; io[i] != -1 && i < MAX_EEPRO; i++) { | 1787 | for (i = 0; i < MAX_EEPRO && io[i] != -1; i++) { |
1788 | dev = alloc_etherdev(sizeof(struct eepro_local)); | 1788 | dev = alloc_etherdev(sizeof(struct eepro_local)); |
1789 | if (!dev) | 1789 | if (!dev) |
1790 | break; | 1790 | break; |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 147c4b088fb3..e8d46cc1bec2 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -3080,7 +3080,9 @@ static const struct net_device_ops ehea_netdev_ops = { | |||
3080 | .ndo_poll_controller = ehea_netpoll, | 3080 | .ndo_poll_controller = ehea_netpoll, |
3081 | #endif | 3081 | #endif |
3082 | .ndo_get_stats = ehea_get_stats, | 3082 | .ndo_get_stats = ehea_get_stats, |
3083 | .ndo_change_mtu = eth_change_mtu, | ||
3083 | .ndo_set_mac_address = ehea_set_mac_addr, | 3084 | .ndo_set_mac_address = ehea_set_mac_addr, |
3085 | .ndo_validate_addr = eth_validate_addr, | ||
3084 | .ndo_set_multicast_list = ehea_set_multicast_list, | 3086 | .ndo_set_multicast_list = ehea_set_multicast_list, |
3085 | .ndo_change_mtu = ehea_change_mtu, | 3087 | .ndo_change_mtu = ehea_change_mtu, |
3086 | .ndo_vlan_rx_register = ehea_vlan_rx_register, | 3088 | .ndo_vlan_rx_register = ehea_vlan_rx_register, |
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 053fb49820b9..160655d24581 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c | |||
@@ -584,7 +584,8 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, | |||
584 | if (np->flags == HAS_MII_XCVR) { | 584 | if (np->flags == HAS_MII_XCVR) { |
585 | int phy, phy_idx = 0; | 585 | int phy, phy_idx = 0; |
586 | 586 | ||
587 | for (phy = 1; phy < 32 && phy_idx < 4; phy++) { | 587 | for (phy = 1; phy < 32 && phy_idx < ARRAY_SIZE(np->phys); |
588 | phy++) { | ||
588 | int mii_status = mdio_read(dev, phy, 1); | 589 | int mii_status = mdio_read(dev, phy, 1); |
589 | 590 | ||
590 | if (mii_status != 0xffff && mii_status != 0x0000) { | 591 | if (mii_status != 0xffff && mii_status != 0x0000) { |
@@ -1216,13 +1217,13 @@ static void fealnx_tx_timeout(struct net_device *dev) | |||
1216 | { | 1217 | { |
1217 | printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); | 1218 | printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); |
1218 | for (i = 0; i < RX_RING_SIZE; i++) | 1219 | for (i = 0; i < RX_RING_SIZE; i++) |
1219 | printk(PR_CONT " %8.8x", | 1220 | printk(KERN_CONT " %8.8x", |
1220 | (unsigned int) np->rx_ring[i].status); | 1221 | (unsigned int) np->rx_ring[i].status); |
1221 | printk(KERN_CONT "\n"); | 1222 | printk(KERN_CONT "\n"); |
1222 | printk(KERN_DEBUG " Tx ring %p: ", np->tx_ring); | 1223 | printk(KERN_DEBUG " Tx ring %p: ", np->tx_ring); |
1223 | for (i = 0; i < TX_RING_SIZE; i++) | 1224 | for (i = 0; i < TX_RING_SIZE; i++) |
1224 | printk(PR_CONT " %4.4x", np->tx_ring[i].status); | 1225 | printk(KERN_CONT " %4.4x", np->tx_ring[i].status); |
1225 | printk(PR_CONT "\n"); | 1226 | printk(KERN_CONT "\n"); |
1226 | } | 1227 | } |
1227 | 1228 | ||
1228 | spin_lock_irqsave(&np->lock, flags); | 1229 | spin_lock_irqsave(&np->lock, flags); |
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 0f19b743749b..d4b98074b1b7 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c | |||
@@ -1642,6 +1642,7 @@ static const struct net_device_ops fec_netdev_ops = { | |||
1642 | .ndo_stop = fec_enet_close, | 1642 | .ndo_stop = fec_enet_close, |
1643 | .ndo_start_xmit = fec_enet_start_xmit, | 1643 | .ndo_start_xmit = fec_enet_start_xmit, |
1644 | .ndo_set_multicast_list = set_multicast_list, | 1644 | .ndo_set_multicast_list = set_multicast_list, |
1645 | .ndo_change_mtu = eth_change_mtu, | ||
1645 | .ndo_validate_addr = eth_validate_addr, | 1646 | .ndo_validate_addr = eth_validate_addr, |
1646 | .ndo_tx_timeout = fec_timeout, | 1647 | .ndo_tx_timeout = fec_timeout, |
1647 | .ndo_set_mac_address = fec_set_mac_address, | 1648 | .ndo_set_mac_address = fec_set_mac_address, |
diff --git a/drivers/net/fec.h b/drivers/net/fec.h index 30b7dd671336..cc47f3f057c7 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h | |||
@@ -46,12 +46,12 @@ | |||
46 | 46 | ||
47 | #else | 47 | #else |
48 | 48 | ||
49 | #define FEC_ECNTRL; 0x000 /* Ethernet control reg */ | 49 | #define FEC_ECNTRL 0x000 /* Ethernet control reg */ |
50 | #define FEC_IEVENT; 0x004 /* Interrupt even reg */ | 50 | #define FEC_IEVENT 0x004 /* Interrupt even reg */ |
51 | #define FEC_IMASK; 0x008 /* Interrupt mask reg */ | 51 | #define FEC_IMASK 0x008 /* Interrupt mask reg */ |
52 | #define FEC_IVEC; 0x00c /* Interrupt vec status reg */ | 52 | #define FEC_IVEC 0x00c /* Interrupt vec status reg */ |
53 | #define FEC_R_DES_ACTIVE; 0x010 /* Receive descriptor reg */ | 53 | #define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */ |
54 | #define FEC_X_DES_ACTIVE; 0x01c /* Transmit descriptor reg */ | 54 | #define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */ |
55 | #define FEC_MII_DATA 0x040 /* MII manage frame reg */ | 55 | #define FEC_MII_DATA 0x040 /* MII manage frame reg */ |
56 | #define FEC_MII_SPEED 0x044 /* MII speed control reg */ | 56 | #define FEC_MII_SPEED 0x044 /* MII speed control reg */ |
57 | #define FEC_R_BOUND 0x08c /* FIFO receive bound reg */ | 57 | #define FEC_R_BOUND 0x08c /* FIFO receive bound reg */ |
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index b892c3ad9a74..2bc2d2b20644 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -754,17 +754,16 @@ static int fs_init_phy(struct net_device *dev) | |||
754 | fep->oldlink = 0; | 754 | fep->oldlink = 0; |
755 | fep->oldspeed = 0; | 755 | fep->oldspeed = 0; |
756 | fep->oldduplex = -1; | 756 | fep->oldduplex = -1; |
757 | if(fep->fpi->phy_node) | 757 | |
758 | phydev = of_phy_connect(dev, fep->fpi->phy_node, | 758 | phydev = of_phy_connect(dev, fep->fpi->phy_node, &fs_adjust_link, 0, |
759 | &fs_adjust_link, 0, | 759 | PHY_INTERFACE_MODE_MII); |
760 | PHY_INTERFACE_MODE_MII); | 760 | if (!phydev) { |
761 | else { | 761 | phydev = of_phy_connect_fixed_link(dev, &fs_adjust_link, |
762 | printk("No phy bus ID specified in BSP code\n"); | 762 | PHY_INTERFACE_MODE_MII); |
763 | return -EINVAL; | ||
764 | } | 763 | } |
765 | if (IS_ERR(phydev)) { | 764 | if (!phydev) { |
766 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | 765 | dev_err(&dev->dev, "Could not attach to PHY\n"); |
767 | return PTR_ERR(phydev); | 766 | return -ENODEV; |
768 | } | 767 | } |
769 | 768 | ||
770 | fep->phydev = phydev; | 769 | fep->phydev = phydev; |
@@ -1005,6 +1004,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, | |||
1005 | goto out_free_fpi; | 1004 | goto out_free_fpi; |
1006 | } | 1005 | } |
1007 | 1006 | ||
1007 | SET_NETDEV_DEV(ndev, &ofdev->dev); | ||
1008 | dev_set_drvdata(&ofdev->dev, ndev); | 1008 | dev_set_drvdata(&ofdev->dev, ndev); |
1009 | 1009 | ||
1010 | fep = netdev_priv(ndev); | 1010 | fep = netdev_priv(ndev); |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 4ae1d259fced..f8ffcbf0bc39 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -156,6 +156,8 @@ static const struct net_device_ops gfar_netdev_ops = { | |||
156 | .ndo_tx_timeout = gfar_timeout, | 156 | .ndo_tx_timeout = gfar_timeout, |
157 | .ndo_do_ioctl = gfar_ioctl, | 157 | .ndo_do_ioctl = gfar_ioctl, |
158 | .ndo_vlan_rx_register = gfar_vlan_rx_register, | 158 | .ndo_vlan_rx_register = gfar_vlan_rx_register, |
159 | .ndo_set_mac_address = eth_mac_addr, | ||
160 | .ndo_validate_addr = eth_validate_addr, | ||
159 | #ifdef CONFIG_NET_POLL_CONTROLLER | 161 | #ifdef CONFIG_NET_POLL_CONTROLLER |
160 | .ndo_poll_controller = gfar_netpoll, | 162 | .ndo_poll_controller = gfar_netpoll, |
161 | #endif | 163 | #endif |
@@ -262,15 +264,6 @@ static int gfar_of_init(struct net_device *dev) | |||
262 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; | 264 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; |
263 | 265 | ||
264 | priv->phy_node = of_parse_phandle(np, "phy-handle", 0); | 266 | priv->phy_node = of_parse_phandle(np, "phy-handle", 0); |
265 | if (!priv->phy_node) { | ||
266 | u32 *fixed_link; | ||
267 | |||
268 | fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL); | ||
269 | if (!fixed_link) { | ||
270 | err = -ENODEV; | ||
271 | goto err_out; | ||
272 | } | ||
273 | } | ||
274 | 267 | ||
275 | /* Find the TBI PHY. If it's not there, we don't support SGMII */ | 268 | /* Find the TBI PHY. If it's not there, we don't support SGMII */ |
276 | priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0); | 269 | priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0); |
@@ -657,13 +650,14 @@ static int init_phy(struct net_device *dev) | |||
657 | 650 | ||
658 | interface = gfar_get_interface(dev); | 651 | interface = gfar_get_interface(dev); |
659 | 652 | ||
660 | if (priv->phy_node) { | 653 | priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0, |
661 | priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, | 654 | interface); |
662 | 0, interface); | 655 | if (!priv->phydev) |
663 | if (!priv->phydev) { | 656 | priv->phydev = of_phy_connect_fixed_link(dev, &adjust_link, |
664 | dev_err(&dev->dev, "error: Could not attach to PHY\n"); | 657 | interface); |
665 | return -ENODEV; | 658 | if (!priv->phydev) { |
666 | } | 659 | dev_err(&dev->dev, "could not attach to PHY\n"); |
660 | return -ENODEV; | ||
667 | } | 661 | } |
668 | 662 | ||
669 | if (interface == PHY_INTERFACE_MODE_SGMII) | 663 | if (interface == PHY_INTERFACE_MODE_SGMII) |
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 155160052c8b..981ab530e9ac 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * devices like TTY. It interfaces between a raw TTY and the | 3 | * devices like TTY. It interfaces between a raw TTY and the |
4 | * kernel's AX.25 protocol layers. | 4 | * kernel's AX.25 protocol layers. |
5 | * | 5 | * |
6 | * Authors: Andreas Könsgen <ajk@iehk.rwth-aachen.de> | 6 | * Authors: Andreas Könsgen <ajk@comnets.uni-bremen.de> |
7 | * Ralf Baechle DL5RB <ralf@linux-mips.org> | 7 | * Ralf Baechle DL5RB <ralf@linux-mips.org> |
8 | * | 8 | * |
9 | * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by | 9 | * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by |
diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 1d5379de6900..8d76cb89dbd6 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c | |||
@@ -188,11 +188,12 @@ void rgmii_put_mdio(struct of_device *ofdev, int input) | |||
188 | void rgmii_detach(struct of_device *ofdev, int input) | 188 | void rgmii_detach(struct of_device *ofdev, int input) |
189 | { | 189 | { |
190 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | 190 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); |
191 | struct rgmii_regs __iomem *p = dev->base; | 191 | struct rgmii_regs __iomem *p; |
192 | |||
193 | mutex_lock(&dev->lock); | ||
194 | 192 | ||
195 | BUG_ON(!dev || dev->users == 0); | 193 | BUG_ON(!dev || dev->users == 0); |
194 | p = dev->base; | ||
195 | |||
196 | mutex_lock(&dev->lock); | ||
196 | 197 | ||
197 | RGMII_DBG(dev, "detach(%d)" NL, input); | 198 | RGMII_DBG(dev, "detach(%d)" NL, input); |
198 | 199 | ||
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index efd9be214885..ac28dd5a4fd1 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
@@ -190,6 +190,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
190 | phy->ops.write_reg = igb_write_phy_reg_igp; | 190 | phy->ops.write_reg = igb_write_phy_reg_igp; |
191 | } | 191 | } |
192 | 192 | ||
193 | /* set lan id */ | ||
194 | hw->bus.func = (rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) >> | ||
195 | E1000_STATUS_FUNC_SHIFT; | ||
196 | |||
193 | /* Set phy->phy_addr and phy->id. */ | 197 | /* Set phy->phy_addr and phy->id. */ |
194 | ret_val = igb_get_phy_id_82575(hw); | 198 | ret_val = igb_get_phy_id_82575(hw); |
195 | if (ret_val) | 199 | if (ret_val) |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index be480292aba1..adb09d32625d 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -127,14 +127,48 @@ static void igb_restore_vlan(struct igb_adapter *); | |||
127 | static void igb_ping_all_vfs(struct igb_adapter *); | 127 | static void igb_ping_all_vfs(struct igb_adapter *); |
128 | static void igb_msg_task(struct igb_adapter *); | 128 | static void igb_msg_task(struct igb_adapter *); |
129 | static int igb_rcv_msg_from_vf(struct igb_adapter *, u32); | 129 | static int igb_rcv_msg_from_vf(struct igb_adapter *, u32); |
130 | static inline void igb_set_rah_pool(struct e1000_hw *, int , int); | ||
131 | static void igb_set_mc_list_pools(struct igb_adapter *, int, u16); | 130 | static void igb_set_mc_list_pools(struct igb_adapter *, int, u16); |
132 | static void igb_vmm_control(struct igb_adapter *); | 131 | static void igb_vmm_control(struct igb_adapter *); |
133 | static inline void igb_set_vmolr(struct e1000_hw *, int); | ||
134 | static inline int igb_set_vf_rlpml(struct igb_adapter *, int, int); | ||
135 | static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *); | 132 | static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *); |
136 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); | 133 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); |
137 | 134 | ||
135 | static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn) | ||
136 | { | ||
137 | u32 reg_data; | ||
138 | |||
139 | reg_data = rd32(E1000_VMOLR(vfn)); | ||
140 | reg_data |= E1000_VMOLR_BAM | /* Accept broadcast */ | ||
141 | E1000_VMOLR_ROPE | /* Accept packets matched in UTA */ | ||
142 | E1000_VMOLR_ROMPE | /* Accept packets matched in MTA */ | ||
143 | E1000_VMOLR_AUPE | /* Accept untagged packets */ | ||
144 | E1000_VMOLR_STRVLAN; /* Strip vlan tags */ | ||
145 | wr32(E1000_VMOLR(vfn), reg_data); | ||
146 | } | ||
147 | |||
148 | static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size, | ||
149 | int vfn) | ||
150 | { | ||
151 | struct e1000_hw *hw = &adapter->hw; | ||
152 | u32 vmolr; | ||
153 | |||
154 | vmolr = rd32(E1000_VMOLR(vfn)); | ||
155 | vmolr &= ~E1000_VMOLR_RLPML_MASK; | ||
156 | vmolr |= size | E1000_VMOLR_LPE; | ||
157 | wr32(E1000_VMOLR(vfn), vmolr); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry) | ||
163 | { | ||
164 | u32 reg_data; | ||
165 | |||
166 | reg_data = rd32(E1000_RAH(entry)); | ||
167 | reg_data &= ~E1000_RAH_POOL_MASK; | ||
168 | reg_data |= E1000_RAH_POOL_1 << pool;; | ||
169 | wr32(E1000_RAH(entry), reg_data); | ||
170 | } | ||
171 | |||
138 | #ifdef CONFIG_PM | 172 | #ifdef CONFIG_PM |
139 | static int igb_suspend(struct pci_dev *, pm_message_t); | 173 | static int igb_suspend(struct pci_dev *, pm_message_t); |
140 | static int igb_resume(struct pci_dev *); | 174 | static int igb_resume(struct pci_dev *); |
@@ -5418,43 +5452,6 @@ static void igb_io_resume(struct pci_dev *pdev) | |||
5418 | igb_get_hw_control(adapter); | 5452 | igb_get_hw_control(adapter); |
5419 | } | 5453 | } |
5420 | 5454 | ||
5421 | static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn) | ||
5422 | { | ||
5423 | u32 reg_data; | ||
5424 | |||
5425 | reg_data = rd32(E1000_VMOLR(vfn)); | ||
5426 | reg_data |= E1000_VMOLR_BAM | /* Accept broadcast */ | ||
5427 | E1000_VMOLR_ROPE | /* Accept packets matched in UTA */ | ||
5428 | E1000_VMOLR_ROMPE | /* Accept packets matched in MTA */ | ||
5429 | E1000_VMOLR_AUPE | /* Accept untagged packets */ | ||
5430 | E1000_VMOLR_STRVLAN; /* Strip vlan tags */ | ||
5431 | wr32(E1000_VMOLR(vfn), reg_data); | ||
5432 | } | ||
5433 | |||
5434 | static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size, | ||
5435 | int vfn) | ||
5436 | { | ||
5437 | struct e1000_hw *hw = &adapter->hw; | ||
5438 | u32 vmolr; | ||
5439 | |||
5440 | vmolr = rd32(E1000_VMOLR(vfn)); | ||
5441 | vmolr &= ~E1000_VMOLR_RLPML_MASK; | ||
5442 | vmolr |= size | E1000_VMOLR_LPE; | ||
5443 | wr32(E1000_VMOLR(vfn), vmolr); | ||
5444 | |||
5445 | return 0; | ||
5446 | } | ||
5447 | |||
5448 | static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry) | ||
5449 | { | ||
5450 | u32 reg_data; | ||
5451 | |||
5452 | reg_data = rd32(E1000_RAH(entry)); | ||
5453 | reg_data &= ~E1000_RAH_POOL_MASK; | ||
5454 | reg_data |= E1000_RAH_POOL_1 << pool;; | ||
5455 | wr32(E1000_RAH(entry), reg_data); | ||
5456 | } | ||
5457 | |||
5458 | static void igb_set_mc_list_pools(struct igb_adapter *adapter, | 5455 | static void igb_set_mc_list_pools(struct igb_adapter *adapter, |
5459 | int entry_count, u16 total_rar_filters) | 5456 | int entry_count, u16 total_rar_filters) |
5460 | { | 5457 | { |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index d53aa9582137..20f9bc626688 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
36 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
37 | 36 | ||
diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c index 73585fd8f29f..d12377b84358 100644 --- a/drivers/net/isa-skeleton.c +++ b/drivers/net/isa-skeleton.c | |||
@@ -430,7 +430,8 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
430 | * hardware interrupt handler. Queue flow control is | 430 | * hardware interrupt handler. Queue flow control is |
431 | * thus managed under this lock as well. | 431 | * thus managed under this lock as well. |
432 | */ | 432 | */ |
433 | spin_lock_irq(&np->lock); | 433 | unsigned long flags; |
434 | spin_lock_irqsave(&np->lock, flags); | ||
434 | 435 | ||
435 | add_to_tx_ring(np, skb, length); | 436 | add_to_tx_ring(np, skb, length); |
436 | dev->trans_start = jiffies; | 437 | dev->trans_start = jiffies; |
@@ -446,7 +447,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
446 | * is when the transmit statistics are updated. | 447 | * is when the transmit statistics are updated. |
447 | */ | 448 | */ |
448 | 449 | ||
449 | spin_unlock_irq(&np->lock); | 450 | spin_unlock_irqrestore(&np->lock, flags); |
450 | #else | 451 | #else |
451 | /* This is the case for older hardware which takes | 452 | /* This is the case for older hardware which takes |
452 | * a single transmit buffer at a time, and it is | 453 | * a single transmit buffer at a time, and it is |
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index cd22323cfd22..1b12c7ba275f 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -327,6 +327,7 @@ struct ixgbe_adapter { | |||
327 | #define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25) | 327 | #define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25) |
328 | #define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 26) | 328 | #define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 26) |
329 | #define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 27) | 329 | #define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 27) |
330 | #define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 28) | ||
330 | #define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 29) | 331 | #define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 29) |
331 | 332 | ||
332 | u32 flags2; | 333 | u32 flags2; |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index d56890f5c9d5..1c7265732900 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c | |||
@@ -106,8 +106,6 @@ static u8 ixgbe_dcbnl_get_state(struct net_device *netdev) | |||
106 | { | 106 | { |
107 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 107 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
108 | 108 | ||
109 | DPRINTK(DRV, INFO, "Get DCB Admin Mode.\n"); | ||
110 | |||
111 | return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); | 109 | return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); |
112 | } | 110 | } |
113 | 111 | ||
@@ -116,8 +114,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) | |||
116 | u8 err = 0; | 114 | u8 err = 0; |
117 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 115 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
118 | 116 | ||
119 | DPRINTK(DRV, INFO, "Set DCB Admin Mode.\n"); | ||
120 | |||
121 | if (state > 0) { | 117 | if (state > 0) { |
122 | /* Turn on DCB */ | 118 | /* Turn on DCB */ |
123 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) | 119 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) |
@@ -138,7 +134,23 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) | |||
138 | adapter->hw.fc.requested_mode = ixgbe_fc_none; | 134 | adapter->hw.fc.requested_mode = ixgbe_fc_none; |
139 | } | 135 | } |
140 | adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; | 136 | adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; |
137 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | ||
138 | adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; | ||
139 | adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; | ||
140 | } | ||
141 | adapter->flags |= IXGBE_FLAG_DCB_ENABLED; | 141 | adapter->flags |= IXGBE_FLAG_DCB_ENABLED; |
142 | #ifdef IXGBE_FCOE | ||
143 | /* Turn on FCoE offload */ | ||
144 | if ((adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) && | ||
145 | (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))) { | ||
146 | adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; | ||
147 | adapter->ring_feature[RING_F_FCOE].indices = | ||
148 | IXGBE_FCRETA_SIZE; | ||
149 | netdev->features |= NETIF_F_FCOE_CRC; | ||
150 | netdev->features |= NETIF_F_FSO; | ||
151 | netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; | ||
152 | } | ||
153 | #endif /* IXGBE_FCOE */ | ||
142 | ixgbe_init_interrupt_scheme(adapter); | 154 | ixgbe_init_interrupt_scheme(adapter); |
143 | if (netif_running(netdev)) | 155 | if (netif_running(netdev)) |
144 | netdev->netdev_ops->ndo_open(netdev); | 156 | netdev->netdev_ops->ndo_open(netdev); |
@@ -154,6 +166,20 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) | |||
154 | adapter->dcb_cfg.pfc_mode_enable = false; | 166 | adapter->dcb_cfg.pfc_mode_enable = false; |
155 | adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; | 167 | adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; |
156 | adapter->flags |= IXGBE_FLAG_RSS_ENABLED; | 168 | adapter->flags |= IXGBE_FLAG_RSS_ENABLED; |
169 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) | ||
170 | adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; | ||
171 | |||
172 | #ifdef IXGBE_FCOE | ||
173 | /* Turn off FCoE offload */ | ||
174 | if (adapter->flags & (IXGBE_FLAG_FCOE_CAPABLE | | ||
175 | IXGBE_FLAG_FCOE_ENABLED)) { | ||
176 | adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; | ||
177 | adapter->ring_feature[RING_F_FCOE].indices = 0; | ||
178 | netdev->features &= ~NETIF_F_FCOE_CRC; | ||
179 | netdev->features &= ~NETIF_F_FSO; | ||
180 | netdev->fcoe_ddp_xid = 0; | ||
181 | } | ||
182 | #endif /* IXGBE_FCOE */ | ||
157 | ixgbe_init_interrupt_scheme(adapter); | 183 | ixgbe_init_interrupt_scheme(adapter); |
158 | if (netif_running(netdev)) | 184 | if (netif_running(netdev)) |
159 | netdev->netdev_ops->ndo_open(netdev); | 185 | netdev->netdev_ops->ndo_open(netdev); |
@@ -169,6 +195,8 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, | |||
169 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 195 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
170 | int i, j; | 196 | int i, j; |
171 | 197 | ||
198 | memset(perm_addr, 0xff, MAX_ADDR_LEN); | ||
199 | |||
172 | for (i = 0; i < netdev->addr_len; i++) | 200 | for (i = 0; i < netdev->addr_len; i++) |
173 | perm_addr[i] = adapter->hw.mac.perm_addr[i]; | 201 | perm_addr[i] = adapter->hw.mac.perm_addr[i]; |
174 | 202 | ||
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a3061aacffd8..200454f30f6a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/in.h> | 34 | #include <linux/in.h> |
35 | #include <linux/ip.h> | 35 | #include <linux/ip.h> |
36 | #include <linux/tcp.h> | 36 | #include <linux/tcp.h> |
37 | #include <linux/pkt_sched.h> | ||
37 | #include <linux/ipv6.h> | 38 | #include <linux/ipv6.h> |
38 | #include <net/checksum.h> | 39 | #include <net/checksum.h> |
39 | #include <net/ip6_checksum.h> | 40 | #include <net/ip6_checksum.h> |
@@ -510,8 +511,11 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, | |||
510 | * @skb: skb currently being received and modified | 511 | * @skb: skb currently being received and modified |
511 | **/ | 512 | **/ |
512 | static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, | 513 | static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, |
513 | u32 status_err, struct sk_buff *skb) | 514 | union ixgbe_adv_rx_desc *rx_desc, |
515 | struct sk_buff *skb) | ||
514 | { | 516 | { |
517 | u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error); | ||
518 | |||
515 | skb->ip_summed = CHECKSUM_NONE; | 519 | skb->ip_summed = CHECKSUM_NONE; |
516 | 520 | ||
517 | /* Rx csum disabled */ | 521 | /* Rx csum disabled */ |
@@ -529,6 +533,16 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, | |||
529 | return; | 533 | return; |
530 | 534 | ||
531 | if (status_err & IXGBE_RXDADV_ERR_TCPE) { | 535 | if (status_err & IXGBE_RXDADV_ERR_TCPE) { |
536 | u16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; | ||
537 | |||
538 | /* | ||
539 | * 82599 errata, UDP frames with a 0 checksum can be marked as | ||
540 | * checksum errors. | ||
541 | */ | ||
542 | if ((pkt_info & IXGBE_RXDADV_PKTTYPE_UDP) && | ||
543 | (adapter->hw.mac.type == ixgbe_mac_82599EB)) | ||
544 | return; | ||
545 | |||
532 | adapter->hw_csum_rx_error++; | 546 | adapter->hw_csum_rx_error++; |
533 | return; | 547 | return; |
534 | } | 548 | } |
@@ -802,7 +816,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
802 | goto next_desc; | 816 | goto next_desc; |
803 | } | 817 | } |
804 | 818 | ||
805 | ixgbe_rx_checksum(adapter, staterr, skb); | 819 | ixgbe_rx_checksum(adapter, rx_desc, skb); |
806 | 820 | ||
807 | /* probably a little skewed due to removing CRC */ | 821 | /* probably a little skewed due to removing CRC */ |
808 | total_rx_bytes += skb->len; | 822 | total_rx_bytes += skb->len; |
@@ -3130,7 +3144,11 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) | |||
3130 | #endif | 3144 | #endif |
3131 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { | 3145 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { |
3132 | DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n"); | 3146 | DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n"); |
3133 | ixgbe_set_rss_queues(adapter); | 3147 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || |
3148 | (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) | ||
3149 | ixgbe_set_fdir_queues(adapter); | ||
3150 | else | ||
3151 | ixgbe_set_rss_queues(adapter); | ||
3134 | } | 3152 | } |
3135 | /* adding FCoE rx rings to the end */ | 3153 | /* adding FCoE rx rings to the end */ |
3136 | f->mask = adapter->num_rx_queues; | 3154 | f->mask = adapter->num_rx_queues; |
@@ -3388,7 +3406,12 @@ static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) | |||
3388 | } | 3406 | } |
3389 | #endif /* CONFIG_IXGBE_DCB */ | 3407 | #endif /* CONFIG_IXGBE_DCB */ |
3390 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { | 3408 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { |
3391 | ixgbe_cache_ring_rss(adapter); | 3409 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || |
3410 | (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) | ||
3411 | ixgbe_cache_ring_fdir(adapter); | ||
3412 | else | ||
3413 | ixgbe_cache_ring_rss(adapter); | ||
3414 | |||
3392 | fcoe_i = f->mask; | 3415 | fcoe_i = f->mask; |
3393 | } | 3416 | } |
3394 | for (i = 0; i < f->indices; i++, fcoe_i++) | 3417 | for (i = 0; i < f->indices; i++, fcoe_i++) |
@@ -3797,8 +3820,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) | |||
3797 | adapter->atr_sample_rate = 20; | 3820 | adapter->atr_sample_rate = 20; |
3798 | adapter->fdir_pballoc = 0; | 3821 | adapter->fdir_pballoc = 0; |
3799 | #ifdef IXGBE_FCOE | 3822 | #ifdef IXGBE_FCOE |
3800 | adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; | 3823 | adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE; |
3801 | adapter->ring_feature[RING_F_FCOE].indices = IXGBE_FCRETA_SIZE; | 3824 | adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; |
3825 | adapter->ring_feature[RING_F_FCOE].indices = 0; | ||
3802 | #endif /* IXGBE_FCOE */ | 3826 | #endif /* IXGBE_FCOE */ |
3803 | } | 3827 | } |
3804 | 3828 | ||
@@ -5116,9 +5140,6 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
5116 | int count = 0; | 5140 | int count = 0; |
5117 | unsigned int f; | 5141 | unsigned int f; |
5118 | 5142 | ||
5119 | r_idx = skb->queue_mapping; | ||
5120 | tx_ring = &adapter->tx_ring[r_idx]; | ||
5121 | |||
5122 | if (adapter->vlgrp && vlan_tx_tag_present(skb)) { | 5143 | if (adapter->vlgrp && vlan_tx_tag_present(skb)) { |
5123 | tx_flags |= vlan_tx_tag_get(skb); | 5144 | tx_flags |= vlan_tx_tag_get(skb); |
5124 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | 5145 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
@@ -5128,11 +5149,19 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
5128 | tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; | 5149 | tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; |
5129 | tx_flags |= IXGBE_TX_FLAGS_VLAN; | 5150 | tx_flags |= IXGBE_TX_FLAGS_VLAN; |
5130 | } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | 5151 | } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
5131 | tx_flags |= (skb->queue_mapping << 13); | 5152 | if (skb->priority != TC_PRIO_CONTROL) { |
5132 | tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; | 5153 | tx_flags |= (skb->queue_mapping << 13); |
5133 | tx_flags |= IXGBE_TX_FLAGS_VLAN; | 5154 | tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; |
5155 | tx_flags |= IXGBE_TX_FLAGS_VLAN; | ||
5156 | } else { | ||
5157 | skb->queue_mapping = | ||
5158 | adapter->ring_feature[RING_F_DCB].indices-1; | ||
5159 | } | ||
5134 | } | 5160 | } |
5135 | 5161 | ||
5162 | r_idx = skb->queue_mapping; | ||
5163 | tx_ring = &adapter->tx_ring[r_idx]; | ||
5164 | |||
5136 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && | 5165 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && |
5137 | (skb->protocol == htons(ETH_P_FCOE))) | 5166 | (skb->protocol == htons(ETH_P_FCOE))) |
5138 | tx_flags |= IXGBE_TX_FLAGS_FCOE; | 5167 | tx_flags |= IXGBE_TX_FLAGS_FCOE; |
@@ -5571,22 +5600,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
5571 | #endif | 5600 | #endif |
5572 | 5601 | ||
5573 | #ifdef IXGBE_FCOE | 5602 | #ifdef IXGBE_FCOE |
5574 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { | 5603 | if (adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) { |
5575 | if (hw->mac.ops.get_device_caps) { | 5604 | if (hw->mac.ops.get_device_caps) { |
5576 | hw->mac.ops.get_device_caps(hw, &device_caps); | 5605 | hw->mac.ops.get_device_caps(hw, &device_caps); |
5577 | if (!(device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS)) { | 5606 | if (device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS) |
5578 | netdev->features |= NETIF_F_FCOE_CRC; | 5607 | adapter->flags &= ~IXGBE_FLAG_FCOE_CAPABLE; |
5579 | netdev->features |= NETIF_F_FSO; | ||
5580 | netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; | ||
5581 | DPRINTK(DRV, INFO, "FCoE enabled, " | ||
5582 | "disabling Flow Director\n"); | ||
5583 | adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; | ||
5584 | adapter->flags &= | ||
5585 | ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; | ||
5586 | adapter->atr_sample_rate = 0; | ||
5587 | } else { | ||
5588 | adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; | ||
5589 | } | ||
5590 | } | 5608 | } |
5591 | } | 5609 | } |
5592 | #endif /* IXGBE_FCOE */ | 5610 | #endif /* IXGBE_FCOE */ |
@@ -5635,7 +5653,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
5635 | adapter->wol = 0; | 5653 | adapter->wol = 0; |
5636 | break; | 5654 | break; |
5637 | } | 5655 | } |
5638 | device_init_wakeup(&adapter->pdev->dev, true); | ||
5639 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | 5656 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); |
5640 | 5657 | ||
5641 | /* pick up the PCI bus settings for reporting later */ | 5658 | /* pick up the PCI bus settings for reporting later */ |
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index d12106b47bf2..2f286091394d 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c | |||
@@ -229,6 +229,7 @@ static int __init jazz_sonic_probe(struct platform_device *pdev) | |||
229 | lp = netdev_priv(dev); | 229 | lp = netdev_priv(dev); |
230 | lp->device = &pdev->dev; | 230 | lp->device = &pdev->dev; |
231 | SET_NETDEV_DEV(dev, &pdev->dev); | 231 | SET_NETDEV_DEV(dev, &pdev->dev); |
232 | platform_set_drvdata(pdev, dev); | ||
232 | 233 | ||
233 | netdev_boot_setup_check(dev); | 234 | netdev_boot_setup_check(dev); |
234 | 235 | ||
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c new file mode 100644 index 000000000000..9a1dea60c1c4 --- /dev/null +++ b/drivers/net/ks8851.c | |||
@@ -0,0 +1,1322 @@ | |||
1 | /* drivers/net/ks8651.c | ||
2 | * | ||
3 | * Copyright 2009 Simtec Electronics | ||
4 | * http://www.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #define DEBUG | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/netdevice.h> | ||
17 | #include <linux/etherdevice.h> | ||
18 | #include <linux/ethtool.h> | ||
19 | #include <linux/cache.h> | ||
20 | #include <linux/crc32.h> | ||
21 | #include <linux/mii.h> | ||
22 | |||
23 | #include <linux/spi/spi.h> | ||
24 | |||
25 | #include "ks8851.h" | ||
26 | |||
27 | /** | ||
28 | * struct ks8851_rxctrl - KS8851 driver rx control | ||
29 | * @mchash: Multicast hash-table data. | ||
30 | * @rxcr1: KS_RXCR1 register setting | ||
31 | * @rxcr2: KS_RXCR2 register setting | ||
32 | * | ||
33 | * Representation of the settings needs to control the receive filtering | ||
34 | * such as the multicast hash-filter and the receive register settings. This | ||
35 | * is used to make the job of working out if the receive settings change and | ||
36 | * then issuing the new settings to the worker that will send the necessary | ||
37 | * commands. | ||
38 | */ | ||
39 | struct ks8851_rxctrl { | ||
40 | u16 mchash[4]; | ||
41 | u16 rxcr1; | ||
42 | u16 rxcr2; | ||
43 | }; | ||
44 | |||
45 | /** | ||
46 | * union ks8851_tx_hdr - tx header data | ||
47 | * @txb: The header as bytes | ||
48 | * @txw: The header as 16bit, little-endian words | ||
49 | * | ||
50 | * A dual representation of the tx header data to allow | ||
51 | * access to individual bytes, and to allow 16bit accesses | ||
52 | * with 16bit alignment. | ||
53 | */ | ||
54 | union ks8851_tx_hdr { | ||
55 | u8 txb[6]; | ||
56 | __le16 txw[3]; | ||
57 | }; | ||
58 | |||
59 | /** | ||
60 | * struct ks8851_net - KS8851 driver private data | ||
61 | * @netdev: The network device we're bound to | ||
62 | * @spidev: The spi device we're bound to. | ||
63 | * @lock: Lock to ensure that the device is not accessed when busy. | ||
64 | * @statelock: Lock on this structure for tx list. | ||
65 | * @mii: The MII state information for the mii calls. | ||
66 | * @rxctrl: RX settings for @rxctrl_work. | ||
67 | * @tx_work: Work queue for tx packets | ||
68 | * @irq_work: Work queue for servicing interrupts | ||
69 | * @rxctrl_work: Work queue for updating RX mode and multicast lists | ||
70 | * @txq: Queue of packets for transmission. | ||
71 | * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. | ||
72 | * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. | ||
73 | * @txh: Space for generating packet TX header in DMA-able data | ||
74 | * @rxd: Space for receiving SPI data, in DMA-able space. | ||
75 | * @txd: Space for transmitting SPI data, in DMA-able space. | ||
76 | * @msg_enable: The message flags controlling driver output (see ethtool). | ||
77 | * @fid: Incrementing frame id tag. | ||
78 | * @rc_ier: Cached copy of KS_IER. | ||
79 | * @rc_rxqcr: Cached copy of KS_RXQCR. | ||
80 | * | ||
81 | * The @lock ensures that the chip is protected when certain operations are | ||
82 | * in progress. When the read or write packet transfer is in progress, most | ||
83 | * of the chip registers are not ccessible until the transfer is finished and | ||
84 | * the DMA has been de-asserted. | ||
85 | * | ||
86 | * The @statelock is used to protect information in the structure which may | ||
87 | * need to be accessed via several sources, such as the network driver layer | ||
88 | * or one of the work queues. | ||
89 | * | ||
90 | * We align the buffers we may use for rx/tx to ensure that if the SPI driver | ||
91 | * wants to DMA map them, it will not have any problems with data the driver | ||
92 | * modifies. | ||
93 | */ | ||
94 | struct ks8851_net { | ||
95 | struct net_device *netdev; | ||
96 | struct spi_device *spidev; | ||
97 | struct mutex lock; | ||
98 | spinlock_t statelock; | ||
99 | |||
100 | union ks8851_tx_hdr txh ____cacheline_aligned; | ||
101 | u8 rxd[8]; | ||
102 | u8 txd[8]; | ||
103 | |||
104 | u32 msg_enable ____cacheline_aligned; | ||
105 | u16 tx_space; | ||
106 | u8 fid; | ||
107 | |||
108 | u16 rc_ier; | ||
109 | u16 rc_rxqcr; | ||
110 | |||
111 | struct mii_if_info mii; | ||
112 | struct ks8851_rxctrl rxctrl; | ||
113 | |||
114 | struct work_struct tx_work; | ||
115 | struct work_struct irq_work; | ||
116 | struct work_struct rxctrl_work; | ||
117 | |||
118 | struct sk_buff_head txq; | ||
119 | |||
120 | struct spi_message spi_msg1; | ||
121 | struct spi_message spi_msg2; | ||
122 | struct spi_transfer spi_xfer1; | ||
123 | struct spi_transfer spi_xfer2[2]; | ||
124 | }; | ||
125 | |||
126 | static int msg_enable; | ||
127 | |||
128 | #define ks_info(_ks, _msg...) dev_info(&(_ks)->spidev->dev, _msg) | ||
129 | #define ks_warn(_ks, _msg...) dev_warn(&(_ks)->spidev->dev, _msg) | ||
130 | #define ks_dbg(_ks, _msg...) dev_dbg(&(_ks)->spidev->dev, _msg) | ||
131 | #define ks_err(_ks, _msg...) dev_err(&(_ks)->spidev->dev, _msg) | ||
132 | |||
133 | /* shift for byte-enable data */ | ||
134 | #define BYTE_EN(_x) ((_x) << 2) | ||
135 | |||
136 | /* turn register number and byte-enable mask into data for start of packet */ | ||
137 | #define MK_OP(_byteen, _reg) (BYTE_EN(_byteen) | (_reg) << (8+2) | (_reg) >> 6) | ||
138 | |||
139 | /* SPI register read/write calls. | ||
140 | * | ||
141 | * All these calls issue SPI transactions to access the chip's registers. They | ||
142 | * all require that the necessary lock is held to prevent accesses when the | ||
143 | * chip is busy transfering packet data (RX/TX FIFO accesses). | ||
144 | */ | ||
145 | |||
146 | /** | ||
147 | * ks8851_wrreg16 - write 16bit register value to chip | ||
148 | * @ks: The chip state | ||
149 | * @reg: The register address | ||
150 | * @val: The value to write | ||
151 | * | ||
152 | * Issue a write to put the value @val into the register specified in @reg. | ||
153 | */ | ||
154 | static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) | ||
155 | { | ||
156 | struct spi_transfer *xfer = &ks->spi_xfer1; | ||
157 | struct spi_message *msg = &ks->spi_msg1; | ||
158 | __le16 txb[2]; | ||
159 | int ret; | ||
160 | |||
161 | txb[0] = cpu_to_le16(MK_OP(reg & 2 ? 0xC : 0x03, reg) | KS_SPIOP_WR); | ||
162 | txb[1] = cpu_to_le16(val); | ||
163 | |||
164 | xfer->tx_buf = txb; | ||
165 | xfer->rx_buf = NULL; | ||
166 | xfer->len = 4; | ||
167 | |||
168 | ret = spi_sync(ks->spidev, msg); | ||
169 | if (ret < 0) | ||
170 | ks_err(ks, "spi_sync() failed\n"); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * ks8851_rx_1msg - select whether to use one or two messages for spi read | ||
175 | * @ks: The device structure | ||
176 | * | ||
177 | * Return whether to generate a single message with a tx and rx buffer | ||
178 | * supplied to spi_sync(), or alternatively send the tx and rx buffers | ||
179 | * as separate messages. | ||
180 | * | ||
181 | * Depending on the hardware in use, a single message may be more efficient | ||
182 | * on interrupts or work done by the driver. | ||
183 | * | ||
184 | * This currently always returns true until we add some per-device data passed | ||
185 | * from the platform code to specify which mode is better. | ||
186 | */ | ||
187 | static inline bool ks8851_rx_1msg(struct ks8851_net *ks) | ||
188 | { | ||
189 | return true; | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * ks8851_rdreg - issue read register command and return the data | ||
194 | * @ks: The device state | ||
195 | * @op: The register address and byte enables in message format. | ||
196 | * @rxb: The RX buffer to return the result into | ||
197 | * @rxl: The length of data expected. | ||
198 | * | ||
199 | * This is the low level read call that issues the necessary spi message(s) | ||
200 | * to read data from the register specified in @op. | ||
201 | */ | ||
202 | static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, | ||
203 | u8 *rxb, unsigned rxl) | ||
204 | { | ||
205 | struct spi_transfer *xfer; | ||
206 | struct spi_message *msg; | ||
207 | __le16 *txb = (__le16 *)ks->txd; | ||
208 | u8 *trx = ks->rxd; | ||
209 | int ret; | ||
210 | |||
211 | txb[0] = cpu_to_le16(op | KS_SPIOP_RD); | ||
212 | |||
213 | if (ks8851_rx_1msg(ks)) { | ||
214 | msg = &ks->spi_msg1; | ||
215 | xfer = &ks->spi_xfer1; | ||
216 | |||
217 | xfer->tx_buf = txb; | ||
218 | xfer->rx_buf = trx; | ||
219 | xfer->len = rxl + 2; | ||
220 | } else { | ||
221 | msg = &ks->spi_msg2; | ||
222 | xfer = ks->spi_xfer2; | ||
223 | |||
224 | xfer->tx_buf = txb; | ||
225 | xfer->rx_buf = NULL; | ||
226 | xfer->len = 2; | ||
227 | |||
228 | xfer++; | ||
229 | xfer->tx_buf = NULL; | ||
230 | xfer->rx_buf = trx; | ||
231 | xfer->len = rxl; | ||
232 | } | ||
233 | |||
234 | ret = spi_sync(ks->spidev, msg); | ||
235 | if (ret < 0) | ||
236 | ks_err(ks, "read: spi_sync() failed\n"); | ||
237 | else if (ks8851_rx_1msg(ks)) | ||
238 | memcpy(rxb, trx + 2, rxl); | ||
239 | else | ||
240 | memcpy(rxb, trx, rxl); | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * ks8851_rdreg8 - read 8 bit register from device | ||
245 | * @ks: The chip information | ||
246 | * @reg: The register address | ||
247 | * | ||
248 | * Read a 8bit register from the chip, returning the result | ||
249 | */ | ||
250 | static unsigned ks8851_rdreg8(struct ks8851_net *ks, unsigned reg) | ||
251 | { | ||
252 | u8 rxb[1]; | ||
253 | |||
254 | ks8851_rdreg(ks, MK_OP(1 << (reg & 3), reg), rxb, 1); | ||
255 | return rxb[0]; | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * ks8851_rdreg16 - read 16 bit register from device | ||
260 | * @ks: The chip information | ||
261 | * @reg: The register address | ||
262 | * | ||
263 | * Read a 16bit register from the chip, returning the result | ||
264 | */ | ||
265 | static unsigned ks8851_rdreg16(struct ks8851_net *ks, unsigned reg) | ||
266 | { | ||
267 | __le16 rx = 0; | ||
268 | |||
269 | ks8851_rdreg(ks, MK_OP(reg & 2 ? 0xC : 0x3, reg), (u8 *)&rx, 2); | ||
270 | return le16_to_cpu(rx); | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * ks8851_rdreg32 - read 32 bit register from device | ||
275 | * @ks: The chip information | ||
276 | * @reg: The register address | ||
277 | * | ||
278 | * Read a 32bit register from the chip. | ||
279 | * | ||
280 | * Note, this read requires the address be aligned to 4 bytes. | ||
281 | */ | ||
282 | static unsigned ks8851_rdreg32(struct ks8851_net *ks, unsigned reg) | ||
283 | { | ||
284 | __le32 rx = 0; | ||
285 | |||
286 | WARN_ON(reg & 3); | ||
287 | |||
288 | ks8851_rdreg(ks, MK_OP(0xf, reg), (u8 *)&rx, 4); | ||
289 | return le32_to_cpu(rx); | ||
290 | } | ||
291 | |||
292 | /** | ||
293 | * ks8851_soft_reset - issue one of the soft reset to the device | ||
294 | * @ks: The device state. | ||
295 | * @op: The bit(s) to set in the GRR | ||
296 | * | ||
297 | * Issue the relevant soft-reset command to the device's GRR register | ||
298 | * specified by @op. | ||
299 | * | ||
300 | * Note, the delays are in there as a caution to ensure that the reset | ||
301 | * has time to take effect and then complete. Since the datasheet does | ||
302 | * not currently specify the exact sequence, we have chosen something | ||
303 | * that seems to work with our device. | ||
304 | */ | ||
305 | static void ks8851_soft_reset(struct ks8851_net *ks, unsigned op) | ||
306 | { | ||
307 | ks8851_wrreg16(ks, KS_GRR, op); | ||
308 | mdelay(1); /* wait a short time to effect reset */ | ||
309 | ks8851_wrreg16(ks, KS_GRR, 0); | ||
310 | mdelay(1); /* wait for condition to clear */ | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * ks8851_write_mac_addr - write mac address to device registers | ||
315 | * @dev: The network device | ||
316 | * | ||
317 | * Update the KS8851 MAC address registers from the address in @dev. | ||
318 | * | ||
319 | * This call assumes that the chip is not running, so there is no need to | ||
320 | * shutdown the RXQ process whilst setting this. | ||
321 | */ | ||
322 | static int ks8851_write_mac_addr(struct net_device *dev) | ||
323 | { | ||
324 | struct ks8851_net *ks = netdev_priv(dev); | ||
325 | u16 *mcp = (u16 *)dev->dev_addr; | ||
326 | |||
327 | mutex_lock(&ks->lock); | ||
328 | |||
329 | ks8851_wrreg16(ks, KS_MARL, mcp[0]); | ||
330 | ks8851_wrreg16(ks, KS_MARM, mcp[1]); | ||
331 | ks8851_wrreg16(ks, KS_MARH, mcp[2]); | ||
332 | |||
333 | mutex_unlock(&ks->lock); | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | /** | ||
339 | * ks8851_init_mac - initialise the mac address | ||
340 | * @ks: The device structure | ||
341 | * | ||
342 | * Get or create the initial mac address for the device and then set that | ||
343 | * into the station address register. Currently we assume that the device | ||
344 | * does not have a valid mac address in it, and so we use random_ether_addr() | ||
345 | * to create a new one. | ||
346 | * | ||
347 | * In future, the driver should check to see if the device has an EEPROM | ||
348 | * attached and whether that has a valid ethernet address in it. | ||
349 | */ | ||
350 | static void ks8851_init_mac(struct ks8851_net *ks) | ||
351 | { | ||
352 | struct net_device *dev = ks->netdev; | ||
353 | |||
354 | random_ether_addr(dev->dev_addr); | ||
355 | ks8851_write_mac_addr(dev); | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * ks8851_irq - device interrupt handler | ||
360 | * @irq: Interrupt number passed from the IRQ hnalder. | ||
361 | * @pw: The private word passed to register_irq(), our struct ks8851_net. | ||
362 | * | ||
363 | * Disable the interrupt from happening again until we've processed the | ||
364 | * current status by scheduling ks8851_irq_work(). | ||
365 | */ | ||
366 | static irqreturn_t ks8851_irq(int irq, void *pw) | ||
367 | { | ||
368 | struct ks8851_net *ks = pw; | ||
369 | |||
370 | disable_irq_nosync(irq); | ||
371 | schedule_work(&ks->irq_work); | ||
372 | return IRQ_HANDLED; | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * ks8851_rdfifo - read data from the receive fifo | ||
377 | * @ks: The device state. | ||
378 | * @buff: The buffer address | ||
379 | * @len: The length of the data to read | ||
380 | * | ||
381 | * Issue an RXQ FIFO read command and read the @len ammount of data from | ||
382 | * the FIFO into the buffer specified by @buff. | ||
383 | */ | ||
384 | static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len) | ||
385 | { | ||
386 | struct spi_transfer *xfer = ks->spi_xfer2; | ||
387 | struct spi_message *msg = &ks->spi_msg2; | ||
388 | u8 txb[1]; | ||
389 | int ret; | ||
390 | |||
391 | if (netif_msg_rx_status(ks)) | ||
392 | ks_dbg(ks, "%s: %d@%p\n", __func__, len, buff); | ||
393 | |||
394 | /* set the operation we're issuing */ | ||
395 | txb[0] = KS_SPIOP_RXFIFO; | ||
396 | |||
397 | xfer->tx_buf = txb; | ||
398 | xfer->rx_buf = NULL; | ||
399 | xfer->len = 1; | ||
400 | |||
401 | xfer++; | ||
402 | xfer->rx_buf = buff; | ||
403 | xfer->tx_buf = NULL; | ||
404 | xfer->len = len; | ||
405 | |||
406 | ret = spi_sync(ks->spidev, msg); | ||
407 | if (ret < 0) | ||
408 | ks_err(ks, "%s: spi_sync() failed\n", __func__); | ||
409 | } | ||
410 | |||
411 | /** | ||
412 | * ks8851_dbg_dumpkkt - dump initial packet contents to debug | ||
413 | * @ks: The device state | ||
414 | * @rxpkt: The data for the received packet | ||
415 | * | ||
416 | * Dump the initial data from the packet to dev_dbg(). | ||
417 | */ | ||
418 | static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt) | ||
419 | { | ||
420 | ks_dbg(ks, "pkt %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n", | ||
421 | rxpkt[4], rxpkt[5], rxpkt[6], rxpkt[7], | ||
422 | rxpkt[8], rxpkt[9], rxpkt[10], rxpkt[11], | ||
423 | rxpkt[12], rxpkt[13], rxpkt[14], rxpkt[15]); | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * ks8851_rx_pkts - receive packets from the host | ||
428 | * @ks: The device information. | ||
429 | * | ||
430 | * This is called from the IRQ work queue when the system detects that there | ||
431 | * are packets in the receive queue. Find out how many packets there are and | ||
432 | * read them from the FIFO. | ||
433 | */ | ||
434 | static void ks8851_rx_pkts(struct ks8851_net *ks) | ||
435 | { | ||
436 | struct sk_buff *skb; | ||
437 | unsigned rxfc; | ||
438 | unsigned rxlen; | ||
439 | unsigned rxstat; | ||
440 | u32 rxh; | ||
441 | u8 *rxpkt; | ||
442 | |||
443 | rxfc = ks8851_rdreg8(ks, KS_RXFC); | ||
444 | |||
445 | if (netif_msg_rx_status(ks)) | ||
446 | ks_dbg(ks, "%s: %d packets\n", __func__, rxfc); | ||
447 | |||
448 | /* Currently we're issuing a read per packet, but we could possibly | ||
449 | * improve the code by issuing a single read, getting the receive | ||
450 | * header, allocating the packet and then reading the packet data | ||
451 | * out in one go. | ||
452 | * | ||
453 | * This form of operation would require us to hold the SPI bus' | ||
454 | * chipselect low during the entie transaction to avoid any | ||
455 | * reset to the data stream comming from the chip. | ||
456 | */ | ||
457 | |||
458 | for (; rxfc != 0; rxfc--) { | ||
459 | rxh = ks8851_rdreg32(ks, KS_RXFHSR); | ||
460 | rxstat = rxh & 0xffff; | ||
461 | rxlen = rxh >> 16; | ||
462 | |||
463 | if (netif_msg_rx_status(ks)) | ||
464 | ks_dbg(ks, "rx: stat 0x%04x, len 0x%04x\n", | ||
465 | rxstat, rxlen); | ||
466 | |||
467 | /* the length of the packet includes the 32bit CRC */ | ||
468 | |||
469 | /* set dma read address */ | ||
470 | ks8851_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI | 0x00); | ||
471 | |||
472 | /* start the packet dma process, and set auto-dequeue rx */ | ||
473 | ks8851_wrreg16(ks, KS_RXQCR, | ||
474 | ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE); | ||
475 | |||
476 | if (rxlen > 0) { | ||
477 | skb = netdev_alloc_skb(ks->netdev, rxlen + 2 + 8); | ||
478 | if (!skb) { | ||
479 | /* todo - dump frame and move on */ | ||
480 | } | ||
481 | |||
482 | /* two bytes to ensure ip is aligned, and four bytes | ||
483 | * for the status header and 4 bytes of garbage */ | ||
484 | skb_reserve(skb, 2 + 4 + 4); | ||
485 | |||
486 | rxpkt = skb_put(skb, rxlen - 4) - 8; | ||
487 | |||
488 | /* align the packet length to 4 bytes, and add 4 bytes | ||
489 | * as we're getting the rx status header as well */ | ||
490 | ks8851_rdfifo(ks, rxpkt, ALIGN(rxlen, 4) + 8); | ||
491 | |||
492 | if (netif_msg_pktdata(ks)) | ||
493 | ks8851_dbg_dumpkkt(ks, rxpkt); | ||
494 | |||
495 | skb->protocol = eth_type_trans(skb, ks->netdev); | ||
496 | netif_rx(skb); | ||
497 | |||
498 | ks->netdev->stats.rx_packets++; | ||
499 | ks->netdev->stats.rx_bytes += rxlen - 4; | ||
500 | } | ||
501 | |||
502 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | ||
503 | } | ||
504 | } | ||
505 | |||
506 | /** | ||
507 | * ks8851_irq_work - work queue handler for dealing with interrupt requests | ||
508 | * @work: The work structure that was scheduled by schedule_work() | ||
509 | * | ||
510 | * This is the handler invoked when the ks8851_irq() is called to find out | ||
511 | * what happened, as we cannot allow ourselves to sleep whilst waiting for | ||
512 | * anything other process has the chip's lock. | ||
513 | * | ||
514 | * Read the interrupt status, work out what needs to be done and then clear | ||
515 | * any of the interrupts that are not needed. | ||
516 | */ | ||
517 | static void ks8851_irq_work(struct work_struct *work) | ||
518 | { | ||
519 | struct ks8851_net *ks = container_of(work, struct ks8851_net, irq_work); | ||
520 | unsigned status; | ||
521 | unsigned handled = 0; | ||
522 | |||
523 | mutex_lock(&ks->lock); | ||
524 | |||
525 | status = ks8851_rdreg16(ks, KS_ISR); | ||
526 | |||
527 | if (netif_msg_intr(ks)) | ||
528 | dev_dbg(&ks->spidev->dev, "%s: status 0x%04x\n", | ||
529 | __func__, status); | ||
530 | |||
531 | if (status & IRQ_LCI) { | ||
532 | /* should do something about checking link status */ | ||
533 | handled |= IRQ_LCI; | ||
534 | } | ||
535 | |||
536 | if (status & IRQ_LDI) { | ||
537 | u16 pmecr = ks8851_rdreg16(ks, KS_PMECR); | ||
538 | pmecr &= ~PMECR_WKEVT_MASK; | ||
539 | ks8851_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK); | ||
540 | |||
541 | handled |= IRQ_LDI; | ||
542 | } | ||
543 | |||
544 | if (status & IRQ_RXPSI) | ||
545 | handled |= IRQ_RXPSI; | ||
546 | |||
547 | if (status & IRQ_TXI) { | ||
548 | handled |= IRQ_TXI; | ||
549 | |||
550 | /* no lock here, tx queue should have been stopped */ | ||
551 | |||
552 | /* update our idea of how much tx space is available to the | ||
553 | * system */ | ||
554 | ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR); | ||
555 | |||
556 | if (netif_msg_intr(ks)) | ||
557 | ks_dbg(ks, "%s: txspace %d\n", __func__, ks->tx_space); | ||
558 | } | ||
559 | |||
560 | if (status & IRQ_RXI) | ||
561 | handled |= IRQ_RXI; | ||
562 | |||
563 | if (status & IRQ_SPIBEI) { | ||
564 | dev_err(&ks->spidev->dev, "%s: spi bus error\n", __func__); | ||
565 | handled |= IRQ_SPIBEI; | ||
566 | } | ||
567 | |||
568 | ks8851_wrreg16(ks, KS_ISR, handled); | ||
569 | |||
570 | if (status & IRQ_RXI) { | ||
571 | /* the datasheet says to disable the rx interrupt during | ||
572 | * packet read-out, however we're masking the interrupt | ||
573 | * from the device so do not bother masking just the RX | ||
574 | * from the device. */ | ||
575 | |||
576 | ks8851_rx_pkts(ks); | ||
577 | } | ||
578 | |||
579 | /* if something stopped the rx process, probably due to wanting | ||
580 | * to change the rx settings, then do something about restarting | ||
581 | * it. */ | ||
582 | if (status & IRQ_RXPSI) { | ||
583 | struct ks8851_rxctrl *rxc = &ks->rxctrl; | ||
584 | |||
585 | /* update the multicast hash table */ | ||
586 | ks8851_wrreg16(ks, KS_MAHTR0, rxc->mchash[0]); | ||
587 | ks8851_wrreg16(ks, KS_MAHTR1, rxc->mchash[1]); | ||
588 | ks8851_wrreg16(ks, KS_MAHTR2, rxc->mchash[2]); | ||
589 | ks8851_wrreg16(ks, KS_MAHTR3, rxc->mchash[3]); | ||
590 | |||
591 | ks8851_wrreg16(ks, KS_RXCR2, rxc->rxcr2); | ||
592 | ks8851_wrreg16(ks, KS_RXCR1, rxc->rxcr1); | ||
593 | } | ||
594 | |||
595 | mutex_unlock(&ks->lock); | ||
596 | |||
597 | if (status & IRQ_TXI) | ||
598 | netif_wake_queue(ks->netdev); | ||
599 | |||
600 | enable_irq(ks->netdev->irq); | ||
601 | } | ||
602 | |||
603 | /** | ||
604 | * calc_txlen - calculate size of message to send packet | ||
605 | * @len: Lenght of data | ||
606 | * | ||
607 | * Returns the size of the TXFIFO message needed to send | ||
608 | * this packet. | ||
609 | */ | ||
610 | static inline unsigned calc_txlen(unsigned len) | ||
611 | { | ||
612 | return ALIGN(len + 4, 4); | ||
613 | } | ||
614 | |||
615 | /** | ||
616 | * ks8851_wrpkt - write packet to TX FIFO | ||
617 | * @ks: The device state. | ||
618 | * @txp: The sk_buff to transmit. | ||
619 | * @irq: IRQ on completion of the packet. | ||
620 | * | ||
621 | * Send the @txp to the chip. This means creating the relevant packet header | ||
622 | * specifying the length of the packet and the other information the chip | ||
623 | * needs, such as IRQ on completion. Send the header and the packet data to | ||
624 | * the device. | ||
625 | */ | ||
626 | static void ks8851_wrpkt(struct ks8851_net *ks, struct sk_buff *txp, bool irq) | ||
627 | { | ||
628 | struct spi_transfer *xfer = ks->spi_xfer2; | ||
629 | struct spi_message *msg = &ks->spi_msg2; | ||
630 | unsigned fid = 0; | ||
631 | int ret; | ||
632 | |||
633 | if (netif_msg_tx_queued(ks)) | ||
634 | dev_dbg(&ks->spidev->dev, "%s: skb %p, %d@%p, irq %d\n", | ||
635 | __func__, txp, txp->len, txp->data, irq); | ||
636 | |||
637 | fid = ks->fid++; | ||
638 | fid &= TXFR_TXFID_MASK; | ||
639 | |||
640 | if (irq) | ||
641 | fid |= TXFR_TXIC; /* irq on completion */ | ||
642 | |||
643 | /* start header at txb[1] to align txw entries */ | ||
644 | ks->txh.txb[1] = KS_SPIOP_TXFIFO; | ||
645 | ks->txh.txw[1] = cpu_to_le16(fid); | ||
646 | ks->txh.txw[2] = cpu_to_le16(txp->len); | ||
647 | |||
648 | xfer->tx_buf = &ks->txh.txb[1]; | ||
649 | xfer->rx_buf = NULL; | ||
650 | xfer->len = 5; | ||
651 | |||
652 | xfer++; | ||
653 | xfer->tx_buf = txp->data; | ||
654 | xfer->rx_buf = NULL; | ||
655 | xfer->len = ALIGN(txp->len, 4); | ||
656 | |||
657 | ret = spi_sync(ks->spidev, msg); | ||
658 | if (ret < 0) | ||
659 | ks_err(ks, "%s: spi_sync() failed\n", __func__); | ||
660 | } | ||
661 | |||
662 | /** | ||
663 | * ks8851_done_tx - update and then free skbuff after transmitting | ||
664 | * @ks: The device state | ||
665 | * @txb: The buffer transmitted | ||
666 | */ | ||
667 | static void ks8851_done_tx(struct ks8851_net *ks, struct sk_buff *txb) | ||
668 | { | ||
669 | struct net_device *dev = ks->netdev; | ||
670 | |||
671 | dev->stats.tx_bytes += txb->len; | ||
672 | dev->stats.tx_packets++; | ||
673 | |||
674 | dev_kfree_skb(txb); | ||
675 | } | ||
676 | |||
677 | /** | ||
678 | * ks8851_tx_work - process tx packet(s) | ||
679 | * @work: The work strucutre what was scheduled. | ||
680 | * | ||
681 | * This is called when a number of packets have been scheduled for | ||
682 | * transmission and need to be sent to the device. | ||
683 | */ | ||
684 | static void ks8851_tx_work(struct work_struct *work) | ||
685 | { | ||
686 | struct ks8851_net *ks = container_of(work, struct ks8851_net, tx_work); | ||
687 | struct sk_buff *txb; | ||
688 | bool last = false; | ||
689 | |||
690 | mutex_lock(&ks->lock); | ||
691 | |||
692 | while (!last) { | ||
693 | txb = skb_dequeue(&ks->txq); | ||
694 | last = skb_queue_empty(&ks->txq); | ||
695 | |||
696 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); | ||
697 | ks8851_wrpkt(ks, txb, last); | ||
698 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | ||
699 | ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE); | ||
700 | |||
701 | ks8851_done_tx(ks, txb); | ||
702 | } | ||
703 | |||
704 | mutex_unlock(&ks->lock); | ||
705 | } | ||
706 | |||
707 | /** | ||
708 | * ks8851_set_powermode - set power mode of the device | ||
709 | * @ks: The device state | ||
710 | * @pwrmode: The power mode value to write to KS_PMECR. | ||
711 | * | ||
712 | * Change the power mode of the chip. | ||
713 | */ | ||
714 | static void ks8851_set_powermode(struct ks8851_net *ks, unsigned pwrmode) | ||
715 | { | ||
716 | unsigned pmecr; | ||
717 | |||
718 | if (netif_msg_hw(ks)) | ||
719 | ks_dbg(ks, "setting power mode %d\n", pwrmode); | ||
720 | |||
721 | pmecr = ks8851_rdreg16(ks, KS_PMECR); | ||
722 | pmecr &= ~PMECR_PM_MASK; | ||
723 | pmecr |= pwrmode; | ||
724 | |||
725 | ks8851_wrreg16(ks, KS_PMECR, pmecr); | ||
726 | } | ||
727 | |||
728 | /** | ||
729 | * ks8851_net_open - open network device | ||
730 | * @dev: The network device being opened. | ||
731 | * | ||
732 | * Called when the network device is marked active, such as a user executing | ||
733 | * 'ifconfig up' on the device. | ||
734 | */ | ||
735 | static int ks8851_net_open(struct net_device *dev) | ||
736 | { | ||
737 | struct ks8851_net *ks = netdev_priv(dev); | ||
738 | |||
739 | /* lock the card, even if we may not actually be doing anything | ||
740 | * else at the moment */ | ||
741 | mutex_lock(&ks->lock); | ||
742 | |||
743 | if (netif_msg_ifup(ks)) | ||
744 | ks_dbg(ks, "opening %s\n", dev->name); | ||
745 | |||
746 | /* bring chip out of any power saving mode it was in */ | ||
747 | ks8851_set_powermode(ks, PMECR_PM_NORMAL); | ||
748 | |||
749 | /* issue a soft reset to the RX/TX QMU to put it into a known | ||
750 | * state. */ | ||
751 | ks8851_soft_reset(ks, GRR_QMU); | ||
752 | |||
753 | /* setup transmission parameters */ | ||
754 | |||
755 | ks8851_wrreg16(ks, KS_TXCR, (TXCR_TXE | /* enable transmit process */ | ||
756 | TXCR_TXPE | /* pad to min length */ | ||
757 | TXCR_TXCRC | /* add CRC */ | ||
758 | TXCR_TXFCE)); /* enable flow control */ | ||
759 | |||
760 | /* auto-increment tx data, reset tx pointer */ | ||
761 | ks8851_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI); | ||
762 | |||
763 | /* setup receiver control */ | ||
764 | |||
765 | ks8851_wrreg16(ks, KS_RXCR1, (RXCR1_RXPAFMA | /* from mac filter */ | ||
766 | RXCR1_RXFCE | /* enable flow control */ | ||
767 | RXCR1_RXBE | /* broadcast enable */ | ||
768 | RXCR1_RXUE | /* unicast enable */ | ||
769 | RXCR1_RXE)); /* enable rx block */ | ||
770 | |||
771 | /* transfer entire frames out in one go */ | ||
772 | ks8851_wrreg16(ks, KS_RXCR2, RXCR2_SRDBL_FRAME); | ||
773 | |||
774 | /* set receive counter timeouts */ | ||
775 | ks8851_wrreg16(ks, KS_RXDTTR, 1000); /* 1ms after first frame to IRQ */ | ||
776 | ks8851_wrreg16(ks, KS_RXDBCTR, 4096); /* >4Kbytes in buffer to IRQ */ | ||
777 | ks8851_wrreg16(ks, KS_RXFCTR, 10); /* 10 frames to IRQ */ | ||
778 | |||
779 | ks->rc_rxqcr = (RXQCR_RXFCTE | /* IRQ on frame count exceeded */ | ||
780 | RXQCR_RXDBCTE | /* IRQ on byte count exceeded */ | ||
781 | RXQCR_RXDTTE); /* IRQ on time exceeded */ | ||
782 | |||
783 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | ||
784 | |||
785 | /* clear then enable interrupts */ | ||
786 | |||
787 | #define STD_IRQ (IRQ_LCI | /* Link Change */ \ | ||
788 | IRQ_TXI | /* TX done */ \ | ||
789 | IRQ_RXI | /* RX done */ \ | ||
790 | IRQ_SPIBEI | /* SPI bus error */ \ | ||
791 | IRQ_TXPSI | /* TX process stop */ \ | ||
792 | IRQ_RXPSI) /* RX process stop */ | ||
793 | |||
794 | ks->rc_ier = STD_IRQ; | ||
795 | ks8851_wrreg16(ks, KS_ISR, STD_IRQ); | ||
796 | ks8851_wrreg16(ks, KS_IER, STD_IRQ); | ||
797 | |||
798 | netif_start_queue(ks->netdev); | ||
799 | |||
800 | if (netif_msg_ifup(ks)) | ||
801 | ks_dbg(ks, "network device %s up\n", dev->name); | ||
802 | |||
803 | mutex_unlock(&ks->lock); | ||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | /** | ||
808 | * ks8851_net_stop - close network device | ||
809 | * @dev: The device being closed. | ||
810 | * | ||
811 | * Called to close down a network device which has been active. Cancell any | ||
812 | * work, shutdown the RX and TX process and then place the chip into a low | ||
813 | * power state whilst it is not being used. | ||
814 | */ | ||
815 | static int ks8851_net_stop(struct net_device *dev) | ||
816 | { | ||
817 | struct ks8851_net *ks = netdev_priv(dev); | ||
818 | |||
819 | if (netif_msg_ifdown(ks)) | ||
820 | ks_info(ks, "%s: shutting down\n", dev->name); | ||
821 | |||
822 | netif_stop_queue(dev); | ||
823 | |||
824 | mutex_lock(&ks->lock); | ||
825 | |||
826 | /* stop any outstanding work */ | ||
827 | flush_work(&ks->irq_work); | ||
828 | flush_work(&ks->tx_work); | ||
829 | flush_work(&ks->rxctrl_work); | ||
830 | |||
831 | /* turn off the IRQs and ack any outstanding */ | ||
832 | ks8851_wrreg16(ks, KS_IER, 0x0000); | ||
833 | ks8851_wrreg16(ks, KS_ISR, 0xffff); | ||
834 | |||
835 | /* shutdown RX process */ | ||
836 | ks8851_wrreg16(ks, KS_RXCR1, 0x0000); | ||
837 | |||
838 | /* shutdown TX process */ | ||
839 | ks8851_wrreg16(ks, KS_TXCR, 0x0000); | ||
840 | |||
841 | /* set powermode to soft power down to save power */ | ||
842 | ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); | ||
843 | |||
844 | /* ensure any queued tx buffers are dumped */ | ||
845 | while (!skb_queue_empty(&ks->txq)) { | ||
846 | struct sk_buff *txb = skb_dequeue(&ks->txq); | ||
847 | |||
848 | if (netif_msg_ifdown(ks)) | ||
849 | ks_dbg(ks, "%s: freeing txb %p\n", __func__, txb); | ||
850 | |||
851 | dev_kfree_skb(txb); | ||
852 | } | ||
853 | |||
854 | mutex_unlock(&ks->lock); | ||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | /** | ||
859 | * ks8851_start_xmit - transmit packet | ||
860 | * @skb: The buffer to transmit | ||
861 | * @dev: The device used to transmit the packet. | ||
862 | * | ||
863 | * Called by the network layer to transmit the @skb. Queue the packet for | ||
864 | * the device and schedule the necessary work to transmit the packet when | ||
865 | * it is free. | ||
866 | * | ||
867 | * We do this to firstly avoid sleeping with the network device locked, | ||
868 | * and secondly so we can round up more than one packet to transmit which | ||
869 | * means we can try and avoid generating too many transmit done interrupts. | ||
870 | */ | ||
871 | static int ks8851_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
872 | { | ||
873 | struct ks8851_net *ks = netdev_priv(dev); | ||
874 | unsigned needed = calc_txlen(skb->len); | ||
875 | int ret = NETDEV_TX_OK; | ||
876 | |||
877 | if (netif_msg_tx_queued(ks)) | ||
878 | ks_dbg(ks, "%s: skb %p, %d@%p\n", __func__, | ||
879 | skb, skb->len, skb->data); | ||
880 | |||
881 | spin_lock(&ks->statelock); | ||
882 | |||
883 | if (needed > ks->tx_space) { | ||
884 | netif_stop_queue(dev); | ||
885 | ret = NETDEV_TX_BUSY; | ||
886 | } else { | ||
887 | ks->tx_space -= needed; | ||
888 | skb_queue_tail(&ks->txq, skb); | ||
889 | } | ||
890 | |||
891 | spin_unlock(&ks->statelock); | ||
892 | schedule_work(&ks->tx_work); | ||
893 | |||
894 | return ret; | ||
895 | } | ||
896 | |||
897 | /** | ||
898 | * ks8851_rxctrl_work - work handler to change rx mode | ||
899 | * @work: The work structure this belongs to. | ||
900 | * | ||
901 | * Lock the device and issue the necessary changes to the receive mode from | ||
902 | * the network device layer. This is done so that we can do this without | ||
903 | * having to sleep whilst holding the network device lock. | ||
904 | * | ||
905 | * Since the recommendation from Micrel is that the RXQ is shutdown whilst the | ||
906 | * receive parameters are programmed, we issue a write to disable the RXQ and | ||
907 | * then wait for the interrupt handler to be triggered once the RXQ shutdown is | ||
908 | * complete. The interrupt handler then writes the new values into the chip. | ||
909 | */ | ||
910 | static void ks8851_rxctrl_work(struct work_struct *work) | ||
911 | { | ||
912 | struct ks8851_net *ks = container_of(work, struct ks8851_net, rxctrl_work); | ||
913 | |||
914 | mutex_lock(&ks->lock); | ||
915 | |||
916 | /* need to shutdown RXQ before modifying filter parameters */ | ||
917 | ks8851_wrreg16(ks, KS_RXCR1, 0x00); | ||
918 | |||
919 | mutex_unlock(&ks->lock); | ||
920 | } | ||
921 | |||
922 | static void ks8851_set_rx_mode(struct net_device *dev) | ||
923 | { | ||
924 | struct ks8851_net *ks = netdev_priv(dev); | ||
925 | struct ks8851_rxctrl rxctrl; | ||
926 | |||
927 | memset(&rxctrl, 0, sizeof(rxctrl)); | ||
928 | |||
929 | if (dev->flags & IFF_PROMISC) { | ||
930 | /* interface to receive everything */ | ||
931 | |||
932 | rxctrl.rxcr1 = RXCR1_RXAE | RXCR1_RXINVF; | ||
933 | } else if (dev->flags & IFF_ALLMULTI) { | ||
934 | /* accept all multicast packets */ | ||
935 | |||
936 | rxctrl.rxcr1 = (RXCR1_RXME | RXCR1_RXAE | | ||
937 | RXCR1_RXPAFMA | RXCR1_RXMAFMA); | ||
938 | } else if (dev->flags & IFF_MULTICAST && dev->mc_count > 0) { | ||
939 | struct dev_mc_list *mcptr = dev->mc_list; | ||
940 | u32 crc; | ||
941 | int i; | ||
942 | |||
943 | /* accept some multicast */ | ||
944 | |||
945 | for (i = dev->mc_count; i > 0; i--) { | ||
946 | crc = ether_crc(ETH_ALEN, mcptr->dmi_addr); | ||
947 | crc >>= (32 - 6); /* get top six bits */ | ||
948 | |||
949 | rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf)); | ||
950 | mcptr = mcptr->next; | ||
951 | } | ||
952 | |||
953 | rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXAE | RXCR1_RXPAFMA; | ||
954 | } else { | ||
955 | /* just accept broadcast / unicast */ | ||
956 | rxctrl.rxcr1 = RXCR1_RXPAFMA; | ||
957 | } | ||
958 | |||
959 | rxctrl.rxcr1 |= (RXCR1_RXUE | /* unicast enable */ | ||
960 | RXCR1_RXBE | /* broadcast enable */ | ||
961 | RXCR1_RXE | /* RX process enable */ | ||
962 | RXCR1_RXFCE); /* enable flow control */ | ||
963 | |||
964 | rxctrl.rxcr2 |= RXCR2_SRDBL_FRAME; | ||
965 | |||
966 | /* schedule work to do the actual set of the data if needed */ | ||
967 | |||
968 | spin_lock(&ks->statelock); | ||
969 | |||
970 | if (memcmp(&rxctrl, &ks->rxctrl, sizeof(rxctrl)) != 0) { | ||
971 | memcpy(&ks->rxctrl, &rxctrl, sizeof(ks->rxctrl)); | ||
972 | schedule_work(&ks->rxctrl_work); | ||
973 | } | ||
974 | |||
975 | spin_unlock(&ks->statelock); | ||
976 | } | ||
977 | |||
978 | static int ks8851_set_mac_address(struct net_device *dev, void *addr) | ||
979 | { | ||
980 | struct sockaddr *sa = addr; | ||
981 | |||
982 | if (netif_running(dev)) | ||
983 | return -EBUSY; | ||
984 | |||
985 | if (!is_valid_ether_addr(sa->sa_data)) | ||
986 | return -EADDRNOTAVAIL; | ||
987 | |||
988 | memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); | ||
989 | return ks8851_write_mac_addr(dev); | ||
990 | } | ||
991 | |||
992 | static int ks8851_net_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | ||
993 | { | ||
994 | struct ks8851_net *ks = netdev_priv(dev); | ||
995 | |||
996 | if (!netif_running(dev)) | ||
997 | return -EINVAL; | ||
998 | |||
999 | return generic_mii_ioctl(&ks->mii, if_mii(req), cmd, NULL); | ||
1000 | } | ||
1001 | |||
1002 | static const struct net_device_ops ks8851_netdev_ops = { | ||
1003 | .ndo_open = ks8851_net_open, | ||
1004 | .ndo_stop = ks8851_net_stop, | ||
1005 | .ndo_do_ioctl = ks8851_net_ioctl, | ||
1006 | .ndo_start_xmit = ks8851_start_xmit, | ||
1007 | .ndo_set_mac_address = ks8851_set_mac_address, | ||
1008 | .ndo_set_rx_mode = ks8851_set_rx_mode, | ||
1009 | .ndo_change_mtu = eth_change_mtu, | ||
1010 | .ndo_validate_addr = eth_validate_addr, | ||
1011 | }; | ||
1012 | |||
1013 | /* ethtool support */ | ||
1014 | |||
1015 | static void ks8851_get_drvinfo(struct net_device *dev, | ||
1016 | struct ethtool_drvinfo *di) | ||
1017 | { | ||
1018 | strlcpy(di->driver, "KS8851", sizeof(di->driver)); | ||
1019 | strlcpy(di->version, "1.00", sizeof(di->version)); | ||
1020 | strlcpy(di->bus_info, dev_name(dev->dev.parent), sizeof(di->bus_info)); | ||
1021 | } | ||
1022 | |||
1023 | static u32 ks8851_get_msglevel(struct net_device *dev) | ||
1024 | { | ||
1025 | struct ks8851_net *ks = netdev_priv(dev); | ||
1026 | return ks->msg_enable; | ||
1027 | } | ||
1028 | |||
1029 | static void ks8851_set_msglevel(struct net_device *dev, u32 to) | ||
1030 | { | ||
1031 | struct ks8851_net *ks = netdev_priv(dev); | ||
1032 | ks->msg_enable = to; | ||
1033 | } | ||
1034 | |||
1035 | static int ks8851_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1036 | { | ||
1037 | struct ks8851_net *ks = netdev_priv(dev); | ||
1038 | return mii_ethtool_gset(&ks->mii, cmd); | ||
1039 | } | ||
1040 | |||
1041 | static int ks8851_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1042 | { | ||
1043 | struct ks8851_net *ks = netdev_priv(dev); | ||
1044 | return mii_ethtool_sset(&ks->mii, cmd); | ||
1045 | } | ||
1046 | |||
1047 | static u32 ks8851_get_link(struct net_device *dev) | ||
1048 | { | ||
1049 | struct ks8851_net *ks = netdev_priv(dev); | ||
1050 | return mii_link_ok(&ks->mii); | ||
1051 | } | ||
1052 | |||
1053 | static int ks8851_nway_reset(struct net_device *dev) | ||
1054 | { | ||
1055 | struct ks8851_net *ks = netdev_priv(dev); | ||
1056 | return mii_nway_restart(&ks->mii); | ||
1057 | } | ||
1058 | |||
1059 | static const struct ethtool_ops ks8851_ethtool_ops = { | ||
1060 | .get_drvinfo = ks8851_get_drvinfo, | ||
1061 | .get_msglevel = ks8851_get_msglevel, | ||
1062 | .set_msglevel = ks8851_set_msglevel, | ||
1063 | .get_settings = ks8851_get_settings, | ||
1064 | .set_settings = ks8851_set_settings, | ||
1065 | .get_link = ks8851_get_link, | ||
1066 | .nway_reset = ks8851_nway_reset, | ||
1067 | }; | ||
1068 | |||
1069 | /* MII interface controls */ | ||
1070 | |||
1071 | /** | ||
1072 | * ks8851_phy_reg - convert MII register into a KS8851 register | ||
1073 | * @reg: MII register number. | ||
1074 | * | ||
1075 | * Return the KS8851 register number for the corresponding MII PHY register | ||
1076 | * if possible. Return zero if the MII register has no direct mapping to the | ||
1077 | * KS8851 register set. | ||
1078 | */ | ||
1079 | static int ks8851_phy_reg(int reg) | ||
1080 | { | ||
1081 | switch (reg) { | ||
1082 | case MII_BMCR: | ||
1083 | return KS_P1MBCR; | ||
1084 | case MII_BMSR: | ||
1085 | return KS_P1MBSR; | ||
1086 | case MII_PHYSID1: | ||
1087 | return KS_PHY1ILR; | ||
1088 | case MII_PHYSID2: | ||
1089 | return KS_PHY1IHR; | ||
1090 | case MII_ADVERTISE: | ||
1091 | return KS_P1ANAR; | ||
1092 | case MII_LPA: | ||
1093 | return KS_P1ANLPR; | ||
1094 | } | ||
1095 | |||
1096 | return 0x0; | ||
1097 | } | ||
1098 | |||
1099 | /** | ||
1100 | * ks8851_phy_read - MII interface PHY register read. | ||
1101 | * @dev: The network device the PHY is on. | ||
1102 | * @phy_addr: Address of PHY (ignored as we only have one) | ||
1103 | * @reg: The register to read. | ||
1104 | * | ||
1105 | * This call reads data from the PHY register specified in @reg. Since the | ||
1106 | * device does not support all the MII registers, the non-existant values | ||
1107 | * are always returned as zero. | ||
1108 | * | ||
1109 | * We return zero for unsupported registers as the MII code does not check | ||
1110 | * the value returned for any error status, and simply returns it to the | ||
1111 | * caller. The mii-tool that the driver was tested with takes any -ve error | ||
1112 | * as real PHY capabilities, thus displaying incorrect data to the user. | ||
1113 | */ | ||
1114 | static int ks8851_phy_read(struct net_device *dev, int phy_addr, int reg) | ||
1115 | { | ||
1116 | struct ks8851_net *ks = netdev_priv(dev); | ||
1117 | int ksreg; | ||
1118 | int result; | ||
1119 | |||
1120 | ksreg = ks8851_phy_reg(reg); | ||
1121 | if (!ksreg) | ||
1122 | return 0x0; /* no error return allowed, so use zero */ | ||
1123 | |||
1124 | mutex_lock(&ks->lock); | ||
1125 | result = ks8851_rdreg16(ks, ksreg); | ||
1126 | mutex_unlock(&ks->lock); | ||
1127 | |||
1128 | return result; | ||
1129 | } | ||
1130 | |||
1131 | static void ks8851_phy_write(struct net_device *dev, | ||
1132 | int phy, int reg, int value) | ||
1133 | { | ||
1134 | struct ks8851_net *ks = netdev_priv(dev); | ||
1135 | int ksreg; | ||
1136 | |||
1137 | ksreg = ks8851_phy_reg(reg); | ||
1138 | if (ksreg) { | ||
1139 | mutex_lock(&ks->lock); | ||
1140 | ks8851_wrreg16(ks, ksreg, value); | ||
1141 | mutex_unlock(&ks->lock); | ||
1142 | } | ||
1143 | } | ||
1144 | |||
1145 | /** | ||
1146 | * ks8851_read_selftest - read the selftest memory info. | ||
1147 | * @ks: The device state | ||
1148 | * | ||
1149 | * Read and check the TX/RX memory selftest information. | ||
1150 | */ | ||
1151 | static int ks8851_read_selftest(struct ks8851_net *ks) | ||
1152 | { | ||
1153 | unsigned both_done = MBIR_TXMBF | MBIR_RXMBF; | ||
1154 | int ret = 0; | ||
1155 | unsigned rd; | ||
1156 | |||
1157 | rd = ks8851_rdreg16(ks, KS_MBIR); | ||
1158 | |||
1159 | if ((rd & both_done) != both_done) { | ||
1160 | ks_warn(ks, "Memory selftest not finished\n"); | ||
1161 | return 0; | ||
1162 | } | ||
1163 | |||
1164 | if (rd & MBIR_TXMBFA) { | ||
1165 | ks_err(ks, "TX memory selftest fail\n"); | ||
1166 | ret |= 1; | ||
1167 | } | ||
1168 | |||
1169 | if (rd & MBIR_RXMBFA) { | ||
1170 | ks_err(ks, "RX memory selftest fail\n"); | ||
1171 | ret |= 2; | ||
1172 | } | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | |||
1177 | /* driver bus management functions */ | ||
1178 | |||
1179 | static int __devinit ks8851_probe(struct spi_device *spi) | ||
1180 | { | ||
1181 | struct net_device *ndev; | ||
1182 | struct ks8851_net *ks; | ||
1183 | int ret; | ||
1184 | |||
1185 | ndev = alloc_etherdev(sizeof(struct ks8851_net)); | ||
1186 | if (!ndev) { | ||
1187 | dev_err(&spi->dev, "failed to alloc ethernet device\n"); | ||
1188 | return -ENOMEM; | ||
1189 | } | ||
1190 | |||
1191 | spi->bits_per_word = 8; | ||
1192 | |||
1193 | ks = netdev_priv(ndev); | ||
1194 | |||
1195 | ks->netdev = ndev; | ||
1196 | ks->spidev = spi; | ||
1197 | ks->tx_space = 6144; | ||
1198 | |||
1199 | mutex_init(&ks->lock); | ||
1200 | spin_lock_init(&ks->statelock); | ||
1201 | |||
1202 | INIT_WORK(&ks->tx_work, ks8851_tx_work); | ||
1203 | INIT_WORK(&ks->irq_work, ks8851_irq_work); | ||
1204 | INIT_WORK(&ks->rxctrl_work, ks8851_rxctrl_work); | ||
1205 | |||
1206 | /* initialise pre-made spi transfer messages */ | ||
1207 | |||
1208 | spi_message_init(&ks->spi_msg1); | ||
1209 | spi_message_add_tail(&ks->spi_xfer1, &ks->spi_msg1); | ||
1210 | |||
1211 | spi_message_init(&ks->spi_msg2); | ||
1212 | spi_message_add_tail(&ks->spi_xfer2[0], &ks->spi_msg2); | ||
1213 | spi_message_add_tail(&ks->spi_xfer2[1], &ks->spi_msg2); | ||
1214 | |||
1215 | /* setup mii state */ | ||
1216 | ks->mii.dev = ndev; | ||
1217 | ks->mii.phy_id = 1, | ||
1218 | ks->mii.phy_id_mask = 1; | ||
1219 | ks->mii.reg_num_mask = 0xf; | ||
1220 | ks->mii.mdio_read = ks8851_phy_read; | ||
1221 | ks->mii.mdio_write = ks8851_phy_write; | ||
1222 | |||
1223 | dev_info(&spi->dev, "message enable is %d\n", msg_enable); | ||
1224 | |||
1225 | /* set the default message enable */ | ||
1226 | ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV | | ||
1227 | NETIF_MSG_PROBE | | ||
1228 | NETIF_MSG_LINK)); | ||
1229 | |||
1230 | skb_queue_head_init(&ks->txq); | ||
1231 | |||
1232 | SET_ETHTOOL_OPS(ndev, &ks8851_ethtool_ops); | ||
1233 | SET_NETDEV_DEV(ndev, &spi->dev); | ||
1234 | |||
1235 | dev_set_drvdata(&spi->dev, ks); | ||
1236 | |||
1237 | ndev->if_port = IF_PORT_100BASET; | ||
1238 | ndev->netdev_ops = &ks8851_netdev_ops; | ||
1239 | ndev->irq = spi->irq; | ||
1240 | |||
1241 | /* simple check for a valid chip being connected to the bus */ | ||
1242 | |||
1243 | if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { | ||
1244 | dev_err(&spi->dev, "failed to read device ID\n"); | ||
1245 | ret = -ENODEV; | ||
1246 | goto err_id; | ||
1247 | } | ||
1248 | |||
1249 | ks8851_read_selftest(ks); | ||
1250 | ks8851_init_mac(ks); | ||
1251 | |||
1252 | ret = request_irq(spi->irq, ks8851_irq, IRQF_TRIGGER_LOW, | ||
1253 | ndev->name, ks); | ||
1254 | if (ret < 0) { | ||
1255 | dev_err(&spi->dev, "failed to get irq\n"); | ||
1256 | goto err_irq; | ||
1257 | } | ||
1258 | |||
1259 | ret = register_netdev(ndev); | ||
1260 | if (ret) { | ||
1261 | dev_err(&spi->dev, "failed to register network device\n"); | ||
1262 | goto err_netdev; | ||
1263 | } | ||
1264 | |||
1265 | dev_info(&spi->dev, "revision %d, MAC %pM, IRQ %d\n", | ||
1266 | CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), | ||
1267 | ndev->dev_addr, ndev->irq); | ||
1268 | |||
1269 | return 0; | ||
1270 | |||
1271 | |||
1272 | err_netdev: | ||
1273 | free_irq(ndev->irq, ndev); | ||
1274 | |||
1275 | err_id: | ||
1276 | err_irq: | ||
1277 | free_netdev(ndev); | ||
1278 | return ret; | ||
1279 | } | ||
1280 | |||
1281 | static int __devexit ks8851_remove(struct spi_device *spi) | ||
1282 | { | ||
1283 | struct ks8851_net *priv = dev_get_drvdata(&spi->dev); | ||
1284 | |||
1285 | if (netif_msg_drv(priv)) | ||
1286 | dev_info(&spi->dev, "remove"); | ||
1287 | |||
1288 | unregister_netdev(priv->netdev); | ||
1289 | free_irq(spi->irq, priv); | ||
1290 | free_netdev(priv->netdev); | ||
1291 | |||
1292 | return 0; | ||
1293 | } | ||
1294 | |||
1295 | static struct spi_driver ks8851_driver = { | ||
1296 | .driver = { | ||
1297 | .name = "ks8851", | ||
1298 | .owner = THIS_MODULE, | ||
1299 | }, | ||
1300 | .probe = ks8851_probe, | ||
1301 | .remove = __devexit_p(ks8851_remove), | ||
1302 | }; | ||
1303 | |||
1304 | static int __init ks8851_init(void) | ||
1305 | { | ||
1306 | return spi_register_driver(&ks8851_driver); | ||
1307 | } | ||
1308 | |||
1309 | static void __exit ks8851_exit(void) | ||
1310 | { | ||
1311 | spi_unregister_driver(&ks8851_driver); | ||
1312 | } | ||
1313 | |||
1314 | module_init(ks8851_init); | ||
1315 | module_exit(ks8851_exit); | ||
1316 | |||
1317 | MODULE_DESCRIPTION("KS8851 Network driver"); | ||
1318 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
1319 | MODULE_LICENSE("GPL"); | ||
1320 | |||
1321 | module_param_named(message, msg_enable, int, 0); | ||
1322 | MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)"); | ||
diff --git a/drivers/net/ks8851.h b/drivers/net/ks8851.h new file mode 100644 index 000000000000..85abe147afbf --- /dev/null +++ b/drivers/net/ks8851.h | |||
@@ -0,0 +1,296 @@ | |||
1 | /* drivers/net/ks8851.h | ||
2 | * | ||
3 | * Copyright 2009 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * KS8851 register definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #define KS_CCR 0x08 | ||
14 | #define CCR_EEPROM (1 << 9) | ||
15 | #define CCR_SPI (1 << 8) | ||
16 | #define CCR_32PIN (1 << 0) | ||
17 | |||
18 | /* MAC address registers */ | ||
19 | #define KS_MARL 0x10 | ||
20 | #define KS_MARM 0x12 | ||
21 | #define KS_MARH 0x14 | ||
22 | |||
23 | #define KS_OBCR 0x20 | ||
24 | #define OBCR_ODS_16mA (1 << 6) | ||
25 | |||
26 | #define KS_EEPCR 0x22 | ||
27 | #define EEPCR_EESA (1 << 4) | ||
28 | #define EEPCR_EESB (1 << 3) | ||
29 | #define EEPCR_EEDO (1 << 2) | ||
30 | #define EEPCR_EESCK (1 << 1) | ||
31 | #define EEPCR_EECS (1 << 0) | ||
32 | |||
33 | #define KS_MBIR 0x24 | ||
34 | #define MBIR_TXMBF (1 << 12) | ||
35 | #define MBIR_TXMBFA (1 << 11) | ||
36 | #define MBIR_RXMBF (1 << 4) | ||
37 | #define MBIR_RXMBFA (1 << 3) | ||
38 | |||
39 | #define KS_GRR 0x26 | ||
40 | #define GRR_QMU (1 << 1) | ||
41 | #define GRR_GSR (1 << 0) | ||
42 | |||
43 | #define KS_WFCR 0x2A | ||
44 | #define WFCR_MPRXE (1 << 7) | ||
45 | #define WFCR_WF3E (1 << 3) | ||
46 | #define WFCR_WF2E (1 << 2) | ||
47 | #define WFCR_WF1E (1 << 1) | ||
48 | #define WFCR_WF0E (1 << 0) | ||
49 | |||
50 | #define KS_WF0CRC0 0x30 | ||
51 | #define KS_WF0CRC1 0x32 | ||
52 | #define KS_WF0BM0 0x34 | ||
53 | #define KS_WF0BM1 0x36 | ||
54 | #define KS_WF0BM2 0x38 | ||
55 | #define KS_WF0BM3 0x3A | ||
56 | |||
57 | #define KS_WF1CRC0 0x40 | ||
58 | #define KS_WF1CRC1 0x42 | ||
59 | #define KS_WF1BM0 0x44 | ||
60 | #define KS_WF1BM1 0x46 | ||
61 | #define KS_WF1BM2 0x48 | ||
62 | #define KS_WF1BM3 0x4A | ||
63 | |||
64 | #define KS_WF2CRC0 0x50 | ||
65 | #define KS_WF2CRC1 0x52 | ||
66 | #define KS_WF2BM0 0x54 | ||
67 | #define KS_WF2BM1 0x56 | ||
68 | #define KS_WF2BM2 0x58 | ||
69 | #define KS_WF2BM3 0x5A | ||
70 | |||
71 | #define KS_WF3CRC0 0x60 | ||
72 | #define KS_WF3CRC1 0x62 | ||
73 | #define KS_WF3BM0 0x64 | ||
74 | #define KS_WF3BM1 0x66 | ||
75 | #define KS_WF3BM2 0x68 | ||
76 | #define KS_WF3BM3 0x6A | ||
77 | |||
78 | #define KS_TXCR 0x70 | ||
79 | #define TXCR_TCGICMP (1 << 8) | ||
80 | #define TXCR_TCGUDP (1 << 7) | ||
81 | #define TXCR_TCGTCP (1 << 6) | ||
82 | #define TXCR_TCGIP (1 << 5) | ||
83 | #define TXCR_FTXQ (1 << 4) | ||
84 | #define TXCR_TXFCE (1 << 3) | ||
85 | #define TXCR_TXPE (1 << 2) | ||
86 | #define TXCR_TXCRC (1 << 1) | ||
87 | #define TXCR_TXE (1 << 0) | ||
88 | |||
89 | #define KS_TXSR 0x72 | ||
90 | #define TXSR_TXLC (1 << 13) | ||
91 | #define TXSR_TXMC (1 << 12) | ||
92 | #define TXSR_TXFID_MASK (0x3f << 0) | ||
93 | #define TXSR_TXFID_SHIFT (0) | ||
94 | #define TXSR_TXFID_GET(_v) (((_v) >> 0) & 0x3f) | ||
95 | |||
96 | #define KS_RXCR1 0x74 | ||
97 | #define RXCR1_FRXQ (1 << 15) | ||
98 | #define RXCR1_RXUDPFCC (1 << 14) | ||
99 | #define RXCR1_RXTCPFCC (1 << 13) | ||
100 | #define RXCR1_RXIPFCC (1 << 12) | ||
101 | #define RXCR1_RXPAFMA (1 << 11) | ||
102 | #define RXCR1_RXFCE (1 << 10) | ||
103 | #define RXCR1_RXEFE (1 << 9) | ||
104 | #define RXCR1_RXMAFMA (1 << 8) | ||
105 | #define RXCR1_RXBE (1 << 7) | ||
106 | #define RXCR1_RXME (1 << 6) | ||
107 | #define RXCR1_RXUE (1 << 5) | ||
108 | #define RXCR1_RXAE (1 << 4) | ||
109 | #define RXCR1_RXINVF (1 << 1) | ||
110 | #define RXCR1_RXE (1 << 0) | ||
111 | |||
112 | #define KS_RXCR2 0x76 | ||
113 | #define RXCR2_SRDBL_MASK (0x7 << 5) | ||
114 | #define RXCR2_SRDBL_SHIFT (5) | ||
115 | #define RXCR2_SRDBL_4B (0x0 << 5) | ||
116 | #define RXCR2_SRDBL_8B (0x1 << 5) | ||
117 | #define RXCR2_SRDBL_16B (0x2 << 5) | ||
118 | #define RXCR2_SRDBL_32B (0x3 << 5) | ||
119 | #define RXCR2_SRDBL_FRAME (0x4 << 5) | ||
120 | #define RXCR2_IUFFP (1 << 4) | ||
121 | #define RXCR2_RXIUFCEZ (1 << 3) | ||
122 | #define RXCR2_UDPLFE (1 << 2) | ||
123 | #define RXCR2_RXICMPFCC (1 << 1) | ||
124 | #define RXCR2_RXSAF (1 << 0) | ||
125 | |||
126 | #define KS_TXMIR 0x78 | ||
127 | |||
128 | #define KS_RXFHSR 0x7C | ||
129 | #define RXFSHR_RXFV (1 << 15) | ||
130 | #define RXFSHR_RXICMPFCS (1 << 13) | ||
131 | #define RXFSHR_RXIPFCS (1 << 12) | ||
132 | #define RXFSHR_RXTCPFCS (1 << 11) | ||
133 | #define RXFSHR_RXUDPFCS (1 << 10) | ||
134 | #define RXFSHR_RXBF (1 << 7) | ||
135 | #define RXFSHR_RXMF (1 << 6) | ||
136 | #define RXFSHR_RXUF (1 << 5) | ||
137 | #define RXFSHR_RXMR (1 << 4) | ||
138 | #define RXFSHR_RXFT (1 << 3) | ||
139 | #define RXFSHR_RXFTL (1 << 2) | ||
140 | #define RXFSHR_RXRF (1 << 1) | ||
141 | #define RXFSHR_RXCE (1 << 0) | ||
142 | |||
143 | #define KS_RXFHBCR 0x7E | ||
144 | #define KS_TXQCR 0x80 | ||
145 | #define TXQCR_AETFE (1 << 2) | ||
146 | #define TXQCR_TXQMAM (1 << 1) | ||
147 | #define TXQCR_METFE (1 << 0) | ||
148 | |||
149 | #define KS_RXQCR 0x82 | ||
150 | #define RXQCR_RXDTTS (1 << 12) | ||
151 | #define RXQCR_RXDBCTS (1 << 11) | ||
152 | #define RXQCR_RXFCTS (1 << 10) | ||
153 | #define RXQCR_RXIPHTOE (1 << 9) | ||
154 | #define RXQCR_RXDTTE (1 << 7) | ||
155 | #define RXQCR_RXDBCTE (1 << 6) | ||
156 | #define RXQCR_RXFCTE (1 << 5) | ||
157 | #define RXQCR_ADRFE (1 << 4) | ||
158 | #define RXQCR_SDA (1 << 3) | ||
159 | #define RXQCR_RRXEF (1 << 0) | ||
160 | |||
161 | #define KS_TXFDPR 0x84 | ||
162 | #define TXFDPR_TXFPAI (1 << 14) | ||
163 | #define TXFDPR_TXFP_MASK (0x7ff << 0) | ||
164 | #define TXFDPR_TXFP_SHIFT (0) | ||
165 | |||
166 | #define KS_RXFDPR 0x86 | ||
167 | #define RXFDPR_RXFPAI (1 << 14) | ||
168 | |||
169 | #define KS_RXDTTR 0x8C | ||
170 | #define KS_RXDBCTR 0x8E | ||
171 | |||
172 | #define KS_IER 0x90 | ||
173 | #define KS_ISR 0x92 | ||
174 | #define IRQ_LCI (1 << 15) | ||
175 | #define IRQ_TXI (1 << 14) | ||
176 | #define IRQ_RXI (1 << 13) | ||
177 | #define IRQ_RXOI (1 << 11) | ||
178 | #define IRQ_TXPSI (1 << 9) | ||
179 | #define IRQ_RXPSI (1 << 8) | ||
180 | #define IRQ_TXSAI (1 << 6) | ||
181 | #define IRQ_RXWFDI (1 << 5) | ||
182 | #define IRQ_RXMPDI (1 << 4) | ||
183 | #define IRQ_LDI (1 << 3) | ||
184 | #define IRQ_EDI (1 << 2) | ||
185 | #define IRQ_SPIBEI (1 << 1) | ||
186 | #define IRQ_DEDI (1 << 0) | ||
187 | |||
188 | #define KS_RXFCTR 0x9C | ||
189 | #define KS_RXFC 0x9D | ||
190 | #define RXFCTR_RXFC_MASK (0xff << 8) | ||
191 | #define RXFCTR_RXFC_SHIFT (8) | ||
192 | #define RXFCTR_RXFC_GET(_v) (((_v) >> 8) & 0xff) | ||
193 | #define RXFCTR_RXFCT_MASK (0xff << 0) | ||
194 | #define RXFCTR_RXFCT_SHIFT (0) | ||
195 | |||
196 | #define KS_TXNTFSR 0x9E | ||
197 | |||
198 | #define KS_MAHTR0 0xA0 | ||
199 | #define KS_MAHTR1 0xA2 | ||
200 | #define KS_MAHTR2 0xA4 | ||
201 | #define KS_MAHTR3 0xA6 | ||
202 | |||
203 | #define KS_FCLWR 0xB0 | ||
204 | #define KS_FCHWR 0xB2 | ||
205 | #define KS_FCOWR 0xB4 | ||
206 | |||
207 | #define KS_CIDER 0xC0 | ||
208 | #define CIDER_ID 0x8870 | ||
209 | #define CIDER_REV_MASK (0x7 << 1) | ||
210 | #define CIDER_REV_SHIFT (1) | ||
211 | #define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7) | ||
212 | |||
213 | #define KS_CGCR 0xC6 | ||
214 | |||
215 | #define KS_IACR 0xC8 | ||
216 | #define IACR_RDEN (1 << 12) | ||
217 | #define IACR_TSEL_MASK (0x3 << 10) | ||
218 | #define IACR_TSEL_SHIFT (10) | ||
219 | #define IACR_TSEL_MIB (0x3 << 10) | ||
220 | #define IACR_ADDR_MASK (0x1f << 0) | ||
221 | #define IACR_ADDR_SHIFT (0) | ||
222 | |||
223 | #define KS_IADLR 0xD0 | ||
224 | #define KS_IAHDR 0xD2 | ||
225 | |||
226 | #define KS_PMECR 0xD4 | ||
227 | #define PMECR_PME_DELAY (1 << 14) | ||
228 | #define PMECR_PME_POL (1 << 12) | ||
229 | #define PMECR_WOL_WAKEUP (1 << 11) | ||
230 | #define PMECR_WOL_MAGICPKT (1 << 10) | ||
231 | #define PMECR_WOL_LINKUP (1 << 9) | ||
232 | #define PMECR_WOL_ENERGY (1 << 8) | ||
233 | #define PMECR_AUTO_WAKE_EN (1 << 7) | ||
234 | #define PMECR_WAKEUP_NORMAL (1 << 6) | ||
235 | #define PMECR_WKEVT_MASK (0xf << 2) | ||
236 | #define PMECR_WKEVT_SHIFT (2) | ||
237 | #define PMECR_WKEVT_GET(_v) (((_v) >> 2) & 0xf) | ||
238 | #define PMECR_WKEVT_ENERGY (0x1 << 2) | ||
239 | #define PMECR_WKEVT_LINK (0x2 << 2) | ||
240 | #define PMECR_WKEVT_MAGICPKT (0x4 << 2) | ||
241 | #define PMECR_WKEVT_FRAME (0x8 << 2) | ||
242 | #define PMECR_PM_MASK (0x3 << 0) | ||
243 | #define PMECR_PM_SHIFT (0) | ||
244 | #define PMECR_PM_NORMAL (0x0 << 0) | ||
245 | #define PMECR_PM_ENERGY (0x1 << 0) | ||
246 | #define PMECR_PM_SOFTDOWN (0x2 << 0) | ||
247 | #define PMECR_PM_POWERSAVE (0x3 << 0) | ||
248 | |||
249 | /* Standard MII PHY data */ | ||
250 | #define KS_P1MBCR 0xE4 | ||
251 | #define KS_P1MBSR 0xE6 | ||
252 | #define KS_PHY1ILR 0xE8 | ||
253 | #define KS_PHY1IHR 0xEA | ||
254 | #define KS_P1ANAR 0xEC | ||
255 | #define KS_P1ANLPR 0xEE | ||
256 | |||
257 | #define KS_P1SCLMD 0xF4 | ||
258 | #define P1SCLMD_LEDOFF (1 << 15) | ||
259 | #define P1SCLMD_TXIDS (1 << 14) | ||
260 | #define P1SCLMD_RESTARTAN (1 << 13) | ||
261 | #define P1SCLMD_DISAUTOMDIX (1 << 10) | ||
262 | #define P1SCLMD_FORCEMDIX (1 << 9) | ||
263 | #define P1SCLMD_AUTONEGEN (1 << 7) | ||
264 | #define P1SCLMD_FORCE100 (1 << 6) | ||
265 | #define P1SCLMD_FORCEFDX (1 << 5) | ||
266 | #define P1SCLMD_ADV_FLOW (1 << 4) | ||
267 | #define P1SCLMD_ADV_100BT_FDX (1 << 3) | ||
268 | #define P1SCLMD_ADV_100BT_HDX (1 << 2) | ||
269 | #define P1SCLMD_ADV_10BT_FDX (1 << 1) | ||
270 | #define P1SCLMD_ADV_10BT_HDX (1 << 0) | ||
271 | |||
272 | #define KS_P1CR 0xF6 | ||
273 | #define P1CR_HP_MDIX (1 << 15) | ||
274 | #define P1CR_REV_POL (1 << 13) | ||
275 | #define P1CR_OP_100M (1 << 10) | ||
276 | #define P1CR_OP_FDX (1 << 9) | ||
277 | #define P1CR_OP_MDI (1 << 7) | ||
278 | #define P1CR_AN_DONE (1 << 6) | ||
279 | #define P1CR_LINK_GOOD (1 << 5) | ||
280 | #define P1CR_PNTR_FLOW (1 << 4) | ||
281 | #define P1CR_PNTR_100BT_FDX (1 << 3) | ||
282 | #define P1CR_PNTR_100BT_HDX (1 << 2) | ||
283 | #define P1CR_PNTR_10BT_FDX (1 << 1) | ||
284 | #define P1CR_PNTR_10BT_HDX (1 << 0) | ||
285 | |||
286 | /* TX Frame control */ | ||
287 | |||
288 | #define TXFR_TXIC (1 << 15) | ||
289 | #define TXFR_TXFID_MASK (0x3f << 0) | ||
290 | #define TXFR_TXFID_SHIFT (0) | ||
291 | |||
292 | /* SPI frame opcodes */ | ||
293 | #define KS_SPIOP_RD (0x00) | ||
294 | #define KS_SPIOP_WR (0x40) | ||
295 | #define KS_SPIOP_RXFIFO (0x80) | ||
296 | #define KS_SPIOP_TXFIFO (0xC0) | ||
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index acd143da161d..61eabcac734c 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c | |||
@@ -179,7 +179,7 @@ static const struct net_device_ops macsonic_netdev_ops = { | |||
179 | .ndo_set_mac_address = eth_mac_addr, | 179 | .ndo_set_mac_address = eth_mac_addr, |
180 | }; | 180 | }; |
181 | 181 | ||
182 | static int __init macsonic_init(struct net_device *dev) | 182 | static int __devinit macsonic_init(struct net_device *dev) |
183 | { | 183 | { |
184 | struct sonic_local* lp = netdev_priv(dev); | 184 | struct sonic_local* lp = netdev_priv(dev); |
185 | 185 | ||
@@ -223,7 +223,7 @@ static int __init macsonic_init(struct net_device *dev) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | static int __init mac_onboard_sonic_ethernet_addr(struct net_device *dev) | 226 | static int __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev) |
227 | { | 227 | { |
228 | struct sonic_local *lp = netdev_priv(dev); | 228 | struct sonic_local *lp = netdev_priv(dev); |
229 | const int prom_addr = ONBOARD_SONIC_PROM_BASE; | 229 | const int prom_addr = ONBOARD_SONIC_PROM_BASE; |
@@ -288,7 +288,7 @@ static int __init mac_onboard_sonic_ethernet_addr(struct net_device *dev) | |||
288 | } else return 0; | 288 | } else return 0; |
289 | } | 289 | } |
290 | 290 | ||
291 | static int __init mac_onboard_sonic_probe(struct net_device *dev) | 291 | static int __devinit mac_onboard_sonic_probe(struct net_device *dev) |
292 | { | 292 | { |
293 | /* Bwahahaha */ | 293 | /* Bwahahaha */ |
294 | static int once_is_more_than_enough; | 294 | static int once_is_more_than_enough; |
@@ -409,7 +409,7 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev) | |||
409 | return macsonic_init(dev); | 409 | return macsonic_init(dev); |
410 | } | 410 | } |
411 | 411 | ||
412 | static int __init mac_nubus_sonic_ethernet_addr(struct net_device *dev, | 412 | static int __devinit mac_nubus_sonic_ethernet_addr(struct net_device *dev, |
413 | unsigned long prom_addr, | 413 | unsigned long prom_addr, |
414 | int id) | 414 | int id) |
415 | { | 415 | { |
@@ -424,7 +424,7 @@ static int __init mac_nubus_sonic_ethernet_addr(struct net_device *dev, | |||
424 | return 0; | 424 | return 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | static int __init macsonic_ident(struct nubus_dev *ndev) | 427 | static int __devinit macsonic_ident(struct nubus_dev *ndev) |
428 | { | 428 | { |
429 | if (ndev->dr_hw == NUBUS_DRHW_ASANTE_LC && | 429 | if (ndev->dr_hw == NUBUS_DRHW_ASANTE_LC && |
430 | ndev->dr_sw == NUBUS_DRSW_SONIC_LC) | 430 | ndev->dr_sw == NUBUS_DRSW_SONIC_LC) |
@@ -449,7 +449,7 @@ static int __init macsonic_ident(struct nubus_dev *ndev) | |||
449 | return -1; | 449 | return -1; |
450 | } | 450 | } |
451 | 451 | ||
452 | static int __init mac_nubus_sonic_probe(struct net_device *dev) | 452 | static int __devinit mac_nubus_sonic_probe(struct net_device *dev) |
453 | { | 453 | { |
454 | static int slots; | 454 | static int slots; |
455 | struct nubus_dev* ndev = NULL; | 455 | struct nubus_dev* ndev = NULL; |
@@ -562,7 +562,7 @@ static int __init mac_nubus_sonic_probe(struct net_device *dev) | |||
562 | return macsonic_init(dev); | 562 | return macsonic_init(dev); |
563 | } | 563 | } |
564 | 564 | ||
565 | static int __init mac_sonic_probe(struct platform_device *pdev) | 565 | static int __devinit mac_sonic_probe(struct platform_device *pdev) |
566 | { | 566 | { |
567 | struct net_device *dev; | 567 | struct net_device *dev; |
568 | struct sonic_local *lp; | 568 | struct sonic_local *lp; |
@@ -575,6 +575,7 @@ static int __init mac_sonic_probe(struct platform_device *pdev) | |||
575 | lp = netdev_priv(dev); | 575 | lp = netdev_priv(dev); |
576 | lp->device = &pdev->dev; | 576 | lp->device = &pdev->dev; |
577 | SET_NETDEV_DEV(dev, &pdev->dev); | 577 | SET_NETDEV_DEV(dev, &pdev->dev); |
578 | platform_set_drvdata(pdev, dev); | ||
578 | 579 | ||
579 | /* This will catch fatal stuff like -ENOMEM as well as success */ | 580 | /* This will catch fatal stuff like -ENOMEM as well as success */ |
580 | err = mac_onboard_sonic_probe(dev); | 581 | err = mac_onboard_sonic_probe(dev); |
diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c index 2845a0560b84..65ec77dc31f5 100644 --- a/drivers/net/mlx4/cmd.c +++ b/drivers/net/mlx4/cmd.c | |||
@@ -80,7 +80,9 @@ enum { | |||
80 | /* Bad management packet (silently discarded): */ | 80 | /* Bad management packet (silently discarded): */ |
81 | CMD_STAT_BAD_PKT = 0x30, | 81 | CMD_STAT_BAD_PKT = 0x30, |
82 | /* More outstanding CQEs in CQ than new CQ size: */ | 82 | /* More outstanding CQEs in CQ than new CQ size: */ |
83 | CMD_STAT_BAD_SIZE = 0x40 | 83 | CMD_STAT_BAD_SIZE = 0x40, |
84 | /* Multi Function device support required: */ | ||
85 | CMD_STAT_MULTI_FUNC_REQ = 0x50, | ||
84 | }; | 86 | }; |
85 | 87 | ||
86 | enum { | 88 | enum { |
@@ -128,6 +130,7 @@ static int mlx4_status_to_errno(u8 status) | |||
128 | [CMD_STAT_LAM_NOT_PRE] = -EAGAIN, | 130 | [CMD_STAT_LAM_NOT_PRE] = -EAGAIN, |
129 | [CMD_STAT_BAD_PKT] = -EINVAL, | 131 | [CMD_STAT_BAD_PKT] = -EINVAL, |
130 | [CMD_STAT_BAD_SIZE] = -ENOMEM, | 132 | [CMD_STAT_BAD_SIZE] = -ENOMEM, |
133 | [CMD_STAT_MULTI_FUNC_REQ] = -EACCES, | ||
131 | }; | 134 | }; |
132 | 135 | ||
133 | if (status >= ARRAY_SIZE(trans_table) || | 136 | if (status >= ARRAY_SIZE(trans_table) || |
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index 091f99052c91..86467b444ac6 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c | |||
@@ -220,7 +220,7 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
220 | { | 220 | { |
221 | cmd->autoneg = AUTONEG_DISABLE; | 221 | cmd->autoneg = AUTONEG_DISABLE; |
222 | cmd->supported = SUPPORTED_10000baseT_Full; | 222 | cmd->supported = SUPPORTED_10000baseT_Full; |
223 | cmd->advertising = SUPPORTED_10000baseT_Full; | 223 | cmd->advertising = ADVERTISED_1000baseT_Full; |
224 | if (netif_carrier_ok(dev)) { | 224 | if (netif_carrier_ok(dev)) { |
225 | cmd->speed = SPEED_10000; | 225 | cmd->speed = SPEED_10000; |
226 | cmd->duplex = DUPLEX_FULL; | 226 | cmd->duplex = DUPLEX_FULL; |
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 018348c01193..dac621b1e9fc 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
@@ -729,7 +729,10 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
729 | 729 | ||
730 | err = mlx4_QUERY_FW(dev); | 730 | err = mlx4_QUERY_FW(dev); |
731 | if (err) { | 731 | if (err) { |
732 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); | 732 | if (err == -EACCES) |
733 | mlx4_info(dev, "non-primary physical function, skipping.\n"); | ||
734 | else | ||
735 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); | ||
733 | return err; | 736 | return err; |
734 | } | 737 | } |
735 | 738 | ||
@@ -1285,6 +1288,7 @@ static struct pci_device_id mlx4_pci_table[] = { | |||
1285 | { PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ | 1288 | { PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ |
1286 | { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */ | 1289 | { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */ |
1287 | { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ | 1290 | { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ |
1291 | { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/ | ||
1288 | { 0, } | 1292 | { 0, } |
1289 | }; | 1293 | }; |
1290 | 1294 | ||
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index e1cdba752e09..f86e05047d19 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -210,6 +210,7 @@ | |||
210 | #define NETXEN_CTX_SIGNATURE 0xdee0 | 210 | #define NETXEN_CTX_SIGNATURE 0xdee0 |
211 | #define NETXEN_CTX_SIGNATURE_V2 0x0002dee0 | 211 | #define NETXEN_CTX_SIGNATURE_V2 0x0002dee0 |
212 | #define NETXEN_CTX_RESET 0xbad0 | 212 | #define NETXEN_CTX_RESET 0xbad0 |
213 | #define NETXEN_CTX_D3_RESET 0xacc0 | ||
213 | #define NETXEN_RCV_PRODUCER(ringid) (ringid) | 214 | #define NETXEN_RCV_PRODUCER(ringid) (ringid) |
214 | 215 | ||
215 | #define PHAN_PEG_RCV_INITIALIZED 0xff01 | 216 | #define PHAN_PEG_RCV_INITIALIZED 0xff01 |
@@ -773,6 +774,8 @@ struct nx_host_tx_ring { | |||
773 | u32 crb_cmd_consumer; | 774 | u32 crb_cmd_consumer; |
774 | u32 num_desc; | 775 | u32 num_desc; |
775 | 776 | ||
777 | struct netdev_queue *txq; | ||
778 | |||
776 | struct netxen_cmd_buffer *cmd_buf_arr; | 779 | struct netxen_cmd_buffer *cmd_buf_arr; |
777 | struct cmd_desc_type0 *desc_head; | 780 | struct cmd_desc_type0 *desc_head; |
778 | dma_addr_t phys_addr; | 781 | dma_addr_t phys_addr; |
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 4754f5cffad0..9f8ae4719e2f 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -684,10 +684,8 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
684 | goto err_out_free; | 684 | goto err_out_free; |
685 | } else { | 685 | } else { |
686 | err = netxen_init_old_ctx(adapter); | 686 | err = netxen_init_old_ctx(adapter); |
687 | if (err) { | 687 | if (err) |
688 | netxen_free_hw_resources(adapter); | 688 | goto err_out_free; |
689 | return err; | ||
690 | } | ||
691 | } | 689 | } |
692 | 690 | ||
693 | return 0; | 691 | return 0; |
@@ -708,15 +706,18 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) | |||
708 | int port = adapter->portnum; | 706 | int port = adapter->portnum; |
709 | 707 | ||
710 | if (adapter->fw_major >= 4) { | 708 | if (adapter->fw_major >= 4) { |
711 | nx_fw_cmd_destroy_tx_ctx(adapter); | ||
712 | nx_fw_cmd_destroy_rx_ctx(adapter); | 709 | nx_fw_cmd_destroy_rx_ctx(adapter); |
710 | nx_fw_cmd_destroy_tx_ctx(adapter); | ||
713 | } else { | 711 | } else { |
714 | netxen_api_lock(adapter); | 712 | netxen_api_lock(adapter); |
715 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), | 713 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), |
716 | NETXEN_CTX_RESET | port); | 714 | NETXEN_CTX_D3_RESET | port); |
717 | netxen_api_unlock(adapter); | 715 | netxen_api_unlock(adapter); |
718 | } | 716 | } |
719 | 717 | ||
718 | /* Allow dma queues to drain after context reset */ | ||
719 | msleep(20); | ||
720 | |||
720 | recv_ctx = &adapter->recv_ctx; | 721 | recv_ctx = &adapter->recv_ctx; |
721 | 722 | ||
722 | if (recv_ctx->hwctx != NULL) { | 723 | if (recv_ctx->hwctx != NULL) { |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index ce3b89d2cbb6..b9123d445c96 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -461,13 +461,14 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
461 | i = 0; | 461 | i = 0; |
462 | 462 | ||
463 | tx_ring = adapter->tx_ring; | 463 | tx_ring = adapter->tx_ring; |
464 | netif_tx_lock_bh(adapter->netdev); | 464 | __netif_tx_lock_bh(tx_ring->txq); |
465 | 465 | ||
466 | producer = tx_ring->producer; | 466 | producer = tx_ring->producer; |
467 | consumer = tx_ring->sw_consumer; | 467 | consumer = tx_ring->sw_consumer; |
468 | 468 | ||
469 | if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) { | 469 | if (nr_desc >= netxen_tx_avail(tx_ring)) { |
470 | netif_tx_unlock_bh(adapter->netdev); | 470 | netif_tx_stop_queue(tx_ring->txq); |
471 | __netif_tx_unlock_bh(tx_ring->txq); | ||
471 | return -EBUSY; | 472 | return -EBUSY; |
472 | } | 473 | } |
473 | 474 | ||
@@ -490,7 +491,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
490 | 491 | ||
491 | netxen_nic_update_cmd_producer(adapter, tx_ring); | 492 | netxen_nic_update_cmd_producer(adapter, tx_ring); |
492 | 493 | ||
493 | netif_tx_unlock_bh(adapter->netdev); | 494 | __netif_tx_unlock_bh(tx_ring->txq); |
494 | 495 | ||
495 | return 0; | 496 | return 0; |
496 | } | 497 | } |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index b899bd51fcd8..7acf204e38c9 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -184,6 +184,13 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) | |||
184 | kfree(recv_ctx->rds_rings); | 184 | kfree(recv_ctx->rds_rings); |
185 | 185 | ||
186 | skip_rds: | 186 | skip_rds: |
187 | if (recv_ctx->sds_rings == NULL) | ||
188 | goto skip_sds; | ||
189 | |||
190 | for(ring = 0; ring < adapter->max_sds_rings; ring++) | ||
191 | recv_ctx->sds_rings[ring].consumer = 0; | ||
192 | |||
193 | skip_sds: | ||
187 | if (adapter->tx_ring == NULL) | 194 | if (adapter->tx_ring == NULL) |
188 | return; | 195 | return; |
189 | 196 | ||
@@ -214,6 +221,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) | |||
214 | adapter->tx_ring = tx_ring; | 221 | adapter->tx_ring = tx_ring; |
215 | 222 | ||
216 | tx_ring->num_desc = adapter->num_txd; | 223 | tx_ring->num_desc = adapter->num_txd; |
224 | tx_ring->txq = netdev_get_tx_queue(netdev, 0); | ||
217 | 225 | ||
218 | cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); | 226 | cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); |
219 | if (cmd_buf_arr == NULL) { | 227 | if (cmd_buf_arr == NULL) { |
@@ -1400,10 +1408,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
1400 | smp_mb(); | 1408 | smp_mb(); |
1401 | 1409 | ||
1402 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { | 1410 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { |
1403 | netif_tx_lock(netdev); | 1411 | __netif_tx_lock(tx_ring->txq, smp_processor_id()); |
1404 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) | 1412 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) |
1405 | netif_wake_queue(netdev); | 1413 | netif_wake_queue(netdev); |
1406 | netif_tx_unlock(netdev); | 1414 | __netif_tx_unlock(tx_ring->txq); |
1407 | } | 1415 | } |
1408 | } | 1416 | } |
1409 | /* | 1417 | /* |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 27539ddf94c4..637ac8b89bac 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -215,9 +215,9 @@ netxen_napi_disable(struct netxen_adapter *adapter) | |||
215 | 215 | ||
216 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 216 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
217 | sds_ring = &recv_ctx->sds_rings[ring]; | 217 | sds_ring = &recv_ctx->sds_rings[ring]; |
218 | napi_disable(&sds_ring->napi); | ||
219 | netxen_nic_disable_int(sds_ring); | 218 | netxen_nic_disable_int(sds_ring); |
220 | synchronize_irq(sds_ring->irq); | 219 | napi_synchronize(&sds_ring->napi); |
220 | napi_disable(&sds_ring->napi); | ||
221 | } | 221 | } |
222 | } | 222 | } |
223 | 223 | ||
@@ -833,11 +833,11 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
833 | 833 | ||
834 | adapter->ahw.linkup = 0; | 834 | adapter->ahw.linkup = 0; |
835 | 835 | ||
836 | netxen_napi_enable(adapter); | ||
837 | |||
838 | if (adapter->max_sds_rings > 1) | 836 | if (adapter->max_sds_rings > 1) |
839 | netxen_config_rss(adapter, 1); | 837 | netxen_config_rss(adapter, 1); |
840 | 838 | ||
839 | netxen_napi_enable(adapter); | ||
840 | |||
841 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) | 841 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) |
842 | netxen_linkevent_request(adapter, 1); | 842 | netxen_linkevent_request(adapter, 1); |
843 | else | 843 | else |
@@ -851,8 +851,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
851 | static void | 851 | static void |
852 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | 852 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) |
853 | { | 853 | { |
854 | spin_lock(&adapter->tx_clean_lock); | ||
854 | netif_carrier_off(netdev); | 855 | netif_carrier_off(netdev); |
855 | netif_stop_queue(netdev); | 856 | netif_tx_disable(netdev); |
856 | 857 | ||
857 | if (adapter->stop_port) | 858 | if (adapter->stop_port) |
858 | adapter->stop_port(adapter); | 859 | adapter->stop_port(adapter); |
@@ -863,9 +864,10 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | |||
863 | netxen_napi_disable(adapter); | 864 | netxen_napi_disable(adapter); |
864 | 865 | ||
865 | netxen_release_tx_buffers(adapter); | 866 | netxen_release_tx_buffers(adapter); |
867 | spin_unlock(&adapter->tx_clean_lock); | ||
866 | 868 | ||
867 | FLUSH_SCHEDULED_WORK(); | ||
868 | del_timer_sync(&adapter->watchdog_timer); | 869 | del_timer_sync(&adapter->watchdog_timer); |
870 | FLUSH_SCHEDULED_WORK(); | ||
869 | } | 871 | } |
870 | 872 | ||
871 | 873 | ||
@@ -943,8 +945,8 @@ err_out_free_sw: | |||
943 | static void | 945 | static void |
944 | netxen_nic_detach(struct netxen_adapter *adapter) | 946 | netxen_nic_detach(struct netxen_adapter *adapter) |
945 | { | 947 | { |
946 | netxen_release_rx_buffers(adapter); | ||
947 | netxen_free_hw_resources(adapter); | 948 | netxen_free_hw_resources(adapter); |
949 | netxen_release_rx_buffers(adapter); | ||
948 | netxen_nic_free_irq(adapter); | 950 | netxen_nic_free_irq(adapter); |
949 | netxen_free_sw_resources(adapter); | 951 | netxen_free_sw_resources(adapter); |
950 | 952 | ||
@@ -1533,10 +1535,12 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1533 | printk(KERN_ALERT | 1535 | printk(KERN_ALERT |
1534 | "%s: Device temperature %d degrees C exceeds" | 1536 | "%s: Device temperature %d degrees C exceeds" |
1535 | " maximum allowed. Hardware has been shut down.\n", | 1537 | " maximum allowed. Hardware has been shut down.\n", |
1536 | netxen_nic_driver_name, temp_val); | 1538 | netdev->name, temp_val); |
1539 | |||
1540 | netif_device_detach(netdev); | ||
1541 | netxen_nic_down(adapter, netdev); | ||
1542 | netxen_nic_detach(adapter); | ||
1537 | 1543 | ||
1538 | netif_carrier_off(netdev); | ||
1539 | netif_stop_queue(netdev); | ||
1540 | rv = 1; | 1544 | rv = 1; |
1541 | } else if (temp_state == NX_TEMP_WARN) { | 1545 | } else if (temp_state == NX_TEMP_WARN) { |
1542 | if (adapter->temp == NX_TEMP_NORMAL) { | 1546 | if (adapter->temp == NX_TEMP_NORMAL) { |
@@ -1544,13 +1548,13 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1544 | "%s: Device temperature %d degrees C " | 1548 | "%s: Device temperature %d degrees C " |
1545 | "exceeds operating range." | 1549 | "exceeds operating range." |
1546 | " Immediate action needed.\n", | 1550 | " Immediate action needed.\n", |
1547 | netxen_nic_driver_name, temp_val); | 1551 | netdev->name, temp_val); |
1548 | } | 1552 | } |
1549 | } else { | 1553 | } else { |
1550 | if (adapter->temp == NX_TEMP_WARN) { | 1554 | if (adapter->temp == NX_TEMP_WARN) { |
1551 | printk(KERN_INFO | 1555 | printk(KERN_INFO |
1552 | "%s: Device temperature is now %d degrees C" | 1556 | "%s: Device temperature is now %d degrees C" |
1553 | " in normal range.\n", netxen_nic_driver_name, | 1557 | " in normal range.\n", netdev->name, |
1554 | temp_val); | 1558 | temp_val); |
1555 | } | 1559 | } |
1556 | } | 1560 | } |
@@ -1623,7 +1627,7 @@ void netxen_watchdog_task(struct work_struct *work) | |||
1623 | struct netxen_adapter *adapter = | 1627 | struct netxen_adapter *adapter = |
1624 | container_of(work, struct netxen_adapter, watchdog_task); | 1628 | container_of(work, struct netxen_adapter, watchdog_task); |
1625 | 1629 | ||
1626 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | 1630 | if (netxen_nic_check_temp(adapter)) |
1627 | return; | 1631 | return; |
1628 | 1632 | ||
1629 | if (!adapter->has_link_events) | 1633 | if (!adapter->has_link_events) |
@@ -1645,6 +1649,9 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1645 | struct netxen_adapter *adapter = | 1649 | struct netxen_adapter *adapter = |
1646 | container_of(work, struct netxen_adapter, tx_timeout_task); | 1650 | container_of(work, struct netxen_adapter, tx_timeout_task); |
1647 | 1651 | ||
1652 | if (!netif_running(adapter->netdev)) | ||
1653 | return; | ||
1654 | |||
1648 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1655 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
1649 | netxen_nic_driver_name, adapter->netdev->name); | 1656 | netxen_nic_driver_name, adapter->netdev->name); |
1650 | 1657 | ||
@@ -1757,7 +1764,8 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
1757 | 1764 | ||
1758 | if ((work_done < budget) && tx_complete) { | 1765 | if ((work_done < budget) && tx_complete) { |
1759 | napi_complete(&sds_ring->napi); | 1766 | napi_complete(&sds_ring->napi); |
1760 | netxen_nic_enable_int(sds_ring); | 1767 | if (netif_running(adapter->netdev)) |
1768 | netxen_nic_enable_int(sds_ring); | ||
1761 | } | 1769 | } |
1762 | 1770 | ||
1763 | return work_done; | 1771 | return work_done; |
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index ec7cf5ac4f05..690b9c76d34e 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c | |||
@@ -156,6 +156,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev); | |||
156 | static int el3_rx(struct net_device *dev); | 156 | static int el3_rx(struct net_device *dev); |
157 | static int el3_close(struct net_device *dev); | 157 | static int el3_close(struct net_device *dev); |
158 | static void el3_tx_timeout(struct net_device *dev); | 158 | static void el3_tx_timeout(struct net_device *dev); |
159 | static void set_rx_mode(struct net_device *dev); | ||
159 | static void set_multicast_list(struct net_device *dev); | 160 | static void set_multicast_list(struct net_device *dev); |
160 | static const struct ethtool_ops netdev_ethtool_ops; | 161 | static const struct ethtool_ops netdev_ethtool_ops; |
161 | 162 | ||
@@ -488,8 +489,7 @@ static void tc589_reset(struct net_device *dev) | |||
488 | /* Switch to register set 1 for normal use. */ | 489 | /* Switch to register set 1 for normal use. */ |
489 | EL3WINDOW(1); | 490 | EL3WINDOW(1); |
490 | 491 | ||
491 | /* Accept b-cast and phys addr only. */ | 492 | set_rx_mode(dev); |
492 | outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); | ||
493 | outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ | 493 | outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ |
494 | outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ | 494 | outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ |
495 | outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ | 495 | outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ |
@@ -700,7 +700,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) | |||
700 | if (fifo_diag & 0x2000) { | 700 | if (fifo_diag & 0x2000) { |
701 | /* Rx underrun */ | 701 | /* Rx underrun */ |
702 | tc589_wait_for_completion(dev, RxReset); | 702 | tc589_wait_for_completion(dev, RxReset); |
703 | set_multicast_list(dev); | 703 | set_rx_mode(dev); |
704 | outw(RxEnable, ioaddr + EL3_CMD); | 704 | outw(RxEnable, ioaddr + EL3_CMD); |
705 | } | 705 | } |
706 | outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); | 706 | outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); |
@@ -905,14 +905,11 @@ static int el3_rx(struct net_device *dev) | |||
905 | return 0; | 905 | return 0; |
906 | } | 906 | } |
907 | 907 | ||
908 | static void set_multicast_list(struct net_device *dev) | 908 | static void set_rx_mode(struct net_device *dev) |
909 | { | 909 | { |
910 | struct el3_private *lp = netdev_priv(dev); | ||
911 | struct pcmcia_device *link = lp->p_dev; | ||
912 | unsigned int ioaddr = dev->base_addr; | 910 | unsigned int ioaddr = dev->base_addr; |
913 | u16 opts = SetRxFilter | RxStation | RxBroadcast; | 911 | u16 opts = SetRxFilter | RxStation | RxBroadcast; |
914 | 912 | ||
915 | if (!pcmcia_dev_present(link)) return; | ||
916 | if (dev->flags & IFF_PROMISC) | 913 | if (dev->flags & IFF_PROMISC) |
917 | opts |= RxMulticast | RxProm; | 914 | opts |= RxMulticast | RxProm; |
918 | else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) | 915 | else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) |
@@ -920,6 +917,16 @@ static void set_multicast_list(struct net_device *dev) | |||
920 | outw(opts, ioaddr + EL3_CMD); | 917 | outw(opts, ioaddr + EL3_CMD); |
921 | } | 918 | } |
922 | 919 | ||
920 | static void set_multicast_list(struct net_device *dev) | ||
921 | { | ||
922 | struct el3_private *priv = netdev_priv(dev); | ||
923 | unsigned long flags; | ||
924 | |||
925 | spin_lock_irqsave(&priv->lock, flags); | ||
926 | set_rx_mode(dev); | ||
927 | spin_unlock_irqrestore(&priv->lock, flags); | ||
928 | } | ||
929 | |||
923 | static int el3_close(struct net_device *dev) | 930 | static int el3_close(struct net_device *dev) |
924 | { | 931 | { |
925 | struct el3_private *lp = netdev_priv(dev); | 932 | struct el3_private *lp = netdev_priv(dev); |
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 33984b737233..22cdd451fb82 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #ifdef CONFIG_OF_GPIO | 31 | #ifdef CONFIG_OF_GPIO |
32 | #include <linux/of_gpio.h> | 32 | #include <linux/of_gpio.h> |
33 | #include <linux/of_mdio.h> | ||
33 | #include <linux/of_platform.h> | 34 | #include <linux/of_platform.h> |
34 | #endif | 35 | #endif |
35 | 36 | ||
@@ -81,13 +82,12 @@ static struct mdiobb_ops mdio_gpio_ops = { | |||
81 | .get_mdio_data = mdio_get, | 82 | .get_mdio_data = mdio_get, |
82 | }; | 83 | }; |
83 | 84 | ||
84 | static int __devinit mdio_gpio_bus_init(struct device *dev, | 85 | static struct mii_bus * __devinit mdio_gpio_bus_init(struct device *dev, |
85 | struct mdio_gpio_platform_data *pdata, | 86 | struct mdio_gpio_platform_data *pdata, |
86 | int bus_id) | 87 | int bus_id) |
87 | { | 88 | { |
88 | struct mii_bus *new_bus; | 89 | struct mii_bus *new_bus; |
89 | struct mdio_gpio_info *bitbang; | 90 | struct mdio_gpio_info *bitbang; |
90 | int ret = -ENOMEM; | ||
91 | int i; | 91 | int i; |
92 | 92 | ||
93 | bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL); | 93 | bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL); |
@@ -104,8 +104,6 @@ static int __devinit mdio_gpio_bus_init(struct device *dev, | |||
104 | 104 | ||
105 | new_bus->name = "GPIO Bitbanged MDIO", | 105 | new_bus->name = "GPIO Bitbanged MDIO", |
106 | 106 | ||
107 | ret = -ENODEV; | ||
108 | |||
109 | new_bus->phy_mask = pdata->phy_mask; | 107 | new_bus->phy_mask = pdata->phy_mask; |
110 | new_bus->irq = pdata->irqs; | 108 | new_bus->irq = pdata->irqs; |
111 | new_bus->parent = dev; | 109 | new_bus->parent = dev; |
@@ -129,15 +127,8 @@ static int __devinit mdio_gpio_bus_init(struct device *dev, | |||
129 | 127 | ||
130 | dev_set_drvdata(dev, new_bus); | 128 | dev_set_drvdata(dev, new_bus); |
131 | 129 | ||
132 | ret = mdiobus_register(new_bus); | 130 | return new_bus; |
133 | if (ret) | ||
134 | goto out_free_all; | ||
135 | |||
136 | return 0; | ||
137 | 131 | ||
138 | out_free_all: | ||
139 | dev_set_drvdata(dev, NULL); | ||
140 | gpio_free(bitbang->mdio); | ||
141 | out_free_mdc: | 132 | out_free_mdc: |
142 | gpio_free(bitbang->mdc); | 133 | gpio_free(bitbang->mdc); |
143 | out_free_bus: | 134 | out_free_bus: |
@@ -145,30 +136,47 @@ out_free_bus: | |||
145 | out_free_bitbang: | 136 | out_free_bitbang: |
146 | kfree(bitbang); | 137 | kfree(bitbang); |
147 | out: | 138 | out: |
148 | return ret; | 139 | return NULL; |
149 | } | 140 | } |
150 | 141 | ||
151 | static void __devexit mdio_gpio_bus_destroy(struct device *dev) | 142 | static void __devinit mdio_gpio_bus_deinit(struct device *dev) |
152 | { | 143 | { |
153 | struct mii_bus *bus = dev_get_drvdata(dev); | 144 | struct mii_bus *bus = dev_get_drvdata(dev); |
154 | struct mdio_gpio_info *bitbang = bus->priv; | 145 | struct mdio_gpio_info *bitbang = bus->priv; |
155 | 146 | ||
156 | mdiobus_unregister(bus); | ||
157 | free_mdio_bitbang(bus); | ||
158 | dev_set_drvdata(dev, NULL); | 147 | dev_set_drvdata(dev, NULL); |
159 | gpio_free(bitbang->mdc); | ||
160 | gpio_free(bitbang->mdio); | 148 | gpio_free(bitbang->mdio); |
149 | gpio_free(bitbang->mdc); | ||
150 | free_mdio_bitbang(bus); | ||
161 | kfree(bitbang); | 151 | kfree(bitbang); |
162 | } | 152 | } |
163 | 153 | ||
154 | static void __devexit mdio_gpio_bus_destroy(struct device *dev) | ||
155 | { | ||
156 | struct mii_bus *bus = dev_get_drvdata(dev); | ||
157 | |||
158 | mdiobus_unregister(bus); | ||
159 | mdio_gpio_bus_deinit(dev); | ||
160 | } | ||
161 | |||
164 | static int __devinit mdio_gpio_probe(struct platform_device *pdev) | 162 | static int __devinit mdio_gpio_probe(struct platform_device *pdev) |
165 | { | 163 | { |
166 | struct mdio_gpio_platform_data *pdata = pdev->dev.platform_data; | 164 | struct mdio_gpio_platform_data *pdata = pdev->dev.platform_data; |
165 | struct mii_bus *new_bus; | ||
166 | int ret; | ||
167 | 167 | ||
168 | if (!pdata) | 168 | if (!pdata) |
169 | return -ENODEV; | 169 | return -ENODEV; |
170 | 170 | ||
171 | return mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); | 171 | new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); |
172 | if (!new_bus) | ||
173 | return -ENODEV; | ||
174 | |||
175 | ret = mdiobus_register(new_bus); | ||
176 | if (ret) | ||
177 | mdio_gpio_bus_deinit(&pdev->dev); | ||
178 | |||
179 | return ret; | ||
172 | } | 180 | } |
173 | 181 | ||
174 | static int __devexit mdio_gpio_remove(struct platform_device *pdev) | 182 | static int __devexit mdio_gpio_remove(struct platform_device *pdev) |
@@ -179,29 +187,12 @@ static int __devexit mdio_gpio_remove(struct platform_device *pdev) | |||
179 | } | 187 | } |
180 | 188 | ||
181 | #ifdef CONFIG_OF_GPIO | 189 | #ifdef CONFIG_OF_GPIO |
182 | static void __devinit add_phy(struct mdio_gpio_platform_data *pdata, | ||
183 | struct device_node *np) | ||
184 | { | ||
185 | const u32 *data; | ||
186 | int len, id, irq; | ||
187 | |||
188 | data = of_get_property(np, "reg", &len); | ||
189 | if (!data || len != 4) | ||
190 | return; | ||
191 | |||
192 | id = *data; | ||
193 | pdata->phy_mask &= ~(1 << id); | ||
194 | |||
195 | irq = of_irq_to_resource(np, 0, NULL); | ||
196 | if (irq) | ||
197 | pdata->irqs[id] = irq; | ||
198 | } | ||
199 | 190 | ||
200 | static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, | 191 | static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, |
201 | const struct of_device_id *match) | 192 | const struct of_device_id *match) |
202 | { | 193 | { |
203 | struct device_node *np = NULL; | ||
204 | struct mdio_gpio_platform_data *pdata; | 194 | struct mdio_gpio_platform_data *pdata; |
195 | struct mii_bus *new_bus; | ||
205 | int ret; | 196 | int ret; |
206 | 197 | ||
207 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 198 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
@@ -215,14 +206,18 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, | |||
215 | 206 | ||
216 | ret = of_get_gpio(ofdev->node, 1); | 207 | ret = of_get_gpio(ofdev->node, 1); |
217 | if (ret < 0) | 208 | if (ret < 0) |
218 | goto out_free; | 209 | goto out_free; |
219 | pdata->mdio = ret; | 210 | pdata->mdio = ret; |
220 | 211 | ||
221 | while ((np = of_get_next_child(ofdev->node, np))) | 212 | new_bus = mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc); |
222 | if (!strcmp(np->type, "ethernet-phy")) | 213 | if (!new_bus) |
223 | add_phy(pdata, np); | 214 | return -ENODEV; |
224 | 215 | ||
225 | return mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc); | 216 | ret = of_mdiobus_register(new_bus, ofdev->node); |
217 | if (ret) | ||
218 | mdio_gpio_bus_deinit(&ofdev->dev); | ||
219 | |||
220 | return ret; | ||
226 | 221 | ||
227 | out_free: | 222 | out_free: |
228 | kfree(pdata); | 223 | kfree(pdata); |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index eba937c46376..b10fedd82143 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -134,8 +134,10 @@ int phy_scan_fixups(struct phy_device *phydev) | |||
134 | 134 | ||
135 | err = fixup->run(phydev); | 135 | err = fixup->run(phydev); |
136 | 136 | ||
137 | if (err < 0) | 137 | if (err < 0) { |
138 | mutex_unlock(&phy_fixup_lock); | ||
138 | return err; | 139 | return err; |
140 | } | ||
139 | } | 141 | } |
140 | } | 142 | } |
141 | mutex_unlock(&phy_fixup_lock); | 143 | mutex_unlock(&phy_fixup_lock); |
diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 7a62f781fef2..2ca8b0d84ee2 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c | |||
@@ -270,6 +270,9 @@ static const struct net_device_ops plip_netdev_ops = { | |||
270 | .ndo_stop = plip_close, | 270 | .ndo_stop = plip_close, |
271 | .ndo_start_xmit = plip_tx_packet, | 271 | .ndo_start_xmit = plip_tx_packet, |
272 | .ndo_do_ioctl = plip_ioctl, | 272 | .ndo_do_ioctl = plip_ioctl, |
273 | .ndo_change_mtu = eth_change_mtu, | ||
274 | .ndo_set_mac_address = eth_mac_addr, | ||
275 | .ndo_validate_addr = eth_validate_addr, | ||
273 | }; | 276 | }; |
274 | 277 | ||
275 | /* Entry point of PLIP driver. | 278 | /* Entry point of PLIP driver. |
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 17c116bb332c..6de8399d6dd9 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
@@ -356,6 +356,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
356 | if (!skb_queue_empty(&ap->rqueue)) | 356 | if (!skb_queue_empty(&ap->rqueue)) |
357 | tasklet_schedule(&ap->tsk); | 357 | tasklet_schedule(&ap->tsk); |
358 | ap_put(ap); | 358 | ap_put(ap); |
359 | tty_unthrottle(tty); | ||
359 | } | 360 | } |
360 | 361 | ||
361 | static void | 362 | static void |
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index aa3d39f38e22..d2fa2db13586 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c | |||
@@ -397,6 +397,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, | |||
397 | if (!skb_queue_empty(&ap->rqueue)) | 397 | if (!skb_queue_empty(&ap->rqueue)) |
398 | tasklet_schedule(&ap->tsk); | 398 | tasklet_schedule(&ap->tsk); |
399 | sp_put(ap); | 399 | sp_put(ap); |
400 | tty_unthrottle(tty); | ||
400 | } | 401 | } |
401 | 402 | ||
402 | static void | 403 | static void |
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index d1a5fb4d6acb..a3932c9f3406 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c | |||
@@ -1411,6 +1411,7 @@ static const struct net_device_ops gelic_netdevice_ops = { | |||
1411 | .ndo_set_multicast_list = gelic_net_set_multi, | 1411 | .ndo_set_multicast_list = gelic_net_set_multi, |
1412 | .ndo_change_mtu = gelic_net_change_mtu, | 1412 | .ndo_change_mtu = gelic_net_change_mtu, |
1413 | .ndo_tx_timeout = gelic_net_tx_timeout, | 1413 | .ndo_tx_timeout = gelic_net_tx_timeout, |
1414 | .ndo_set_mac_address = eth_mac_addr, | ||
1414 | .ndo_validate_addr = eth_validate_addr, | 1415 | .ndo_validate_addr = eth_validate_addr, |
1415 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1416 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1416 | .ndo_poll_controller = gelic_net_poll_controller, | 1417 | .ndo_poll_controller = gelic_net_poll_controller, |
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index b6b3ca9bdb21..6932b08d746b 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c | |||
@@ -2707,6 +2707,7 @@ static const struct net_device_ops gelic_wl_netdevice_ops = { | |||
2707 | .ndo_set_multicast_list = gelic_net_set_multi, | 2707 | .ndo_set_multicast_list = gelic_net_set_multi, |
2708 | .ndo_change_mtu = gelic_net_change_mtu, | 2708 | .ndo_change_mtu = gelic_net_change_mtu, |
2709 | .ndo_tx_timeout = gelic_net_tx_timeout, | 2709 | .ndo_tx_timeout = gelic_net_tx_timeout, |
2710 | .ndo_set_mac_address = eth_mac_addr, | ||
2710 | .ndo_validate_addr = eth_validate_addr, | 2711 | .ndo_validate_addr = eth_validate_addr, |
2711 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2712 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2712 | .ndo_poll_controller = gelic_net_poll_controller, | 2713 | .ndo_poll_controller = gelic_net_poll_controller, |
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index ed63d23a6452..961b5397a531 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -49,8 +49,8 @@ | |||
49 | #include <asm/processor.h> | 49 | #include <asm/processor.h> |
50 | 50 | ||
51 | #define DRV_NAME "r6040" | 51 | #define DRV_NAME "r6040" |
52 | #define DRV_VERSION "0.23" | 52 | #define DRV_VERSION "0.24" |
53 | #define DRV_RELDATE "05May2009" | 53 | #define DRV_RELDATE "08Jul2009" |
54 | 54 | ||
55 | /* PHY CHIP Address */ | 55 | /* PHY CHIP Address */ |
56 | #define PHY1_ADDR 1 /* For MAC1 */ | 56 | #define PHY1_ADDR 1 /* For MAC1 */ |
@@ -704,8 +704,11 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id) | |||
704 | /* Read MISR status and clear */ | 704 | /* Read MISR status and clear */ |
705 | status = ioread16(ioaddr + MISR); | 705 | status = ioread16(ioaddr + MISR); |
706 | 706 | ||
707 | if (status == 0x0000 || status == 0xffff) | 707 | if (status == 0x0000 || status == 0xffff) { |
708 | /* Restore RDC MAC interrupt */ | ||
709 | iowrite16(misr, ioaddr + MIER); | ||
708 | return IRQ_NONE; | 710 | return IRQ_NONE; |
711 | } | ||
709 | 712 | ||
710 | /* RX interrupt request */ | 713 | /* RX interrupt request */ |
711 | if (status & RX_INTS) { | 714 | if (status & RX_INTS) { |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 4b53b58d75fc..b82780d805f5 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -2060,8 +2060,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2060 | } | 2060 | } |
2061 | } | 2061 | } |
2062 | 2062 | ||
2063 | pci_set_master(pdev); | ||
2064 | |||
2065 | /* ioremap MMIO region */ | 2063 | /* ioremap MMIO region */ |
2066 | ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE); | 2064 | ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE); |
2067 | if (!ioaddr) { | 2065 | if (!ioaddr) { |
@@ -2089,6 +2087,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2089 | 2087 | ||
2090 | RTL_W16(IntrStatus, 0xffff); | 2088 | RTL_W16(IntrStatus, 0xffff); |
2091 | 2089 | ||
2090 | pci_set_master(pdev); | ||
2091 | |||
2092 | /* Identify chip attached to board */ | 2092 | /* Identify chip attached to board */ |
2093 | rtl8169_get_mac_version(tp, ioaddr); | 2093 | rtl8169_get_mac_version(tp, ioaddr); |
2094 | 2094 | ||
@@ -3874,6 +3874,15 @@ static void rtl_shutdown(struct pci_dev *pdev) | |||
3874 | spin_unlock_irq(&tp->lock); | 3874 | spin_unlock_irq(&tp->lock); |
3875 | 3875 | ||
3876 | if (system_state == SYSTEM_POWER_OFF) { | 3876 | if (system_state == SYSTEM_POWER_OFF) { |
3877 | /* WoL fails with some 8168 when the receiver is disabled. */ | ||
3878 | if (tp->features & RTL_FEATURE_WOL) { | ||
3879 | pci_clear_master(pdev); | ||
3880 | |||
3881 | RTL_W8(ChipCmd, CmdRxEnb); | ||
3882 | /* PCI commit */ | ||
3883 | RTL_R8(ChipCmd); | ||
3884 | } | ||
3885 | |||
3877 | pci_wake_from_d3(pdev, true); | 3886 | pci_wake_from_d3(pdev, true); |
3878 | pci_set_power_state(pdev, PCI_D3hot); | 3887 | pci_set_power_state(pdev, PCI_D3hot); |
3879 | } | 3888 | } |
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index 18821f217e19..e3156c97bb58 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c | |||
@@ -1593,6 +1593,7 @@ out: | |||
1593 | static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = { | 1593 | static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = { |
1594 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) }, | 1594 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) }, |
1595 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) }, | 1595 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) }, |
1596 | { PCI_DEVICE(0x1088, 0x2031) }, | ||
1596 | { 0, } | 1597 | { 0, } |
1597 | }; | 1598 | }; |
1598 | MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table); | 1599 | MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table); |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 60d502eef4fc..543af2044f40 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -3854,8 +3854,10 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3854 | skge->speed = -1; | 3854 | skge->speed = -1; |
3855 | skge->advertising = skge_supported_modes(hw); | 3855 | skge->advertising = skge_supported_modes(hw); |
3856 | 3856 | ||
3857 | if (device_may_wakeup(&hw->pdev->dev)) | 3857 | if (device_can_wakeup(&hw->pdev->dev)) { |
3858 | skge->wol = wol_supported(hw) & WAKE_MAGIC; | 3858 | skge->wol = wol_supported(hw) & WAKE_MAGIC; |
3859 | device_set_wakeup_enable(&hw->pdev->dev, skge->wol); | ||
3860 | } | ||
3859 | 3861 | ||
3860 | hw->dev[port] = dev; | 3862 | hw->dev[port] = dev; |
3861 | 3863 | ||
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index daf961ab68bc..3550c5dcd93c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1151,14 +1151,7 @@ stopped: | |||
1151 | 1151 | ||
1152 | /* reset the Rx prefetch unit */ | 1152 | /* reset the Rx prefetch unit */ |
1153 | sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); | 1153 | sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); |
1154 | 1154 | mmiowb(); | |
1155 | /* Reset the RAM Buffer receive queue */ | ||
1156 | sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_RST_SET); | ||
1157 | |||
1158 | /* Reset Rx MAC FIFO */ | ||
1159 | sky2_write8(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), GMF_RST_SET); | ||
1160 | |||
1161 | sky2_read8(hw, B0_CTST); | ||
1162 | } | 1155 | } |
1163 | 1156 | ||
1164 | /* Clean out receive buffer area, assumes receiver hardware stopped */ | 1157 | /* Clean out receive buffer area, assumes receiver hardware stopped */ |
@@ -1825,12 +1818,6 @@ static int sky2_down(struct net_device *dev) | |||
1825 | if (netif_msg_ifdown(sky2)) | 1818 | if (netif_msg_ifdown(sky2)) |
1826 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); | 1819 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); |
1827 | 1820 | ||
1828 | /* Disable port IRQ */ | ||
1829 | imask = sky2_read32(hw, B0_IMSK); | ||
1830 | imask &= ~portirq_msk[port]; | ||
1831 | sky2_write32(hw, B0_IMSK, imask); | ||
1832 | sky2_read32(hw, B0_IMSK); | ||
1833 | |||
1834 | /* Force flow control off */ | 1821 | /* Force flow control off */ |
1835 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 1822 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
1836 | 1823 | ||
@@ -1870,8 +1857,6 @@ static int sky2_down(struct net_device *dev) | |||
1870 | 1857 | ||
1871 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET); | 1858 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET); |
1872 | 1859 | ||
1873 | sky2_rx_stop(sky2); | ||
1874 | |||
1875 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 1860 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
1876 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 1861 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
1877 | 1862 | ||
@@ -1881,6 +1866,14 @@ static int sky2_down(struct net_device *dev) | |||
1881 | sky2_write32(hw, STAT_ISR_TIMER_CNT, 0); | 1866 | sky2_write32(hw, STAT_ISR_TIMER_CNT, 0); |
1882 | sky2_read8(hw, STAT_ISR_TIMER_CTRL); | 1867 | sky2_read8(hw, STAT_ISR_TIMER_CTRL); |
1883 | 1868 | ||
1869 | sky2_rx_stop(sky2); | ||
1870 | |||
1871 | /* Disable port IRQ */ | ||
1872 | imask = sky2_read32(hw, B0_IMSK); | ||
1873 | imask &= ~portirq_msk[port]; | ||
1874 | sky2_write32(hw, B0_IMSK, imask); | ||
1875 | sky2_read32(hw, B0_IMSK); | ||
1876 | |||
1884 | synchronize_irq(hw->pdev->irq); | 1877 | synchronize_irq(hw->pdev->irq); |
1885 | napi_synchronize(&hw->napi); | 1878 | napi_synchronize(&hw->napi); |
1886 | 1879 | ||
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index fdcbaf8dfa73..1c70e999cc50 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -1774,6 +1774,7 @@ static const struct net_device_ops smc_netdev_ops = { | |||
1774 | .ndo_start_xmit = smc_hard_start_xmit, | 1774 | .ndo_start_xmit = smc_hard_start_xmit, |
1775 | .ndo_tx_timeout = smc_timeout, | 1775 | .ndo_tx_timeout = smc_timeout, |
1776 | .ndo_set_multicast_list = smc_set_multicast_list, | 1776 | .ndo_set_multicast_list = smc_set_multicast_list, |
1777 | .ndo_change_mtu = eth_change_mtu, | ||
1777 | .ndo_validate_addr = eth_validate_addr, | 1778 | .ndo_validate_addr = eth_validate_addr, |
1778 | .ndo_set_mac_address = eth_mac_addr, | 1779 | .ndo_set_mac_address = eth_mac_addr, |
1779 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1780 | #ifdef CONFIG_NET_POLL_CONTROLLER |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index f1f773b17fe1..57a159fac99f 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -186,7 +186,8 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) | |||
186 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) | 186 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) |
187 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | 187 | #define SMC_IRQ_FLAGS (-1) /* from resource */ |
188 | 188 | ||
189 | #elif defined(CONFIG_MACH_LOGICPD_PXA270) | 189 | #elif defined(CONFIG_MACH_LOGICPD_PXA270) \ |
190 | || defined(CONFIG_MACH_NOMADIK_8815NHK) | ||
190 | 191 | ||
191 | #define SMC_CAN_USE_8BIT 0 | 192 | #define SMC_CAN_USE_8BIT 0 |
192 | #define SMC_CAN_USE_16BIT 1 | 193 | #define SMC_CAN_USE_16BIT 1 |
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 66067f9d91c0..94b6d2658ddc 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c | |||
@@ -1779,6 +1779,7 @@ static const struct net_device_ops smsc911x_netdev_ops = { | |||
1779 | .ndo_get_stats = smsc911x_get_stats, | 1779 | .ndo_get_stats = smsc911x_get_stats, |
1780 | .ndo_set_multicast_list = smsc911x_set_multicast_list, | 1780 | .ndo_set_multicast_list = smsc911x_set_multicast_list, |
1781 | .ndo_do_ioctl = smsc911x_do_ioctl, | 1781 | .ndo_do_ioctl = smsc911x_do_ioctl, |
1782 | .ndo_change_mtu = eth_change_mtu, | ||
1782 | .ndo_validate_addr = eth_validate_addr, | 1783 | .ndo_validate_addr = eth_validate_addr, |
1783 | .ndo_set_mac_address = smsc911x_set_mac_address, | 1784 | .ndo_set_mac_address = smsc911x_set_mac_address, |
1784 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1785 | #ifdef CONFIG_NET_POLL_CONTROLLER |
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index a82fb2aca4cb..f1e5e4542c2a 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c | |||
@@ -1016,7 +1016,9 @@ static const struct net_device_ops vnet_ops = { | |||
1016 | .ndo_open = vnet_open, | 1016 | .ndo_open = vnet_open, |
1017 | .ndo_stop = vnet_close, | 1017 | .ndo_stop = vnet_close, |
1018 | .ndo_set_multicast_list = vnet_set_rx_mode, | 1018 | .ndo_set_multicast_list = vnet_set_rx_mode, |
1019 | .ndo_change_mtu = eth_change_mtu, | ||
1019 | .ndo_set_mac_address = vnet_set_mac_addr, | 1020 | .ndo_set_mac_address = vnet_set_mac_addr, |
1021 | .ndo_validate_addr = eth_validate_addr, | ||
1020 | .ndo_tx_timeout = vnet_tx_timeout, | 1022 | .ndo_tx_timeout = vnet_tx_timeout, |
1021 | .ndo_change_mtu = vnet_change_mtu, | 1023 | .ndo_change_mtu = vnet_change_mtu, |
1022 | .ndo_start_xmit = vnet_start_xmit, | 1024 | .ndo_start_xmit = vnet_start_xmit, |
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index 9d896116cf76..08a6c41c1599 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c | |||
@@ -1912,7 +1912,7 @@ static int __init ibmtr_init(void) | |||
1912 | 1912 | ||
1913 | find_turbo_adapters(io); | 1913 | find_turbo_adapters(io); |
1914 | 1914 | ||
1915 | for (i = 0; io[i] && (i < IBMTR_MAX_ADAPTERS); i++) { | 1915 | for (i = 0; i < IBMTR_MAX_ADAPTERS && io[i]; i++) { |
1916 | struct net_device *dev; | 1916 | struct net_device *dev; |
1917 | irq[i] = 0; | 1917 | irq[i] = 0; |
1918 | mem[i] = 0; | 1918 | mem[i] = 0; |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 40c6eba775ce..3b957e6412ee 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -1590,13 +1590,13 @@ static int init_phy(struct net_device *dev) | |||
1590 | priv->oldspeed = 0; | 1590 | priv->oldspeed = 0; |
1591 | priv->oldduplex = -1; | 1591 | priv->oldduplex = -1; |
1592 | 1592 | ||
1593 | if (!ug_info->phy_node) | ||
1594 | return 0; | ||
1595 | |||
1596 | phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0, | 1593 | phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0, |
1597 | priv->phy_interface); | 1594 | priv->phy_interface); |
1595 | if (!phydev) | ||
1596 | phydev = of_phy_connect_fixed_link(dev, &adjust_link, | ||
1597 | priv->phy_interface); | ||
1598 | if (!phydev) { | 1598 | if (!phydev) { |
1599 | printk("%s: Could not attach to PHY\n", dev->name); | 1599 | dev_err(&dev->dev, "Could not attach to PHY\n"); |
1600 | return -ENODEV; | 1600 | return -ENODEV; |
1601 | } | 1601 | } |
1602 | 1602 | ||
@@ -3608,9 +3608,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3608 | struct ucc_geth_private *ugeth = NULL; | 3608 | struct ucc_geth_private *ugeth = NULL; |
3609 | struct ucc_geth_info *ug_info; | 3609 | struct ucc_geth_info *ug_info; |
3610 | struct resource res; | 3610 | struct resource res; |
3611 | struct device_node *phy; | ||
3612 | int err, ucc_num, max_speed = 0; | 3611 | int err, ucc_num, max_speed = 0; |
3613 | const u32 *fixed_link; | ||
3614 | const unsigned int *prop; | 3612 | const unsigned int *prop; |
3615 | const char *sprop; | 3613 | const char *sprop; |
3616 | const void *mac_addr; | 3614 | const void *mac_addr; |
@@ -3708,15 +3706,8 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3708 | 3706 | ||
3709 | ug_info->uf_info.regs = res.start; | 3707 | ug_info->uf_info.regs = res.start; |
3710 | ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); | 3708 | ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); |
3711 | fixed_link = of_get_property(np, "fixed-link", NULL); | 3709 | |
3712 | if (fixed_link) { | 3710 | ug_info->phy_node = of_parse_phandle(np, "phy-handle", 0); |
3713 | phy = NULL; | ||
3714 | } else { | ||
3715 | phy = of_parse_phandle(np, "phy-handle", 0); | ||
3716 | if (phy == NULL) | ||
3717 | return -ENODEV; | ||
3718 | } | ||
3719 | ug_info->phy_node = phy; | ||
3720 | 3711 | ||
3721 | /* Find the TBI PHY node. If it's not there, we don't support SGMII */ | 3712 | /* Find the TBI PHY node. If it's not there, we don't support SGMII */ |
3722 | ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0); | 3713 | ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0); |
@@ -3725,7 +3716,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3725 | prop = of_get_property(np, "phy-connection-type", NULL); | 3716 | prop = of_get_property(np, "phy-connection-type", NULL); |
3726 | if (!prop) { | 3717 | if (!prop) { |
3727 | /* handle interface property present in old trees */ | 3718 | /* handle interface property present in old trees */ |
3728 | prop = of_get_property(phy, "interface", NULL); | 3719 | prop = of_get_property(ug_info->phy_node, "interface", NULL); |
3729 | if (prop != NULL) { | 3720 | if (prop != NULL) { |
3730 | phy_interface = enet_to_phy_interface[*prop]; | 3721 | phy_interface = enet_to_phy_interface[*prop]; |
3731 | max_speed = enet_to_speed[*prop]; | 3722 | max_speed = enet_to_speed[*prop]; |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index a906d3998131..c47237c2d638 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -369,4 +369,12 @@ config USB_NET_INT51X1 | |||
369 | (Powerline Communications) solution with an Intellon | 369 | (Powerline Communications) solution with an Intellon |
370 | INT51x1/INT5200 chip, like the "devolo dLan duo". | 370 | INT51x1/INT5200 chip, like the "devolo dLan duo". |
371 | 371 | ||
372 | config USB_CDC_PHONET | ||
373 | tristate "CDC Phonet support" | ||
374 | depends on PHONET | ||
375 | help | ||
376 | Choose this option to support the Phonet interface to a Nokia | ||
377 | cellular modem, as found on most Nokia handsets with the | ||
378 | "PC suite" USB profile. | ||
379 | |||
372 | endmenu | 380 | endmenu |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index b870b0b1cbe0..e17afb78f372 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -21,4 +21,5 @@ obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o | |||
21 | obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o | 21 | obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o |
22 | obj-$(CONFIG_USB_USBNET) += usbnet.o | 22 | obj-$(CONFIG_USB_USBNET) += usbnet.o |
23 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o | 23 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o |
24 | obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o | ||
24 | 25 | ||
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c new file mode 100644 index 000000000000..792af72da8ac --- /dev/null +++ b/drivers/net/usb/cdc-phonet.c | |||
@@ -0,0 +1,461 @@ | |||
1 | /* | ||
2 | * phonet.c -- USB CDC Phonet host driver | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved. | ||
5 | * | ||
6 | * Author: Rémi Denis-Courmont | ||
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 | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Â See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/usb.h> | ||
26 | #include <linux/usb/cdc.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/if_arp.h> | ||
29 | #include <linux/if_phonet.h> | ||
30 | |||
31 | #define PN_MEDIA_USB 0x1B | ||
32 | |||
33 | static const unsigned rxq_size = 17; | ||
34 | |||
35 | struct usbpn_dev { | ||
36 | struct net_device *dev; | ||
37 | |||
38 | struct usb_interface *intf, *data_intf; | ||
39 | struct usb_device *usb; | ||
40 | unsigned int tx_pipe, rx_pipe; | ||
41 | u8 active_setting; | ||
42 | u8 disconnected; | ||
43 | |||
44 | unsigned tx_queue; | ||
45 | spinlock_t tx_lock; | ||
46 | |||
47 | spinlock_t rx_lock; | ||
48 | struct sk_buff *rx_skb; | ||
49 | struct urb *urbs[0]; | ||
50 | }; | ||
51 | |||
52 | static void tx_complete(struct urb *req); | ||
53 | static void rx_complete(struct urb *req); | ||
54 | |||
55 | /* | ||
56 | * Network device callbacks | ||
57 | */ | ||
58 | static int usbpn_xmit(struct sk_buff *skb, struct net_device *dev) | ||
59 | { | ||
60 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
61 | struct urb *req = NULL; | ||
62 | unsigned long flags; | ||
63 | int err; | ||
64 | |||
65 | if (skb->protocol != htons(ETH_P_PHONET)) | ||
66 | goto drop; | ||
67 | |||
68 | req = usb_alloc_urb(0, GFP_ATOMIC); | ||
69 | if (!req) | ||
70 | goto drop; | ||
71 | usb_fill_bulk_urb(req, pnd->usb, pnd->tx_pipe, skb->data, skb->len, | ||
72 | tx_complete, skb); | ||
73 | req->transfer_flags = URB_ZERO_PACKET; | ||
74 | err = usb_submit_urb(req, GFP_ATOMIC); | ||
75 | if (err) { | ||
76 | usb_free_urb(req); | ||
77 | goto drop; | ||
78 | } | ||
79 | |||
80 | spin_lock_irqsave(&pnd->tx_lock, flags); | ||
81 | pnd->tx_queue++; | ||
82 | if (pnd->tx_queue >= dev->tx_queue_len) | ||
83 | netif_stop_queue(dev); | ||
84 | spin_unlock_irqrestore(&pnd->tx_lock, flags); | ||
85 | return 0; | ||
86 | |||
87 | drop: | ||
88 | dev_kfree_skb(skb); | ||
89 | dev->stats.tx_dropped++; | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static void tx_complete(struct urb *req) | ||
94 | { | ||
95 | struct sk_buff *skb = req->context; | ||
96 | struct net_device *dev = skb->dev; | ||
97 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
98 | |||
99 | switch (req->status) { | ||
100 | case 0: | ||
101 | dev->stats.tx_bytes += skb->len; | ||
102 | break; | ||
103 | |||
104 | case -ENOENT: | ||
105 | case -ECONNRESET: | ||
106 | case -ESHUTDOWN: | ||
107 | dev->stats.tx_aborted_errors++; | ||
108 | default: | ||
109 | dev->stats.tx_errors++; | ||
110 | dev_dbg(&dev->dev, "TX error (%d)\n", req->status); | ||
111 | } | ||
112 | dev->stats.tx_packets++; | ||
113 | |||
114 | spin_lock(&pnd->tx_lock); | ||
115 | pnd->tx_queue--; | ||
116 | netif_wake_queue(dev); | ||
117 | spin_unlock(&pnd->tx_lock); | ||
118 | |||
119 | dev_kfree_skb_any(skb); | ||
120 | usb_free_urb(req); | ||
121 | } | ||
122 | |||
123 | static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags) | ||
124 | { | ||
125 | struct net_device *dev = pnd->dev; | ||
126 | struct page *page; | ||
127 | int err; | ||
128 | |||
129 | page = __netdev_alloc_page(dev, gfp_flags); | ||
130 | if (!page) | ||
131 | return -ENOMEM; | ||
132 | |||
133 | usb_fill_bulk_urb(req, pnd->usb, pnd->rx_pipe, page_address(page), | ||
134 | PAGE_SIZE, rx_complete, dev); | ||
135 | req->transfer_flags = 0; | ||
136 | err = usb_submit_urb(req, gfp_flags); | ||
137 | if (unlikely(err)) { | ||
138 | dev_dbg(&dev->dev, "RX submit error (%d)\n", err); | ||
139 | netdev_free_page(dev, page); | ||
140 | } | ||
141 | return err; | ||
142 | } | ||
143 | |||
144 | static void rx_complete(struct urb *req) | ||
145 | { | ||
146 | struct net_device *dev = req->context; | ||
147 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
148 | struct page *page = virt_to_page(req->transfer_buffer); | ||
149 | struct sk_buff *skb; | ||
150 | unsigned long flags; | ||
151 | |||
152 | switch (req->status) { | ||
153 | case 0: | ||
154 | spin_lock_irqsave(&pnd->rx_lock, flags); | ||
155 | skb = pnd->rx_skb; | ||
156 | if (!skb) { | ||
157 | skb = pnd->rx_skb = netdev_alloc_skb(dev, 12); | ||
158 | if (likely(skb)) { | ||
159 | /* Can't use pskb_pull() on page in IRQ */ | ||
160 | memcpy(skb_put(skb, 1), page_address(page), 1); | ||
161 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, | ||
162 | page, 1, req->actual_length); | ||
163 | page = NULL; | ||
164 | } | ||
165 | } else { | ||
166 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, | ||
167 | page, 0, req->actual_length); | ||
168 | page = NULL; | ||
169 | } | ||
170 | if (req->actual_length < PAGE_SIZE) | ||
171 | pnd->rx_skb = NULL; /* Last fragment */ | ||
172 | else | ||
173 | skb = NULL; | ||
174 | spin_unlock_irqrestore(&pnd->rx_lock, flags); | ||
175 | if (skb) { | ||
176 | skb->protocol = htons(ETH_P_PHONET); | ||
177 | skb_reset_mac_header(skb); | ||
178 | __skb_pull(skb, 1); | ||
179 | skb->dev = dev; | ||
180 | dev->stats.rx_packets++; | ||
181 | dev->stats.rx_bytes += skb->len; | ||
182 | |||
183 | netif_rx(skb); | ||
184 | } | ||
185 | goto resubmit; | ||
186 | |||
187 | case -ENOENT: | ||
188 | case -ECONNRESET: | ||
189 | case -ESHUTDOWN: | ||
190 | req = NULL; | ||
191 | break; | ||
192 | |||
193 | case -EOVERFLOW: | ||
194 | dev->stats.rx_over_errors++; | ||
195 | dev_dbg(&dev->dev, "RX overflow\n"); | ||
196 | break; | ||
197 | |||
198 | case -EILSEQ: | ||
199 | dev->stats.rx_crc_errors++; | ||
200 | break; | ||
201 | } | ||
202 | |||
203 | dev->stats.rx_errors++; | ||
204 | resubmit: | ||
205 | if (page) | ||
206 | netdev_free_page(dev, page); | ||
207 | if (req) | ||
208 | rx_submit(pnd, req, GFP_ATOMIC); | ||
209 | } | ||
210 | |||
211 | static int usbpn_close(struct net_device *dev); | ||
212 | |||
213 | static int usbpn_open(struct net_device *dev) | ||
214 | { | ||
215 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
216 | int err; | ||
217 | unsigned i; | ||
218 | unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; | ||
219 | |||
220 | err = usb_set_interface(pnd->usb, num, pnd->active_setting); | ||
221 | if (err) | ||
222 | return err; | ||
223 | |||
224 | for (i = 0; i < rxq_size; i++) { | ||
225 | struct urb *req = usb_alloc_urb(0, GFP_KERNEL); | ||
226 | |||
227 | if (!req || rx_submit(pnd, req, GFP_KERNEL)) { | ||
228 | usbpn_close(dev); | ||
229 | return -ENOMEM; | ||
230 | } | ||
231 | pnd->urbs[i] = req; | ||
232 | } | ||
233 | |||
234 | netif_wake_queue(dev); | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static int usbpn_close(struct net_device *dev) | ||
239 | { | ||
240 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
241 | unsigned i; | ||
242 | unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; | ||
243 | |||
244 | netif_stop_queue(dev); | ||
245 | |||
246 | for (i = 0; i < rxq_size; i++) { | ||
247 | struct urb *req = pnd->urbs[i]; | ||
248 | |||
249 | if (!req) | ||
250 | continue; | ||
251 | usb_kill_urb(req); | ||
252 | usb_free_urb(req); | ||
253 | pnd->urbs[i] = NULL; | ||
254 | } | ||
255 | |||
256 | return usb_set_interface(pnd->usb, num, !pnd->active_setting); | ||
257 | } | ||
258 | |||
259 | static int usbpn_set_mtu(struct net_device *dev, int new_mtu) | ||
260 | { | ||
261 | if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU)) | ||
262 | return -EINVAL; | ||
263 | |||
264 | dev->mtu = new_mtu; | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static const struct net_device_ops usbpn_ops = { | ||
269 | .ndo_open = usbpn_open, | ||
270 | .ndo_stop = usbpn_close, | ||
271 | .ndo_start_xmit = usbpn_xmit, | ||
272 | .ndo_change_mtu = usbpn_set_mtu, | ||
273 | }; | ||
274 | |||
275 | static void usbpn_setup(struct net_device *dev) | ||
276 | { | ||
277 | dev->features = 0; | ||
278 | dev->netdev_ops = &usbpn_ops, | ||
279 | dev->header_ops = &phonet_header_ops; | ||
280 | dev->type = ARPHRD_PHONET; | ||
281 | dev->flags = IFF_POINTOPOINT | IFF_NOARP; | ||
282 | dev->mtu = PHONET_MAX_MTU; | ||
283 | dev->hard_header_len = 1; | ||
284 | dev->dev_addr[0] = PN_MEDIA_USB; | ||
285 | dev->addr_len = 1; | ||
286 | dev->tx_queue_len = 3; | ||
287 | |||
288 | dev->destructor = free_netdev; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * USB driver callbacks | ||
293 | */ | ||
294 | static struct usb_device_id usbpn_ids[] = { | ||
295 | { | ||
296 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | ||
297 | | USB_DEVICE_ID_MATCH_INT_CLASS | ||
298 | | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | ||
299 | .idVendor = 0x0421, /* Nokia */ | ||
300 | .bInterfaceClass = USB_CLASS_COMM, | ||
301 | .bInterfaceSubClass = 0xFE, | ||
302 | }, | ||
303 | { }, | ||
304 | }; | ||
305 | |||
306 | MODULE_DEVICE_TABLE(usb, usbpn_ids); | ||
307 | |||
308 | static struct usb_driver usbpn_driver; | ||
309 | |||
310 | int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
311 | { | ||
312 | static const char ifname[] = "usbpn%d"; | ||
313 | const struct usb_cdc_union_desc *union_header = NULL; | ||
314 | const struct usb_cdc_header_desc *phonet_header = NULL; | ||
315 | const struct usb_host_interface *data_desc; | ||
316 | struct usb_interface *data_intf; | ||
317 | struct usb_device *usbdev = interface_to_usbdev(intf); | ||
318 | struct net_device *dev; | ||
319 | struct usbpn_dev *pnd; | ||
320 | u8 *data; | ||
321 | int len, err; | ||
322 | |||
323 | data = intf->altsetting->extra; | ||
324 | len = intf->altsetting->extralen; | ||
325 | while (len >= 3) { | ||
326 | u8 dlen = data[0]; | ||
327 | if (dlen < 3) | ||
328 | return -EINVAL; | ||
329 | |||
330 | /* bDescriptorType */ | ||
331 | if (data[1] == USB_DT_CS_INTERFACE) { | ||
332 | /* bDescriptorSubType */ | ||
333 | switch (data[2]) { | ||
334 | case USB_CDC_UNION_TYPE: | ||
335 | if (union_header || dlen < 5) | ||
336 | break; | ||
337 | union_header = | ||
338 | (struct usb_cdc_union_desc *)data; | ||
339 | break; | ||
340 | case 0xAB: | ||
341 | if (phonet_header || dlen < 5) | ||
342 | break; | ||
343 | phonet_header = | ||
344 | (struct usb_cdc_header_desc *)data; | ||
345 | break; | ||
346 | } | ||
347 | } | ||
348 | data += dlen; | ||
349 | len -= dlen; | ||
350 | } | ||
351 | |||
352 | if (!union_header || !phonet_header) | ||
353 | return -EINVAL; | ||
354 | |||
355 | data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0); | ||
356 | if (data_intf == NULL) | ||
357 | return -ENODEV; | ||
358 | /* Data interface has one inactive and one active setting */ | ||
359 | if (data_intf->num_altsetting != 2) | ||
360 | return -EINVAL; | ||
361 | if (data_intf->altsetting[0].desc.bNumEndpoints == 0 | ||
362 | && data_intf->altsetting[1].desc.bNumEndpoints == 2) | ||
363 | data_desc = data_intf->altsetting + 1; | ||
364 | else | ||
365 | if (data_intf->altsetting[0].desc.bNumEndpoints == 2 | ||
366 | && data_intf->altsetting[1].desc.bNumEndpoints == 0) | ||
367 | data_desc = data_intf->altsetting; | ||
368 | else | ||
369 | return -EINVAL; | ||
370 | |||
371 | dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size, | ||
372 | ifname, usbpn_setup); | ||
373 | if (!dev) | ||
374 | return -ENOMEM; | ||
375 | |||
376 | pnd = netdev_priv(dev); | ||
377 | SET_NETDEV_DEV(dev, &intf->dev); | ||
378 | netif_stop_queue(dev); | ||
379 | |||
380 | pnd->dev = dev; | ||
381 | pnd->usb = usb_get_dev(usbdev); | ||
382 | pnd->intf = intf; | ||
383 | pnd->data_intf = data_intf; | ||
384 | spin_lock_init(&pnd->tx_lock); | ||
385 | spin_lock_init(&pnd->rx_lock); | ||
386 | /* Endpoints */ | ||
387 | if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { | ||
388 | pnd->rx_pipe = usb_rcvbulkpipe(usbdev, | ||
389 | data_desc->endpoint[0].desc.bEndpointAddress); | ||
390 | pnd->tx_pipe = usb_sndbulkpipe(usbdev, | ||
391 | data_desc->endpoint[1].desc.bEndpointAddress); | ||
392 | } else { | ||
393 | pnd->rx_pipe = usb_rcvbulkpipe(usbdev, | ||
394 | data_desc->endpoint[1].desc.bEndpointAddress); | ||
395 | pnd->tx_pipe = usb_sndbulkpipe(usbdev, | ||
396 | data_desc->endpoint[0].desc.bEndpointAddress); | ||
397 | } | ||
398 | pnd->active_setting = data_desc - data_intf->altsetting; | ||
399 | |||
400 | err = usb_driver_claim_interface(&usbpn_driver, data_intf, pnd); | ||
401 | if (err) | ||
402 | goto out; | ||
403 | |||
404 | /* Force inactive mode until the network device is brought UP */ | ||
405 | usb_set_interface(usbdev, union_header->bSlaveInterface0, | ||
406 | !pnd->active_setting); | ||
407 | usb_set_intfdata(intf, pnd); | ||
408 | |||
409 | err = register_netdev(dev); | ||
410 | if (err) { | ||
411 | usb_driver_release_interface(&usbpn_driver, data_intf); | ||
412 | goto out; | ||
413 | } | ||
414 | |||
415 | dev_dbg(&dev->dev, "USB CDC Phonet device found\n"); | ||
416 | return 0; | ||
417 | |||
418 | out: | ||
419 | usb_set_intfdata(intf, NULL); | ||
420 | free_netdev(dev); | ||
421 | return err; | ||
422 | } | ||
423 | |||
424 | static void usbpn_disconnect(struct usb_interface *intf) | ||
425 | { | ||
426 | struct usbpn_dev *pnd = usb_get_intfdata(intf); | ||
427 | struct usb_device *usb = pnd->usb; | ||
428 | |||
429 | if (pnd->disconnected) | ||
430 | return; | ||
431 | |||
432 | pnd->disconnected = 1; | ||
433 | usb_driver_release_interface(&usbpn_driver, | ||
434 | (pnd->intf == intf) ? pnd->data_intf : pnd->intf); | ||
435 | unregister_netdev(pnd->dev); | ||
436 | usb_put_dev(usb); | ||
437 | } | ||
438 | |||
439 | static struct usb_driver usbpn_driver = { | ||
440 | .name = "cdc_phonet", | ||
441 | .probe = usbpn_probe, | ||
442 | .disconnect = usbpn_disconnect, | ||
443 | .id_table = usbpn_ids, | ||
444 | }; | ||
445 | |||
446 | static int __init usbpn_init(void) | ||
447 | { | ||
448 | return usb_register(&usbpn_driver); | ||
449 | } | ||
450 | |||
451 | static void __exit usbpn_exit(void) | ||
452 | { | ||
453 | usb_deregister(&usbpn_driver); | ||
454 | } | ||
455 | |||
456 | module_init(usbpn_init); | ||
457 | module_exit(usbpn_exit); | ||
458 | |||
459 | MODULE_AUTHOR("Remi Denis-Courmont"); | ||
460 | MODULE_DESCRIPTION("USB CDC Phonet host interface"); | ||
461 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index cd35d50e46d4..45cebfb302cf 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c | |||
@@ -311,7 +311,7 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
311 | * bmCRC = 0 : CRC = 0xDEADBEEF | 311 | * bmCRC = 0 : CRC = 0xDEADBEEF |
312 | */ | 312 | */ |
313 | if (header & BIT(14)) | 313 | if (header & BIT(14)) |
314 | crc2 = ~crc32_le(~0, skb2->data, len); | 314 | crc2 = ~crc32_le(~0, skb2->data, skb2->len); |
315 | else | 315 | else |
316 | crc2 = 0xdeadbeef; | 316 | crc2 = 0xdeadbeef; |
317 | 317 | ||
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index e01314789718..1f9ec29fce50 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
@@ -999,6 +999,9 @@ static const struct net_device_ops kaweth_netdev_ops = { | |||
999 | .ndo_tx_timeout = kaweth_tx_timeout, | 999 | .ndo_tx_timeout = kaweth_tx_timeout, |
1000 | .ndo_set_multicast_list = kaweth_set_rx_mode, | 1000 | .ndo_set_multicast_list = kaweth_set_rx_mode, |
1001 | .ndo_get_stats = kaweth_netdev_stats, | 1001 | .ndo_get_stats = kaweth_netdev_stats, |
1002 | .ndo_change_mtu = eth_change_mtu, | ||
1003 | .ndo_set_mac_address = eth_mac_addr, | ||
1004 | .ndo_validate_addr = eth_validate_addr, | ||
1002 | }; | 1005 | }; |
1003 | 1006 | ||
1004 | static int kaweth_probe( | 1007 | static int kaweth_probe( |
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 73acbd244aa1..631d269ac980 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c | |||
@@ -1493,6 +1493,9 @@ static const struct net_device_ops pegasus_netdev_ops = { | |||
1493 | .ndo_set_multicast_list = pegasus_set_multicast, | 1493 | .ndo_set_multicast_list = pegasus_set_multicast, |
1494 | .ndo_get_stats = pegasus_netdev_stats, | 1494 | .ndo_get_stats = pegasus_netdev_stats, |
1495 | .ndo_tx_timeout = pegasus_tx_timeout, | 1495 | .ndo_tx_timeout = pegasus_tx_timeout, |
1496 | .ndo_change_mtu = eth_change_mtu, | ||
1497 | .ndo_set_mac_address = eth_mac_addr, | ||
1498 | .ndo_validate_addr = eth_validate_addr, | ||
1496 | }; | 1499 | }; |
1497 | 1500 | ||
1498 | static struct usb_driver pegasus_driver = { | 1501 | static struct usb_driver pegasus_driver = { |
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index d3489a3c4c03..88c30a58b4bd 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c | |||
@@ -621,6 +621,7 @@ static const struct net_device_ops rhine_netdev_ops = { | |||
621 | .ndo_start_xmit = rhine_start_tx, | 621 | .ndo_start_xmit = rhine_start_tx, |
622 | .ndo_get_stats = rhine_get_stats, | 622 | .ndo_get_stats = rhine_get_stats, |
623 | .ndo_set_multicast_list = rhine_set_rx_mode, | 623 | .ndo_set_multicast_list = rhine_set_rx_mode, |
624 | .ndo_change_mtu = eth_change_mtu, | ||
624 | .ndo_validate_addr = eth_validate_addr, | 625 | .ndo_validate_addr = eth_validate_addr, |
625 | .ndo_set_mac_address = eth_mac_addr, | 626 | .ndo_set_mac_address = eth_mac_addr, |
626 | .ndo_do_ioctl = netdev_ioctl, | 627 | .ndo_do_ioctl = netdev_ioctl, |
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index d26e7b485315..eb0337c49546 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config ATH_COMMON | 1 | config ATH_COMMON |
2 | tristate "Atheros Wireless Cards" | 2 | tristate "Atheros Wireless Cards" |
3 | depends on WLAN_80211 | ||
3 | depends on ATH5K || ATH9K || AR9170_USB | 4 | depends on ATH5K || ATH9K || AR9170_USB |
4 | 5 | ||
5 | source "drivers/net/wireless/ath/ath5k/Kconfig" | 6 | source "drivers/net/wireless/ath/ath5k/Kconfig" |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index ea045151f953..029c1bc7468f 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -2970,6 +2970,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2970 | if (modparam_nohwcrypt) | 2970 | if (modparam_nohwcrypt) |
2971 | return -EOPNOTSUPP; | 2971 | return -EOPNOTSUPP; |
2972 | 2972 | ||
2973 | if (sc->opmode == NL80211_IFTYPE_AP) | ||
2974 | return -EOPNOTSUPP; | ||
2975 | |||
2973 | switch (key->alg) { | 2976 | switch (key->alg) { |
2974 | case ALG_WEP: | 2977 | case ALG_WEP: |
2975 | case ALG_TKIP: | 2978 | case ALG_TKIP: |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 1aeafb511ddd..aad259b4c197 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -478,6 +478,18 @@ void ath9k_ani_reset(struct ath_hw *ah) | |||
478 | "Reset ANI state opmode %u\n", ah->opmode); | 478 | "Reset ANI state opmode %u\n", ah->opmode); |
479 | ah->stats.ast_ani_reset++; | 479 | ah->stats.ast_ani_reset++; |
480 | 480 | ||
481 | if (ah->opmode == NL80211_IFTYPE_AP) { | ||
482 | /* | ||
483 | * ath9k_hw_ani_control() will only process items set on | ||
484 | * ah->ani_function | ||
485 | */ | ||
486 | if (IS_CHAN_2GHZ(chan)) | ||
487 | ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | | ||
488 | ATH9K_ANI_FIRSTEP_LEVEL); | ||
489 | else | ||
490 | ah->ani_function = 0; | ||
491 | } | ||
492 | |||
481 | ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); | 493 | ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); |
482 | ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); | 494 | ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); |
483 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); | 495 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b61a071788a5..4ccf48e396df 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -355,7 +355,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
355 | } | 355 | } |
356 | 356 | ||
357 | if (bf_next == NULL) { | 357 | if (bf_next == NULL) { |
358 | INIT_LIST_HEAD(&bf_head); | 358 | /* |
359 | * Make sure the last desc is reclaimed if it | ||
360 | * not a holding desc. | ||
361 | */ | ||
362 | if (!bf_last->bf_stale) | ||
363 | list_move_tail(&bf->list, &bf_head); | ||
364 | else | ||
365 | INIT_LIST_HEAD(&bf_head); | ||
359 | } else { | 366 | } else { |
360 | ASSERT(!list_empty(bf_q)); | 367 | ASSERT(!list_empty(bf_q)); |
361 | list_move_tail(&bf->list, &bf_head); | 368 | list_move_tail(&bf->list, &bf_head); |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index eef370bd1211..bf3d25ba7be1 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -474,6 +474,21 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, | |||
474 | return 0; | 474 | return 0; |
475 | } | 475 | } |
476 | 476 | ||
477 | /* | ||
478 | * Some users have reported their EEPROM programmed with | ||
479 | * 0x8000 set, this is not a supported regulatory domain | ||
480 | * but since we have more than one user with it we need | ||
481 | * a solution for them. We default to 0x64, which is the | ||
482 | * default Atheros world regulatory domain. | ||
483 | */ | ||
484 | static void ath_regd_sanitize(struct ath_regulatory *reg) | ||
485 | { | ||
486 | if (reg->current_rd != COUNTRY_ERD_FLAG) | ||
487 | return; | ||
488 | printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n"); | ||
489 | reg->current_rd = 0x64; | ||
490 | } | ||
491 | |||
477 | int | 492 | int |
478 | ath_regd_init(struct ath_regulatory *reg, | 493 | ath_regd_init(struct ath_regulatory *reg, |
479 | struct wiphy *wiphy, | 494 | struct wiphy *wiphy, |
@@ -486,6 +501,8 @@ ath_regd_init(struct ath_regulatory *reg, | |||
486 | if (!reg) | 501 | if (!reg) |
487 | return -EINVAL; | 502 | return -EINVAL; |
488 | 503 | ||
504 | ath_regd_sanitize(reg); | ||
505 | |||
489 | printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); | 506 | printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); |
490 | 507 | ||
491 | if (!ath_regd_is_eeprom_valid(reg)) { | 508 | if (!ath_regd_is_eeprom_valid(reg)) { |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index f580c2812d91..40448067e4cc 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -648,6 +648,7 @@ struct b43_wl { | |||
648 | u8 nr_devs; | 648 | u8 nr_devs; |
649 | 649 | ||
650 | bool radiotap_enabled; | 650 | bool radiotap_enabled; |
651 | bool radio_enabled; | ||
651 | 652 | ||
652 | /* The beacon we are currently using (AP or IBSS mode). | 653 | /* The beacon we are currently using (AP or IBSS mode). |
653 | * This beacon stuff is protected by the irq_lock. */ | 654 | * This beacon stuff is protected by the irq_lock. */ |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 6456afebdba1..e71c8d9cd706 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -3497,8 +3497,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3497 | if (phy->ops->set_rx_antenna) | 3497 | if (phy->ops->set_rx_antenna) |
3498 | phy->ops->set_rx_antenna(dev, antenna); | 3498 | phy->ops->set_rx_antenna(dev, antenna); |
3499 | 3499 | ||
3500 | if (!!conf->radio_enabled != phy->radio_on) { | 3500 | if (wl->radio_enabled != phy->radio_on) { |
3501 | if (conf->radio_enabled) { | 3501 | if (wl->radio_enabled) { |
3502 | b43_software_rfkill(dev, false); | 3502 | b43_software_rfkill(dev, false); |
3503 | b43info(dev->wl, "Radio turned on by software\n"); | 3503 | b43info(dev->wl, "Radio turned on by software\n"); |
3504 | if (!dev->radio_hw_enable) { | 3504 | if (!dev->radio_hw_enable) { |
@@ -4339,6 +4339,7 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4339 | wl->beacon0_uploaded = 0; | 4339 | wl->beacon0_uploaded = 0; |
4340 | wl->beacon1_uploaded = 0; | 4340 | wl->beacon1_uploaded = 0; |
4341 | wl->beacon_templates_virgin = 1; | 4341 | wl->beacon_templates_virgin = 1; |
4342 | wl->radio_enabled = 1; | ||
4342 | 4343 | ||
4343 | mutex_lock(&wl->mutex); | 4344 | mutex_lock(&wl->mutex); |
4344 | 4345 | ||
@@ -4378,6 +4379,7 @@ static void b43_op_stop(struct ieee80211_hw *hw) | |||
4378 | if (b43_status(dev) >= B43_STAT_STARTED) | 4379 | if (b43_status(dev) >= B43_STAT_STARTED) |
4379 | b43_wireless_core_stop(dev); | 4380 | b43_wireless_core_stop(dev); |
4380 | b43_wireless_core_exit(dev); | 4381 | b43_wireless_core_exit(dev); |
4382 | wl->radio_enabled = 0; | ||
4381 | mutex_unlock(&wl->mutex); | 4383 | mutex_unlock(&wl->mutex); |
4382 | 4384 | ||
4383 | cancel_work_sync(&(wl->txpower_adjust_work)); | 4385 | cancel_work_sync(&(wl->txpower_adjust_work)); |
@@ -4560,6 +4562,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4560 | B43_WARN_ON(1); | 4562 | B43_WARN_ON(1); |
4561 | 4563 | ||
4562 | dev->phy.gmode = have_2ghz_phy; | 4564 | dev->phy.gmode = have_2ghz_phy; |
4565 | dev->phy.radio_on = 1; | ||
4563 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; | 4566 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; |
4564 | b43_wireless_core_reset(dev, tmp); | 4567 | b43_wireless_core_reset(dev, tmp); |
4565 | 4568 | ||
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 3cfc30307a27..6c3a74964ab8 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = { | 36 | static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = { |
37 | PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), | 37 | PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), |
38 | PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476), | ||
38 | PCMCIA_DEVICE_NULL, | 39 | PCMCIA_DEVICE_NULL, |
39 | }; | 40 | }; |
40 | 41 | ||
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 77fda148ac46..038baa8869e2 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -607,6 +607,7 @@ struct b43legacy_wl { | |||
607 | u8 nr_devs; | 607 | u8 nr_devs; |
608 | 608 | ||
609 | bool radiotap_enabled; | 609 | bool radiotap_enabled; |
610 | bool radio_enabled; | ||
610 | 611 | ||
611 | /* The beacon we are currently using (AP or IBSS mode). | 612 | /* The beacon we are currently using (AP or IBSS mode). |
612 | * This beacon stuff is protected by the irq_lock. */ | 613 | * This beacon stuff is protected by the irq_lock. */ |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index e5136fb65ddd..c4973c1942bf 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -2689,8 +2689,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2689 | /* Antennas for RX and management frame TX. */ | 2689 | /* Antennas for RX and management frame TX. */ |
2690 | b43legacy_mgmtframe_txantenna(dev, antenna_tx); | 2690 | b43legacy_mgmtframe_txantenna(dev, antenna_tx); |
2691 | 2691 | ||
2692 | if (!!conf->radio_enabled != phy->radio_on) { | 2692 | if (wl->radio_enabled != phy->radio_on) { |
2693 | if (conf->radio_enabled) { | 2693 | if (wl->radio_enabled) { |
2694 | b43legacy_radio_turn_on(dev); | 2694 | b43legacy_radio_turn_on(dev); |
2695 | b43legacyinfo(dev->wl, "Radio turned on by software\n"); | 2695 | b43legacyinfo(dev->wl, "Radio turned on by software\n"); |
2696 | if (!dev->radio_hw_enable) | 2696 | if (!dev->radio_hw_enable) |
@@ -3441,6 +3441,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3441 | wl->beacon0_uploaded = 0; | 3441 | wl->beacon0_uploaded = 0; |
3442 | wl->beacon1_uploaded = 0; | 3442 | wl->beacon1_uploaded = 0; |
3443 | wl->beacon_templates_virgin = 1; | 3443 | wl->beacon_templates_virgin = 1; |
3444 | wl->radio_enabled = 1; | ||
3444 | 3445 | ||
3445 | mutex_lock(&wl->mutex); | 3446 | mutex_lock(&wl->mutex); |
3446 | 3447 | ||
@@ -3479,6 +3480,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) | |||
3479 | if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) | 3480 | if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) |
3480 | b43legacy_wireless_core_stop(dev); | 3481 | b43legacy_wireless_core_stop(dev); |
3481 | b43legacy_wireless_core_exit(dev); | 3482 | b43legacy_wireless_core_exit(dev); |
3483 | wl->radio_enabled = 0; | ||
3482 | mutex_unlock(&wl->mutex); | 3484 | mutex_unlock(&wl->mutex); |
3483 | } | 3485 | } |
3484 | 3486 | ||
@@ -3620,6 +3622,7 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) | |||
3620 | have_bphy = 1; | 3622 | have_bphy = 1; |
3621 | 3623 | ||
3622 | dev->phy.gmode = (have_gphy || have_bphy); | 3624 | dev->phy.gmode = (have_gphy || have_bphy); |
3625 | dev->phy.radio_on = 1; | ||
3623 | tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0; | 3626 | tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0; |
3624 | b43legacy_wireless_core_reset(dev, tmp); | 3627 | b43legacy_wireless_core_reset(dev, tmp); |
3625 | 3628 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6d1519e1f011..355f50ea7fef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2675,12 +2675,10 @@ static ssize_t show_power_level(struct device *d, | |||
2675 | struct device_attribute *attr, char *buf) | 2675 | struct device_attribute *attr, char *buf) |
2676 | { | 2676 | { |
2677 | struct iwl_priv *priv = dev_get_drvdata(d); | 2677 | struct iwl_priv *priv = dev_get_drvdata(d); |
2678 | int mode = priv->power_data.user_power_setting; | ||
2679 | int level = priv->power_data.power_mode; | 2678 | int level = priv->power_data.power_mode; |
2680 | char *p = buf; | 2679 | char *p = buf; |
2681 | 2680 | ||
2682 | p += sprintf(p, "INDEX:%d\t", level); | 2681 | p += sprintf(p, "%d\n", level); |
2683 | p += sprintf(p, "USER:%d\n", mode); | ||
2684 | return p - buf + 1; | 2682 | return p - buf + 1; |
2685 | } | 2683 | } |
2686 | 2684 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 85ae7a62109c..9bbeec9427f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -872,7 +872,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
872 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); | 872 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); |
873 | 873 | ||
874 | /* Set up entry for this TFD in Tx byte-count array */ | 874 | /* Set up entry for this TFD in Tx byte-count array */ |
875 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, | 875 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
876 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, | ||
876 | le16_to_cpu(tx_cmd->len)); | 877 | le16_to_cpu(tx_cmd->len)); |
877 | 878 | ||
878 | pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, | 879 | pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index cb9bd4c8f25e..956798f2c80c 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -3643,12 +3643,10 @@ static ssize_t show_power_level(struct device *d, | |||
3643 | struct device_attribute *attr, char *buf) | 3643 | struct device_attribute *attr, char *buf) |
3644 | { | 3644 | { |
3645 | struct iwl_priv *priv = dev_get_drvdata(d); | 3645 | struct iwl_priv *priv = dev_get_drvdata(d); |
3646 | int mode = priv->power_data.user_power_setting; | ||
3647 | int level = priv->power_data.power_mode; | 3646 | int level = priv->power_data.power_mode; |
3648 | char *p = buf; | 3647 | char *p = buf; |
3649 | 3648 | ||
3650 | p += sprintf(p, "INDEX:%d\t", level); | 3649 | p += sprintf(p, "%d\n", level); |
3651 | p += sprintf(p, "USER:%d\n", mode); | ||
3652 | return p - buf + 1; | 3650 | return p - buf + 1; |
3653 | } | 3651 | } |
3654 | 3652 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig index 1eccb6df46dd..030401d367d3 100644 --- a/drivers/net/wireless/iwmc3200wifi/Kconfig +++ b/drivers/net/wireless/iwmc3200wifi/Kconfig | |||
@@ -4,6 +4,15 @@ config IWM | |||
4 | depends on CFG80211 | 4 | depends on CFG80211 |
5 | select WIRELESS_EXT | 5 | select WIRELESS_EXT |
6 | select FW_LOADER | 6 | select FW_LOADER |
7 | help | ||
8 | The Intel Wireless Multicomm 3200 hardware is a combo | ||
9 | card with GPS, Bluetooth, WiMax and 802.11 radios. It | ||
10 | runs over SDIO and is typically found on Moorestown | ||
11 | based platform. This driver takes care of the 802.11 | ||
12 | part, which is a fullmac one. | ||
13 | |||
14 | If you choose to build it as a module, it'll be called | ||
15 | iwmc3200wifi.ko. | ||
7 | 16 | ||
8 | config IWM_DEBUG | 17 | config IWM_DEBUG |
9 | bool "Enable full debugging output in iwmc3200wifi" | 18 | bool "Enable full debugging output in iwmc3200wifi" |
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index aaa20c6885c8..aea5ccf24ccf 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c | |||
@@ -151,8 +151,8 @@ void iwm_if_free(struct iwm_priv *iwm) | |||
151 | return; | 151 | return; |
152 | 152 | ||
153 | free_netdev(iwm_to_ndev(iwm)); | 153 | free_netdev(iwm_to_ndev(iwm)); |
154 | iwm_wdev_free(iwm); | ||
155 | iwm_priv_deinit(iwm); | 154 | iwm_priv_deinit(iwm); |
155 | iwm_wdev_free(iwm); | ||
156 | } | 156 | } |
157 | 157 | ||
158 | int iwm_if_add(struct iwm_priv *iwm) | 158 | int iwm_if_add(struct iwm_priv *iwm) |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 01db705a38ec..685098148e10 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -135,8 +135,14 @@ int lbs_update_hw_spec(struct lbs_private *priv) | |||
135 | /* Clamp region code to 8-bit since FW spec indicates that it should | 135 | /* Clamp region code to 8-bit since FW spec indicates that it should |
136 | * only ever be 8-bit, even though the field size is 16-bit. Some firmware | 136 | * only ever be 8-bit, even though the field size is 16-bit. Some firmware |
137 | * returns non-zero high 8 bits here. | 137 | * returns non-zero high 8 bits here. |
138 | * | ||
139 | * Firmware version 4.0.102 used in CF8381 has region code shifted. We | ||
140 | * need to check for this problem and handle it properly. | ||
138 | */ | 141 | */ |
139 | priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; | 142 | if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4) |
143 | priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF; | ||
144 | else | ||
145 | priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; | ||
140 | 146 | ||
141 | for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { | 147 | for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { |
142 | /* use the region code to search for the index */ | 148 | /* use the region code to search for the index */ |
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 48da157d6cda..72f3479a4d70 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h | |||
@@ -234,6 +234,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
234 | /** Mesh enable bit in FW capability */ | 234 | /** Mesh enable bit in FW capability */ |
235 | #define MESH_CAPINFO_ENABLE_MASK (1<<16) | 235 | #define MESH_CAPINFO_ENABLE_MASK (1<<16) |
236 | 236 | ||
237 | /** FW definition from Marvell v4 */ | ||
238 | #define MRVL_FW_V4 (0x04) | ||
237 | /** FW definition from Marvell v5 */ | 239 | /** FW definition from Marvell v5 */ |
238 | #define MRVL_FW_V5 (0x05) | 240 | #define MRVL_FW_V5 (0x05) |
239 | /** FW definition from Marvell v10 */ | 241 | /** FW definition from Marvell v10 */ |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index e789c6e9938c..7916ca3f84c8 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -418,6 +418,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
418 | continue; | 418 | continue; |
419 | 419 | ||
420 | if (!data2->started || !hwsim_ps_rx_ok(data2, skb) || | 420 | if (!data2->started || !hwsim_ps_rx_ok(data2, skb) || |
421 | !data->channel || !data2->channel || | ||
421 | data->channel->center_freq != data2->channel->center_freq || | 422 | data->channel->center_freq != data2->channel->center_freq || |
422 | !(data->group & data2->group)) | 423 | !(data->group & data2->group)) |
423 | continue; | 424 | continue; |
@@ -708,7 +709,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops = | |||
708 | static void mac80211_hwsim_free(void) | 709 | static void mac80211_hwsim_free(void) |
709 | { | 710 | { |
710 | struct list_head tmplist, *i, *tmp; | 711 | struct list_head tmplist, *i, *tmp; |
711 | struct mac80211_hwsim_data *data; | 712 | struct mac80211_hwsim_data *data, *tmpdata; |
712 | 713 | ||
713 | INIT_LIST_HEAD(&tmplist); | 714 | INIT_LIST_HEAD(&tmplist); |
714 | 715 | ||
@@ -717,7 +718,7 @@ static void mac80211_hwsim_free(void) | |||
717 | list_move(i, &tmplist); | 718 | list_move(i, &tmplist); |
718 | spin_unlock_bh(&hwsim_radio_lock); | 719 | spin_unlock_bh(&hwsim_radio_lock); |
719 | 720 | ||
720 | list_for_each_entry(data, &tmplist, list) { | 721 | list_for_each_entry_safe(data, tmpdata, &tmplist, list) { |
721 | debugfs_remove(data->debugfs_group); | 722 | debugfs_remove(data->debugfs_group); |
722 | debugfs_remove(data->debugfs_ps); | 723 | debugfs_remove(data->debugfs_ps); |
723 | debugfs_remove(data->debugfs); | 724 | debugfs_remove(data->debugfs); |
@@ -1166,8 +1167,8 @@ static void __exit exit_mac80211_hwsim(void) | |||
1166 | { | 1167 | { |
1167 | printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); | 1168 | printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); |
1168 | 1169 | ||
1169 | unregister_netdev(hwsim_mon); | ||
1170 | mac80211_hwsim_free(); | 1170 | mac80211_hwsim_free(); |
1171 | unregister_netdev(hwsim_mon); | ||
1171 | } | 1172 | } |
1172 | 1173 | ||
1173 | 1174 | ||
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 345593c4accb..a370e510f19f 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -2521,6 +2521,8 @@ static const struct net_device_ops orinoco_netdev_ops = { | |||
2521 | .ndo_start_xmit = orinoco_xmit, | 2521 | .ndo_start_xmit = orinoco_xmit, |
2522 | .ndo_set_multicast_list = orinoco_set_multicast_list, | 2522 | .ndo_set_multicast_list = orinoco_set_multicast_list, |
2523 | .ndo_change_mtu = orinoco_change_mtu, | 2523 | .ndo_change_mtu = orinoco_change_mtu, |
2524 | .ndo_set_mac_address = eth_mac_addr, | ||
2525 | .ndo_validate_addr = eth_validate_addr, | ||
2524 | .ndo_tx_timeout = orinoco_tx_timeout, | 2526 | .ndo_tx_timeout = orinoco_tx_timeout, |
2525 | .ndo_get_stats = orinoco_get_stats, | 2527 | .ndo_get_stats = orinoco_get_stats, |
2526 | }; | 2528 | }; |
@@ -2555,7 +2557,6 @@ struct net_device | |||
2555 | priv->wireless_data.spy_data = &priv->spy_data; | 2557 | priv->wireless_data.spy_data = &priv->spy_data; |
2556 | dev->wireless_data = &priv->wireless_data; | 2558 | dev->wireless_data = &priv->wireless_data; |
2557 | #endif | 2559 | #endif |
2558 | /* we use the default eth_mac_addr for setting the MAC addr */ | ||
2559 | 2560 | ||
2560 | /* Reserve space in skb for the SNAP header */ | 2561 | /* Reserve space in skb for the SNAP header */ |
2561 | dev->hard_header_len += ENCAPS_OVERHEAD; | 2562 | dev->hard_header_len += ENCAPS_OVERHEAD; |
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 48d81d98e12d..22ca122bd798 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -912,13 +912,14 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
912 | } | 912 | } |
913 | 913 | ||
914 | __skb_unlink(entry, &priv->tx_queue); | 914 | __skb_unlink(entry, &priv->tx_queue); |
915 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | ||
916 | 915 | ||
917 | frame_len = entry->len; | 916 | frame_len = entry->len; |
918 | entry_hdr = (struct p54_hdr *) entry->data; | 917 | entry_hdr = (struct p54_hdr *) entry->data; |
919 | entry_data = (struct p54_tx_data *) entry_hdr->data; | 918 | entry_data = (struct p54_tx_data *) entry_hdr->data; |
920 | priv->tx_stats[entry_data->hw_queue].len--; | 919 | if (priv->tx_stats[entry_data->hw_queue].len) |
920 | priv->tx_stats[entry_data->hw_queue].len--; | ||
921 | priv->stats.dot11ACKFailureCount += payload->tries - 1; | 921 | priv->stats.dot11ACKFailureCount += payload->tries - 1; |
922 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | ||
922 | 923 | ||
923 | /* | 924 | /* |
924 | * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are | 925 | * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are |
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 83116baeb110..72c7dbd39d0a 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
@@ -635,7 +635,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
635 | 635 | ||
636 | hw = p54_init_common(sizeof(*priv)); | 636 | hw = p54_init_common(sizeof(*priv)); |
637 | if (!hw) { | 637 | if (!hw) { |
638 | dev_err(&priv->spi->dev, "could not alloc ieee80211_hw"); | 638 | dev_err(&spi->dev, "could not alloc ieee80211_hw"); |
639 | return -ENOMEM; | 639 | return -ENOMEM; |
640 | } | 640 | } |
641 | 641 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 66daf68ff0ee..ce75426764a1 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1550,7 +1550,9 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1550 | rt2500usb_register_read(rt2x00dev, MAC_CSR0, ®); | 1550 | rt2500usb_register_read(rt2x00dev, MAC_CSR0, ®); |
1551 | rt2x00_set_chip(rt2x00dev, RT2570, value, reg); | 1551 | rt2x00_set_chip(rt2x00dev, RT2570, value, reg); |
1552 | 1552 | ||
1553 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0)) { | 1553 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0) || |
1554 | rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { | ||
1555 | |||
1554 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | 1556 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); |
1555 | return -ENODEV; | 1557 | return -ENODEV; |
1556 | } | 1558 | } |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c index b44253592243..cf9f899fe0e6 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c | |||
@@ -208,11 +208,12 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev) | |||
208 | { | 208 | { |
209 | struct rtl8187_priv *priv = dev->priv; | 209 | struct rtl8187_priv *priv = dev->priv; |
210 | 210 | ||
211 | rtl8187_unregister_led(&priv->led_tx); | ||
212 | /* turn the LED off before exiting */ | 211 | /* turn the LED off before exiting */ |
213 | queue_delayed_work(dev->workqueue, &priv->led_off, 0); | 212 | queue_delayed_work(dev->workqueue, &priv->led_off, 0); |
214 | cancel_delayed_work_sync(&priv->led_off); | 213 | cancel_delayed_work_sync(&priv->led_off); |
214 | cancel_delayed_work_sync(&priv->led_on); | ||
215 | rtl8187_unregister_led(&priv->led_rx); | 215 | rtl8187_unregister_led(&priv->led_rx); |
216 | rtl8187_unregister_led(&priv->led_tx); | ||
216 | } | 217 | } |
217 | #endif /* def CONFIG_RTL8187_LED */ | 218 | #endif /* def CONFIG_RTL8187_LED */ |
218 | 219 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 14a19baff214..0e6e44689cc6 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -38,7 +38,6 @@ static struct usb_device_id usb_ids[] = { | |||
38 | /* ZD1211 */ | 38 | /* ZD1211 */ |
39 | { USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 }, | 39 | { USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 }, |
40 | { USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 }, | 40 | { USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 }, |
41 | { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 }, | ||
42 | { USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 }, | 41 | { USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 }, |
43 | { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, | 42 | { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, |
44 | { USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 }, | 43 | { USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 }, |
@@ -61,6 +60,7 @@ static struct usb_device_id usb_ids[] = { | |||
61 | { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, | 60 | { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, |
62 | { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, | 61 | { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, |
63 | /* ZD1211B */ | 62 | /* ZD1211B */ |
63 | { USB_DEVICE(0x054c, 0x0257), .driver_info = DEVICE_ZD1211B }, | ||
64 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, | 64 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, |
65 | { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B }, | 65 | { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B }, |
66 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, | 66 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, |
@@ -87,6 +87,7 @@ static struct usb_device_id usb_ids[] = { | |||
87 | { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, | 87 | { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, |
88 | { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, | 88 | { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, |
89 | { USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B }, | 89 | { USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B }, |
90 | { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B }, | ||
90 | /* "Driverless" devices that need ejecting */ | 91 | /* "Driverless" devices that need ejecting */ |
91 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, | 92 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, |
92 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, | 93 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, |
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index aee967d7f760..bacaa536fd51 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -9,6 +9,10 @@ | |||
9 | * out of the OpenFirmware device tree and using it to populate an mii_bus. | 9 | * out of the OpenFirmware device tree and using it to populate an mii_bus. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/netdevice.h> | ||
15 | #include <linux/err.h> | ||
12 | #include <linux/phy.h> | 16 | #include <linux/phy.h> |
13 | #include <linux/of.h> | 17 | #include <linux/of.h> |
14 | #include <linux/of_mdio.h> | 18 | #include <linux/of_mdio.h> |
@@ -137,3 +141,41 @@ struct phy_device *of_phy_connect(struct net_device *dev, | |||
137 | return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy; | 141 | return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy; |
138 | } | 142 | } |
139 | EXPORT_SYMBOL(of_phy_connect); | 143 | EXPORT_SYMBOL(of_phy_connect); |
144 | |||
145 | /** | ||
146 | * of_phy_connect_fixed_link - Parse fixed-link property and return a dummy phy | ||
147 | * @dev: pointer to net_device claiming the phy | ||
148 | * @hndlr: Link state callback for the network device | ||
149 | * @iface: PHY data interface type | ||
150 | * | ||
151 | * This function is a temporary stop-gap and will be removed soon. It is | ||
152 | * only to support the fs_enet, ucc_geth and gianfar Ethernet drivers. Do | ||
153 | * not call this function from new drivers. | ||
154 | */ | ||
155 | struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, | ||
156 | void (*hndlr)(struct net_device *), | ||
157 | phy_interface_t iface) | ||
158 | { | ||
159 | struct device_node *net_np; | ||
160 | char bus_id[MII_BUS_ID_SIZE + 3]; | ||
161 | struct phy_device *phy; | ||
162 | const u32 *phy_id; | ||
163 | int sz; | ||
164 | |||
165 | if (!dev->dev.parent) | ||
166 | return NULL; | ||
167 | |||
168 | net_np = dev_archdata_get_node(&dev->dev.parent->archdata); | ||
169 | if (!net_np) | ||
170 | return NULL; | ||
171 | |||
172 | phy_id = of_get_property(net_np, "fixed-link", &sz); | ||
173 | if (!phy_id || sz < sizeof(*phy_id)) | ||
174 | return NULL; | ||
175 | |||
176 | sprintf(bus_id, PHY_ID_FMT, "0", phy_id[0]); | ||
177 | |||
178 | phy = phy_connect(dev, bus_id, hndlr, 0, iface); | ||
179 | return IS_ERR(phy) ? NULL : phy; | ||
180 | } | ||
181 | EXPORT_SYMBOL(of_phy_connect_fixed_link); | ||
diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c index e1f6ce03705e..3c2270a8300c 100644 --- a/drivers/oprofile/oprofile_stats.c +++ b/drivers/oprofile/oprofile_stats.c | |||
@@ -33,6 +33,7 @@ void oprofile_reset_stats(void) | |||
33 | atomic_set(&oprofile_stats.sample_lost_no_mm, 0); | 33 | atomic_set(&oprofile_stats.sample_lost_no_mm, 0); |
34 | atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); | 34 | atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); |
35 | atomic_set(&oprofile_stats.event_lost_overflow, 0); | 35 | atomic_set(&oprofile_stats.event_lost_overflow, 0); |
36 | atomic_set(&oprofile_stats.bt_lost_no_mapping, 0); | ||
36 | } | 37 | } |
37 | 38 | ||
38 | 39 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index a5b9f6ae507b..d703e73fffa7 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/pci_hotplug.h> | 32 | #include <linux/pci_hotplug.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
37 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
38 | #include <linux/kthread.h> | 37 | #include <linux/kthread.h> |
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 2fa47af992a8..0ff689afa757 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
39 | #include <linux/pci_hotplug.h> | 38 | #include <linux/pci_hotplug.h> |
40 | #include <linux/kthread.h> | 39 | #include <linux/kthread.h> |
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 8450f4a6568a..e6089bdb6e5b 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/pci_hotplug.h> | 35 | #include <linux/pci_hotplug.h> |
36 | #include <linux/smp_lock.h> | ||
36 | #include <linux/debugfs.h> | 37 | #include <linux/debugfs.h> |
37 | #include "cpqphp.h" | 38 | #include "cpqphp.h" |
38 | 39 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index ff4034502d24..8aab8edf123e 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
35 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
36 | #include "../pci.h" | 35 | #include "../pci.h" |
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index ec22284eed30..e1c1ec540893 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/pci.h> | 11 | #include <linux/pci.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/syscalls.h> | 12 | #include <linux/syscalls.h> |
14 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
15 | #include "pci.h" | 14 | #include "pci.h" |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index be2fd6f91639..fb45f5ee8df1 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -973,7 +973,7 @@ static int acer_rfkill_set(void *data, bool blocked) | |||
973 | { | 973 | { |
974 | acpi_status status; | 974 | acpi_status status; |
975 | u32 cap = (unsigned long)data; | 975 | u32 cap = (unsigned long)data; |
976 | status = set_u32(!!blocked, cap); | 976 | status = set_u32(!blocked, cap); |
977 | if (ACPI_FAILURE(status)) | 977 | if (ACPI_FAILURE(status)) |
978 | return -ENODEV; | 978 | return -ENODEV; |
979 | return 0; | 979 | return 0; |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 4ac2311c00af..ca508564a181 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -171,7 +171,7 @@ static int hp_wmi_tablet_state(void) | |||
171 | static int hp_wmi_set_block(void *data, bool blocked) | 171 | static int hp_wmi_set_block(void *data, bool blocked) |
172 | { | 172 | { |
173 | unsigned long b = (unsigned long) data; | 173 | unsigned long b = (unsigned long) data; |
174 | int query = BIT(b + 8) | ((!!blocked) << b); | 174 | int query = BIT(b + 8) | ((!blocked) << b); |
175 | 175 | ||
176 | return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query); | 176 | return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query); |
177 | } | 177 | } |
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index 8bde92126d34..b787335a8419 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c | |||
@@ -33,14 +33,14 @@ static enum power_supply_property *prop; | |||
33 | 33 | ||
34 | static unsigned long wm97xx_read_bat(struct power_supply *bat_ps) | 34 | static unsigned long wm97xx_read_bat(struct power_supply *bat_ps) |
35 | { | 35 | { |
36 | return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data, | 36 | return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev->parent), |
37 | pdata->batt_aux) * pdata->batt_mult / | 37 | pdata->batt_aux) * pdata->batt_mult / |
38 | pdata->batt_div; | 38 | pdata->batt_div; |
39 | } | 39 | } |
40 | 40 | ||
41 | static unsigned long wm97xx_read_temp(struct power_supply *bat_ps) | 41 | static unsigned long wm97xx_read_temp(struct power_supply *bat_ps) |
42 | { | 42 | { |
43 | return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data, | 43 | return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev->parent), |
44 | pdata->temp_aux) * pdata->temp_mult / | 44 | pdata->temp_aux) * pdata->temp_mult / |
45 | pdata->temp_div; | 45 | pdata->temp_div; |
46 | } | 46 | } |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index f8b1f04f26b8..c11770f5b368 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1696,8 +1696,7 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device, | |||
1696 | DBF_DEV_EVENT(DBF_ERR, device, "%s", | 1696 | DBF_DEV_EVENT(DBF_ERR, device, "%s", |
1697 | "unsolicited interrupt received " | 1697 | "unsolicited interrupt received " |
1698 | "(sense available)"); | 1698 | "(sense available)"); |
1699 | device->discipline->dump_sense_dbf(device, NULL, irb, | 1699 | device->discipline->dump_sense_dbf(device, irb, "unsolicited"); |
1700 | "unsolicited"); | ||
1701 | } | 1700 | } |
1702 | 1701 | ||
1703 | dasd_schedule_device_bh(device); | 1702 | dasd_schedule_device_bh(device); |
@@ -2941,42 +2940,20 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page) | |||
2941 | } | 2940 | } |
2942 | 2941 | ||
2943 | static void | 2942 | static void |
2944 | dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req, | 2943 | dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct irb *irb, |
2945 | struct irb *irb, char *reason) | 2944 | char *reason) |
2946 | { | 2945 | { |
2947 | u64 *sense; | 2946 | u64 *sense; |
2948 | int sl; | ||
2949 | struct tsb *tsb; | ||
2950 | 2947 | ||
2951 | sense = NULL; | 2948 | sense = (u64 *) dasd_get_sense(irb); |
2952 | tsb = NULL; | ||
2953 | if (req && scsw_is_tm(&req->irb.scsw)) { | ||
2954 | if (irb->scsw.tm.tcw) | ||
2955 | tsb = tcw_get_tsb( | ||
2956 | (struct tcw *)(unsigned long)irb->scsw.tm.tcw); | ||
2957 | if (tsb && (irb->scsw.tm.fcxs == 0x01)) { | ||
2958 | switch (tsb->flags & 0x07) { | ||
2959 | case 1: /* tsa_iostat */ | ||
2960 | sense = (u64 *)tsb->tsa.iostat.sense; | ||
2961 | break; | ||
2962 | case 2: /* ts_ddpc */ | ||
2963 | sense = (u64 *)tsb->tsa.ddpc.sense; | ||
2964 | break; | ||
2965 | case 3: /* tsa_intrg */ | ||
2966 | break; | ||
2967 | } | ||
2968 | } | ||
2969 | } else { | ||
2970 | if (irb->esw.esw0.erw.cons) | ||
2971 | sense = (u64 *)irb->ecw; | ||
2972 | } | ||
2973 | if (sense) { | 2949 | if (sense) { |
2974 | for (sl = 0; sl < 4; sl++) { | 2950 | DBF_DEV_EVENT(DBF_EMERG, device, |
2975 | DBF_DEV_EVENT(DBF_EMERG, device, | 2951 | "%s: %s %02x%02x%02x %016llx %016llx %016llx " |
2976 | "%s: %016llx %016llx %016llx %016llx", | 2952 | "%016llx", reason, |
2977 | reason, sense[0], sense[1], sense[2], | 2953 | scsw_is_tm(&irb->scsw) ? "t" : "c", |
2978 | sense[3]); | 2954 | scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw), |
2979 | } | 2955 | scsw_dstat(&irb->scsw), sense[0], sense[1], |
2956 | sense[2], sense[3]); | ||
2980 | } else { | 2957 | } else { |
2981 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", | 2958 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", |
2982 | "SORRY - NO VALID SENSE AVAILABLE\n"); | 2959 | "SORRY - NO VALID SENSE AVAILABLE\n"); |
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index d970ce2814be..cb8f9cef7429 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c | |||
@@ -172,7 +172,7 @@ dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb) | |||
172 | device = cqr->startdev; | 172 | device = cqr->startdev; |
173 | /* dump sense data to s390 debugfeature*/ | 173 | /* dump sense data to s390 debugfeature*/ |
174 | if (device->discipline && device->discipline->dump_sense_dbf) | 174 | if (device->discipline && device->discipline->dump_sense_dbf) |
175 | device->discipline->dump_sense_dbf(device, cqr, irb, "log"); | 175 | device->discipline->dump_sense_dbf(device, irb, "log"); |
176 | } | 176 | } |
177 | EXPORT_SYMBOL(dasd_log_sense_dbf); | 177 | EXPORT_SYMBOL(dasd_log_sense_dbf); |
178 | 178 | ||
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index e21ee735f926..31849ad5e59f 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -241,7 +241,7 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device, | |||
241 | /* check for unsolicited interrupts */ | 241 | /* check for unsolicited interrupts */ |
242 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | 242 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", |
243 | "unsolicited interrupt received"); | 243 | "unsolicited interrupt received"); |
244 | device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited"); | 244 | device->discipline->dump_sense_dbf(device, irb, "unsolicited"); |
245 | dasd_schedule_device_bh(device); | 245 | dasd_schedule_device_bh(device); |
246 | return; | 246 | return; |
247 | }; | 247 | }; |
@@ -444,17 +444,20 @@ dasd_fba_fill_info(struct dasd_device * device, | |||
444 | } | 444 | } |
445 | 445 | ||
446 | static void | 446 | static void |
447 | dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req, | 447 | dasd_fba_dump_sense_dbf(struct dasd_device *device, struct irb *irb, |
448 | struct irb *irb, char *reason) | 448 | char *reason) |
449 | { | 449 | { |
450 | int sl; | 450 | u64 *sense; |
451 | if (irb->esw.esw0.erw.cons) { | 451 | |
452 | for (sl = 0; sl < 4; sl++) { | 452 | sense = (u64 *) dasd_get_sense(irb); |
453 | DBF_DEV_EVENT(DBF_EMERG, device, | 453 | if (sense) { |
454 | "%s: %08x %08x %08x %08x", | 454 | DBF_DEV_EVENT(DBF_EMERG, device, |
455 | reason, irb->ecw[8 * 0], irb->ecw[8 * 1], | 455 | "%s: %s %02x%02x%02x %016llx %016llx %016llx " |
456 | irb->ecw[8 * 2], irb->ecw[8 * 3]); | 456 | "%016llx", reason, |
457 | } | 457 | scsw_is_tm(&irb->scsw) ? "t" : "c", |
458 | scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw), | ||
459 | scsw_dstat(&irb->scsw), sense[0], sense[1], | ||
460 | sense[2], sense[3]); | ||
458 | } else { | 461 | } else { |
459 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", | 462 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", |
460 | "SORRY - NO VALID SENSE AVAILABLE\n"); | 463 | "SORRY - NO VALID SENSE AVAILABLE\n"); |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index fd63b2f2bda9..b699ca356ac5 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -284,8 +284,7 @@ struct dasd_discipline { | |||
284 | dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *); | 284 | dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *); |
285 | void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, | 285 | void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, |
286 | struct irb *); | 286 | struct irb *); |
287 | void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *, | 287 | void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *); |
288 | struct irb *, char *); | ||
289 | 288 | ||
290 | void (*handle_unsolicited_interrupt) (struct dasd_device *, | 289 | void (*handle_unsolicited_interrupt) (struct dasd_device *, |
291 | struct irb *); | 290 | struct irb *); |
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 4ce3f72ee1c1..df918ef27965 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/major.h> | 16 | #include <linux/major.h> |
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/blkpg.h> | 18 | #include <linux/blkpg.h> |
19 | #include <linux/smp_lock.h> | ||
19 | 20 | ||
20 | #include <asm/ccwdev.h> | 21 | #include <asm/ccwdev.h> |
21 | #include <asm/cmb.h> | 22 | #include <asm/cmb.h> |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 016f9e9d2591..d34617682a62 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -964,7 +964,8 @@ static int dcssblk_freeze(struct device *dev) | |||
964 | break; | 964 | break; |
965 | } | 965 | } |
966 | if (rc) | 966 | if (rc) |
967 | pr_err("Suspend failed because device %s is writeable.\n", | 967 | pr_err("Suspending the system failed because DCSS device %s " |
968 | "is writable\n", | ||
968 | dev_info->segment_name); | 969 | dev_info->segment_name); |
969 | return rc; | 970 | return rc; |
970 | } | 971 | } |
@@ -987,8 +988,8 @@ static int dcssblk_restore(struct device *dev) | |||
987 | goto out_panic; | 988 | goto out_panic; |
988 | } | 989 | } |
989 | if (start != entry->start || end != entry->end) { | 990 | if (start != entry->start || end != entry->end) { |
990 | pr_err("Mismatch of start / end address after " | 991 | pr_err("The address range of DCSS %s changed " |
991 | "resuming device %s\n", | 992 | "while the system was suspended\n", |
992 | entry->segment_name); | 993 | entry->segment_name); |
993 | goto out_panic; | 994 | goto out_panic; |
994 | } | 995 | } |
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 2e9e1ecd6d82..db442cd6621e 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c | |||
@@ -443,7 +443,7 @@ fail: | |||
443 | */ | 443 | */ |
444 | static void xpram_resume_error(const char *message) | 444 | static void xpram_resume_error(const char *message) |
445 | { | 445 | { |
446 | pr_err("Resume error: %s\n", message); | 446 | pr_err("Resuming the system failed: %s\n", message); |
447 | panic("xpram resume error\n"); | 447 | panic("xpram resume error\n"); |
448 | } | 448 | } |
449 | 449 | ||
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 7892550d7932..3234e90bd7f9 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c | |||
@@ -320,7 +320,7 @@ static int mon_open(struct inode *inode, struct file *filp) | |||
320 | goto out_path; | 320 | goto out_path; |
321 | } | 321 | } |
322 | filp->private_data = monpriv; | 322 | filp->private_data = monpriv; |
323 | dev_set_drvdata(&monreader_device, monpriv); | 323 | dev_set_drvdata(monreader_device, monpriv); |
324 | unlock_kernel(); | 324 | unlock_kernel(); |
325 | return nonseekable_open(inode, filp); | 325 | return nonseekable_open(inode, filp); |
326 | 326 | ||
@@ -463,7 +463,7 @@ static struct miscdevice mon_dev = { | |||
463 | *****************************************************************************/ | 463 | *****************************************************************************/ |
464 | static int monreader_freeze(struct device *dev) | 464 | static int monreader_freeze(struct device *dev) |
465 | { | 465 | { |
466 | struct mon_private *monpriv = dev_get_drvdata(&dev); | 466 | struct mon_private *monpriv = dev_get_drvdata(dev); |
467 | int rc; | 467 | int rc; |
468 | 468 | ||
469 | if (!monpriv) | 469 | if (!monpriv) |
diff --git a/drivers/s390/char/sclp_rw.h b/drivers/s390/char/sclp_rw.h index 85f491ea929c..7a7bfc947d97 100644 --- a/drivers/s390/char/sclp_rw.h +++ b/drivers/s390/char/sclp_rw.h | |||
@@ -92,5 +92,10 @@ void sclp_set_columns(struct sclp_buffer *, unsigned short); | |||
92 | void sclp_set_htab(struct sclp_buffer *, unsigned short); | 92 | void sclp_set_htab(struct sclp_buffer *, unsigned short); |
93 | int sclp_chars_in_buffer(struct sclp_buffer *); | 93 | int sclp_chars_in_buffer(struct sclp_buffer *); |
94 | 94 | ||
95 | #ifdef CONFIG_SCLP_CONSOLE | ||
95 | void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event); | 96 | void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event); |
97 | #else | ||
98 | static inline void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event) { } | ||
99 | #endif | ||
100 | |||
96 | #endif /* __SCLP_RW_H__ */ | 101 | #endif /* __SCLP_RW_H__ */ |
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index cb7854c10c04..f2bc287b69e4 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c | |||
@@ -250,14 +250,14 @@ static int vmwdt_resume(void) | |||
250 | static int vmwdt_suspend(void) | 250 | static int vmwdt_suspend(void) |
251 | { | 251 | { |
252 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { | 252 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { |
253 | pr_err("The watchdog is in use. " | 253 | pr_err("The system cannot be suspended while the watchdog" |
254 | "This prevents hibernation or suspend.\n"); | 254 | " is in use\n"); |
255 | return NOTIFY_BAD; | 255 | return NOTIFY_BAD; |
256 | } | 256 | } |
257 | if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) { | 257 | if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) { |
258 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); | 258 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); |
259 | pr_err("The watchdog is running. " | 259 | pr_err("The system cannot be suspended while the watchdog" |
260 | "This prevents hibernation or suspend.\n"); | 260 | " is running\n"); |
261 | return NOTIFY_BAD; | 261 | return NOTIFY_BAD; |
262 | } | 262 | } |
263 | return NOTIFY_DONE; | 263 | return NOTIFY_DONE; |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 727a809636d8..ed3dcdea7fe1 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -1145,12 +1145,17 @@ ap_config_timeout(unsigned long ptr) | |||
1145 | */ | 1145 | */ |
1146 | static inline void ap_schedule_poll_timer(void) | 1146 | static inline void ap_schedule_poll_timer(void) |
1147 | { | 1147 | { |
1148 | ktime_t hr_time; | ||
1148 | if (ap_using_interrupts() || ap_suspend_flag) | 1149 | if (ap_using_interrupts() || ap_suspend_flag) |
1149 | return; | 1150 | return; |
1150 | if (hrtimer_is_queued(&ap_poll_timer)) | 1151 | if (hrtimer_is_queued(&ap_poll_timer)) |
1151 | return; | 1152 | return; |
1152 | hrtimer_start(&ap_poll_timer, ktime_set(0, poll_timeout), | 1153 | if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) { |
1153 | HRTIMER_MODE_ABS); | 1154 | hr_time = ktime_set(0, poll_timeout); |
1155 | hrtimer_forward_now(&ap_poll_timer, hr_time); | ||
1156 | hrtimer_restart(&ap_poll_timer); | ||
1157 | } | ||
1158 | return; | ||
1154 | } | 1159 | } |
1155 | 1160 | ||
1156 | /** | 1161 | /** |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 650bcef08f2a..cd78c501803a 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/moduleparam.h> | 10 | #include <linux/moduleparam.h> |
11 | #include <linux/vmalloc.h> | 11 | #include <linux/vmalloc.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/list.h> | 12 | #include <linux/list.h> |
14 | 13 | ||
15 | #include <scsi/scsi_tcq.h> | 14 | #include <scsi/scsi_tcq.h> |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 4d6f2fe1cfe9..9230402c45af 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1656,6 +1656,10 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd) | |||
1656 | md->nr_entries = req_schp->k_use_sg; | 1656 | md->nr_entries = req_schp->k_use_sg; |
1657 | md->offset = 0; | 1657 | md->offset = 0; |
1658 | md->null_mapped = hp->dxferp ? 0 : 1; | 1658 | md->null_mapped = hp->dxferp ? 0 : 1; |
1659 | if (dxfer_dir == SG_DXFER_TO_FROM_DEV) | ||
1660 | md->from_user = 1; | ||
1661 | else | ||
1662 | md->from_user = 0; | ||
1659 | } | 1663 | } |
1660 | 1664 | ||
1661 | if (iov_count) { | 1665 | if (iov_count) { |
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index 34b4ae0fe760..c108b1a0ce98 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c | |||
@@ -236,7 +236,6 @@ static int sport_startup(struct uart_port *port) | |||
236 | int retval; | 236 | int retval; |
237 | 237 | ||
238 | pr_debug("%s enter\n", __func__); | 238 | pr_debug("%s enter\n", __func__); |
239 | memset(buffer, 20, '\0'); | ||
240 | snprintf(buffer, 20, "%s rx", up->name); | 239 | snprintf(buffer, 20, "%s rx", up->name); |
241 | retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 240 | retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up); |
242 | if (retval) { | 241 | if (retval) { |
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c index 698048f64f5e..f7c24baa1416 100644 --- a/drivers/serial/msm_serial.c +++ b/drivers/serial/msm_serial.c | |||
@@ -730,7 +730,6 @@ static int __devexit msm_serial_remove(struct platform_device *pdev) | |||
730 | } | 730 | } |
731 | 731 | ||
732 | static struct platform_driver msm_platform_driver = { | 732 | static struct platform_driver msm_platform_driver = { |
733 | .probe = msm_serial_probe, | ||
734 | .remove = msm_serial_remove, | 733 | .remove = msm_serial_remove, |
735 | .driver = { | 734 | .driver = { |
736 | .name = "msm_serial", | 735 | .name = "msm_serial", |
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index 131030f693c7..100e7a5c5ea1 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c | |||
@@ -678,7 +678,8 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, | |||
678 | sprom->board_rev = tuple.TupleData[1]; | 678 | sprom->board_rev = tuple.TupleData[1]; |
679 | break; | 679 | break; |
680 | case SSB_PCMCIA_CIS_PA: | 680 | case SSB_PCMCIA_CIS_PA: |
681 | GOTO_ERROR_ON(tuple.TupleDataLen != 9, | 681 | GOTO_ERROR_ON((tuple.TupleDataLen != 9) && |
682 | (tuple.TupleDataLen != 10), | ||
682 | "pa tpl size"); | 683 | "pa tpl size"); |
683 | sprom->pa0b0 = tuple.TupleData[1] | | 684 | sprom->pa0b0 = tuple.TupleData[1] | |
684 | ((u16)tuple.TupleData[2] << 8); | 685 | ((u16)tuple.TupleData[2] << 8); |
@@ -718,7 +719,8 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, | |||
718 | sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1]; | 719 | sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1]; |
719 | break; | 720 | break; |
720 | case SSB_PCMCIA_CIS_BFLAGS: | 721 | case SSB_PCMCIA_CIS_BFLAGS: |
721 | GOTO_ERROR_ON(tuple.TupleDataLen != 3, | 722 | GOTO_ERROR_ON((tuple.TupleDataLen != 3) && |
723 | (tuple.TupleDataLen != 5), | ||
722 | "bfl tpl size"); | 724 | "bfl tpl size"); |
723 | sprom->boardflags_lo = tuple.TupleData[1] | | 725 | sprom->boardflags_lo = tuple.TupleData[1] | |
724 | ((u16)tuple.TupleData[2] << 8); | 726 | ((u16)tuple.TupleData[2] << 8); |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 348bf61a8fec..975ecddbce30 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -103,8 +103,6 @@ source "drivers/staging/pohmelfs/Kconfig" | |||
103 | 103 | ||
104 | source "drivers/staging/stlc45xx/Kconfig" | 104 | source "drivers/staging/stlc45xx/Kconfig" |
105 | 105 | ||
106 | source "drivers/staging/uc2322/Kconfig" | ||
107 | |||
108 | source "drivers/staging/b3dfg/Kconfig" | 106 | source "drivers/staging/b3dfg/Kconfig" |
109 | 107 | ||
110 | source "drivers/staging/phison/Kconfig" | 108 | source "drivers/staging/phison/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 8d61d7b4debf..2241ae1b21ee 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -34,7 +34,6 @@ obj-$(CONFIG_ANDROID) += android/ | |||
34 | obj-$(CONFIG_DST) += dst/ | 34 | obj-$(CONFIG_DST) += dst/ |
35 | obj-$(CONFIG_POHMELFS) += pohmelfs/ | 35 | obj-$(CONFIG_POHMELFS) += pohmelfs/ |
36 | obj-$(CONFIG_STLC45XX) += stlc45xx/ | 36 | obj-$(CONFIG_STLC45XX) += stlc45xx/ |
37 | obj-$(CONFIG_USB_SERIAL_ATEN2011) += uc2322/ | ||
38 | obj-$(CONFIG_B3DFG) += b3dfg/ | 37 | obj-$(CONFIG_B3DFG) += b3dfg/ |
39 | obj-$(CONFIG_IDE_PHISON) += phison/ | 38 | obj-$(CONFIG_IDE_PHISON) += phison/ |
40 | obj-$(CONFIG_PLAN9AUTH) += p9auth/ | 39 | obj-$(CONFIG_PLAN9AUTH) += p9auth/ |
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index fe72240f5a9e..f934393f3959 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c | |||
@@ -96,19 +96,21 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) | |||
96 | 96 | ||
97 | read_lock(&tasklist_lock); | 97 | read_lock(&tasklist_lock); |
98 | for_each_process(p) { | 98 | for_each_process(p) { |
99 | struct mm_struct *mm; | ||
99 | int oom_adj; | 100 | int oom_adj; |
100 | 101 | ||
101 | task_lock(p); | 102 | task_lock(p); |
102 | if (!p->mm) { | 103 | mm = p->mm; |
104 | if (!mm) { | ||
103 | task_unlock(p); | 105 | task_unlock(p); |
104 | continue; | 106 | continue; |
105 | } | 107 | } |
106 | oom_adj = p->oomkilladj; | 108 | oom_adj = mm->oom_adj; |
107 | if (oom_adj < min_adj) { | 109 | if (oom_adj < min_adj) { |
108 | task_unlock(p); | 110 | task_unlock(p); |
109 | continue; | 111 | continue; |
110 | } | 112 | } |
111 | tasksize = get_mm_rss(p->mm); | 113 | tasksize = get_mm_rss(mm); |
112 | task_unlock(p); | 114 | task_unlock(p); |
113 | if (tasksize <= 0) | 115 | if (tasksize <= 0) |
114 | continue; | 116 | continue; |
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index baf83c6a9412..e3c3adc282e2 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c | |||
@@ -45,6 +45,8 @@ Devices: [JR3] PCI force sensor board (jr3_pci) | |||
45 | #include <linux/delay.h> | 45 | #include <linux/delay.h> |
46 | #include <linux/ctype.h> | 46 | #include <linux/ctype.h> |
47 | #include <linux/firmware.h> | 47 | #include <linux/firmware.h> |
48 | #include <linux/jiffies.h> | ||
49 | #include <linux/timer.h> | ||
48 | #include "comedi_pci.h" | 50 | #include "comedi_pci.h" |
49 | #include "jr3_pci.h" | 51 | #include "jr3_pci.h" |
50 | 52 | ||
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 92121cf8c45c..5d9bab352c1d 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c | |||
@@ -111,9 +111,13 @@ static const struct s626_board s626_boards[] = { | |||
111 | #define PCI_VENDOR_ID_S626 0x1131 | 111 | #define PCI_VENDOR_ID_S626 0x1131 |
112 | #define PCI_DEVICE_ID_S626 0x7146 | 112 | #define PCI_DEVICE_ID_S626 0x7146 |
113 | 113 | ||
114 | /* | ||
115 | * For devices with vendor:device id == 0x1131:0x7146 you must specify | ||
116 | * also subvendor:subdevice ids, because otherwise it will conflict with | ||
117 | * Philips SAA7146 media/dvb based cards. | ||
118 | */ | ||
114 | static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { | 119 | static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { |
115 | {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 120 | {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, 0x6000, 0x0272, 0, 0, 0}, |
116 | 0}, | ||
117 | {0} | 121 | {0} |
118 | }; | 122 | }; |
119 | 123 | ||
@@ -499,25 +503,26 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
499 | resource_size_t resourceStart; | 503 | resource_size_t resourceStart; |
500 | dma_addr_t appdma; | 504 | dma_addr_t appdma; |
501 | struct comedi_subdevice *s; | 505 | struct comedi_subdevice *s; |
502 | struct pci_dev *pdev; | 506 | const struct pci_device_id *ids; |
507 | struct pci_dev *pdev = NULL; | ||
503 | 508 | ||
504 | if (alloc_private(dev, sizeof(struct s626_private)) < 0) | 509 | if (alloc_private(dev, sizeof(struct s626_private)) < 0) |
505 | return -ENOMEM; | 510 | return -ENOMEM; |
506 | 511 | ||
507 | for (pdev = pci_get_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, | 512 | for (i = 0; i < (ARRAY_SIZE(s626_pci_table) - 1) && !pdev; i++) { |
508 | NULL); pdev != NULL; | 513 | ids = &s626_pci_table[i]; |
509 | pdev = pci_get_device(PCI_VENDOR_ID_S626, | 514 | do { |
510 | PCI_DEVICE_ID_S626, pdev)) { | 515 | pdev = pci_get_subsys(ids->vendor, ids->device, ids->subvendor, |
511 | if (it->options[0] || it->options[1]) { | 516 | ids->subdevice, pdev); |
512 | if (pdev->bus->number == it->options[0] && | 517 | |
513 | PCI_SLOT(pdev->devfn) == it->options[1]) { | 518 | if ((it->options[0] || it->options[1]) && pdev) { |
514 | /* matches requested bus/slot */ | 519 | /* matches requested bus/slot */ |
520 | if (pdev->bus->number == it->options[0] && | ||
521 | PCI_SLOT(pdev->devfn) == it->options[1]) | ||
522 | break; | ||
523 | } else | ||
515 | break; | 524 | break; |
516 | } | 525 | } while (1); |
517 | } else { | ||
518 | /* no bus/slot specified */ | ||
519 | break; | ||
520 | } | ||
521 | } | 526 | } |
522 | devpriv->pdev = pdev; | 527 | devpriv->pdev = pdev; |
523 | 528 | ||
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c index a5e4acab089e..bb22347af60e 100644 --- a/drivers/staging/go7007/s2250-loader.c +++ b/drivers/staging/go7007/s2250-loader.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/smp_lock.h> | ||
20 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
21 | #include <dvb-usb.h> | 22 | #include <dvb-usb.h> |
22 | 23 | ||
diff --git a/drivers/staging/meilhaus/TODO b/drivers/staging/meilhaus/TODO index 6ec25203089c..d6ce39823de6 100644 --- a/drivers/staging/meilhaus/TODO +++ b/drivers/staging/meilhaus/TODO | |||
@@ -7,4 +7,4 @@ TODO: | |||
7 | - possible comedi merge | 7 | - possible comedi merge |
8 | 8 | ||
9 | Please send cleanup patches to Greg Kroah-Hartman <greg@kroah.com> | 9 | Please send cleanup patches to Greg Kroah-Hartman <greg@kroah.com> |
10 | and CC: David Kiliani <mail@davidkiliani.de> | 10 | and CC: David Kiliani <mail@davidkiliani.de> and Meilhaus Support <support@meilhaus.de> |
diff --git a/drivers/staging/rspiusb/rspiusb.c b/drivers/staging/rspiusb/rspiusb.c index 1cdfe69585ea..2f8155c1968b 100644 --- a/drivers/staging/rspiusb/rspiusb.c +++ b/drivers/staging/rspiusb/rspiusb.c | |||
@@ -444,8 +444,7 @@ static void piusb_write_bulk_callback(struct urb *urb) | |||
444 | __func__, status); | 444 | __func__, status); |
445 | 445 | ||
446 | pdx->pendingWrite = 0; | 446 | pdx->pendingWrite = 0; |
447 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 447 | kfree(urb->transfer_buffer); |
448 | urb->transfer_buffer, urb->transfer_dma); | ||
449 | } | 448 | } |
450 | 449 | ||
451 | int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, | 450 | int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, |
@@ -457,9 +456,7 @@ int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, | |||
457 | 456 | ||
458 | urb = usb_alloc_urb(0, GFP_KERNEL); | 457 | urb = usb_alloc_urb(0, GFP_KERNEL); |
459 | if (urb != NULL) { | 458 | if (urb != NULL) { |
460 | kbuf = | 459 | kbuf = kmalloc(len, GFP_KERNEL); |
461 | usb_buffer_alloc(pdx->udev, len, GFP_KERNEL, | ||
462 | &urb->transfer_dma); | ||
463 | if (!kbuf) { | 460 | if (!kbuf) { |
464 | dev_err(&pdx->udev->dev, "buffer_alloc failed\n"); | 461 | dev_err(&pdx->udev->dev, "buffer_alloc failed\n"); |
465 | return -ENOMEM; | 462 | return -ENOMEM; |
@@ -470,7 +467,6 @@ int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, | |||
470 | } | 467 | } |
471 | usb_fill_bulk_urb(urb, pdx->udev, pdx->hEP[io->endpoint], kbuf, | 468 | usb_fill_bulk_urb(urb, pdx->udev, pdx->hEP[io->endpoint], kbuf, |
472 | len, piusb_write_bulk_callback, pdx); | 469 | len, piusb_write_bulk_callback, pdx); |
473 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
474 | err = usb_submit_urb(urb, GFP_KERNEL); | 470 | err = usb_submit_urb(urb, GFP_KERNEL); |
475 | if (err) { | 471 | if (err) { |
476 | dev_err(&pdx->udev->dev, | 472 | dev_err(&pdx->udev->dev, |
@@ -641,7 +637,7 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) | |||
641 | numPagesRequired = | 637 | numPagesRequired = |
642 | ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; | 638 | ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; |
643 | dbg("Number of pages needed = %d", numPagesRequired); | 639 | dbg("Number of pages needed = %d", numPagesRequired); |
644 | maplist_p = vmalloc(numPagesRequired * sizeof(struct page)); | 640 | maplist_p = vmalloc(numPagesRequired * sizeof(struct page *)); |
645 | if (!maplist_p) { | 641 | if (!maplist_p) { |
646 | dbg("Can't Allocate Memory for maplist_p"); | 642 | dbg("Can't Allocate Memory for maplist_p"); |
647 | return -ENOMEM; | 643 | return -ENOMEM; |
@@ -712,9 +708,7 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) | |||
712 | usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i], | 708 | usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i], |
713 | pdx->udev, | 709 | pdx->udev, |
714 | epAddr, | 710 | epAddr, |
715 | (dma_addr_t *) sg_dma_address(&pdx-> | 711 | NULL, // non-DMA HC? buy a better hardware |
716 | sgl[frameInfo] | ||
717 | [i]), | ||
718 | sg_dma_len(&pdx->sgl[frameInfo][i]), | 712 | sg_dma_len(&pdx->sgl[frameInfo][i]), |
719 | piusb_readPIXEL_callback, (void *)pdx); | 713 | piusb_readPIXEL_callback, (void *)pdx); |
720 | pdx->PixelUrb[frameInfo][i]->transfer_dma = | 714 | pdx->PixelUrb[frameInfo][i]->transfer_dma = |
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h index 5e5b3f2b7eb1..29e3b53e52a1 100644 --- a/drivers/staging/rt2870/rt2870.h +++ b/drivers/staging/rt2870/rt2870.h | |||
@@ -89,6 +89,7 @@ | |||
89 | {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \ | 89 | {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \ |
90 | {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \ | 90 | {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \ |
91 | {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */ \ | 91 | {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */ \ |
92 | {USB_DEVICE(0x0DF6,0x003F)}, /* Sitecom WL-608 */ \ | ||
92 | {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \ | 93 | {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \ |
93 | {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \ | 94 | {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \ |
94 | {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \ | 95 | {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \ |
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c index 93af37e2d31a..54b4b718f84a 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c | |||
@@ -461,19 +461,19 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee, | |||
461 | struct iw_request_info *info, | 461 | struct iw_request_info *info, |
462 | union iwreq_data *wrqu, char *extra) | 462 | union iwreq_data *wrqu, char *extra) |
463 | { | 463 | { |
464 | strcpy(wrqu->name, "802.11"); | 464 | strlcpy(wrqu->name, "802.11", IFNAMSIZ); |
465 | if(ieee->modulation & IEEE80211_CCK_MODULATION){ | 465 | if(ieee->modulation & IEEE80211_CCK_MODULATION){ |
466 | strcat(wrqu->name, "b"); | 466 | strlcat(wrqu->name, "b", IFNAMSIZ); |
467 | if(ieee->modulation & IEEE80211_OFDM_MODULATION) | 467 | if(ieee->modulation & IEEE80211_OFDM_MODULATION) |
468 | strcat(wrqu->name, "/g"); | 468 | strlcat(wrqu->name, "/g", IFNAMSIZ); |
469 | }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) | 469 | }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) |
470 | strcat(wrqu->name, "g"); | 470 | strlcat(wrqu->name, "g", IFNAMSIZ); |
471 | 471 | ||
472 | if((ieee->state == IEEE80211_LINKED) || | 472 | if((ieee->state == IEEE80211_LINKED) || |
473 | (ieee->state == IEEE80211_LINKED_SCANNING)) | 473 | (ieee->state == IEEE80211_LINKED_SCANNING)) |
474 | strcat(wrqu->name," linked"); | 474 | strlcat(wrqu->name," link", IFNAMSIZ); |
475 | else if(ieee->state != IEEE80211_NOLINK) | 475 | else if(ieee->state != IEEE80211_NOLINK) |
476 | strcat(wrqu->name," link.."); | 476 | strlcat(wrqu->name," .....", IFNAMSIZ); |
477 | 477 | ||
478 | 478 | ||
479 | return 0; | 479 | return 0; |
diff --git a/drivers/staging/rtl8192su/Kconfig b/drivers/staging/rtl8192su/Kconfig index 4b5552c5926e..770f41280f21 100644 --- a/drivers/staging/rtl8192su/Kconfig +++ b/drivers/staging/rtl8192su/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config RTL8192SU | 1 | config RTL8192SU |
2 | tristate "RealTek RTL8192SU Wireless LAN NIC driver" | 2 | tristate "RealTek RTL8192SU Wireless LAN NIC driver" |
3 | depends on PCI | 3 | depends on PCI |
4 | depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS | 4 | depends on WIRELESS_EXT |
5 | default N | 5 | default N |
6 | ---help--- | 6 | ---help--- |
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c index f408b4583b82..759032db4a34 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c | |||
@@ -118,7 +118,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
118 | #else | 118 | #else |
119 | ieee = (struct ieee80211_device *)dev->priv; | 119 | ieee = (struct ieee80211_device *)dev->priv; |
120 | #endif | 120 | #endif |
121 | dev->hard_start_xmit = ieee80211_xmit; | ||
122 | 121 | ||
123 | memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv); | 122 | memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv); |
124 | ieee->dev = dev; | 123 | ieee->dev = dev; |
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c index 1f50c46dcb90..191dc3fbbe32 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c | |||
@@ -548,21 +548,21 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee, | |||
548 | struct iw_request_info *info, | 548 | struct iw_request_info *info, |
549 | union iwreq_data *wrqu, char *extra) | 549 | union iwreq_data *wrqu, char *extra) |
550 | { | 550 | { |
551 | strcpy(wrqu->name, "802.11"); | 551 | strlcpy(wrqu->name, "802.11", IFNAMSIZ); |
552 | if(ieee->modulation & IEEE80211_CCK_MODULATION){ | 552 | if(ieee->modulation & IEEE80211_CCK_MODULATION){ |
553 | strcat(wrqu->name, "b"); | 553 | strlcat(wrqu->name, "b", IFNAMSIZ); |
554 | if(ieee->modulation & IEEE80211_OFDM_MODULATION) | 554 | if(ieee->modulation & IEEE80211_OFDM_MODULATION) |
555 | strcat(wrqu->name, "/g"); | 555 | strlcat(wrqu->name, "/g", IFNAMSIZ); |
556 | }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) | 556 | }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) |
557 | strcat(wrqu->name, "g"); | 557 | strlcat(wrqu->name, "g", IFNAMSIZ); |
558 | if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) | 558 | if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) |
559 | strcat(wrqu->name, "/n"); | 559 | strlcat(wrqu->name, "/n", IFNAMSIZ); |
560 | 560 | ||
561 | if((ieee->state == IEEE80211_LINKED) || | 561 | if((ieee->state == IEEE80211_LINKED) || |
562 | (ieee->state == IEEE80211_LINKED_SCANNING)) | 562 | (ieee->state == IEEE80211_LINKED_SCANNING)) |
563 | strcat(wrqu->name," linked"); | 563 | strlcat(wrqu->name, " link", IFNAMSIZ); |
564 | else if(ieee->state != IEEE80211_NOLINK) | 564 | else if(ieee->state != IEEE80211_NOLINK) |
565 | strcat(wrqu->name," link.."); | 565 | strlcat(wrqu->name, " .....", IFNAMSIZ); |
566 | 566 | ||
567 | 567 | ||
568 | return 0; | 568 | return 0; |
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index f1423d714496..4ab250743e81 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c | |||
@@ -12132,6 +12132,19 @@ static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct | |||
12132 | } | 12132 | } |
12133 | #endif | 12133 | #endif |
12134 | 12134 | ||
12135 | static const struct net_device_ops rtl8192_netdev_ops = { | ||
12136 | .ndo_open = rtl8192_open, | ||
12137 | .ndo_stop = rtl8192_close, | ||
12138 | .ndo_get_stats = rtl8192_stats, | ||
12139 | .ndo_tx_timeout = tx_timeout, | ||
12140 | .ndo_do_ioctl = rtl8192_ioctl, | ||
12141 | .ndo_set_multicast_list = r8192_set_multicast, | ||
12142 | .ndo_set_mac_address = r8192_set_mac_adr, | ||
12143 | .ndo_validate_addr = eth_validate_addr, | ||
12144 | .ndo_change_mtu = eth_change_mtu, | ||
12145 | .ndo_start_xmit = ieee80211_xmit, | ||
12146 | }; | ||
12147 | |||
12135 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) | 12148 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) |
12136 | static int __devinit rtl8192_usb_probe(struct usb_interface *intf, | 12149 | static int __devinit rtl8192_usb_probe(struct usb_interface *intf, |
12137 | const struct usb_device_id *id) | 12150 | const struct usb_device_id *id) |
@@ -12186,15 +12199,7 @@ static void * __devinit rtl8192_usb_probe(struct usb_device *udev, | |||
12186 | priv->ops = &rtl8192u_ops; | 12199 | priv->ops = &rtl8192u_ops; |
12187 | #endif | 12200 | #endif |
12188 | 12201 | ||
12189 | dev->open = rtl8192_open; | 12202 | dev->netdev_ops = &rtl8192_netdev_ops; |
12190 | dev->stop = rtl8192_close; | ||
12191 | //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit; | ||
12192 | dev->tx_timeout = tx_timeout; | ||
12193 | //dev->wireless_handlers = &r8192_wx_handlers_def; | ||
12194 | dev->do_ioctl = rtl8192_ioctl; | ||
12195 | dev->set_multicast_list = r8192_set_multicast; | ||
12196 | dev->set_mac_address = r8192_set_mac_adr; | ||
12197 | dev->get_stats = rtl8192_stats; | ||
12198 | 12203 | ||
12199 | //DMESG("Oops: i'm coming\n"); | 12204 | //DMESG("Oops: i'm coming\n"); |
12200 | #if WIRELESS_EXT >= 12 | 12205 | #if WIRELESS_EXT >= 12 |
diff --git a/drivers/staging/rtl8192su/r8192U_pm.c b/drivers/staging/rtl8192su/r8192U_pm.c index 92c95aa36638..b1531a8d0cde 100644 --- a/drivers/staging/rtl8192su/r8192U_pm.c +++ b/drivers/staging/rtl8192su/r8192U_pm.c | |||
@@ -35,7 +35,9 @@ int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state) | |||
35 | return 0; | 35 | return 0; |
36 | } | 36 | } |
37 | 37 | ||
38 | dev->stop(dev); | 38 | if (dev->netdev_ops->ndo_stop) |
39 | dev->netdev_ops->ndo_stop(dev); | ||
40 | |||
39 | mdelay(10); | 41 | mdelay(10); |
40 | 42 | ||
41 | netif_device_detach(dev); | 43 | netif_device_detach(dev); |
@@ -61,7 +63,9 @@ int rtl8192U_resume (struct usb_interface *intf) | |||
61 | } | 63 | } |
62 | 64 | ||
63 | netif_device_attach(dev); | 65 | netif_device_attach(dev); |
64 | dev->open(dev); | 66 | |
67 | if (dev->netdev_ops->ndo_open) | ||
68 | dev->netdev_ops->ndo_open(dev); | ||
65 | } | 69 | } |
66 | 70 | ||
67 | return 0; | 71 | return 0; |
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 90b29b564631..0fdf8c6dc648 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c | |||
@@ -360,18 +360,18 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
360 | if (port_paranoia_check(port, __func__) != 0) { | 360 | if (port_paranoia_check(port, __func__) != 0) { |
361 | dbg("%s - port_paranoia_check, exiting\n", __func__); | 361 | dbg("%s - port_paranoia_check, exiting\n", __func__); |
362 | qt_port->ReadBulkStopped = 1; | 362 | qt_port->ReadBulkStopped = 1; |
363 | return; | 363 | goto exit; |
364 | } | 364 | } |
365 | 365 | ||
366 | if (!serial) { | 366 | if (!serial) { |
367 | dbg("%s - bad serial pointer, exiting\n", __func__); | 367 | dbg("%s - bad serial pointer, exiting\n", __func__); |
368 | return; | 368 | goto exit; |
369 | } | 369 | } |
370 | if (qt_port->closePending == 1) { | 370 | if (qt_port->closePending == 1) { |
371 | /* Were closing , stop reading */ | 371 | /* Were closing , stop reading */ |
372 | dbg("%s - (qt_port->closepending == 1\n", __func__); | 372 | dbg("%s - (qt_port->closepending == 1\n", __func__); |
373 | qt_port->ReadBulkStopped = 1; | 373 | qt_port->ReadBulkStopped = 1; |
374 | return; | 374 | goto exit; |
375 | } | 375 | } |
376 | 376 | ||
377 | /* | 377 | /* |
@@ -381,7 +381,7 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
381 | */ | 381 | */ |
382 | if (qt_port->RxHolding == 1) { | 382 | if (qt_port->RxHolding == 1) { |
383 | qt_port->ReadBulkStopped = 1; | 383 | qt_port->ReadBulkStopped = 1; |
384 | return; | 384 | goto exit; |
385 | } | 385 | } |
386 | 386 | ||
387 | if (urb->status) { | 387 | if (urb->status) { |
@@ -389,7 +389,7 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
389 | 389 | ||
390 | dbg("%s - nonzero read bulk status received: %d\n", | 390 | dbg("%s - nonzero read bulk status received: %d\n", |
391 | __func__, urb->status); | 391 | __func__, urb->status); |
392 | return; | 392 | goto exit; |
393 | } | 393 | } |
394 | 394 | ||
395 | if (tty && RxCount) { | 395 | if (tty && RxCount) { |
@@ -463,6 +463,8 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
463 | } | 463 | } |
464 | 464 | ||
465 | schedule_work(&port->work); | 465 | schedule_work(&port->work); |
466 | exit: | ||
467 | tty_kref_put(tty); | ||
466 | } | 468 | } |
467 | 469 | ||
468 | /* | 470 | /* |
@@ -736,6 +738,11 @@ static int qt_startup(struct usb_serial *serial) | |||
736 | if (!qt_port) { | 738 | if (!qt_port) { |
737 | dbg("%s: kmalloc for quatech_port (%d) failed!.", | 739 | dbg("%s: kmalloc for quatech_port (%d) failed!.", |
738 | __func__, i); | 740 | __func__, i); |
741 | for(--i; i >= 0; i--) { | ||
742 | port = serial->port[i]; | ||
743 | kfree(usb_get_serial_port_data(port)); | ||
744 | usb_set_serial_port_data(port, NULL); | ||
745 | } | ||
739 | return -ENOMEM; | 746 | return -ENOMEM; |
740 | } | 747 | } |
741 | spin_lock_init(&qt_port->lock); | 748 | spin_lock_init(&qt_port->lock); |
@@ -866,7 +873,7 @@ static void qt_release(struct usb_serial *serial) | |||
866 | 873 | ||
867 | } | 874 | } |
868 | 875 | ||
869 | int qt_open(struct tty_struct *tty, | 876 | static int qt_open(struct tty_struct *tty, |
870 | struct usb_serial_port *port, struct file *filp) | 877 | struct usb_serial_port *port, struct file *filp) |
871 | { | 878 | { |
872 | struct usb_serial *serial; | 879 | struct usb_serial *serial; |
@@ -1041,17 +1048,19 @@ static void qt_block_until_empty(struct tty_struct *tty, | |||
1041 | } | 1048 | } |
1042 | } | 1049 | } |
1043 | 1050 | ||
1044 | static void qt_close(struct tty_struct *tty, struct usb_serial_port *port, | 1051 | static void qt_close(struct usb_serial_port *port) |
1045 | struct file *filp) | ||
1046 | { | 1052 | { |
1047 | struct usb_serial *serial = port->serial; | 1053 | struct usb_serial *serial = port->serial; |
1048 | struct quatech_port *qt_port; | 1054 | struct quatech_port *qt_port; |
1049 | struct quatech_port *port0; | 1055 | struct quatech_port *port0; |
1056 | struct tty_struct *tty; | ||
1050 | int status; | 1057 | int status; |
1051 | unsigned int index; | 1058 | unsigned int index; |
1052 | status = 0; | 1059 | status = 0; |
1053 | 1060 | ||
1054 | dbg("%s - port %d\n", __func__, port->number); | 1061 | dbg("%s - port %d\n", __func__, port->number); |
1062 | |||
1063 | tty = tty_port_tty_get(&port->port); | ||
1055 | index = tty->index - serial->minor; | 1064 | index = tty->index - serial->minor; |
1056 | 1065 | ||
1057 | qt_port = qt_get_port_private(port); | 1066 | qt_port = qt_get_port_private(port); |
@@ -1066,6 +1075,7 @@ static void qt_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
1066 | /* wait up to for transmitter to empty */ | 1075 | /* wait up to for transmitter to empty */ |
1067 | if (serial->dev) | 1076 | if (serial->dev) |
1068 | qt_block_until_empty(tty, qt_port); | 1077 | qt_block_until_empty(tty, qt_port); |
1078 | tty_kref_put(tty); | ||
1069 | 1079 | ||
1070 | /* Close uart channel */ | 1080 | /* Close uart channel */ |
1071 | status = qt_close_channel(serial, index); | 1081 | status = qt_close_channel(serial, index); |
diff --git a/drivers/staging/stlc45xx/stlc45xx.c b/drivers/staging/stlc45xx/stlc45xx.c index cfdaac9b747e..a137c78fac09 100644 --- a/drivers/staging/stlc45xx/stlc45xx.c +++ b/drivers/staging/stlc45xx/stlc45xx.c | |||
@@ -2235,24 +2235,6 @@ static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw, | |||
2235 | stlc45xx_debug(DEBUG_FUNC, "%s", __func__); | 2235 | stlc45xx_debug(DEBUG_FUNC, "%s", __func__); |
2236 | } | 2236 | } |
2237 | 2237 | ||
2238 | static int stlc45xx_op_config_interface(struct ieee80211_hw *hw, | ||
2239 | struct ieee80211_vif *vif, | ||
2240 | struct ieee80211_if_conf *conf) | ||
2241 | { | ||
2242 | struct stlc45xx *stlc = hw->priv; | ||
2243 | |||
2244 | stlc45xx_debug(DEBUG_FUNC, "%s", __func__); | ||
2245 | |||
2246 | mutex_lock(&stlc->mutex); | ||
2247 | |||
2248 | memcpy(stlc->bssid, conf->bssid, ETH_ALEN); | ||
2249 | stlc45xx_tx_setup(stlc); | ||
2250 | |||
2251 | mutex_unlock(&stlc->mutex); | ||
2252 | |||
2253 | return 0; | ||
2254 | } | ||
2255 | |||
2256 | static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed) | 2238 | static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed) |
2257 | { | 2239 | { |
2258 | struct stlc45xx *stlc = hw->priv; | 2240 | struct stlc45xx *stlc = hw->priv; |
@@ -2295,6 +2277,14 @@ static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw, | |||
2295 | { | 2277 | { |
2296 | struct stlc45xx *stlc = hw->priv; | 2278 | struct stlc45xx *stlc = hw->priv; |
2297 | 2279 | ||
2280 | stlc45xx_debug(DEBUG_FUNC, "%s", __func__); | ||
2281 | mutex_lock(&stlc->mutex); | ||
2282 | |||
2283 | memcpy(stlc->bssid, info->bssid, ETH_ALEN); | ||
2284 | stlc45xx_tx_setup(stlc); | ||
2285 | |||
2286 | mutex_unlock(&stlc->mutex); | ||
2287 | |||
2298 | if (changed & BSS_CHANGED_ASSOC) { | 2288 | if (changed & BSS_CHANGED_ASSOC) { |
2299 | stlc->associated = info->assoc; | 2289 | stlc->associated = info->assoc; |
2300 | if (info->assoc) | 2290 | if (info->assoc) |
@@ -2357,7 +2347,6 @@ static const struct ieee80211_ops stlc45xx_ops = { | |||
2357 | .add_interface = stlc45xx_op_add_interface, | 2347 | .add_interface = stlc45xx_op_add_interface, |
2358 | .remove_interface = stlc45xx_op_remove_interface, | 2348 | .remove_interface = stlc45xx_op_remove_interface, |
2359 | .config = stlc45xx_op_config, | 2349 | .config = stlc45xx_op_config, |
2360 | .config_interface = stlc45xx_op_config_interface, | ||
2361 | .configure_filter = stlc45xx_op_configure_filter, | 2350 | .configure_filter = stlc45xx_op_configure_filter, |
2362 | .tx = stlc45xx_op_tx, | 2351 | .tx = stlc45xx_op_tx, |
2363 | .bss_info_changed = stlc45xx_op_bss_info_changed, | 2352 | .bss_info_changed = stlc45xx_op_bss_info_changed, |
diff --git a/drivers/staging/uc2322/Kconfig b/drivers/staging/uc2322/Kconfig deleted file mode 100644 index 2e0c6e79df2b..000000000000 --- a/drivers/staging/uc2322/Kconfig +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | config USB_SERIAL_ATEN2011 | ||
2 | tristate "ATEN 2011 USB to serial device support" | ||
3 | depends on USB_SERIAL | ||
4 | default N | ||
5 | ---help--- | ||
6 | Say Y here if you want to use a ATEN 2011 dual port USB to serial | ||
7 | adapter. | ||
8 | |||
9 | To compile this driver as a module, choose M here: the module will be | ||
10 | called aten2011. | ||
diff --git a/drivers/staging/uc2322/Makefile b/drivers/staging/uc2322/Makefile deleted file mode 100644 index 49c18d6e579f..000000000000 --- a/drivers/staging/uc2322/Makefile +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | obj-$(CONFIG_USB_SERIAL_ATEN2011) += aten2011.o | ||
diff --git a/drivers/staging/uc2322/TODO b/drivers/staging/uc2322/TODO deleted file mode 100644 index c189a64c4185..000000000000 --- a/drivers/staging/uc2322/TODO +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | TODO: | ||
2 | - checkpatch.pl cleanups | ||
3 | - remove dead and useless code (auditing the tty ioctls to | ||
4 | verify that they really are correct and needed.) | ||
5 | |||
6 | Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and | ||
7 | Russell Lang <gsview@ghostgum.com.au>. | ||
diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c deleted file mode 100644 index 39d0926d1a90..000000000000 --- a/drivers/staging/uc2322/aten2011.c +++ /dev/null | |||
@@ -1,2430 +0,0 @@ | |||
1 | /* | ||
2 | * Aten 2011 USB serial driver for 4 port devices | ||
3 | * | ||
4 | * Copyright (C) 2000 Inside Out Networks | ||
5 | * Copyright (C) 2001-2002, 2009 Greg Kroah-Hartman <greg@kroah.com> | ||
6 | * Copyright (C) 2009 Novell Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/tty.h> | ||
20 | #include <linux/tty_driver.h> | ||
21 | #include <linux/tty_flip.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/serial.h> | ||
24 | #include <linux/uaccess.h> | ||
25 | #include <linux/usb.h> | ||
26 | #include <linux/usb/serial.h> | ||
27 | |||
28 | |||
29 | #define ZLP_REG1 0x3A /* Zero_Flag_Reg1 58 */ | ||
30 | #define ZLP_REG2 0x3B /* Zero_Flag_Reg2 59 */ | ||
31 | #define ZLP_REG3 0x3C /* Zero_Flag_Reg3 60 */ | ||
32 | #define ZLP_REG4 0x3D /* Zero_Flag_Reg4 61 */ | ||
33 | #define ZLP_REG5 0x3E /* Zero_Flag_Reg5 62 */ | ||
34 | |||
35 | /* Interrupt Rotinue Defines */ | ||
36 | #define SERIAL_IIR_RLS 0x06 | ||
37 | #define SERIAL_IIR_RDA 0x04 | ||
38 | #define SERIAL_IIR_CTI 0x0c | ||
39 | #define SERIAL_IIR_THR 0x02 | ||
40 | #define SERIAL_IIR_MS 0x00 | ||
41 | |||
42 | /* Emulation of the bit mask on the LINE STATUS REGISTER. */ | ||
43 | #define SERIAL_LSR_DR 0x0001 | ||
44 | #define SERIAL_LSR_OE 0x0002 | ||
45 | #define SERIAL_LSR_PE 0x0004 | ||
46 | #define SERIAL_LSR_FE 0x0008 | ||
47 | #define SERIAL_LSR_BI 0x0010 | ||
48 | #define SERIAL_LSR_THRE 0x0020 | ||
49 | #define SERIAL_LSR_TEMT 0x0040 | ||
50 | #define SERIAL_LSR_FIFOERR 0x0080 | ||
51 | |||
52 | /* MSR bit defines(place holders) */ | ||
53 | #define ATEN_MSR_DELTA_CTS 0x10 | ||
54 | #define ATEN_MSR_DELTA_DSR 0x20 | ||
55 | #define ATEN_MSR_DELTA_RI 0x40 | ||
56 | #define ATEN_MSR_DELTA_CD 0x80 | ||
57 | |||
58 | /* Serial Port register Address */ | ||
59 | #define RECEIVE_BUFFER_REGISTER ((__u16)(0x00)) | ||
60 | #define TRANSMIT_HOLDING_REGISTER ((__u16)(0x00)) | ||
61 | #define INTERRUPT_ENABLE_REGISTER ((__u16)(0x01)) | ||
62 | #define INTERRUPT_IDENT_REGISTER ((__u16)(0x02)) | ||
63 | #define FIFO_CONTROL_REGISTER ((__u16)(0x02)) | ||
64 | #define LINE_CONTROL_REGISTER ((__u16)(0x03)) | ||
65 | #define MODEM_CONTROL_REGISTER ((__u16)(0x04)) | ||
66 | #define LINE_STATUS_REGISTER ((__u16)(0x05)) | ||
67 | #define MODEM_STATUS_REGISTER ((__u16)(0x06)) | ||
68 | #define SCRATCH_PAD_REGISTER ((__u16)(0x07)) | ||
69 | #define DIVISOR_LATCH_LSB ((__u16)(0x00)) | ||
70 | #define DIVISOR_LATCH_MSB ((__u16)(0x01)) | ||
71 | |||
72 | #define SP1_REGISTER ((__u16)(0x00)) | ||
73 | #define CONTROL1_REGISTER ((__u16)(0x01)) | ||
74 | #define CLK_MULTI_REGISTER ((__u16)(0x02)) | ||
75 | #define CLK_START_VALUE_REGISTER ((__u16)(0x03)) | ||
76 | #define DCR1_REGISTER ((__u16)(0x04)) | ||
77 | #define GPIO_REGISTER ((__u16)(0x07)) | ||
78 | |||
79 | #define SERIAL_LCR_DLAB ((__u16)(0x0080)) | ||
80 | |||
81 | /* | ||
82 | * URB POOL related defines | ||
83 | */ | ||
84 | #define NUM_URBS 16 /* URB Count */ | ||
85 | #define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ | ||
86 | |||
87 | #define USB_VENDOR_ID_ATENINTL 0x0557 | ||
88 | #define ATENINTL_DEVICE_ID_2011 0x2011 | ||
89 | #define ATENINTL_DEVICE_ID_7820 0x7820 | ||
90 | |||
91 | static struct usb_device_id id_table[] = { | ||
92 | { USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_2011) }, | ||
93 | { USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_7820) }, | ||
94 | { } /* terminating entry */ | ||
95 | }; | ||
96 | MODULE_DEVICE_TABLE(usb, id_table); | ||
97 | |||
98 | /* This structure holds all of the local port information */ | ||
99 | struct ATENINTL_port { | ||
100 | int port_num; /*Actual port number in the device(1,2,etc)*/ | ||
101 | __u8 bulk_out_endpoint; /* the bulk out endpoint handle */ | ||
102 | unsigned char *bulk_out_buffer; /* buffer used for the bulk out endpoint */ | ||
103 | struct urb *write_urb; /* write URB for this port */ | ||
104 | __u8 bulk_in_endpoint; /* the bulk in endpoint handle */ | ||
105 | unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */ | ||
106 | struct urb *read_urb; /* read URB for this port */ | ||
107 | __u8 shadowLCR; /* last LCR value received */ | ||
108 | __u8 shadowMCR; /* last MCR value received */ | ||
109 | char open; | ||
110 | char chaseResponsePending; | ||
111 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ | ||
112 | wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */ | ||
113 | struct async_icount icount; | ||
114 | struct usb_serial_port *port; /* loop back to the owner of this object */ | ||
115 | /*Offsets*/ | ||
116 | __u8 SpRegOffset; | ||
117 | __u8 ControlRegOffset; | ||
118 | __u8 DcrRegOffset; | ||
119 | /* for processing control URBS in interrupt context */ | ||
120 | struct urb *control_urb; | ||
121 | char *ctrl_buf; | ||
122 | int MsrLsr; | ||
123 | |||
124 | struct urb *write_urb_pool[NUM_URBS]; | ||
125 | /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */ | ||
126 | struct ktermios tmp_termios; /* stores the old termios settings */ | ||
127 | spinlock_t lock; /* private lock */ | ||
128 | }; | ||
129 | |||
130 | /* This structure holds all of the individual serial device information */ | ||
131 | struct ATENINTL_serial { | ||
132 | __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */ | ||
133 | unsigned char *interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */ | ||
134 | struct urb *interrupt_read_urb; /* our interrupt urb */ | ||
135 | __u8 bulk_in_endpoint; /* the bulk in endpoint handle */ | ||
136 | unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */ | ||
137 | struct urb *read_urb; /* our bulk read urb */ | ||
138 | __u8 bulk_out_endpoint; /* the bulk out endpoint handle */ | ||
139 | struct usb_serial *serial; /* loop back to the owner of this object */ | ||
140 | int ATEN2011_spectrum_2or4ports; /* this says the number of ports in the device */ | ||
141 | /* Indicates about the no.of opened ports of an individual USB-serial adapater. */ | ||
142 | unsigned int NoOfOpenPorts; | ||
143 | /* a flag for Status endpoint polling */ | ||
144 | unsigned char status_polling_started; | ||
145 | }; | ||
146 | |||
147 | static void ATEN2011_set_termios(struct tty_struct *tty, | ||
148 | struct usb_serial_port *port, | ||
149 | struct ktermios *old_termios); | ||
150 | static void ATEN2011_change_port_settings(struct tty_struct *tty, | ||
151 | struct ATENINTL_port *ATEN2011_port, | ||
152 | struct ktermios *old_termios); | ||
153 | |||
154 | /************************************* | ||
155 | * Bit definitions for each register * | ||
156 | *************************************/ | ||
157 | #define LCR_BITS_5 0x00 /* 5 bits/char */ | ||
158 | #define LCR_BITS_6 0x01 /* 6 bits/char */ | ||
159 | #define LCR_BITS_7 0x02 /* 7 bits/char */ | ||
160 | #define LCR_BITS_8 0x03 /* 8 bits/char */ | ||
161 | #define LCR_BITS_MASK 0x03 /* Mask for bits/char field */ | ||
162 | |||
163 | #define LCR_STOP_1 0x00 /* 1 stop bit */ | ||
164 | #define LCR_STOP_1_5 0x04 /* 1.5 stop bits (if 5 bits/char) */ | ||
165 | #define LCR_STOP_2 0x04 /* 2 stop bits (if 6-8 bits/char) */ | ||
166 | #define LCR_STOP_MASK 0x04 /* Mask for stop bits field */ | ||
167 | |||
168 | #define LCR_PAR_NONE 0x00 /* No parity */ | ||
169 | #define LCR_PAR_ODD 0x08 /* Odd parity */ | ||
170 | #define LCR_PAR_EVEN 0x18 /* Even parity */ | ||
171 | #define LCR_PAR_MARK 0x28 /* Force parity bit to 1 */ | ||
172 | #define LCR_PAR_SPACE 0x38 /* Force parity bit to 0 */ | ||
173 | #define LCR_PAR_MASK 0x38 /* Mask for parity field */ | ||
174 | |||
175 | #define LCR_SET_BREAK 0x40 /* Set Break condition */ | ||
176 | #define LCR_DL_ENABLE 0x80 /* Enable access to divisor latch */ | ||
177 | |||
178 | #define MCR_DTR 0x01 /* Assert DTR */ | ||
179 | #define MCR_RTS 0x02 /* Assert RTS */ | ||
180 | #define MCR_OUT1 0x04 /* Loopback only: Sets state of RI */ | ||
181 | #define MCR_MASTER_IE 0x08 /* Enable interrupt outputs */ | ||
182 | #define MCR_LOOPBACK 0x10 /* Set internal (digital) loopback mode */ | ||
183 | #define MCR_XON_ANY 0x20 /* Enable any char to exit XOFF mode */ | ||
184 | |||
185 | #define ATEN2011_MSR_CTS 0x10 /* Current state of CTS */ | ||
186 | #define ATEN2011_MSR_DSR 0x20 /* Current state of DSR */ | ||
187 | #define ATEN2011_MSR_RI 0x40 /* Current state of RI */ | ||
188 | #define ATEN2011_MSR_CD 0x80 /* Current state of CD */ | ||
189 | |||
190 | |||
191 | static int debug; | ||
192 | |||
193 | /* | ||
194 | * Version Information | ||
195 | */ | ||
196 | #define DRIVER_VERSION "2.0" | ||
197 | #define DRIVER_DESC "ATENINTL 2011 USB Serial Adapter" | ||
198 | |||
199 | /* | ||
200 | * Defines used for sending commands to port | ||
201 | */ | ||
202 | |||
203 | #define ATEN_WDR_TIMEOUT (50) /* default urb timeout */ | ||
204 | |||
205 | /* Requests */ | ||
206 | #define ATEN_RD_RTYPE 0xC0 | ||
207 | #define ATEN_WR_RTYPE 0x40 | ||
208 | #define ATEN_RDREQ 0x0D | ||
209 | #define ATEN_WRREQ 0x0E | ||
210 | #define ATEN_CTRL_TIMEOUT 500 | ||
211 | #define VENDOR_READ_LENGTH (0x01) | ||
212 | |||
213 | /* set to 1 for RS485 mode and 0 for RS232 mode */ | ||
214 | /* FIXME make this somehow dynamic and not build time specific */ | ||
215 | static int RS485mode; | ||
216 | |||
217 | static int set_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 val) | ||
218 | { | ||
219 | struct usb_device *dev = port->serial->dev; | ||
220 | val = val & 0x00ff; | ||
221 | |||
222 | dbg("%s: is %x, value %x", __func__, reg, val); | ||
223 | |||
224 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ATEN_WRREQ, | ||
225 | ATEN_WR_RTYPE, val, reg, NULL, 0, | ||
226 | ATEN_WDR_TIMEOUT); | ||
227 | } | ||
228 | |||
229 | static int get_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 *val) | ||
230 | { | ||
231 | struct usb_device *dev = port->serial->dev; | ||
232 | int ret; | ||
233 | |||
234 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ATEN_RDREQ, | ||
235 | ATEN_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH, | ||
236 | ATEN_WDR_TIMEOUT); | ||
237 | dbg("%s: offset is %x, return val %x", __func__, reg, *val); | ||
238 | *val = (*val) & 0x00ff; | ||
239 | return ret; | ||
240 | } | ||
241 | |||
242 | static int set_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 val) | ||
243 | { | ||
244 | struct usb_device *dev = port->serial->dev; | ||
245 | struct ATENINTL_serial *a_serial; | ||
246 | __u16 minor; | ||
247 | |||
248 | a_serial = usb_get_serial_data(port->serial); | ||
249 | minor = port->serial->minor; | ||
250 | if (minor == SERIAL_TTY_NO_MINOR) | ||
251 | minor = 0; | ||
252 | val = val & 0x00ff; | ||
253 | |||
254 | /* | ||
255 | * For the UART control registers, | ||
256 | * the application number need to be Or'ed | ||
257 | */ | ||
258 | if (a_serial->ATEN2011_spectrum_2or4ports == 4) | ||
259 | val |= (((__u16)port->number - minor) + 1) << 8; | ||
260 | else { | ||
261 | if (((__u16) port->number - minor) == 0) | ||
262 | val |= (((__u16)port->number - minor) + 1) << 8; | ||
263 | else | ||
264 | val |= (((__u16)port->number - minor) + 2) << 8; | ||
265 | } | ||
266 | dbg("%s: application number is %x", __func__, val); | ||
267 | |||
268 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ATEN_WRREQ, | ||
269 | ATEN_WR_RTYPE, val, reg, NULL, 0, | ||
270 | ATEN_WDR_TIMEOUT); | ||
271 | } | ||
272 | |||
273 | static int get_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 *val) | ||
274 | { | ||
275 | struct usb_device *dev = port->serial->dev; | ||
276 | int ret = 0; | ||
277 | __u16 wval; | ||
278 | struct ATENINTL_serial *a_serial; | ||
279 | __u16 minor = port->serial->minor; | ||
280 | |||
281 | a_serial = usb_get_serial_data(port->serial); | ||
282 | if (minor == SERIAL_TTY_NO_MINOR) | ||
283 | minor = 0; | ||
284 | |||
285 | /* wval is same as application number */ | ||
286 | if (a_serial->ATEN2011_spectrum_2or4ports == 4) | ||
287 | wval = (((__u16)port->number - minor) + 1) << 8; | ||
288 | else { | ||
289 | if (((__u16) port->number - minor) == 0) | ||
290 | wval = (((__u16) port->number - minor) + 1) << 8; | ||
291 | else | ||
292 | wval = (((__u16) port->number - minor) + 2) << 8; | ||
293 | } | ||
294 | dbg("%s: application number is %x", __func__, wval); | ||
295 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ATEN_RDREQ, | ||
296 | ATEN_RD_RTYPE, wval, reg, val, VENDOR_READ_LENGTH, | ||
297 | ATEN_WDR_TIMEOUT); | ||
298 | *val = (*val) & 0x00ff; | ||
299 | return ret; | ||
300 | } | ||
301 | |||
302 | static int handle_newMsr(struct ATENINTL_port *port, __u8 newMsr) | ||
303 | { | ||
304 | struct ATENINTL_port *ATEN2011_port; | ||
305 | struct async_icount *icount; | ||
306 | ATEN2011_port = port; | ||
307 | icount = &ATEN2011_port->icount; | ||
308 | if (newMsr & | ||
309 | (ATEN_MSR_DELTA_CTS | ATEN_MSR_DELTA_DSR | ATEN_MSR_DELTA_RI | | ||
310 | ATEN_MSR_DELTA_CD)) { | ||
311 | icount = &ATEN2011_port->icount; | ||
312 | |||
313 | /* update input line counters */ | ||
314 | if (newMsr & ATEN_MSR_DELTA_CTS) | ||
315 | icount->cts++; | ||
316 | if (newMsr & ATEN_MSR_DELTA_DSR) | ||
317 | icount->dsr++; | ||
318 | if (newMsr & ATEN_MSR_DELTA_CD) | ||
319 | icount->dcd++; | ||
320 | if (newMsr & ATEN_MSR_DELTA_RI) | ||
321 | icount->rng++; | ||
322 | } | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static int handle_newLsr(struct ATENINTL_port *port, __u8 newLsr) | ||
328 | { | ||
329 | struct async_icount *icount; | ||
330 | |||
331 | dbg("%s - %02x", __func__, newLsr); | ||
332 | |||
333 | if (newLsr & SERIAL_LSR_BI) { | ||
334 | /* | ||
335 | * Parity and Framing errors only count if they occur exclusive | ||
336 | * of a break being received. | ||
337 | */ | ||
338 | newLsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI); | ||
339 | } | ||
340 | |||
341 | /* update input line counters */ | ||
342 | icount = &port->icount; | ||
343 | if (newLsr & SERIAL_LSR_BI) | ||
344 | icount->brk++; | ||
345 | if (newLsr & SERIAL_LSR_OE) | ||
346 | icount->overrun++; | ||
347 | if (newLsr & SERIAL_LSR_PE) | ||
348 | icount->parity++; | ||
349 | if (newLsr & SERIAL_LSR_FE) | ||
350 | icount->frame++; | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static void ATEN2011_control_callback(struct urb *urb) | ||
356 | { | ||
357 | unsigned char *data; | ||
358 | struct ATENINTL_port *ATEN2011_port; | ||
359 | __u8 regval = 0x0; | ||
360 | |||
361 | switch (urb->status) { | ||
362 | case 0: | ||
363 | /* success */ | ||
364 | break; | ||
365 | case -ECONNRESET: | ||
366 | case -ENOENT: | ||
367 | case -ESHUTDOWN: | ||
368 | /* this urb is terminated, clean up */ | ||
369 | dbg("%s - urb shutting down with status: %d", __func__, | ||
370 | urb->status); | ||
371 | return; | ||
372 | default: | ||
373 | dbg("%s - nonzero urb status received: %d", __func__, | ||
374 | urb->status); | ||
375 | goto exit; | ||
376 | } | ||
377 | |||
378 | ATEN2011_port = (struct ATENINTL_port *)urb->context; | ||
379 | |||
380 | dbg("%s urb buffer size is %d", __func__, urb->actual_length); | ||
381 | dbg("%s ATEN2011_port->MsrLsr is %d port %d", __func__, | ||
382 | ATEN2011_port->MsrLsr, ATEN2011_port->port_num); | ||
383 | data = urb->transfer_buffer; | ||
384 | regval = (__u8) data[0]; | ||
385 | dbg("%s data is %x", __func__, regval); | ||
386 | if (ATEN2011_port->MsrLsr == 0) | ||
387 | handle_newMsr(ATEN2011_port, regval); | ||
388 | else if (ATEN2011_port->MsrLsr == 1) | ||
389 | handle_newLsr(ATEN2011_port, regval); | ||
390 | |||
391 | exit: | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | static int ATEN2011_get_reg(struct ATENINTL_port *ATEN, __u16 Wval, __u16 reg, | ||
396 | __u16 *val) | ||
397 | { | ||
398 | struct usb_device *dev = ATEN->port->serial->dev; | ||
399 | struct usb_ctrlrequest *dr = NULL; | ||
400 | unsigned char *buffer = NULL; | ||
401 | int ret = 0; | ||
402 | buffer = (__u8 *) ATEN->ctrl_buf; | ||
403 | |||
404 | dr = (void *)(buffer + 2); | ||
405 | dr->bRequestType = ATEN_RD_RTYPE; | ||
406 | dr->bRequest = ATEN_RDREQ; | ||
407 | dr->wValue = cpu_to_le16(Wval); | ||
408 | dr->wIndex = cpu_to_le16(reg); | ||
409 | dr->wLength = cpu_to_le16(2); | ||
410 | |||
411 | usb_fill_control_urb(ATEN->control_urb, dev, usb_rcvctrlpipe(dev, 0), | ||
412 | (unsigned char *)dr, buffer, 2, | ||
413 | ATEN2011_control_callback, ATEN); | ||
414 | ATEN->control_urb->transfer_buffer_length = 2; | ||
415 | ret = usb_submit_urb(ATEN->control_urb, GFP_ATOMIC); | ||
416 | return ret; | ||
417 | } | ||
418 | |||
419 | static void ATEN2011_interrupt_callback(struct urb *urb) | ||
420 | { | ||
421 | int result; | ||
422 | int length; | ||
423 | struct ATENINTL_port *ATEN2011_port; | ||
424 | struct ATENINTL_serial *ATEN2011_serial; | ||
425 | struct usb_serial *serial; | ||
426 | __u16 Data; | ||
427 | unsigned char *data; | ||
428 | __u8 sp[5], st; | ||
429 | int i; | ||
430 | __u16 wval; | ||
431 | int minor; | ||
432 | |||
433 | dbg("%s", " : Entering"); | ||
434 | |||
435 | ATEN2011_serial = (struct ATENINTL_serial *)urb->context; | ||
436 | |||
437 | switch (urb->status) { | ||
438 | case 0: | ||
439 | /* success */ | ||
440 | break; | ||
441 | case -ECONNRESET: | ||
442 | case -ENOENT: | ||
443 | case -ESHUTDOWN: | ||
444 | /* this urb is terminated, clean up */ | ||
445 | dbg("%s - urb shutting down with status: %d", __func__, | ||
446 | urb->status); | ||
447 | return; | ||
448 | default: | ||
449 | dbg("%s - nonzero urb status received: %d", __func__, | ||
450 | urb->status); | ||
451 | goto exit; | ||
452 | } | ||
453 | length = urb->actual_length; | ||
454 | data = urb->transfer_buffer; | ||
455 | |||
456 | serial = ATEN2011_serial->serial; | ||
457 | |||
458 | /* ATENINTL get 5 bytes | ||
459 | * Byte 1 IIR Port 1 (port.number is 0) | ||
460 | * Byte 2 IIR Port 2 (port.number is 1) | ||
461 | * Byte 3 IIR Port 3 (port.number is 2) | ||
462 | * Byte 4 IIR Port 4 (port.number is 3) | ||
463 | * Byte 5 FIFO status for both */ | ||
464 | |||
465 | if (length && length > 5) { | ||
466 | dbg("%s", "Wrong data !!!"); | ||
467 | return; | ||
468 | } | ||
469 | |||
470 | /* MATRIX */ | ||
471 | if (ATEN2011_serial->ATEN2011_spectrum_2or4ports == 4) { | ||
472 | sp[0] = (__u8) data[0]; | ||
473 | sp[1] = (__u8) data[1]; | ||
474 | sp[2] = (__u8) data[2]; | ||
475 | sp[3] = (__u8) data[3]; | ||
476 | st = (__u8) data[4]; | ||
477 | } else { | ||
478 | sp[0] = (__u8) data[0]; | ||
479 | sp[1] = (__u8) data[2]; | ||
480 | /* sp[2]=(__u8)data[2]; */ | ||
481 | /* sp[3]=(__u8)data[3]; */ | ||
482 | st = (__u8) data[4]; | ||
483 | |||
484 | } | ||
485 | for (i = 0; i < serial->num_ports; i++) { | ||
486 | ATEN2011_port = usb_get_serial_port_data(serial->port[i]); | ||
487 | minor = serial->minor; | ||
488 | if (minor == SERIAL_TTY_NO_MINOR) | ||
489 | minor = 0; | ||
490 | if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2) | ||
491 | && (i != 0)) | ||
492 | wval = | ||
493 | (((__u16) serial->port[i]->number - | ||
494 | (__u16) (minor)) + 2) << 8; | ||
495 | else | ||
496 | wval = | ||
497 | (((__u16) serial->port[i]->number - | ||
498 | (__u16) (minor)) + 1) << 8; | ||
499 | if (ATEN2011_port->open != 0) { | ||
500 | if (sp[i] & 0x01) { | ||
501 | dbg("SP%d No Interrupt !!!", i); | ||
502 | } else { | ||
503 | switch (sp[i] & 0x0f) { | ||
504 | case SERIAL_IIR_RLS: | ||
505 | dbg("Serial Port %d: Receiver status error or address bit detected in 9-bit mode", i); | ||
506 | ATEN2011_port->MsrLsr = 1; | ||
507 | ATEN2011_get_reg(ATEN2011_port, wval, | ||
508 | LINE_STATUS_REGISTER, | ||
509 | &Data); | ||
510 | break; | ||
511 | case SERIAL_IIR_MS: | ||
512 | dbg("Serial Port %d: Modem status change", i); | ||
513 | ATEN2011_port->MsrLsr = 0; | ||
514 | ATEN2011_get_reg(ATEN2011_port, wval, | ||
515 | MODEM_STATUS_REGISTER, | ||
516 | &Data); | ||
517 | break; | ||
518 | } | ||
519 | } | ||
520 | } | ||
521 | |||
522 | } | ||
523 | exit: | ||
524 | if (ATEN2011_serial->status_polling_started == 0) | ||
525 | return; | ||
526 | |||
527 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
528 | if (result) { | ||
529 | dev_err(&urb->dev->dev, | ||
530 | "%s - Error %d submitting interrupt urb\n", | ||
531 | __func__, result); | ||
532 | } | ||
533 | |||
534 | return; | ||
535 | } | ||
536 | |||
537 | static void ATEN2011_bulk_in_callback(struct urb *urb) | ||
538 | { | ||
539 | int status; | ||
540 | unsigned char *data; | ||
541 | struct usb_serial *serial; | ||
542 | struct usb_serial_port *port; | ||
543 | struct ATENINTL_serial *ATEN2011_serial; | ||
544 | struct ATENINTL_port *ATEN2011_port; | ||
545 | struct tty_struct *tty; | ||
546 | |||
547 | if (urb->status) { | ||
548 | dbg("nonzero read bulk status received: %d", urb->status); | ||
549 | return; | ||
550 | } | ||
551 | |||
552 | ATEN2011_port = (struct ATENINTL_port *)urb->context; | ||
553 | |||
554 | port = (struct usb_serial_port *)ATEN2011_port->port; | ||
555 | serial = port->serial; | ||
556 | |||
557 | dbg("%s", "Entering..."); | ||
558 | |||
559 | data = urb->transfer_buffer; | ||
560 | ATEN2011_serial = usb_get_serial_data(serial); | ||
561 | |||
562 | if (urb->actual_length) { | ||
563 | tty = tty_port_tty_get(&ATEN2011_port->port->port); | ||
564 | if (tty) { | ||
565 | tty_buffer_request_room(tty, urb->actual_length); | ||
566 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
567 | tty_flip_buffer_push(tty); | ||
568 | tty_kref_put(tty); | ||
569 | } | ||
570 | |||
571 | ATEN2011_port->icount.rx += urb->actual_length; | ||
572 | dbg("ATEN2011_port->icount.rx is %d:", | ||
573 | ATEN2011_port->icount.rx); | ||
574 | } | ||
575 | |||
576 | if (!ATEN2011_port->read_urb) { | ||
577 | dbg("%s", "URB KILLED !!!"); | ||
578 | return; | ||
579 | } | ||
580 | |||
581 | if (ATEN2011_port->read_urb->status != -EINPROGRESS) { | ||
582 | ATEN2011_port->read_urb->dev = serial->dev; | ||
583 | |||
584 | status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC); | ||
585 | if (status) | ||
586 | dbg("usb_submit_urb(read bulk) failed, status = %d", status); | ||
587 | } | ||
588 | } | ||
589 | |||
590 | static void ATEN2011_bulk_out_data_callback(struct urb *urb) | ||
591 | { | ||
592 | struct ATENINTL_port *ATEN2011_port; | ||
593 | struct tty_struct *tty; | ||
594 | |||
595 | if (urb->status) { | ||
596 | dbg("nonzero write bulk status received:%d", urb->status); | ||
597 | return; | ||
598 | } | ||
599 | |||
600 | ATEN2011_port = (struct ATENINTL_port *)urb->context; | ||
601 | |||
602 | dbg("%s", "Entering ........."); | ||
603 | |||
604 | tty = tty_port_tty_get(&ATEN2011_port->port->port); | ||
605 | |||
606 | if (tty && ATEN2011_port->open) | ||
607 | /* tell the tty driver that something has changed */ | ||
608 | tty_wakeup(tty); | ||
609 | |||
610 | /* schedule_work(&ATEN2011_port->port->work); */ | ||
611 | tty_kref_put(tty); | ||
612 | |||
613 | } | ||
614 | |||
615 | #ifdef ATENSerialProbe | ||
616 | static int ATEN2011_serial_probe(struct usb_serial *serial, | ||
617 | const struct usb_device_id *id) | ||
618 | { | ||
619 | |||
620 | /*need to implement the mode_reg reading and updating\ | ||
621 | structures usb_serial_ device_type\ | ||
622 | (i.e num_ports, num_bulkin,bulkout etc) */ | ||
623 | /* Also we can update the changes attach */ | ||
624 | return 1; | ||
625 | } | ||
626 | #endif | ||
627 | |||
628 | static int ATEN2011_open(struct tty_struct *tty, struct usb_serial_port *port, | ||
629 | struct file *filp) | ||
630 | { | ||
631 | int response; | ||
632 | int j; | ||
633 | struct usb_serial *serial; | ||
634 | struct urb *urb; | ||
635 | __u16 Data; | ||
636 | int status; | ||
637 | struct ATENINTL_serial *ATEN2011_serial; | ||
638 | struct ATENINTL_port *ATEN2011_port; | ||
639 | struct ktermios tmp_termios; | ||
640 | int minor; | ||
641 | |||
642 | serial = port->serial; | ||
643 | |||
644 | ATEN2011_port = usb_get_serial_port_data(port); | ||
645 | |||
646 | if (ATEN2011_port == NULL) | ||
647 | return -ENODEV; | ||
648 | |||
649 | ATEN2011_serial = usb_get_serial_data(serial); | ||
650 | if (ATEN2011_serial == NULL) | ||
651 | return -ENODEV; | ||
652 | |||
653 | /* increment the number of opened ports counter here */ | ||
654 | ATEN2011_serial->NoOfOpenPorts++; | ||
655 | |||
656 | usb_clear_halt(serial->dev, port->write_urb->pipe); | ||
657 | usb_clear_halt(serial->dev, port->read_urb->pipe); | ||
658 | |||
659 | /* Initialising the write urb pool */ | ||
660 | for (j = 0; j < NUM_URBS; ++j) { | ||
661 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
662 | ATEN2011_port->write_urb_pool[j] = urb; | ||
663 | |||
664 | if (urb == NULL) { | ||
665 | err("No more urbs???"); | ||
666 | continue; | ||
667 | } | ||
668 | |||
669 | urb->transfer_buffer = NULL; | ||
670 | urb->transfer_buffer = | ||
671 | kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); | ||
672 | if (!urb->transfer_buffer) { | ||
673 | err("%s-out of memory for urb buffers.", __func__); | ||
674 | continue; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | /***************************************************************************** | ||
679 | * Initialize ATEN2011 -- Write Init values to corresponding Registers | ||
680 | * | ||
681 | * Register Index | ||
682 | * 1 : IER | ||
683 | * 2 : FCR | ||
684 | * 3 : LCR | ||
685 | * 4 : MCR | ||
686 | * | ||
687 | * 0x08 : SP1/2 Control Reg | ||
688 | *****************************************************************************/ | ||
689 | |||
690 | /* NEED to check the fallowing Block */ | ||
691 | |||
692 | Data = 0x0; | ||
693 | status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data); | ||
694 | if (status < 0) { | ||
695 | dbg("Reading Spreg failed"); | ||
696 | return -1; | ||
697 | } | ||
698 | Data |= 0x80; | ||
699 | status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data); | ||
700 | if (status < 0) { | ||
701 | dbg("writing Spreg failed"); | ||
702 | return -1; | ||
703 | } | ||
704 | |||
705 | Data &= ~0x80; | ||
706 | status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data); | ||
707 | if (status < 0) { | ||
708 | dbg("writing Spreg failed"); | ||
709 | return -1; | ||
710 | } | ||
711 | |||
712 | /* End of block to be checked */ | ||
713 | /**************************CHECK***************************/ | ||
714 | |||
715 | if (RS485mode == 0) | ||
716 | Data = 0xC0; | ||
717 | else | ||
718 | Data = 0x00; | ||
719 | status = set_uart_reg(port, SCRATCH_PAD_REGISTER, Data); | ||
720 | if (status < 0) { | ||
721 | dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x", status); | ||
722 | return -1; | ||
723 | } else | ||
724 | dbg("SCRATCH_PAD_REGISTER Writing success status%d", status); | ||
725 | |||
726 | /**************************CHECK***************************/ | ||
727 | |||
728 | Data = 0x0; | ||
729 | status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data); | ||
730 | if (status < 0) { | ||
731 | dbg("Reading Controlreg failed"); | ||
732 | return -1; | ||
733 | } | ||
734 | Data |= 0x08; /* Driver done bit */ | ||
735 | Data |= 0x20; /* rx_disable */ | ||
736 | status = 0; | ||
737 | status = | ||
738 | set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data); | ||
739 | if (status < 0) { | ||
740 | dbg("writing Controlreg failed"); | ||
741 | return -1; | ||
742 | } | ||
743 | /* | ||
744 | * do register settings here | ||
745 | * Set all regs to the device default values. | ||
746 | * First Disable all interrupts. | ||
747 | */ | ||
748 | |||
749 | Data = 0x00; | ||
750 | status = set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); | ||
751 | if (status < 0) { | ||
752 | dbg("disableing interrupts failed"); | ||
753 | return -1; | ||
754 | } | ||
755 | /* Set FIFO_CONTROL_REGISTER to the default value */ | ||
756 | Data = 0x00; | ||
757 | status = set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); | ||
758 | if (status < 0) { | ||
759 | dbg("Writing FIFO_CONTROL_REGISTER failed"); | ||
760 | return -1; | ||
761 | } | ||
762 | |||
763 | Data = 0xcf; /* chk */ | ||
764 | status = set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); | ||
765 | if (status < 0) { | ||
766 | dbg("Writing FIFO_CONTROL_REGISTER failed"); | ||
767 | return -1; | ||
768 | } | ||
769 | |||
770 | Data = 0x03; /* LCR_BITS_8 */ | ||
771 | status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data); | ||
772 | ATEN2011_port->shadowLCR = Data; | ||
773 | |||
774 | Data = 0x0b; /* MCR_DTR|MCR_RTS|MCR_MASTER_IE */ | ||
775 | status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | ||
776 | ATEN2011_port->shadowMCR = Data; | ||
777 | |||
778 | #ifdef Check | ||
779 | Data = 0x00; | ||
780 | status = get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); | ||
781 | ATEN2011_port->shadowLCR = Data; | ||
782 | |||
783 | Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */ | ||
784 | status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data); | ||
785 | |||
786 | Data = 0x0c; | ||
787 | status = set_uart_reg(port, DIVISOR_LATCH_LSB, Data); | ||
788 | |||
789 | Data = 0x0; | ||
790 | status = set_uart_reg(port, DIVISOR_LATCH_MSB, Data); | ||
791 | |||
792 | Data = 0x00; | ||
793 | status = get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); | ||
794 | |||
795 | /* Data = ATEN2011_port->shadowLCR; */ /* data latch disable */ | ||
796 | Data = Data & ~SERIAL_LCR_DLAB; | ||
797 | status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data); | ||
798 | ATEN2011_port->shadowLCR = Data; | ||
799 | #endif | ||
800 | /* clearing Bulkin and Bulkout Fifo */ | ||
801 | Data = 0x0; | ||
802 | status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data); | ||
803 | |||
804 | Data = Data | 0x0c; | ||
805 | status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data); | ||
806 | |||
807 | Data = Data & ~0x0c; | ||
808 | status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data); | ||
809 | /* Finally enable all interrupts */ | ||
810 | Data = 0x0; | ||
811 | Data = 0x0c; | ||
812 | status = set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); | ||
813 | |||
814 | /* clearing rx_disable */ | ||
815 | Data = 0x0; | ||
816 | status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data); | ||
817 | Data = Data & ~0x20; | ||
818 | status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data); | ||
819 | |||
820 | /* rx_negate */ | ||
821 | Data = 0x0; | ||
822 | status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data); | ||
823 | Data = Data | 0x10; | ||
824 | status = 0; | ||
825 | status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data); | ||
826 | |||
827 | /* | ||
828 | * Check to see if we've set up our endpoint info yet | ||
829 | * (can't set it up in ATEN2011_startup as the structures | ||
830 | * were not set up at that time.) | ||
831 | */ | ||
832 | if (ATEN2011_serial->NoOfOpenPorts == 1) { | ||
833 | /* start the status polling here */ | ||
834 | ATEN2011_serial->status_polling_started = 1; | ||
835 | /* If not yet set, Set here */ | ||
836 | ATEN2011_serial->interrupt_in_buffer = | ||
837 | serial->port[0]->interrupt_in_buffer; | ||
838 | ATEN2011_serial->interrupt_in_endpoint = | ||
839 | serial->port[0]->interrupt_in_endpointAddress; | ||
840 | ATEN2011_serial->interrupt_read_urb = | ||
841 | serial->port[0]->interrupt_in_urb; | ||
842 | |||
843 | /* set up interrupt urb */ | ||
844 | usb_fill_int_urb(ATEN2011_serial->interrupt_read_urb, | ||
845 | serial->dev, | ||
846 | usb_rcvintpipe(serial->dev, | ||
847 | ATEN2011_serial-> | ||
848 | interrupt_in_endpoint), | ||
849 | ATEN2011_serial->interrupt_in_buffer, | ||
850 | ATEN2011_serial->interrupt_read_urb-> | ||
851 | transfer_buffer_length, | ||
852 | ATEN2011_interrupt_callback, ATEN2011_serial, | ||
853 | ATEN2011_serial->interrupt_read_urb->interval); | ||
854 | |||
855 | /* start interrupt read for ATEN2011 * | ||
856 | * will continue as long as ATEN2011 is connected */ | ||
857 | |||
858 | response = | ||
859 | usb_submit_urb(ATEN2011_serial->interrupt_read_urb, | ||
860 | GFP_KERNEL); | ||
861 | if (response) { | ||
862 | dbg("%s - Error %d submitting interrupt urb", | ||
863 | __func__, response); | ||
864 | } | ||
865 | |||
866 | } | ||
867 | |||
868 | /* | ||
869 | * See if we've set up our endpoint info yet | ||
870 | * (can't set it up in ATEN2011_startup as the | ||
871 | * structures were not set up at that time.) | ||
872 | */ | ||
873 | |||
874 | dbg("port number is %d", port->number); | ||
875 | dbg("serial number is %d", port->serial->minor); | ||
876 | dbg("Bulkin endpoint is %d", port->bulk_in_endpointAddress); | ||
877 | dbg("BulkOut endpoint is %d", port->bulk_out_endpointAddress); | ||
878 | dbg("Interrupt endpoint is %d", | ||
879 | port->interrupt_in_endpointAddress); | ||
880 | dbg("port's number in the device is %d", ATEN2011_port->port_num); | ||
881 | ATEN2011_port->bulk_in_buffer = port->bulk_in_buffer; | ||
882 | ATEN2011_port->bulk_in_endpoint = port->bulk_in_endpointAddress; | ||
883 | ATEN2011_port->read_urb = port->read_urb; | ||
884 | ATEN2011_port->bulk_out_endpoint = port->bulk_out_endpointAddress; | ||
885 | |||
886 | minor = port->serial->minor; | ||
887 | if (minor == SERIAL_TTY_NO_MINOR) | ||
888 | minor = 0; | ||
889 | |||
890 | /* set up our bulk in urb */ | ||
891 | if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2) | ||
892 | && (((__u16) port->number - (__u16) (minor)) != 0)) { | ||
893 | usb_fill_bulk_urb(ATEN2011_port->read_urb, serial->dev, | ||
894 | usb_rcvbulkpipe(serial->dev, | ||
895 | (port-> | ||
896 | bulk_in_endpointAddress + | ||
897 | 2)), port->bulk_in_buffer, | ||
898 | ATEN2011_port->read_urb-> | ||
899 | transfer_buffer_length, | ||
900 | ATEN2011_bulk_in_callback, ATEN2011_port); | ||
901 | } else | ||
902 | usb_fill_bulk_urb(ATEN2011_port->read_urb, | ||
903 | serial->dev, | ||
904 | usb_rcvbulkpipe(serial->dev, | ||
905 | port-> | ||
906 | bulk_in_endpointAddress), | ||
907 | port->bulk_in_buffer, | ||
908 | ATEN2011_port->read_urb-> | ||
909 | transfer_buffer_length, | ||
910 | ATEN2011_bulk_in_callback, ATEN2011_port); | ||
911 | |||
912 | dbg("ATEN2011_open: bulkin endpoint is %d", | ||
913 | port->bulk_in_endpointAddress); | ||
914 | response = usb_submit_urb(ATEN2011_port->read_urb, GFP_KERNEL); | ||
915 | if (response) { | ||
916 | err("%s - Error %d submitting control urb", __func__, | ||
917 | response); | ||
918 | } | ||
919 | |||
920 | /* initialize our wait queues */ | ||
921 | init_waitqueue_head(&ATEN2011_port->wait_chase); | ||
922 | init_waitqueue_head(&ATEN2011_port->wait_command); | ||
923 | |||
924 | /* initialize our icount structure */ | ||
925 | memset(&(ATEN2011_port->icount), 0x00, sizeof(ATEN2011_port->icount)); | ||
926 | |||
927 | /* initialize our port settings */ | ||
928 | ATEN2011_port->shadowMCR = MCR_MASTER_IE; /* Must set to enable ints! */ | ||
929 | ATEN2011_port->chaseResponsePending = 0; | ||
930 | /* send a open port command */ | ||
931 | ATEN2011_port->open = 1; | ||
932 | /* ATEN2011_change_port_settings(ATEN2011_port,old_termios); */ | ||
933 | /* Setup termios */ | ||
934 | ATEN2011_set_termios(tty, port, &tmp_termios); | ||
935 | ATEN2011_port->icount.tx = 0; | ||
936 | ATEN2011_port->icount.rx = 0; | ||
937 | |||
938 | dbg("usb_serial serial:%x ATEN2011_port:%x\nATEN2011_serial:%x usb_serial_port port:%x", | ||
939 | (unsigned int)serial, (unsigned int)ATEN2011_port, | ||
940 | (unsigned int)ATEN2011_serial, (unsigned int)port); | ||
941 | |||
942 | return 0; | ||
943 | |||
944 | } | ||
945 | |||
946 | static int ATEN2011_chars_in_buffer(struct tty_struct *tty) | ||
947 | { | ||
948 | struct usb_serial_port *port = tty->driver_data; | ||
949 | int i; | ||
950 | int chars = 0; | ||
951 | struct ATENINTL_port *ATEN2011_port; | ||
952 | |||
953 | /* dbg("%s"," ATEN2011_chars_in_buffer:entering ..........."); */ | ||
954 | |||
955 | ATEN2011_port = usb_get_serial_port_data(port); | ||
956 | if (ATEN2011_port == NULL) { | ||
957 | dbg("%s", "ATEN2011_break:leaving ..........."); | ||
958 | return -1; | ||
959 | } | ||
960 | |||
961 | for (i = 0; i < NUM_URBS; ++i) | ||
962 | if (ATEN2011_port->write_urb_pool[i]->status == -EINPROGRESS) | ||
963 | chars += URB_TRANSFER_BUFFER_SIZE; | ||
964 | |||
965 | dbg("%s - returns %d", __func__, chars); | ||
966 | return chars; | ||
967 | |||
968 | } | ||
969 | |||
970 | static void ATEN2011_block_until_tx_empty(struct tty_struct *tty, | ||
971 | struct ATENINTL_port *ATEN2011_port) | ||
972 | { | ||
973 | int timeout = HZ / 10; | ||
974 | int wait = 30; | ||
975 | int count; | ||
976 | |||
977 | while (1) { | ||
978 | count = ATEN2011_chars_in_buffer(tty); | ||
979 | |||
980 | /* Check for Buffer status */ | ||
981 | if (count <= 0) | ||
982 | return; | ||
983 | |||
984 | /* Block the thread for a while */ | ||
985 | interruptible_sleep_on_timeout(&ATEN2011_port->wait_chase, | ||
986 | timeout); | ||
987 | |||
988 | /* No activity.. count down section */ | ||
989 | wait--; | ||
990 | if (wait == 0) { | ||
991 | dbg("%s - TIMEOUT", __func__); | ||
992 | return; | ||
993 | } else { | ||
994 | /* Reset timout value back to seconds */ | ||
995 | wait = 30; | ||
996 | } | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | static void ATEN2011_close(struct tty_struct *tty, struct usb_serial_port *port, | ||
1001 | struct file *filp) | ||
1002 | { | ||
1003 | struct usb_serial *serial; | ||
1004 | struct ATENINTL_serial *ATEN2011_serial; | ||
1005 | struct ATENINTL_port *ATEN2011_port; | ||
1006 | int no_urbs; | ||
1007 | __u16 Data; | ||
1008 | |||
1009 | dbg("%s", "ATEN2011_close:entering..."); | ||
1010 | serial = port->serial; | ||
1011 | |||
1012 | /* take the Adpater and port's private data */ | ||
1013 | ATEN2011_serial = usb_get_serial_data(serial); | ||
1014 | ATEN2011_port = usb_get_serial_port_data(port); | ||
1015 | if ((ATEN2011_serial == NULL) || (ATEN2011_port == NULL)) | ||
1016 | return; | ||
1017 | |||
1018 | if (serial->dev) { | ||
1019 | /* flush and block(wait) until tx is empty */ | ||
1020 | ATEN2011_block_until_tx_empty(tty, ATEN2011_port); | ||
1021 | } | ||
1022 | /* kill the ports URB's */ | ||
1023 | for (no_urbs = 0; no_urbs < NUM_URBS; no_urbs++) | ||
1024 | usb_kill_urb(ATEN2011_port->write_urb_pool[no_urbs]); | ||
1025 | /* Freeing Write URBs */ | ||
1026 | for (no_urbs = 0; no_urbs < NUM_URBS; ++no_urbs) { | ||
1027 | kfree(ATEN2011_port->write_urb_pool[no_urbs]->transfer_buffer); | ||
1028 | usb_free_urb(ATEN2011_port->write_urb_pool[no_urbs]); | ||
1029 | } | ||
1030 | /* While closing port, shutdown all bulk read, write * | ||
1031 | * and interrupt read if they exists */ | ||
1032 | if (serial->dev) { | ||
1033 | if (ATEN2011_port->write_urb) { | ||
1034 | dbg("%s", "Shutdown bulk write"); | ||
1035 | usb_kill_urb(ATEN2011_port->write_urb); | ||
1036 | } | ||
1037 | if (ATEN2011_port->read_urb) { | ||
1038 | dbg("%s", "Shutdown bulk read"); | ||
1039 | usb_kill_urb(ATEN2011_port->read_urb); | ||
1040 | } | ||
1041 | if ((&ATEN2011_port->control_urb)) { | ||
1042 | dbg("%s", "Shutdown control read"); | ||
1043 | /* usb_kill_urb (ATEN2011_port->control_urb); */ | ||
1044 | |||
1045 | } | ||
1046 | } | ||
1047 | /* if(ATEN2011_port->ctrl_buf != NULL) */ | ||
1048 | /* kfree(ATEN2011_port->ctrl_buf); */ | ||
1049 | /* decrement the no.of open ports counter of an individual USB-serial adapter. */ | ||
1050 | ATEN2011_serial->NoOfOpenPorts--; | ||
1051 | dbg("NoOfOpenPorts in close%d:in port%d", | ||
1052 | ATEN2011_serial->NoOfOpenPorts, port->number); | ||
1053 | if (ATEN2011_serial->NoOfOpenPorts == 0) { | ||
1054 | /* stop the stus polling here */ | ||
1055 | ATEN2011_serial->status_polling_started = 0; | ||
1056 | if (ATEN2011_serial->interrupt_read_urb) { | ||
1057 | dbg("%s", "Shutdown interrupt_read_urb"); | ||
1058 | /* ATEN2011_serial->interrupt_in_buffer=NULL; */ | ||
1059 | /* usb_kill_urb (ATEN2011_serial->interrupt_read_urb); */ | ||
1060 | } | ||
1061 | } | ||
1062 | if (ATEN2011_port->write_urb) { | ||
1063 | /* if this urb had a transfer buffer already (old tx) free it */ | ||
1064 | kfree(ATEN2011_port->write_urb->transfer_buffer); | ||
1065 | usb_free_urb(ATEN2011_port->write_urb); | ||
1066 | } | ||
1067 | |||
1068 | /* clear the MCR & IER */ | ||
1069 | Data = 0x00; | ||
1070 | set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | ||
1071 | Data = 0x00; | ||
1072 | set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); | ||
1073 | |||
1074 | ATEN2011_port->open = 0; | ||
1075 | dbg("%s", "Leaving ............"); | ||
1076 | |||
1077 | } | ||
1078 | |||
1079 | static void ATEN2011_block_until_chase_response(struct tty_struct *tty, | ||
1080 | struct ATENINTL_port | ||
1081 | *ATEN2011_port) | ||
1082 | { | ||
1083 | int timeout = 1 * HZ; | ||
1084 | int wait = 10; | ||
1085 | int count; | ||
1086 | |||
1087 | while (1) { | ||
1088 | count = ATEN2011_chars_in_buffer(tty); | ||
1089 | |||
1090 | /* Check for Buffer status */ | ||
1091 | if (count <= 0) { | ||
1092 | ATEN2011_port->chaseResponsePending = 0; | ||
1093 | return; | ||
1094 | } | ||
1095 | |||
1096 | /* Block the thread for a while */ | ||
1097 | interruptible_sleep_on_timeout(&ATEN2011_port->wait_chase, | ||
1098 | timeout); | ||
1099 | /* No activity.. count down section */ | ||
1100 | wait--; | ||
1101 | if (wait == 0) { | ||
1102 | dbg("%s - TIMEOUT", __func__); | ||
1103 | return; | ||
1104 | } else { | ||
1105 | /* Reset timout value back to seconds */ | ||
1106 | wait = 10; | ||
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | } | ||
1111 | |||
1112 | static void ATEN2011_break(struct tty_struct *tty, int break_state) | ||
1113 | { | ||
1114 | struct usb_serial_port *port = tty->driver_data; | ||
1115 | unsigned char data; | ||
1116 | struct usb_serial *serial; | ||
1117 | struct ATENINTL_serial *ATEN2011_serial; | ||
1118 | struct ATENINTL_port *ATEN2011_port; | ||
1119 | |||
1120 | dbg("%s", "Entering ..........."); | ||
1121 | dbg("ATEN2011_break: Start"); | ||
1122 | |||
1123 | serial = port->serial; | ||
1124 | |||
1125 | ATEN2011_serial = usb_get_serial_data(serial); | ||
1126 | ATEN2011_port = usb_get_serial_port_data(port); | ||
1127 | |||
1128 | if ((ATEN2011_serial == NULL) || (ATEN2011_port == NULL)) | ||
1129 | return; | ||
1130 | |||
1131 | /* flush and chase */ | ||
1132 | ATEN2011_port->chaseResponsePending = 1; | ||
1133 | |||
1134 | if (serial->dev) { | ||
1135 | /* flush and block until tx is empty */ | ||
1136 | ATEN2011_block_until_chase_response(tty, ATEN2011_port); | ||
1137 | } | ||
1138 | |||
1139 | if (break_state == -1) | ||
1140 | data = ATEN2011_port->shadowLCR | LCR_SET_BREAK; | ||
1141 | else | ||
1142 | data = ATEN2011_port->shadowLCR & ~LCR_SET_BREAK; | ||
1143 | |||
1144 | ATEN2011_port->shadowLCR = data; | ||
1145 | dbg("ATEN2011_break ATEN2011_port->shadowLCR is %x", | ||
1146 | ATEN2011_port->shadowLCR); | ||
1147 | set_uart_reg(port, LINE_CONTROL_REGISTER, ATEN2011_port->shadowLCR); | ||
1148 | |||
1149 | return; | ||
1150 | } | ||
1151 | |||
1152 | static int ATEN2011_write_room(struct tty_struct *tty) | ||
1153 | { | ||
1154 | struct usb_serial_port *port = tty->driver_data; | ||
1155 | int i; | ||
1156 | int room = 0; | ||
1157 | struct ATENINTL_port *ATEN2011_port; | ||
1158 | |||
1159 | ATEN2011_port = usb_get_serial_port_data(port); | ||
1160 | if (ATEN2011_port == NULL) { | ||
1161 | dbg("%s", "ATEN2011_break:leaving ..........."); | ||
1162 | return -1; | ||
1163 | } | ||
1164 | |||
1165 | for (i = 0; i < NUM_URBS; ++i) | ||
1166 | if (ATEN2011_port->write_urb_pool[i]->status != -EINPROGRESS) | ||
1167 | room += URB_TRANSFER_BUFFER_SIZE; | ||
1168 | |||
1169 | dbg("%s - returns %d", __func__, room); | ||
1170 | return room; | ||
1171 | |||
1172 | } | ||
1173 | |||
1174 | static int ATEN2011_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
1175 | const unsigned char *data, int count) | ||
1176 | { | ||
1177 | int status; | ||
1178 | int i; | ||
1179 | int bytes_sent = 0; | ||
1180 | int transfer_size; | ||
1181 | int minor; | ||
1182 | |||
1183 | struct ATENINTL_port *ATEN2011_port; | ||
1184 | struct usb_serial *serial; | ||
1185 | struct ATENINTL_serial *ATEN2011_serial; | ||
1186 | struct urb *urb; | ||
1187 | const unsigned char *current_position = data; | ||
1188 | unsigned char *data1; | ||
1189 | dbg("%s", "entering ..........."); | ||
1190 | |||
1191 | serial = port->serial; | ||
1192 | |||
1193 | ATEN2011_port = usb_get_serial_port_data(port); | ||
1194 | if (ATEN2011_port == NULL) { | ||
1195 | dbg("%s", "ATEN2011_port is NULL"); | ||
1196 | return -1; | ||
1197 | } | ||
1198 | |||
1199 | ATEN2011_serial = usb_get_serial_data(serial); | ||
1200 | if (ATEN2011_serial == NULL) { | ||
1201 | dbg("%s", "ATEN2011_serial is NULL"); | ||
1202 | return -1; | ||
1203 | } | ||
1204 | |||
1205 | /* try to find a free urb in the list */ | ||
1206 | urb = NULL; | ||
1207 | |||
1208 | for (i = 0; i < NUM_URBS; ++i) { | ||
1209 | if (ATEN2011_port->write_urb_pool[i]->status != -EINPROGRESS) { | ||
1210 | urb = ATEN2011_port->write_urb_pool[i]; | ||
1211 | dbg("URB:%d", i); | ||
1212 | break; | ||
1213 | } | ||
1214 | } | ||
1215 | |||
1216 | if (urb == NULL) { | ||
1217 | dbg("%s - no more free urbs", __func__); | ||
1218 | goto exit; | ||
1219 | } | ||
1220 | |||
1221 | if (urb->transfer_buffer == NULL) { | ||
1222 | urb->transfer_buffer = | ||
1223 | kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); | ||
1224 | |||
1225 | if (urb->transfer_buffer == NULL) { | ||
1226 | err("%s no more kernel memory...", __func__); | ||
1227 | goto exit; | ||
1228 | } | ||
1229 | } | ||
1230 | transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE); | ||
1231 | |||
1232 | memcpy(urb->transfer_buffer, current_position, transfer_size); | ||
1233 | /* usb_serial_debug_data (__FILE__, __func__, transfer_size, urb->transfer_buffer); */ | ||
1234 | |||
1235 | /* fill urb with data and submit */ | ||
1236 | minor = port->serial->minor; | ||
1237 | if (minor == SERIAL_TTY_NO_MINOR) | ||
1238 | minor = 0; | ||
1239 | if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2) | ||
1240 | && (((__u16) port->number - (__u16) (minor)) != 0)) { | ||
1241 | usb_fill_bulk_urb(urb, ATEN2011_serial->serial->dev, | ||
1242 | usb_sndbulkpipe(ATEN2011_serial->serial->dev, | ||
1243 | (port-> | ||
1244 | bulk_out_endpointAddress) + | ||
1245 | 2), urb->transfer_buffer, | ||
1246 | transfer_size, | ||
1247 | ATEN2011_bulk_out_data_callback, | ||
1248 | ATEN2011_port); | ||
1249 | } else | ||
1250 | |||
1251 | usb_fill_bulk_urb(urb, | ||
1252 | ATEN2011_serial->serial->dev, | ||
1253 | usb_sndbulkpipe(ATEN2011_serial->serial->dev, | ||
1254 | port-> | ||
1255 | bulk_out_endpointAddress), | ||
1256 | urb->transfer_buffer, transfer_size, | ||
1257 | ATEN2011_bulk_out_data_callback, | ||
1258 | ATEN2011_port); | ||
1259 | |||
1260 | data1 = urb->transfer_buffer; | ||
1261 | dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress); | ||
1262 | /* for(i=0;i < urb->actual_length;i++) */ | ||
1263 | /* dbg("Data is %c ",data1[i]); */ | ||
1264 | |||
1265 | /* send it down the pipe */ | ||
1266 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
1267 | |||
1268 | if (status) { | ||
1269 | err("%s - usb_submit_urb(write bulk) failed with status = %d", | ||
1270 | __func__, status); | ||
1271 | bytes_sent = status; | ||
1272 | goto exit; | ||
1273 | } | ||
1274 | bytes_sent = transfer_size; | ||
1275 | ATEN2011_port->icount.tx += transfer_size; | ||
1276 | dbg("ATEN2011_port->icount.tx is %d:", ATEN2011_port->icount.tx); | ||
1277 | |||
1278 | exit: | ||
1279 | return bytes_sent; | ||
1280 | } | ||
1281 | |||
1282 | static void ATEN2011_throttle(struct tty_struct *tty) | ||
1283 | { | ||
1284 | struct usb_serial_port *port = tty->driver_data; | ||
1285 | struct ATENINTL_port *ATEN2011_port; | ||
1286 | int status; | ||
1287 | |||
1288 | dbg("- port %d", port->number); | ||
1289 | |||
1290 | ATEN2011_port = usb_get_serial_port_data(port); | ||
1291 | |||
1292 | if (ATEN2011_port == NULL) | ||
1293 | return; | ||
1294 | |||
1295 | if (!ATEN2011_port->open) { | ||
1296 | dbg("%s", "port not opened"); | ||
1297 | return; | ||
1298 | } | ||
1299 | |||
1300 | dbg("%s", "Entering .......... "); | ||
1301 | |||
1302 | if (!tty) { | ||
1303 | dbg("%s - no tty available", __func__); | ||
1304 | return; | ||
1305 | } | ||
1306 | |||
1307 | /* if we are implementing XON/XOFF, send the stop character */ | ||
1308 | if (I_IXOFF(tty)) { | ||
1309 | unsigned char stop_char = STOP_CHAR(tty); | ||
1310 | status = ATEN2011_write(tty, port, &stop_char, 1); | ||
1311 | if (status <= 0) | ||
1312 | return; | ||
1313 | } | ||
1314 | |||
1315 | /* if we are implementing RTS/CTS, toggle that line */ | ||
1316 | if (tty->termios->c_cflag & CRTSCTS) { | ||
1317 | ATEN2011_port->shadowMCR &= ~MCR_RTS; | ||
1318 | status = set_uart_reg(port, MODEM_CONTROL_REGISTER, | ||
1319 | ATEN2011_port->shadowMCR); | ||
1320 | if (status < 0) | ||
1321 | return; | ||
1322 | } | ||
1323 | |||
1324 | return; | ||
1325 | } | ||
1326 | |||
1327 | static void ATEN2011_unthrottle(struct tty_struct *tty) | ||
1328 | { | ||
1329 | struct usb_serial_port *port = tty->driver_data; | ||
1330 | int status; | ||
1331 | struct ATENINTL_port *ATEN2011_port = usb_get_serial_port_data(port); | ||
1332 | |||
1333 | if (ATEN2011_port == NULL) | ||
1334 | return; | ||
1335 | |||
1336 | if (!ATEN2011_port->open) { | ||
1337 | dbg("%s - port not opened", __func__); | ||
1338 | return; | ||
1339 | } | ||
1340 | |||
1341 | dbg("%s", "Entering .......... "); | ||
1342 | |||
1343 | if (!tty) { | ||
1344 | dbg("%s - no tty available", __func__); | ||
1345 | return; | ||
1346 | } | ||
1347 | |||
1348 | /* if we are implementing XON/XOFF, send the start character */ | ||
1349 | if (I_IXOFF(tty)) { | ||
1350 | unsigned char start_char = START_CHAR(tty); | ||
1351 | status = ATEN2011_write(tty, port, &start_char, 1); | ||
1352 | if (status <= 0) | ||
1353 | return; | ||
1354 | } | ||
1355 | |||
1356 | /* if we are implementing RTS/CTS, toggle that line */ | ||
1357 | if (tty->termios->c_cflag & CRTSCTS) { | ||
1358 | ATEN2011_port->shadowMCR |= MCR_RTS; | ||
1359 | status = set_uart_reg(port, MODEM_CONTROL_REGISTER, | ||
1360 | ATEN2011_port->shadowMCR); | ||
1361 | if (status < 0) | ||
1362 | return; | ||
1363 | } | ||
1364 | |||
1365 | return; | ||
1366 | } | ||
1367 | |||
1368 | static int ATEN2011_tiocmget(struct tty_struct *tty, struct file *file) | ||
1369 | { | ||
1370 | struct usb_serial_port *port = tty->driver_data; | ||
1371 | struct ATENINTL_port *ATEN2011_port; | ||
1372 | unsigned int result; | ||
1373 | __u16 msr; | ||
1374 | __u16 mcr; | ||
1375 | /* unsigned int mcr; */ | ||
1376 | int status = 0; | ||
1377 | ATEN2011_port = usb_get_serial_port_data(port); | ||
1378 | |||
1379 | dbg("%s - port %d", __func__, port->number); | ||
1380 | |||
1381 | if (ATEN2011_port == NULL) | ||
1382 | return -ENODEV; | ||
1383 | |||
1384 | status = get_uart_reg(port, MODEM_STATUS_REGISTER, &msr); | ||
1385 | status = get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr); | ||
1386 | /* mcr = ATEN2011_port->shadowMCR; */ | ||
1387 | /* COMMENT2: the Fallowing three line are commented for updating only MSR values */ | ||
1388 | result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) | ||
1389 | | ((mcr & MCR_RTS) ? TIOCM_RTS : 0) | ||
1390 | | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0) | ||
1391 | | ((msr & ATEN2011_MSR_CTS) ? TIOCM_CTS : 0) | ||
1392 | | ((msr & ATEN2011_MSR_CD) ? TIOCM_CAR : 0) | ||
1393 | | ((msr & ATEN2011_MSR_RI) ? TIOCM_RI : 0) | ||
1394 | | ((msr & ATEN2011_MSR_DSR) ? TIOCM_DSR : 0); | ||
1395 | |||
1396 | dbg("%s - 0x%04X", __func__, result); | ||
1397 | |||
1398 | return result; | ||
1399 | } | ||
1400 | |||
1401 | static int ATEN2011_tiocmset(struct tty_struct *tty, struct file *file, | ||
1402 | unsigned int set, unsigned int clear) | ||
1403 | { | ||
1404 | struct usb_serial_port *port = tty->driver_data; | ||
1405 | struct ATENINTL_port *ATEN2011_port; | ||
1406 | unsigned int mcr; | ||
1407 | unsigned int status; | ||
1408 | |||
1409 | dbg("%s - port %d", __func__, port->number); | ||
1410 | |||
1411 | ATEN2011_port = usb_get_serial_port_data(port); | ||
1412 | |||
1413 | if (ATEN2011_port == NULL) | ||
1414 | return -ENODEV; | ||
1415 | |||
1416 | mcr = ATEN2011_port->shadowMCR; | ||
1417 | if (clear & TIOCM_RTS) | ||
1418 | mcr &= ~MCR_RTS; | ||
1419 | if (clear & TIOCM_DTR) | ||
1420 | mcr &= ~MCR_DTR; | ||
1421 | if (clear & TIOCM_LOOP) | ||
1422 | mcr &= ~MCR_LOOPBACK; | ||
1423 | |||
1424 | if (set & TIOCM_RTS) | ||
1425 | mcr |= MCR_RTS; | ||
1426 | if (set & TIOCM_DTR) | ||
1427 | mcr |= MCR_DTR; | ||
1428 | if (set & TIOCM_LOOP) | ||
1429 | mcr |= MCR_LOOPBACK; | ||
1430 | |||
1431 | ATEN2011_port->shadowMCR = mcr; | ||
1432 | |||
1433 | status = set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr); | ||
1434 | if (status < 0) { | ||
1435 | dbg("setting MODEM_CONTROL_REGISTER Failed"); | ||
1436 | return -1; | ||
1437 | } | ||
1438 | |||
1439 | return 0; | ||
1440 | } | ||
1441 | |||
1442 | static void ATEN2011_set_termios(struct tty_struct *tty, | ||
1443 | struct usb_serial_port *port, | ||
1444 | struct ktermios *old_termios) | ||
1445 | { | ||
1446 | int status; | ||
1447 | unsigned int cflag; | ||
1448 | struct usb_serial *serial; | ||
1449 | struct ATENINTL_port *ATEN2011_port; | ||
1450 | |||
1451 | dbg("ATEN2011_set_termios: START"); | ||
1452 | |||
1453 | serial = port->serial; | ||
1454 | |||
1455 | ATEN2011_port = usb_get_serial_port_data(port); | ||
1456 | |||
1457 | if (ATEN2011_port == NULL) | ||
1458 | return; | ||
1459 | |||
1460 | if (!ATEN2011_port->open) { | ||
1461 | dbg("%s - port not opened", __func__); | ||
1462 | return; | ||
1463 | } | ||
1464 | |||
1465 | dbg("%s", "setting termios - "); | ||
1466 | |||
1467 | cflag = tty->termios->c_cflag; | ||
1468 | |||
1469 | dbg("%s - cflag %08x iflag %08x", __func__, | ||
1470 | tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); | ||
1471 | |||
1472 | if (old_termios) { | ||
1473 | dbg("%s - old clfag %08x old iflag %08x", __func__, | ||
1474 | old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); | ||
1475 | } | ||
1476 | |||
1477 | dbg("%s - port %d", __func__, port->number); | ||
1478 | |||
1479 | /* change the port settings to the new ones specified */ | ||
1480 | |||
1481 | ATEN2011_change_port_settings(tty, ATEN2011_port, old_termios); | ||
1482 | |||
1483 | if (!ATEN2011_port->read_urb) { | ||
1484 | dbg("%s", "URB KILLED !!!!!"); | ||
1485 | return; | ||
1486 | } | ||
1487 | |||
1488 | if (ATEN2011_port->read_urb->status != -EINPROGRESS) { | ||
1489 | ATEN2011_port->read_urb->dev = serial->dev; | ||
1490 | status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC); | ||
1491 | if (status) { | ||
1492 | dbg | ||
1493 | (" usb_submit_urb(read bulk) failed, status = %d", | ||
1494 | status); | ||
1495 | } | ||
1496 | } | ||
1497 | return; | ||
1498 | } | ||
1499 | |||
1500 | static int get_lsr_info(struct tty_struct *tty, | ||
1501 | struct ATENINTL_port *ATEN2011_port, | ||
1502 | unsigned int __user *value) | ||
1503 | { | ||
1504 | int count; | ||
1505 | unsigned int result = 0; | ||
1506 | |||
1507 | count = ATEN2011_chars_in_buffer(tty); | ||
1508 | if (count == 0) { | ||
1509 | dbg("%s -- Empty", __func__); | ||
1510 | result = TIOCSER_TEMT; | ||
1511 | } | ||
1512 | |||
1513 | if (copy_to_user(value, &result, sizeof(int))) | ||
1514 | return -EFAULT; | ||
1515 | return 0; | ||
1516 | } | ||
1517 | |||
1518 | static int get_number_bytes_avail(struct tty_struct *tty, | ||
1519 | struct ATENINTL_port *ATEN2011_port, | ||
1520 | unsigned int __user *value) | ||
1521 | { | ||
1522 | unsigned int result = 0; | ||
1523 | |||
1524 | if (!tty) | ||
1525 | return -ENOIOCTLCMD; | ||
1526 | |||
1527 | result = tty->read_cnt; | ||
1528 | |||
1529 | dbg("%s(%d) = %d", __func__, ATEN2011_port->port->number, result); | ||
1530 | if (copy_to_user(value, &result, sizeof(int))) | ||
1531 | return -EFAULT; | ||
1532 | |||
1533 | return -ENOIOCTLCMD; | ||
1534 | } | ||
1535 | |||
1536 | static int set_modem_info(struct ATENINTL_port *ATEN2011_port, unsigned int cmd, | ||
1537 | unsigned int __user *value) | ||
1538 | { | ||
1539 | unsigned int mcr; | ||
1540 | unsigned int arg; | ||
1541 | __u16 Data; | ||
1542 | int status; | ||
1543 | struct usb_serial_port *port; | ||
1544 | |||
1545 | if (ATEN2011_port == NULL) | ||
1546 | return -1; | ||
1547 | |||
1548 | port = (struct usb_serial_port *)ATEN2011_port->port; | ||
1549 | |||
1550 | mcr = ATEN2011_port->shadowMCR; | ||
1551 | |||
1552 | if (copy_from_user(&arg, value, sizeof(int))) | ||
1553 | return -EFAULT; | ||
1554 | |||
1555 | switch (cmd) { | ||
1556 | case TIOCMBIS: | ||
1557 | if (arg & TIOCM_RTS) | ||
1558 | mcr |= MCR_RTS; | ||
1559 | if (arg & TIOCM_DTR) | ||
1560 | mcr |= MCR_RTS; | ||
1561 | if (arg & TIOCM_LOOP) | ||
1562 | mcr |= MCR_LOOPBACK; | ||
1563 | break; | ||
1564 | |||
1565 | case TIOCMBIC: | ||
1566 | if (arg & TIOCM_RTS) | ||
1567 | mcr &= ~MCR_RTS; | ||
1568 | if (arg & TIOCM_DTR) | ||
1569 | mcr &= ~MCR_RTS; | ||
1570 | if (arg & TIOCM_LOOP) | ||
1571 | mcr &= ~MCR_LOOPBACK; | ||
1572 | break; | ||
1573 | |||
1574 | case TIOCMSET: | ||
1575 | /* turn off the RTS and DTR and LOOPBACK | ||
1576 | * and then only turn on what was asked to */ | ||
1577 | mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK); | ||
1578 | mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0); | ||
1579 | mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0); | ||
1580 | mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0); | ||
1581 | break; | ||
1582 | } | ||
1583 | |||
1584 | ATEN2011_port->shadowMCR = mcr; | ||
1585 | |||
1586 | Data = ATEN2011_port->shadowMCR; | ||
1587 | status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | ||
1588 | if (status < 0) { | ||
1589 | dbg("setting MODEM_CONTROL_REGISTER Failed"); | ||
1590 | return -1; | ||
1591 | } | ||
1592 | |||
1593 | return 0; | ||
1594 | } | ||
1595 | |||
1596 | static int get_modem_info(struct ATENINTL_port *ATEN2011_port, | ||
1597 | unsigned int __user *value) | ||
1598 | { | ||
1599 | unsigned int result = 0; | ||
1600 | __u16 msr; | ||
1601 | unsigned int mcr = ATEN2011_port->shadowMCR; | ||
1602 | int status; | ||
1603 | |||
1604 | status = get_uart_reg(ATEN2011_port->port, MODEM_STATUS_REGISTER, &msr); | ||
1605 | result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) /* 0x002 */ | ||
1606 | |((mcr & MCR_RTS) ? TIOCM_RTS : 0) /* 0x004 */ | ||
1607 | |((msr & ATEN2011_MSR_CTS) ? TIOCM_CTS : 0) /* 0x020 */ | ||
1608 | |((msr & ATEN2011_MSR_CD) ? TIOCM_CAR : 0) /* 0x040 */ | ||
1609 | |((msr & ATEN2011_MSR_RI) ? TIOCM_RI : 0) /* 0x080 */ | ||
1610 | |((msr & ATEN2011_MSR_DSR) ? TIOCM_DSR : 0); /* 0x100 */ | ||
1611 | |||
1612 | dbg("%s -- %x", __func__, result); | ||
1613 | |||
1614 | if (copy_to_user(value, &result, sizeof(int))) | ||
1615 | return -EFAULT; | ||
1616 | return 0; | ||
1617 | } | ||
1618 | |||
1619 | static int get_serial_info(struct ATENINTL_port *ATEN2011_port, | ||
1620 | struct serial_struct __user *retinfo) | ||
1621 | { | ||
1622 | struct serial_struct tmp; | ||
1623 | |||
1624 | if (ATEN2011_port == NULL) | ||
1625 | return -1; | ||
1626 | |||
1627 | if (!retinfo) | ||
1628 | return -EFAULT; | ||
1629 | |||
1630 | memset(&tmp, 0, sizeof(tmp)); | ||
1631 | |||
1632 | tmp.type = PORT_16550A; | ||
1633 | tmp.line = ATEN2011_port->port->serial->minor; | ||
1634 | if (tmp.line == SERIAL_TTY_NO_MINOR) | ||
1635 | tmp.line = 0; | ||
1636 | tmp.port = ATEN2011_port->port->number; | ||
1637 | tmp.irq = 0; | ||
1638 | tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; | ||
1639 | tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; | ||
1640 | tmp.baud_base = 9600; | ||
1641 | tmp.close_delay = 5 * HZ; | ||
1642 | tmp.closing_wait = 30 * HZ; | ||
1643 | |||
1644 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
1645 | return -EFAULT; | ||
1646 | return 0; | ||
1647 | } | ||
1648 | |||
1649 | static int ATEN2011_ioctl(struct tty_struct *tty, struct file *file, | ||
1650 | unsigned int cmd, unsigned long arg) | ||
1651 | { | ||
1652 | struct usb_serial_port *port = tty->driver_data; | ||
1653 | struct ATENINTL_port *ATEN2011_port; | ||
1654 | struct async_icount cnow; | ||
1655 | struct async_icount cprev; | ||
1656 | struct serial_icounter_struct icount; | ||
1657 | int ATENret = 0; | ||
1658 | unsigned int __user *user_arg = (unsigned int __user *)arg; | ||
1659 | |||
1660 | ATEN2011_port = usb_get_serial_port_data(port); | ||
1661 | |||
1662 | if (ATEN2011_port == NULL) | ||
1663 | return -1; | ||
1664 | |||
1665 | dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); | ||
1666 | |||
1667 | switch (cmd) { | ||
1668 | /* return number of bytes available */ | ||
1669 | |||
1670 | case TIOCINQ: | ||
1671 | dbg("%s (%d) TIOCINQ", __func__, port->number); | ||
1672 | return get_number_bytes_avail(tty, ATEN2011_port, user_arg); | ||
1673 | break; | ||
1674 | |||
1675 | case TIOCOUTQ: | ||
1676 | dbg("%s (%d) TIOCOUTQ", __func__, port->number); | ||
1677 | return put_user(ATEN2011_chars_in_buffer(tty), user_arg); | ||
1678 | break; | ||
1679 | |||
1680 | case TIOCSERGETLSR: | ||
1681 | dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); | ||
1682 | return get_lsr_info(tty, ATEN2011_port, user_arg); | ||
1683 | return 0; | ||
1684 | |||
1685 | case TIOCMBIS: | ||
1686 | case TIOCMBIC: | ||
1687 | case TIOCMSET: | ||
1688 | dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__, | ||
1689 | port->number); | ||
1690 | ATENret = set_modem_info(ATEN2011_port, cmd, user_arg); | ||
1691 | return ATENret; | ||
1692 | |||
1693 | case TIOCMGET: | ||
1694 | dbg("%s (%d) TIOCMGET", __func__, port->number); | ||
1695 | return get_modem_info(ATEN2011_port, user_arg); | ||
1696 | |||
1697 | case TIOCGSERIAL: | ||
1698 | dbg("%s (%d) TIOCGSERIAL", __func__, port->number); | ||
1699 | return get_serial_info(ATEN2011_port, | ||
1700 | (struct serial_struct __user *)arg); | ||
1701 | |||
1702 | case TIOCSSERIAL: | ||
1703 | dbg("%s (%d) TIOCSSERIAL", __func__, port->number); | ||
1704 | break; | ||
1705 | |||
1706 | case TIOCMIWAIT: | ||
1707 | dbg("%s (%d) TIOCMIWAIT", __func__, port->number); | ||
1708 | cprev = ATEN2011_port->icount; | ||
1709 | while (1) { | ||
1710 | /* see if a signal did it */ | ||
1711 | if (signal_pending(current)) | ||
1712 | return -ERESTARTSYS; | ||
1713 | cnow = ATEN2011_port->icount; | ||
1714 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | ||
1715 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) | ||
1716 | return -EIO; /* no change => error */ | ||
1717 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || | ||
1718 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || | ||
1719 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || | ||
1720 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { | ||
1721 | return 0; | ||
1722 | } | ||
1723 | cprev = cnow; | ||
1724 | } | ||
1725 | /* NOTREACHED */ | ||
1726 | break; | ||
1727 | |||
1728 | case TIOCGICOUNT: | ||
1729 | cnow = ATEN2011_port->icount; | ||
1730 | icount.cts = cnow.cts; | ||
1731 | icount.dsr = cnow.dsr; | ||
1732 | icount.rng = cnow.rng; | ||
1733 | icount.dcd = cnow.dcd; | ||
1734 | icount.rx = cnow.rx; | ||
1735 | icount.tx = cnow.tx; | ||
1736 | icount.frame = cnow.frame; | ||
1737 | icount.overrun = cnow.overrun; | ||
1738 | icount.parity = cnow.parity; | ||
1739 | icount.brk = cnow.brk; | ||
1740 | icount.buf_overrun = cnow.buf_overrun; | ||
1741 | |||
1742 | dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, | ||
1743 | port->number, icount.rx, icount.tx); | ||
1744 | if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) | ||
1745 | return -EFAULT; | ||
1746 | return 0; | ||
1747 | |||
1748 | default: | ||
1749 | break; | ||
1750 | } | ||
1751 | |||
1752 | return -ENOIOCTLCMD; | ||
1753 | } | ||
1754 | |||
1755 | static int ATEN2011_calc_baud_rate_divisor(int baudRate, int *divisor, | ||
1756 | __u16 *clk_sel_val) | ||
1757 | { | ||
1758 | dbg("%s - %d", __func__, baudRate); | ||
1759 | |||
1760 | if (baudRate <= 115200) { | ||
1761 | *divisor = 115200 / baudRate; | ||
1762 | *clk_sel_val = 0x0; | ||
1763 | } | ||
1764 | if ((baudRate > 115200) && (baudRate <= 230400)) { | ||
1765 | *divisor = 230400 / baudRate; | ||
1766 | *clk_sel_val = 0x10; | ||
1767 | } else if ((baudRate > 230400) && (baudRate <= 403200)) { | ||
1768 | *divisor = 403200 / baudRate; | ||
1769 | *clk_sel_val = 0x20; | ||
1770 | } else if ((baudRate > 403200) && (baudRate <= 460800)) { | ||
1771 | *divisor = 460800 / baudRate; | ||
1772 | *clk_sel_val = 0x30; | ||
1773 | } else if ((baudRate > 460800) && (baudRate <= 806400)) { | ||
1774 | *divisor = 806400 / baudRate; | ||
1775 | *clk_sel_val = 0x40; | ||
1776 | } else if ((baudRate > 806400) && (baudRate <= 921600)) { | ||
1777 | *divisor = 921600 / baudRate; | ||
1778 | *clk_sel_val = 0x50; | ||
1779 | } else if ((baudRate > 921600) && (baudRate <= 1572864)) { | ||
1780 | *divisor = 1572864 / baudRate; | ||
1781 | *clk_sel_val = 0x60; | ||
1782 | } else if ((baudRate > 1572864) && (baudRate <= 3145728)) { | ||
1783 | *divisor = 3145728 / baudRate; | ||
1784 | *clk_sel_val = 0x70; | ||
1785 | } | ||
1786 | return 0; | ||
1787 | } | ||
1788 | |||
1789 | static int ATEN2011_send_cmd_write_baud_rate(struct ATENINTL_port | ||
1790 | *ATEN2011_port, int baudRate) | ||
1791 | { | ||
1792 | int divisor = 0; | ||
1793 | int status; | ||
1794 | __u16 Data; | ||
1795 | unsigned char number; | ||
1796 | __u16 clk_sel_val; | ||
1797 | struct usb_serial_port *port; | ||
1798 | int minor; | ||
1799 | |||
1800 | if (ATEN2011_port == NULL) | ||
1801 | return -1; | ||
1802 | |||
1803 | port = (struct usb_serial_port *)ATEN2011_port->port; | ||
1804 | |||
1805 | dbg("%s", "Entering .......... "); | ||
1806 | |||
1807 | minor = ATEN2011_port->port->serial->minor; | ||
1808 | if (minor == SERIAL_TTY_NO_MINOR) | ||
1809 | minor = 0; | ||
1810 | number = ATEN2011_port->port->number - minor; | ||
1811 | |||
1812 | dbg("%s - port = %d, baud = %d", __func__, | ||
1813 | ATEN2011_port->port->number, baudRate); | ||
1814 | /* reset clk_uart_sel in spregOffset */ | ||
1815 | if (baudRate > 115200) { | ||
1816 | #ifdef HW_flow_control | ||
1817 | /* | ||
1818 | * NOTE: need to see the pther register to modify | ||
1819 | * setting h/w flow control bit to 1; | ||
1820 | */ | ||
1821 | /* Data = ATEN2011_port->shadowMCR; */ | ||
1822 | Data = 0x2b; | ||
1823 | ATEN2011_port->shadowMCR = Data; | ||
1824 | status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | ||
1825 | if (status < 0) { | ||
1826 | dbg("Writing spreg failed in set_serial_baud"); | ||
1827 | return -1; | ||
1828 | } | ||
1829 | #endif | ||
1830 | |||
1831 | } else { | ||
1832 | #ifdef HW_flow_control | ||
1833 | /* setting h/w flow control bit to 0; */ | ||
1834 | /* Data = ATEN2011_port->shadowMCR; */ | ||
1835 | Data = 0xb; | ||
1836 | ATEN2011_port->shadowMCR = Data; | ||
1837 | status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | ||
1838 | if (status < 0) { | ||
1839 | dbg("Writing spreg failed in set_serial_baud"); | ||
1840 | return -1; | ||
1841 | } | ||
1842 | #endif | ||
1843 | |||
1844 | } | ||
1845 | |||
1846 | if (1) /* baudRate <= 115200) */ { | ||
1847 | clk_sel_val = 0x0; | ||
1848 | Data = 0x0; | ||
1849 | status = | ||
1850 | ATEN2011_calc_baud_rate_divisor(baudRate, &divisor, | ||
1851 | &clk_sel_val); | ||
1852 | status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data); | ||
1853 | if (status < 0) { | ||
1854 | dbg("reading spreg failed in set_serial_baud"); | ||
1855 | return -1; | ||
1856 | } | ||
1857 | Data = (Data & 0x8f) | clk_sel_val; | ||
1858 | status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data); | ||
1859 | if (status < 0) { | ||
1860 | dbg("Writing spreg failed in set_serial_baud"); | ||
1861 | return -1; | ||
1862 | } | ||
1863 | /* Calculate the Divisor */ | ||
1864 | |||
1865 | if (status) { | ||
1866 | err("%s - bad baud rate", __func__); | ||
1867 | dbg("%s", "bad baud rate"); | ||
1868 | return status; | ||
1869 | } | ||
1870 | /* Enable access to divisor latch */ | ||
1871 | Data = ATEN2011_port->shadowLCR | SERIAL_LCR_DLAB; | ||
1872 | ATEN2011_port->shadowLCR = Data; | ||
1873 | set_uart_reg(port, LINE_CONTROL_REGISTER, Data); | ||
1874 | |||
1875 | /* Write the divisor */ | ||
1876 | Data = (unsigned char)(divisor & 0xff); | ||
1877 | dbg("set_serial_baud Value to write DLL is %x", Data); | ||
1878 | set_uart_reg(port, DIVISOR_LATCH_LSB, Data); | ||
1879 | |||
1880 | Data = (unsigned char)((divisor & 0xff00) >> 8); | ||
1881 | dbg("set_serial_baud Value to write DLM is %x", Data); | ||
1882 | set_uart_reg(port, DIVISOR_LATCH_MSB, Data); | ||
1883 | |||
1884 | /* Disable access to divisor latch */ | ||
1885 | Data = ATEN2011_port->shadowLCR & ~SERIAL_LCR_DLAB; | ||
1886 | ATEN2011_port->shadowLCR = Data; | ||
1887 | set_uart_reg(port, LINE_CONTROL_REGISTER, Data); | ||
1888 | |||
1889 | } | ||
1890 | |||
1891 | return status; | ||
1892 | } | ||
1893 | |||
1894 | static void ATEN2011_change_port_settings(struct tty_struct *tty, | ||
1895 | struct ATENINTL_port *ATEN2011_port, | ||
1896 | struct ktermios *old_termios) | ||
1897 | { | ||
1898 | int baud; | ||
1899 | unsigned cflag; | ||
1900 | unsigned iflag; | ||
1901 | __u8 lData; | ||
1902 | __u8 lParity; | ||
1903 | __u8 lStop; | ||
1904 | int status; | ||
1905 | __u16 Data; | ||
1906 | struct usb_serial_port *port; | ||
1907 | struct usb_serial *serial; | ||
1908 | |||
1909 | if (ATEN2011_port == NULL) | ||
1910 | return; | ||
1911 | |||
1912 | port = (struct usb_serial_port *)ATEN2011_port->port; | ||
1913 | |||
1914 | serial = port->serial; | ||
1915 | |||
1916 | dbg("%s - port %d", __func__, ATEN2011_port->port->number); | ||
1917 | |||
1918 | if (!ATEN2011_port->open) { | ||
1919 | dbg("%s - port not opened", __func__); | ||
1920 | return; | ||
1921 | } | ||
1922 | |||
1923 | if ((!tty) || (!tty->termios)) { | ||
1924 | dbg("%s - no tty structures", __func__); | ||
1925 | return; | ||
1926 | } | ||
1927 | |||
1928 | dbg("%s", "Entering .......... "); | ||
1929 | |||
1930 | lData = LCR_BITS_8; | ||
1931 | lStop = LCR_STOP_1; | ||
1932 | lParity = LCR_PAR_NONE; | ||
1933 | |||
1934 | cflag = tty->termios->c_cflag; | ||
1935 | iflag = tty->termios->c_iflag; | ||
1936 | |||
1937 | /* Change the number of bits */ | ||
1938 | |||
1939 | /* COMMENT1: the below Line"if(cflag & CSIZE)" is added for the errors we get for serial loop data test i.e serial_loopback.pl -v */ | ||
1940 | /* if(cflag & CSIZE) */ | ||
1941 | { | ||
1942 | switch (cflag & CSIZE) { | ||
1943 | case CS5: | ||
1944 | lData = LCR_BITS_5; | ||
1945 | break; | ||
1946 | |||
1947 | case CS6: | ||
1948 | lData = LCR_BITS_6; | ||
1949 | break; | ||
1950 | |||
1951 | case CS7: | ||
1952 | lData = LCR_BITS_7; | ||
1953 | break; | ||
1954 | default: | ||
1955 | case CS8: | ||
1956 | lData = LCR_BITS_8; | ||
1957 | break; | ||
1958 | } | ||
1959 | } | ||
1960 | /* Change the Parity bit */ | ||
1961 | if (cflag & PARENB) { | ||
1962 | if (cflag & PARODD) { | ||
1963 | lParity = LCR_PAR_ODD; | ||
1964 | dbg("%s - parity = odd", __func__); | ||
1965 | } else { | ||
1966 | lParity = LCR_PAR_EVEN; | ||
1967 | dbg("%s - parity = even", __func__); | ||
1968 | } | ||
1969 | |||
1970 | } else { | ||
1971 | dbg("%s - parity = none", __func__); | ||
1972 | } | ||
1973 | |||
1974 | if (cflag & CMSPAR) | ||
1975 | lParity = lParity | 0x20; | ||
1976 | |||
1977 | /* Change the Stop bit */ | ||
1978 | if (cflag & CSTOPB) { | ||
1979 | lStop = LCR_STOP_2; | ||
1980 | dbg("%s - stop bits = 2", __func__); | ||
1981 | } else { | ||
1982 | lStop = LCR_STOP_1; | ||
1983 | dbg("%s - stop bits = 1", __func__); | ||
1984 | } | ||
1985 | |||
1986 | /* Update the LCR with the correct value */ | ||
1987 | ATEN2011_port->shadowLCR &= | ||
1988 | ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); | ||
1989 | ATEN2011_port->shadowLCR |= (lData | lParity | lStop); | ||
1990 | |||
1991 | dbg | ||
1992 | ("ATEN2011_change_port_settings ATEN2011_port->shadowLCR is %x", | ||
1993 | ATEN2011_port->shadowLCR); | ||
1994 | /* Disable Interrupts */ | ||
1995 | Data = 0x00; | ||
1996 | set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); | ||
1997 | |||
1998 | Data = 0x00; | ||
1999 | set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); | ||
2000 | |||
2001 | Data = 0xcf; | ||
2002 | set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); | ||
2003 | |||
2004 | /* Send the updated LCR value to the ATEN2011 */ | ||
2005 | Data = ATEN2011_port->shadowLCR; | ||
2006 | |||
2007 | set_uart_reg(port, LINE_CONTROL_REGISTER, Data); | ||
2008 | |||
2009 | Data = 0x00b; | ||
2010 | ATEN2011_port->shadowMCR = Data; | ||
2011 | set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | ||
2012 | Data = 0x00b; | ||
2013 | set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | ||
2014 | |||
2015 | /* set up the MCR register and send it to the ATEN2011 */ | ||
2016 | |||
2017 | ATEN2011_port->shadowMCR = MCR_MASTER_IE; | ||
2018 | if (cflag & CBAUD) | ||
2019 | ATEN2011_port->shadowMCR |= (MCR_DTR | MCR_RTS); | ||
2020 | |||
2021 | if (cflag & CRTSCTS) | ||
2022 | ATEN2011_port->shadowMCR |= (MCR_XON_ANY); | ||
2023 | else | ||
2024 | ATEN2011_port->shadowMCR &= ~(MCR_XON_ANY); | ||
2025 | |||
2026 | Data = ATEN2011_port->shadowMCR; | ||
2027 | set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | ||
2028 | |||
2029 | /* Determine divisor based on baud rate */ | ||
2030 | baud = tty_get_baud_rate(tty); | ||
2031 | |||
2032 | if (!baud) { | ||
2033 | /* pick a default, any default... */ | ||
2034 | dbg("%s", "Picked default baud..."); | ||
2035 | baud = 9600; | ||
2036 | } | ||
2037 | |||
2038 | dbg("%s - baud rate = %d", __func__, baud); | ||
2039 | status = ATEN2011_send_cmd_write_baud_rate(ATEN2011_port, baud); | ||
2040 | |||
2041 | /* Enable Interrupts */ | ||
2042 | Data = 0x0c; | ||
2043 | set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); | ||
2044 | |||
2045 | if (ATEN2011_port->read_urb->status != -EINPROGRESS) { | ||
2046 | ATEN2011_port->read_urb->dev = serial->dev; | ||
2047 | |||
2048 | status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC); | ||
2049 | |||
2050 | if (status) { | ||
2051 | dbg | ||
2052 | (" usb_submit_urb(read bulk) failed, status = %d", | ||
2053 | status); | ||
2054 | } | ||
2055 | } | ||
2056 | dbg | ||
2057 | ("ATEN2011_change_port_settings ATEN2011_port->shadowLCR is End %x", | ||
2058 | ATEN2011_port->shadowLCR); | ||
2059 | |||
2060 | return; | ||
2061 | } | ||
2062 | |||
2063 | static int ATEN2011_calc_num_ports(struct usb_serial *serial) | ||
2064 | { | ||
2065 | |||
2066 | __u16 Data = 0x00; | ||
2067 | int ret = 0; | ||
2068 | int ATEN2011_2or4ports; | ||
2069 | ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | ||
2070 | ATEN_RDREQ, ATEN_RD_RTYPE, 0, GPIO_REGISTER, | ||
2071 | &Data, VENDOR_READ_LENGTH, ATEN_WDR_TIMEOUT); | ||
2072 | |||
2073 | /* ghostgum: here is where the problem appears to bet */ | ||
2074 | /* Which of the following are needed? */ | ||
2075 | /* Greg used the serial->type->num_ports=2 */ | ||
2076 | /* But the code in the ATEN2011_open relies on serial->num_ports=2 */ | ||
2077 | if ((Data & 0x01) == 0) { | ||
2078 | ATEN2011_2or4ports = 2; | ||
2079 | serial->type->num_ports = 2; | ||
2080 | serial->num_ports = 2; | ||
2081 | } | ||
2082 | /* else if(serial->interface->cur_altsetting->desc.bNumEndpoints == 9) */ | ||
2083 | else { | ||
2084 | ATEN2011_2or4ports = 4; | ||
2085 | serial->type->num_ports = 4; | ||
2086 | serial->num_ports = 4; | ||
2087 | |||
2088 | } | ||
2089 | |||
2090 | return ATEN2011_2or4ports; | ||
2091 | } | ||
2092 | |||
2093 | static int ATEN2011_startup(struct usb_serial *serial) | ||
2094 | { | ||
2095 | struct ATENINTL_serial *ATEN2011_serial; | ||
2096 | struct ATENINTL_port *ATEN2011_port; | ||
2097 | struct usb_device *dev; | ||
2098 | int i, status; | ||
2099 | int minor; | ||
2100 | |||
2101 | __u16 Data; | ||
2102 | dbg("%s", " ATEN2011_startup :entering.........."); | ||
2103 | |||
2104 | if (!serial) { | ||
2105 | dbg("%s", "Invalid Handler"); | ||
2106 | return -1; | ||
2107 | } | ||
2108 | |||
2109 | dev = serial->dev; | ||
2110 | |||
2111 | dbg("%s", "Entering..."); | ||
2112 | |||
2113 | /* create our private serial structure */ | ||
2114 | ATEN2011_serial = kzalloc(sizeof(struct ATENINTL_serial), GFP_KERNEL); | ||
2115 | if (ATEN2011_serial == NULL) { | ||
2116 | err("%s - Out of memory", __func__); | ||
2117 | return -ENOMEM; | ||
2118 | } | ||
2119 | |||
2120 | /* resetting the private structure field values to zero */ | ||
2121 | memset(ATEN2011_serial, 0, sizeof(struct ATENINTL_serial)); | ||
2122 | |||
2123 | ATEN2011_serial->serial = serial; | ||
2124 | /* initilize status polling flag to 0 */ | ||
2125 | ATEN2011_serial->status_polling_started = 0; | ||
2126 | |||
2127 | usb_set_serial_data(serial, ATEN2011_serial); | ||
2128 | ATEN2011_serial->ATEN2011_spectrum_2or4ports = | ||
2129 | ATEN2011_calc_num_ports(serial); | ||
2130 | /* we set up the pointers to the endpoints in the ATEN2011_open * | ||
2131 | * function, as the structures aren't created yet. */ | ||
2132 | |||
2133 | /* set up port private structures */ | ||
2134 | for (i = 0; i < serial->num_ports; ++i) { | ||
2135 | ATEN2011_port = | ||
2136 | kmalloc(sizeof(struct ATENINTL_port), GFP_KERNEL); | ||
2137 | if (ATEN2011_port == NULL) { | ||
2138 | err("%s - Out of memory", __func__); | ||
2139 | usb_set_serial_data(serial, NULL); | ||
2140 | kfree(ATEN2011_serial); | ||
2141 | return -ENOMEM; | ||
2142 | } | ||
2143 | memset(ATEN2011_port, 0, sizeof(struct ATENINTL_port)); | ||
2144 | |||
2145 | /* | ||
2146 | * Initialize all port interrupt end point to port 0 | ||
2147 | * int endpoint. Our device has only one interrupt end point | ||
2148 | * comman to all port | ||
2149 | */ | ||
2150 | /* serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress; */ | ||
2151 | |||
2152 | ATEN2011_port->port = serial->port[i]; | ||
2153 | usb_set_serial_port_data(serial->port[i], ATEN2011_port); | ||
2154 | |||
2155 | minor = serial->port[i]->serial->minor; | ||
2156 | if (minor == SERIAL_TTY_NO_MINOR) | ||
2157 | minor = 0; | ||
2158 | ATEN2011_port->port_num = | ||
2159 | ((serial->port[i]->number - minor) + 1); | ||
2160 | |||
2161 | if (ATEN2011_port->port_num == 1) { | ||
2162 | ATEN2011_port->SpRegOffset = 0x0; | ||
2163 | ATEN2011_port->ControlRegOffset = 0x1; | ||
2164 | ATEN2011_port->DcrRegOffset = 0x4; | ||
2165 | } else if ((ATEN2011_port->port_num == 2) | ||
2166 | && (ATEN2011_serial->ATEN2011_spectrum_2or4ports == | ||
2167 | 4)) { | ||
2168 | ATEN2011_port->SpRegOffset = 0x8; | ||
2169 | ATEN2011_port->ControlRegOffset = 0x9; | ||
2170 | ATEN2011_port->DcrRegOffset = 0x16; | ||
2171 | } else if ((ATEN2011_port->port_num == 2) | ||
2172 | && (ATEN2011_serial->ATEN2011_spectrum_2or4ports == | ||
2173 | 2)) { | ||
2174 | ATEN2011_port->SpRegOffset = 0xa; | ||
2175 | ATEN2011_port->ControlRegOffset = 0xb; | ||
2176 | ATEN2011_port->DcrRegOffset = 0x19; | ||
2177 | } else if ((ATEN2011_port->port_num == 3) | ||
2178 | && (ATEN2011_serial->ATEN2011_spectrum_2or4ports == | ||
2179 | 4)) { | ||
2180 | ATEN2011_port->SpRegOffset = 0xa; | ||
2181 | ATEN2011_port->ControlRegOffset = 0xb; | ||
2182 | ATEN2011_port->DcrRegOffset = 0x19; | ||
2183 | } else if ((ATEN2011_port->port_num == 4) | ||
2184 | && (ATEN2011_serial->ATEN2011_spectrum_2or4ports == | ||
2185 | 4)) { | ||
2186 | ATEN2011_port->SpRegOffset = 0xc; | ||
2187 | ATEN2011_port->ControlRegOffset = 0xd; | ||
2188 | ATEN2011_port->DcrRegOffset = 0x1c; | ||
2189 | } | ||
2190 | |||
2191 | usb_set_serial_port_data(serial->port[i], ATEN2011_port); | ||
2192 | |||
2193 | /* enable rx_disable bit in control register */ | ||
2194 | |||
2195 | status = get_reg_sync(serial->port[i], | ||
2196 | ATEN2011_port->ControlRegOffset, &Data); | ||
2197 | if (status < 0) { | ||
2198 | dbg("Reading ControlReg failed status-0x%x", | ||
2199 | status); | ||
2200 | break; | ||
2201 | } else | ||
2202 | dbg | ||
2203 | ("ControlReg Reading success val is %x, status%d", | ||
2204 | Data, status); | ||
2205 | Data |= 0x08; /* setting driver done bit */ | ||
2206 | Data |= 0x04; /* sp1_bit to have cts change reflect in modem status reg */ | ||
2207 | |||
2208 | /* Data |= 0x20; */ /* rx_disable bit */ | ||
2209 | status = set_reg_sync(serial->port[i], | ||
2210 | ATEN2011_port->ControlRegOffset, Data); | ||
2211 | if (status < 0) { | ||
2212 | dbg | ||
2213 | ("Writing ControlReg failed(rx_disable) status-0x%x", | ||
2214 | status); | ||
2215 | break; | ||
2216 | } else | ||
2217 | dbg | ||
2218 | ("ControlReg Writing success(rx_disable) status%d", | ||
2219 | status); | ||
2220 | |||
2221 | /* | ||
2222 | * Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 | ||
2223 | * and 0x24 in DCR3 | ||
2224 | */ | ||
2225 | Data = 0x01; | ||
2226 | status = set_reg_sync(serial->port[i], | ||
2227 | (__u16)(ATEN2011_port->DcrRegOffset + 0), | ||
2228 | Data); | ||
2229 | if (status < 0) { | ||
2230 | dbg("Writing DCR0 failed status-0x%x", status); | ||
2231 | break; | ||
2232 | } else | ||
2233 | dbg("DCR0 Writing success status%d", status); | ||
2234 | |||
2235 | Data = 0x05; | ||
2236 | status = set_reg_sync(serial->port[i], | ||
2237 | (__u16)(ATEN2011_port->DcrRegOffset + 1), | ||
2238 | Data); | ||
2239 | if (status < 0) { | ||
2240 | dbg("Writing DCR1 failed status-0x%x", status); | ||
2241 | break; | ||
2242 | } else | ||
2243 | dbg("DCR1 Writing success status%d", status); | ||
2244 | |||
2245 | Data = 0x24; | ||
2246 | status = set_reg_sync(serial->port[i], | ||
2247 | (__u16)(ATEN2011_port->DcrRegOffset + 2), | ||
2248 | Data); | ||
2249 | if (status < 0) { | ||
2250 | dbg("Writing DCR2 failed status-0x%x", status); | ||
2251 | break; | ||
2252 | } else | ||
2253 | dbg("DCR2 Writing success status%d", status); | ||
2254 | |||
2255 | /* write values in clkstart0x0 and clkmulti 0x20 */ | ||
2256 | Data = 0x0; | ||
2257 | status = set_reg_sync(serial->port[i], CLK_START_VALUE_REGISTER, | ||
2258 | Data); | ||
2259 | if (status < 0) { | ||
2260 | dbg | ||
2261 | ("Writing CLK_START_VALUE_REGISTER failed status-0x%x", | ||
2262 | status); | ||
2263 | break; | ||
2264 | } else | ||
2265 | dbg | ||
2266 | ("CLK_START_VALUE_REGISTER Writing success status%d", | ||
2267 | status); | ||
2268 | |||
2269 | Data = 0x20; | ||
2270 | status = set_reg_sync(serial->port[i], CLK_MULTI_REGISTER, | ||
2271 | Data); | ||
2272 | if (status < 0) { | ||
2273 | dbg | ||
2274 | ("Writing CLK_MULTI_REGISTER failed status-0x%x", | ||
2275 | status); | ||
2276 | break; | ||
2277 | } else | ||
2278 | dbg("CLK_MULTI_REGISTER Writing success status%d", | ||
2279 | status); | ||
2280 | |||
2281 | /* Zero Length flag register */ | ||
2282 | if ((ATEN2011_port->port_num != 1) | ||
2283 | && (ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)) { | ||
2284 | |||
2285 | Data = 0xff; | ||
2286 | status = set_reg_sync(serial->port[i], | ||
2287 | (__u16)(ZLP_REG1 + ((__u16)ATEN2011_port->port_num)), | ||
2288 | Data); | ||
2289 | dbg("ZLIP offset%x", | ||
2290 | (__u16) (ZLP_REG1 + | ||
2291 | ((__u16) ATEN2011_port->port_num))); | ||
2292 | if (status < 0) { | ||
2293 | dbg | ||
2294 | ("Writing ZLP_REG%d failed status-0x%x", | ||
2295 | i + 2, status); | ||
2296 | break; | ||
2297 | } else | ||
2298 | dbg("ZLP_REG%d Writing success status%d", | ||
2299 | i + 2, status); | ||
2300 | } else { | ||
2301 | Data = 0xff; | ||
2302 | status = set_reg_sync(serial->port[i], | ||
2303 | (__u16)(ZLP_REG1 + ((__u16)ATEN2011_port->port_num) - 0x1), | ||
2304 | Data); | ||
2305 | dbg("ZLIP offset%x", | ||
2306 | (__u16) (ZLP_REG1 + | ||
2307 | ((__u16) ATEN2011_port->port_num) - | ||
2308 | 0x1)); | ||
2309 | if (status < 0) { | ||
2310 | dbg | ||
2311 | ("Writing ZLP_REG%d failed status-0x%x", | ||
2312 | i + 1, status); | ||
2313 | break; | ||
2314 | } else | ||
2315 | dbg("ZLP_REG%d Writing success status%d", | ||
2316 | i + 1, status); | ||
2317 | |||
2318 | } | ||
2319 | ATEN2011_port->control_urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
2320 | ATEN2011_port->ctrl_buf = kmalloc(16, GFP_KERNEL); | ||
2321 | |||
2322 | } | ||
2323 | |||
2324 | /* Zero Length flag enable */ | ||
2325 | Data = 0x0f; | ||
2326 | status = set_reg_sync(serial->port[0], ZLP_REG5, Data); | ||
2327 | if (status < 0) { | ||
2328 | dbg("Writing ZLP_REG5 failed status-0x%x", status); | ||
2329 | return -1; | ||
2330 | } else | ||
2331 | dbg("ZLP_REG5 Writing success status%d", status); | ||
2332 | |||
2333 | /* setting configuration feature to one */ | ||
2334 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | ||
2335 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ); | ||
2336 | return 0; | ||
2337 | } | ||
2338 | |||
2339 | static void ATEN2011_release(struct usb_serial *serial) | ||
2340 | { | ||
2341 | int i; | ||
2342 | struct ATENINTL_port *ATEN2011_port; | ||
2343 | |||
2344 | /* check for the ports to be closed,close the ports and disconnect */ | ||
2345 | |||
2346 | /* free private structure allocated for serial port * | ||
2347 | * stop reads and writes on all ports */ | ||
2348 | |||
2349 | for (i = 0; i < serial->num_ports; ++i) { | ||
2350 | ATEN2011_port = usb_get_serial_port_data(serial->port[i]); | ||
2351 | kfree(ATEN2011_port->ctrl_buf); | ||
2352 | usb_kill_urb(ATEN2011_port->control_urb); | ||
2353 | kfree(ATEN2011_port); | ||
2354 | usb_set_serial_port_data(serial->port[i], NULL); | ||
2355 | } | ||
2356 | |||
2357 | /* free private structure allocated for serial device */ | ||
2358 | |||
2359 | kfree(usb_get_serial_data(serial)); | ||
2360 | usb_set_serial_data(serial, NULL); | ||
2361 | } | ||
2362 | |||
2363 | static struct usb_serial_driver aten_serial_driver = { | ||
2364 | .driver = { | ||
2365 | .owner = THIS_MODULE, | ||
2366 | .name = "aten2011", | ||
2367 | }, | ||
2368 | .description = DRIVER_DESC, | ||
2369 | .id_table = id_table, | ||
2370 | .open = ATEN2011_open, | ||
2371 | .close = ATEN2011_close, | ||
2372 | .write = ATEN2011_write, | ||
2373 | .write_room = ATEN2011_write_room, | ||
2374 | .chars_in_buffer = ATEN2011_chars_in_buffer, | ||
2375 | .throttle = ATEN2011_throttle, | ||
2376 | .unthrottle = ATEN2011_unthrottle, | ||
2377 | .calc_num_ports = ATEN2011_calc_num_ports, | ||
2378 | |||
2379 | .ioctl = ATEN2011_ioctl, | ||
2380 | .set_termios = ATEN2011_set_termios, | ||
2381 | .break_ctl = ATEN2011_break, | ||
2382 | .tiocmget = ATEN2011_tiocmget, | ||
2383 | .tiocmset = ATEN2011_tiocmset, | ||
2384 | .attach = ATEN2011_startup, | ||
2385 | .release = ATEN2011_release, | ||
2386 | .read_bulk_callback = ATEN2011_bulk_in_callback, | ||
2387 | .read_int_callback = ATEN2011_interrupt_callback, | ||
2388 | }; | ||
2389 | |||
2390 | static struct usb_driver aten_driver = { | ||
2391 | .name = "aten2011", | ||
2392 | .probe = usb_serial_probe, | ||
2393 | .disconnect = usb_serial_disconnect, | ||
2394 | .id_table = id_table, | ||
2395 | }; | ||
2396 | |||
2397 | static int __init aten_init(void) | ||
2398 | { | ||
2399 | int retval; | ||
2400 | |||
2401 | /* Register with the usb serial */ | ||
2402 | retval = usb_serial_register(&aten_serial_driver); | ||
2403 | if (retval) | ||
2404 | return retval; | ||
2405 | |||
2406 | printk(KERN_INFO KBUILD_MODNAME ":" | ||
2407 | DRIVER_DESC " " DRIVER_VERSION "\n"); | ||
2408 | |||
2409 | /* Register with the usb */ | ||
2410 | retval = usb_register(&aten_driver); | ||
2411 | if (retval) | ||
2412 | usb_serial_deregister(&aten_serial_driver); | ||
2413 | |||
2414 | return retval; | ||
2415 | } | ||
2416 | |||
2417 | static void __exit aten_exit(void) | ||
2418 | { | ||
2419 | usb_deregister(&aten_driver); | ||
2420 | usb_serial_deregister(&aten_serial_driver); | ||
2421 | } | ||
2422 | |||
2423 | module_init(aten_init); | ||
2424 | module_exit(aten_exit); | ||
2425 | |||
2426 | /* Module information */ | ||
2427 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
2428 | MODULE_LICENSE("GPL"); | ||
2429 | |||
2430 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index 0ab9d15f3439..f5416af1e902 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <linux/fb.h> | 22 | #include <linux/fb.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/vmalloc.h> | ||
24 | 25 | ||
25 | #include "udlfb.h" | 26 | #include "udlfb.h" |
26 | 27 | ||
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 22f93dd0ba03..251220dc8851 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/smp_lock.h> | ||
21 | #include <linux/file.h> | 22 | #include <linux/file.h> |
22 | #include <linux/tcp.h> | 23 | #include <linux/tcp.h> |
23 | #include <linux/in.h> | 24 | #include <linux/in.h> |
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index a10ed27acbc2..f43ca416e4a8 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c | |||
@@ -344,7 +344,7 @@ static CHIP_INFO chip_info_table[]= { | |||
344 | }; | 344 | }; |
345 | 345 | ||
346 | static struct pci_device_id device_id_table[] __devinitdata = { | 346 | static struct pci_device_id device_id_table[] __devinitdata = { |
347 | { 0x1106, 0x3253, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (int)&chip_info_table[0]}, | 347 | { 0x1106, 0x3253, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long)&chip_info_table[0]}, |
348 | { 0, } | 348 | { 0, } |
349 | }; | 349 | }; |
350 | #endif | 350 | #endif |
@@ -369,7 +369,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | |||
369 | 369 | ||
370 | #ifdef CONFIG_PM | 370 | #ifdef CONFIG_PM |
371 | static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); | 371 | static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); |
372 | static int viawget_suspend(struct pci_dev *pcid, u32 state); | 372 | static int viawget_suspend(struct pci_dev *pcid, pm_message_t state); |
373 | static int viawget_resume(struct pci_dev *pcid); | 373 | static int viawget_resume(struct pci_dev *pcid); |
374 | struct notifier_block device_notifier = { | 374 | struct notifier_block device_notifier = { |
375 | notifier_call: device_notify_reboot, | 375 | notifier_call: device_notify_reboot, |
@@ -3941,7 +3941,7 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) | |||
3941 | while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { | 3941 | while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { |
3942 | if(pci_dev_driver(pdev) == &device_driver) { | 3942 | if(pci_dev_driver(pdev) == &device_driver) { |
3943 | if (pci_get_drvdata(pdev)) | 3943 | if (pci_get_drvdata(pdev)) |
3944 | viawget_suspend(pdev, 3); | 3944 | viawget_suspend(pdev, PMSG_HIBERNATE); |
3945 | } | 3945 | } |
3946 | } | 3946 | } |
3947 | } | 3947 | } |
@@ -3949,7 +3949,7 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) | |||
3949 | } | 3949 | } |
3950 | 3950 | ||
3951 | static int | 3951 | static int |
3952 | viawget_suspend(struct pci_dev *pcid, u32 state) | 3952 | viawget_suspend(struct pci_dev *pcid, pm_message_t state) |
3953 | { | 3953 | { |
3954 | int power_status; // to silence the compiler | 3954 | int power_status; // to silence the compiler |
3955 | 3955 | ||
@@ -3971,7 +3971,7 @@ viawget_suspend(struct pci_dev *pcid, u32 state) | |||
3971 | memset(pMgmt->abyCurrBSSID, 0, 6); | 3971 | memset(pMgmt->abyCurrBSSID, 0, 6); |
3972 | pMgmt->eCurrState = WMAC_STATE_IDLE; | 3972 | pMgmt->eCurrState = WMAC_STATE_IDLE; |
3973 | pci_disable_device(pcid); | 3973 | pci_disable_device(pcid); |
3974 | power_status = pci_set_power_state(pcid, state); | 3974 | power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state)); |
3975 | spin_unlock_irq(&pDevice->lock); | 3975 | spin_unlock_irq(&pDevice->lock); |
3976 | return 0; | 3976 | return 0; |
3977 | } | 3977 | } |
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index a913efc69669..40de151f2789 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c | |||
@@ -257,6 +257,7 @@ | |||
257 | #include <linux/fs.h> /* everything... */ | 257 | #include <linux/fs.h> /* everything... */ |
258 | #include <linux/errno.h> /* error codes */ | 258 | #include <linux/errno.h> /* error codes */ |
259 | #include <linux/slab.h> | 259 | #include <linux/slab.h> |
260 | #include <linux/smp_lock.h> | ||
260 | #include <linux/mm.h> | 261 | #include <linux/mm.h> |
261 | #include <linux/ioport.h> | 262 | #include <linux/ioport.h> |
262 | #include <linux/interrupt.h> | 263 | #include <linux/interrupt.h> |
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c index b52cc830c0b4..f3873f650bb4 100644 --- a/drivers/telephony/phonedev.c +++ b/drivers/telephony/phonedev.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/phonedev.h> | 24 | #include <linux/phonedev.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/smp_lock.h> | ||
27 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
28 | #include <asm/system.h> | 27 | #include <asm/system.h> |
29 | 28 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 3f1045993474..e1f89416ef8c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -387,6 +387,7 @@ static void acm_rx_tasklet(unsigned long _acm) | |||
387 | struct acm_ru *rcv; | 387 | struct acm_ru *rcv; |
388 | unsigned long flags; | 388 | unsigned long flags; |
389 | unsigned char throttled; | 389 | unsigned char throttled; |
390 | struct usb_host_endpoint *ep; | ||
390 | 391 | ||
391 | dbg("Entering acm_rx_tasklet"); | 392 | dbg("Entering acm_rx_tasklet"); |
392 | 393 | ||
@@ -462,11 +463,20 @@ urbs: | |||
462 | 463 | ||
463 | rcv->buffer = buf; | 464 | rcv->buffer = buf; |
464 | 465 | ||
465 | usb_fill_bulk_urb(rcv->urb, acm->dev, | 466 | ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out) |
466 | acm->rx_endpoint, | 467 | [usb_pipeendpoint(acm->rx_endpoint)]; |
467 | buf->base, | 468 | if (usb_endpoint_xfer_int(&ep->desc)) |
468 | acm->readsize, | 469 | usb_fill_int_urb(rcv->urb, acm->dev, |
469 | acm_read_bulk, rcv); | 470 | acm->rx_endpoint, |
471 | buf->base, | ||
472 | acm->readsize, | ||
473 | acm_read_bulk, rcv, ep->desc.bInterval); | ||
474 | else | ||
475 | usb_fill_bulk_urb(rcv->urb, acm->dev, | ||
476 | acm->rx_endpoint, | ||
477 | buf->base, | ||
478 | acm->readsize, | ||
479 | acm_read_bulk, rcv); | ||
470 | rcv->urb->transfer_dma = buf->dma; | 480 | rcv->urb->transfer_dma = buf->dma; |
471 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 481 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
472 | 482 | ||
@@ -740,7 +750,7 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty) | |||
740 | { | 750 | { |
741 | struct acm *acm = tty->driver_data; | 751 | struct acm *acm = tty->driver_data; |
742 | if (!ACM_READY(acm)) | 752 | if (!ACM_READY(acm)) |
743 | return -EINVAL; | 753 | return 0; |
744 | /* | 754 | /* |
745 | * This is inaccurate (overcounts), but it works. | 755 | * This is inaccurate (overcounts), but it works. |
746 | */ | 756 | */ |
@@ -1227,9 +1237,14 @@ made_compressed_probe: | |||
1227 | goto alloc_fail7; | 1237 | goto alloc_fail7; |
1228 | } | 1238 | } |
1229 | 1239 | ||
1230 | usb_fill_bulk_urb(snd->urb, usb_dev, | 1240 | if (usb_endpoint_xfer_int(epwrite)) |
1231 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | 1241 | usb_fill_int_urb(snd->urb, usb_dev, |
1232 | NULL, acm->writesize, acm_write_bulk, snd); | 1242 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), |
1243 | NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); | ||
1244 | else | ||
1245 | usb_fill_bulk_urb(snd->urb, usb_dev, | ||
1246 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | ||
1247 | NULL, acm->writesize, acm_write_bulk, snd); | ||
1233 | snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1248 | snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1234 | snd->instance = acm; | 1249 | snd->instance = acm; |
1235 | } | 1250 | } |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 0fe434505ac4..ba589d4ca8bc 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
20 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
21 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 3703789d0d2a..b09a527f7341 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
@@ -751,7 +751,7 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
751 | { | 751 | { |
752 | struct device *dev = &data->usb_dev->dev; | 752 | struct device *dev = &data->usb_dev->dev; |
753 | char *buffer; | 753 | char *buffer; |
754 | int rv; | 754 | int rv = 0; |
755 | 755 | ||
756 | buffer = kmalloc(0x18, GFP_KERNEL); | 756 | buffer = kmalloc(0x18, GFP_KERNEL); |
757 | if (!buffer) | 757 | if (!buffer) |
@@ -763,7 +763,7 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
763 | 0, 0, buffer, 0x18, USBTMC_TIMEOUT); | 763 | 0, 0, buffer, 0x18, USBTMC_TIMEOUT); |
764 | if (rv < 0) { | 764 | if (rv < 0) { |
765 | dev_err(dev, "usb_control_msg returned %d\n", rv); | 765 | dev_err(dev, "usb_control_msg returned %d\n", rv); |
766 | return rv; | 766 | goto err_out; |
767 | } | 767 | } |
768 | 768 | ||
769 | dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); | 769 | dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); |
@@ -773,7 +773,8 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
773 | dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); | 773 | dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); |
774 | if (buffer[0] != USBTMC_STATUS_SUCCESS) { | 774 | if (buffer[0] != USBTMC_STATUS_SUCCESS) { |
775 | dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); | 775 | dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); |
776 | return -EPERM; | 776 | rv = -EPERM; |
777 | goto err_out; | ||
777 | } | 778 | } |
778 | 779 | ||
779 | data->capabilities.interface_capabilities = buffer[4]; | 780 | data->capabilities.interface_capabilities = buffer[4]; |
@@ -781,8 +782,9 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
781 | data->capabilities.usb488_interface_capabilities = buffer[14]; | 782 | data->capabilities.usb488_interface_capabilities = buffer[14]; |
782 | data->capabilities.usb488_device_capabilities = buffer[15]; | 783 | data->capabilities.usb488_device_capabilities = buffer[15]; |
783 | 784 | ||
785 | err_out: | ||
784 | kfree(buffer); | 786 | kfree(buffer); |
785 | return 0; | 787 | return rv; |
786 | } | 788 | } |
787 | 789 | ||
788 | #define capability_attribute(name) \ | 790 | #define capability_attribute(name) \ |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 69280c35b5cb..ad925946f869 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -28,7 +28,7 @@ comment "Miscellaneous USB options" | |||
28 | depends on USB | 28 | depends on USB |
29 | 29 | ||
30 | config USB_DEVICEFS | 30 | config USB_DEVICEFS |
31 | bool "USB device filesystem (DEPRECATED)" if EMBEDDED | 31 | bool "USB device filesystem (DEPRECATED)" |
32 | depends on USB | 32 | depends on USB |
33 | ---help--- | 33 | ---help--- |
34 | If you say Y here (and to "/proc file system support" in the "File | 34 | If you say Y here (and to "/proc file system support" in the "File |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 24dfb33f90cb..a16c538d0132 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -80,38 +80,18 @@ static int usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, | |||
80 | int max_tx; | 80 | int max_tx; |
81 | int i; | 81 | int i; |
82 | 82 | ||
83 | /* Allocate space for the SS endpoint companion descriptor */ | ||
84 | ep->ss_ep_comp = kzalloc(sizeof(struct usb_host_ss_ep_comp), | ||
85 | GFP_KERNEL); | ||
86 | if (!ep->ss_ep_comp) | ||
87 | return -ENOMEM; | ||
88 | desc = (struct usb_ss_ep_comp_descriptor *) buffer; | 83 | desc = (struct usb_ss_ep_comp_descriptor *) buffer; |
89 | if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP) { | 84 | if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP) { |
90 | dev_warn(ddev, "No SuperSpeed endpoint companion for config %d " | 85 | dev_warn(ddev, "No SuperSpeed endpoint companion for config %d " |
91 | " interface %d altsetting %d ep %d: " | 86 | " interface %d altsetting %d ep %d: " |
92 | "using minimum values\n", | 87 | "using minimum values\n", |
93 | cfgno, inum, asnum, ep->desc.bEndpointAddress); | 88 | cfgno, inum, asnum, ep->desc.bEndpointAddress); |
94 | ep->ss_ep_comp->desc.bLength = USB_DT_SS_EP_COMP_SIZE; | ||
95 | ep->ss_ep_comp->desc.bDescriptorType = USB_DT_SS_ENDPOINT_COMP; | ||
96 | ep->ss_ep_comp->desc.bMaxBurst = 0; | ||
97 | /* | ||
98 | * Leave bmAttributes as zero, which will mean no streams for | ||
99 | * bulk, and isoc won't support multiple bursts of packets. | ||
100 | * With bursts of only one packet, and a Mult of 1, the max | ||
101 | * amount of data moved per endpoint service interval is one | ||
102 | * packet. | ||
103 | */ | ||
104 | if (usb_endpoint_xfer_isoc(&ep->desc) || | ||
105 | usb_endpoint_xfer_int(&ep->desc)) | ||
106 | ep->ss_ep_comp->desc.wBytesPerInterval = | ||
107 | ep->desc.wMaxPacketSize; | ||
108 | /* | 89 | /* |
109 | * The next descriptor is for an Endpoint or Interface, | 90 | * The next descriptor is for an Endpoint or Interface, |
110 | * no extra descriptors to copy into the companion structure, | 91 | * no extra descriptors to copy into the companion structure, |
111 | * and we didn't eat up any of the buffer. | 92 | * and we didn't eat up any of the buffer. |
112 | */ | 93 | */ |
113 | retval = 0; | 94 | return 0; |
114 | goto valid; | ||
115 | } | 95 | } |
116 | memcpy(&ep->ss_ep_comp->desc, desc, USB_DT_SS_EP_COMP_SIZE); | 96 | memcpy(&ep->ss_ep_comp->desc, desc, USB_DT_SS_EP_COMP_SIZE); |
117 | desc = &ep->ss_ep_comp->desc; | 97 | desc = &ep->ss_ep_comp->desc; |
@@ -320,6 +300,28 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
320 | buffer += i; | 300 | buffer += i; |
321 | size -= i; | 301 | size -= i; |
322 | 302 | ||
303 | /* Allocate space for the SS endpoint companion descriptor */ | ||
304 | endpoint->ss_ep_comp = kzalloc(sizeof(struct usb_host_ss_ep_comp), | ||
305 | GFP_KERNEL); | ||
306 | if (!endpoint->ss_ep_comp) | ||
307 | return -ENOMEM; | ||
308 | |||
309 | /* Fill in some default values (may be overwritten later) */ | ||
310 | endpoint->ss_ep_comp->desc.bLength = USB_DT_SS_EP_COMP_SIZE; | ||
311 | endpoint->ss_ep_comp->desc.bDescriptorType = USB_DT_SS_ENDPOINT_COMP; | ||
312 | endpoint->ss_ep_comp->desc.bMaxBurst = 0; | ||
313 | /* | ||
314 | * Leave bmAttributes as zero, which will mean no streams for | ||
315 | * bulk, and isoc won't support multiple bursts of packets. | ||
316 | * With bursts of only one packet, and a Mult of 1, the max | ||
317 | * amount of data moved per endpoint service interval is one | ||
318 | * packet. | ||
319 | */ | ||
320 | if (usb_endpoint_xfer_isoc(&endpoint->desc) || | ||
321 | usb_endpoint_xfer_int(&endpoint->desc)) | ||
322 | endpoint->ss_ep_comp->desc.wBytesPerInterval = | ||
323 | endpoint->desc.wMaxPacketSize; | ||
324 | |||
323 | if (size > 0) { | 325 | if (size > 0) { |
324 | retval = usb_parse_ss_endpoint_companion(ddev, cfgno, | 326 | retval = usb_parse_ss_endpoint_companion(ddev, cfgno, |
325 | inum, asnum, endpoint, num_ep, buffer, | 327 | inum, asnum, endpoint, num_ep, buffer, |
@@ -329,6 +331,10 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
329 | retval = buffer - buffer0; | 331 | retval = buffer - buffer0; |
330 | } | 332 | } |
331 | } else { | 333 | } else { |
334 | dev_warn(ddev, "config %d interface %d altsetting %d " | ||
335 | "endpoint 0x%X has no " | ||
336 | "SuperSpeed companion descriptor\n", | ||
337 | cfgno, inum, asnum, d->bEndpointAddress); | ||
332 | retval = buffer - buffer0; | 338 | retval = buffer - buffer0; |
333 | } | 339 | } |
334 | } else { | 340 | } else { |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 73c108d117b4..96f11715cd26 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -136,17 +136,19 @@ static const struct class_info clas_info[] = | |||
136 | {USB_CLASS_AUDIO, "audio"}, | 136 | {USB_CLASS_AUDIO, "audio"}, |
137 | {USB_CLASS_COMM, "comm."}, | 137 | {USB_CLASS_COMM, "comm."}, |
138 | {USB_CLASS_HID, "HID"}, | 138 | {USB_CLASS_HID, "HID"}, |
139 | {USB_CLASS_HUB, "hub"}, | ||
140 | {USB_CLASS_PHYSICAL, "PID"}, | 139 | {USB_CLASS_PHYSICAL, "PID"}, |
140 | {USB_CLASS_STILL_IMAGE, "still"}, | ||
141 | {USB_CLASS_PRINTER, "print"}, | 141 | {USB_CLASS_PRINTER, "print"}, |
142 | {USB_CLASS_MASS_STORAGE, "stor."}, | 142 | {USB_CLASS_MASS_STORAGE, "stor."}, |
143 | {USB_CLASS_HUB, "hub"}, | ||
143 | {USB_CLASS_CDC_DATA, "data"}, | 144 | {USB_CLASS_CDC_DATA, "data"}, |
144 | {USB_CLASS_APP_SPEC, "app."}, | ||
145 | {USB_CLASS_VENDOR_SPEC, "vend."}, | ||
146 | {USB_CLASS_STILL_IMAGE, "still"}, | ||
147 | {USB_CLASS_CSCID, "scard"}, | 145 | {USB_CLASS_CSCID, "scard"}, |
148 | {USB_CLASS_CONTENT_SEC, "c-sec"}, | 146 | {USB_CLASS_CONTENT_SEC, "c-sec"}, |
149 | {USB_CLASS_VIDEO, "video"}, | 147 | {USB_CLASS_VIDEO, "video"}, |
148 | {USB_CLASS_WIRELESS_CONTROLLER, "wlcon"}, | ||
149 | {USB_CLASS_MISC, "misc"}, | ||
150 | {USB_CLASS_APP_SPEC, "app."}, | ||
151 | {USB_CLASS_VENDOR_SPEC, "vend."}, | ||
150 | {-1, "unk."} /* leave as last */ | 152 | {-1, "unk."} /* leave as last */ |
151 | }; | 153 | }; |
152 | 154 | ||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 308609039c73..38b8bce782d6 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -325,21 +325,34 @@ static void async_completed(struct urb *urb) | |||
325 | struct async *as = urb->context; | 325 | struct async *as = urb->context; |
326 | struct dev_state *ps = as->ps; | 326 | struct dev_state *ps = as->ps; |
327 | struct siginfo sinfo; | 327 | struct siginfo sinfo; |
328 | struct pid *pid = NULL; | ||
329 | uid_t uid = 0; | ||
330 | uid_t euid = 0; | ||
331 | u32 secid = 0; | ||
332 | int signr; | ||
328 | 333 | ||
329 | spin_lock(&ps->lock); | 334 | spin_lock(&ps->lock); |
330 | list_move_tail(&as->asynclist, &ps->async_completed); | 335 | list_move_tail(&as->asynclist, &ps->async_completed); |
331 | spin_unlock(&ps->lock); | ||
332 | as->status = urb->status; | 336 | as->status = urb->status; |
333 | if (as->signr) { | 337 | signr = as->signr; |
338 | if (signr) { | ||
334 | sinfo.si_signo = as->signr; | 339 | sinfo.si_signo = as->signr; |
335 | sinfo.si_errno = as->status; | 340 | sinfo.si_errno = as->status; |
336 | sinfo.si_code = SI_ASYNCIO; | 341 | sinfo.si_code = SI_ASYNCIO; |
337 | sinfo.si_addr = as->userurb; | 342 | sinfo.si_addr = as->userurb; |
338 | kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid, | 343 | pid = as->pid; |
339 | as->euid, as->secid); | 344 | uid = as->uid; |
345 | euid = as->euid; | ||
346 | secid = as->secid; | ||
340 | } | 347 | } |
341 | snoop(&urb->dev->dev, "urb complete\n"); | 348 | snoop(&urb->dev->dev, "urb complete\n"); |
342 | snoop_urb(urb, as->userurb); | 349 | snoop_urb(urb, as->userurb); |
350 | spin_unlock(&ps->lock); | ||
351 | |||
352 | if (signr) | ||
353 | kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid, | ||
354 | euid, secid); | ||
355 | |||
343 | wake_up(&ps->wait); | 356 | wake_up(&ps->wait); |
344 | } | 357 | } |
345 | 358 | ||
@@ -982,7 +995,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
982 | USBDEVFS_URB_ZERO_PACKET | | 995 | USBDEVFS_URB_ZERO_PACKET | |
983 | USBDEVFS_URB_NO_INTERRUPT)) | 996 | USBDEVFS_URB_NO_INTERRUPT)) |
984 | return -EINVAL; | 997 | return -EINVAL; |
985 | if (!uurb->buffer) | 998 | if (uurb->buffer_length > 0 && !uurb->buffer) |
986 | return -EINVAL; | 999 | return -EINVAL; |
987 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && | 1000 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && |
988 | (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { | 1001 | (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { |
@@ -1038,11 +1051,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1038 | is_in = 0; | 1051 | is_in = 0; |
1039 | uurb->endpoint &= ~USB_DIR_IN; | 1052 | uurb->endpoint &= ~USB_DIR_IN; |
1040 | } | 1053 | } |
1041 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
1042 | uurb->buffer, uurb->buffer_length)) { | ||
1043 | kfree(dr); | ||
1044 | return -EFAULT; | ||
1045 | } | ||
1046 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " | 1054 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " |
1047 | "bRrequestType=%02x wValue=%04x " | 1055 | "bRrequestType=%02x wValue=%04x " |
1048 | "wIndex=%04x wLength=%04x\n", | 1056 | "wIndex=%04x wLength=%04x\n", |
@@ -1062,9 +1070,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1062 | uurb->number_of_packets = 0; | 1070 | uurb->number_of_packets = 0; |
1063 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1071 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1064 | return -EINVAL; | 1072 | return -EINVAL; |
1065 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
1066 | uurb->buffer, uurb->buffer_length)) | ||
1067 | return -EFAULT; | ||
1068 | snoop(&ps->dev->dev, "bulk urb\n"); | 1073 | snoop(&ps->dev->dev, "bulk urb\n"); |
1069 | break; | 1074 | break; |
1070 | 1075 | ||
@@ -1106,28 +1111,35 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1106 | return -EINVAL; | 1111 | return -EINVAL; |
1107 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1112 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1108 | return -EINVAL; | 1113 | return -EINVAL; |
1109 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
1110 | uurb->buffer, uurb->buffer_length)) | ||
1111 | return -EFAULT; | ||
1112 | snoop(&ps->dev->dev, "interrupt urb\n"); | 1114 | snoop(&ps->dev->dev, "interrupt urb\n"); |
1113 | break; | 1115 | break; |
1114 | 1116 | ||
1115 | default: | 1117 | default: |
1116 | return -EINVAL; | 1118 | return -EINVAL; |
1117 | } | 1119 | } |
1118 | as = alloc_async(uurb->number_of_packets); | 1120 | if (uurb->buffer_length > 0 && |
1119 | if (!as) { | 1121 | !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, |
1122 | uurb->buffer, uurb->buffer_length)) { | ||
1120 | kfree(isopkt); | 1123 | kfree(isopkt); |
1121 | kfree(dr); | 1124 | kfree(dr); |
1122 | return -ENOMEM; | 1125 | return -EFAULT; |
1123 | } | 1126 | } |
1124 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL); | 1127 | as = alloc_async(uurb->number_of_packets); |
1125 | if (!as->urb->transfer_buffer) { | 1128 | if (!as) { |
1126 | kfree(isopkt); | 1129 | kfree(isopkt); |
1127 | kfree(dr); | 1130 | kfree(dr); |
1128 | free_async(as); | ||
1129 | return -ENOMEM; | 1131 | return -ENOMEM; |
1130 | } | 1132 | } |
1133 | if (uurb->buffer_length > 0) { | ||
1134 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, | ||
1135 | GFP_KERNEL); | ||
1136 | if (!as->urb->transfer_buffer) { | ||
1137 | kfree(isopkt); | ||
1138 | kfree(dr); | ||
1139 | free_async(as); | ||
1140 | return -ENOMEM; | ||
1141 | } | ||
1142 | } | ||
1131 | as->urb->dev = ps->dev; | 1143 | as->urb->dev = ps->dev; |
1132 | as->urb->pipe = (uurb->type << 30) | | 1144 | as->urb->pipe = (uurb->type << 30) | |
1133 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | | 1145 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | |
@@ -1169,7 +1181,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1169 | kfree(isopkt); | 1181 | kfree(isopkt); |
1170 | as->ps = ps; | 1182 | as->ps = ps; |
1171 | as->userurb = arg; | 1183 | as->userurb = arg; |
1172 | if (uurb->endpoint & USB_DIR_IN) | 1184 | if (is_in && uurb->buffer_length > 0) |
1173 | as->userbuffer = uurb->buffer; | 1185 | as->userbuffer = uurb->buffer; |
1174 | else | 1186 | else |
1175 | as->userbuffer = NULL; | 1187 | as->userbuffer = NULL; |
@@ -1179,9 +1191,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1179 | as->uid = cred->uid; | 1191 | as->uid = cred->uid; |
1180 | as->euid = cred->euid; | 1192 | as->euid = cred->euid; |
1181 | security_task_getsecid(current, &as->secid); | 1193 | security_task_getsecid(current, &as->secid); |
1182 | if (!is_in) { | 1194 | if (!is_in && uurb->buffer_length > 0) { |
1183 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, | 1195 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, |
1184 | as->urb->transfer_buffer_length)) { | 1196 | uurb->buffer_length)) { |
1185 | free_async(as); | 1197 | free_async(as); |
1186 | return -EFAULT; | 1198 | return -EFAULT; |
1187 | } | 1199 | } |
@@ -1231,22 +1243,22 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1231 | if (as->userbuffer) | 1243 | if (as->userbuffer) |
1232 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, | 1244 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, |
1233 | urb->transfer_buffer_length)) | 1245 | urb->transfer_buffer_length)) |
1234 | return -EFAULT; | 1246 | goto err_out; |
1235 | if (put_user(as->status, &userurb->status)) | 1247 | if (put_user(as->status, &userurb->status)) |
1236 | return -EFAULT; | 1248 | goto err_out; |
1237 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1249 | if (put_user(urb->actual_length, &userurb->actual_length)) |
1238 | return -EFAULT; | 1250 | goto err_out; |
1239 | if (put_user(urb->error_count, &userurb->error_count)) | 1251 | if (put_user(urb->error_count, &userurb->error_count)) |
1240 | return -EFAULT; | 1252 | goto err_out; |
1241 | 1253 | ||
1242 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { | 1254 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { |
1243 | for (i = 0; i < urb->number_of_packets; i++) { | 1255 | for (i = 0; i < urb->number_of_packets; i++) { |
1244 | if (put_user(urb->iso_frame_desc[i].actual_length, | 1256 | if (put_user(urb->iso_frame_desc[i].actual_length, |
1245 | &userurb->iso_frame_desc[i].actual_length)) | 1257 | &userurb->iso_frame_desc[i].actual_length)) |
1246 | return -EFAULT; | 1258 | goto err_out; |
1247 | if (put_user(urb->iso_frame_desc[i].status, | 1259 | if (put_user(urb->iso_frame_desc[i].status, |
1248 | &userurb->iso_frame_desc[i].status)) | 1260 | &userurb->iso_frame_desc[i].status)) |
1249 | return -EFAULT; | 1261 | goto err_out; |
1250 | } | 1262 | } |
1251 | } | 1263 | } |
1252 | 1264 | ||
@@ -1255,6 +1267,10 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1255 | if (put_user(addr, (void __user * __user *)arg)) | 1267 | if (put_user(addr, (void __user * __user *)arg)) |
1256 | return -EFAULT; | 1268 | return -EFAULT; |
1257 | return 0; | 1269 | return 0; |
1270 | |||
1271 | err_out: | ||
1272 | free_async(as); | ||
1273 | return -EFAULT; | ||
1258 | } | 1274 | } |
1259 | 1275 | ||
1260 | static struct async *reap_as(struct dev_state *ps) | 1276 | static struct async *reap_as(struct dev_state *ps) |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index d397ecfd5b17..ec5c67ea07b7 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -227,6 +227,10 @@ struct hc_driver { | |||
227 | /* has a port been handed over to a companion? */ | 227 | /* has a port been handed over to a companion? */ |
228 | int (*port_handed_over)(struct usb_hcd *, int); | 228 | int (*port_handed_over)(struct usb_hcd *, int); |
229 | 229 | ||
230 | /* CLEAR_TT_BUFFER completion callback */ | ||
231 | void (*clear_tt_buffer_complete)(struct usb_hcd *, | ||
232 | struct usb_host_endpoint *); | ||
233 | |||
230 | /* xHCI specific functions */ | 234 | /* xHCI specific functions */ |
231 | /* Called by usb_alloc_dev to alloc HC device structures */ | 235 | /* Called by usb_alloc_dev to alloc HC device structures */ |
232 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); | 236 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2af3b4f06054..71f86c60d83c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -450,10 +450,10 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) | |||
450 | * talking to TTs must queue control transfers (not just bulk and iso), so | 450 | * talking to TTs must queue control transfers (not just bulk and iso), so |
451 | * both can talk to the same hub concurrently. | 451 | * both can talk to the same hub concurrently. |
452 | */ | 452 | */ |
453 | static void hub_tt_kevent (struct work_struct *work) | 453 | static void hub_tt_work(struct work_struct *work) |
454 | { | 454 | { |
455 | struct usb_hub *hub = | 455 | struct usb_hub *hub = |
456 | container_of(work, struct usb_hub, tt.kevent); | 456 | container_of(work, struct usb_hub, tt.clear_work); |
457 | unsigned long flags; | 457 | unsigned long flags; |
458 | int limit = 100; | 458 | int limit = 100; |
459 | 459 | ||
@@ -462,6 +462,7 @@ static void hub_tt_kevent (struct work_struct *work) | |||
462 | struct list_head *next; | 462 | struct list_head *next; |
463 | struct usb_tt_clear *clear; | 463 | struct usb_tt_clear *clear; |
464 | struct usb_device *hdev = hub->hdev; | 464 | struct usb_device *hdev = hub->hdev; |
465 | const struct hc_driver *drv; | ||
465 | int status; | 466 | int status; |
466 | 467 | ||
467 | next = hub->tt.clear_list.next; | 468 | next = hub->tt.clear_list.next; |
@@ -471,21 +472,25 @@ static void hub_tt_kevent (struct work_struct *work) | |||
471 | /* drop lock so HCD can concurrently report other TT errors */ | 472 | /* drop lock so HCD can concurrently report other TT errors */ |
472 | spin_unlock_irqrestore (&hub->tt.lock, flags); | 473 | spin_unlock_irqrestore (&hub->tt.lock, flags); |
473 | status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt); | 474 | status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt); |
474 | spin_lock_irqsave (&hub->tt.lock, flags); | ||
475 | |||
476 | if (status) | 475 | if (status) |
477 | dev_err (&hdev->dev, | 476 | dev_err (&hdev->dev, |
478 | "clear tt %d (%04x) error %d\n", | 477 | "clear tt %d (%04x) error %d\n", |
479 | clear->tt, clear->devinfo, status); | 478 | clear->tt, clear->devinfo, status); |
479 | |||
480 | /* Tell the HCD, even if the operation failed */ | ||
481 | drv = clear->hcd->driver; | ||
482 | if (drv->clear_tt_buffer_complete) | ||
483 | (drv->clear_tt_buffer_complete)(clear->hcd, clear->ep); | ||
484 | |||
480 | kfree(clear); | 485 | kfree(clear); |
486 | spin_lock_irqsave(&hub->tt.lock, flags); | ||
481 | } | 487 | } |
482 | spin_unlock_irqrestore (&hub->tt.lock, flags); | 488 | spin_unlock_irqrestore (&hub->tt.lock, flags); |
483 | } | 489 | } |
484 | 490 | ||
485 | /** | 491 | /** |
486 | * usb_hub_tt_clear_buffer - clear control/bulk TT state in high speed hub | 492 | * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub |
487 | * @udev: the device whose split transaction failed | 493 | * @urb: an URB associated with the failed or incomplete split transaction |
488 | * @pipe: identifies the endpoint of the failed transaction | ||
489 | * | 494 | * |
490 | * High speed HCDs use this to tell the hub driver that some split control or | 495 | * High speed HCDs use this to tell the hub driver that some split control or |
491 | * bulk transaction failed in a way that requires clearing internal state of | 496 | * bulk transaction failed in a way that requires clearing internal state of |
@@ -495,8 +500,10 @@ static void hub_tt_kevent (struct work_struct *work) | |||
495 | * It may not be possible for that hub to handle additional full (or low) | 500 | * It may not be possible for that hub to handle additional full (or low) |
496 | * speed transactions until that state is fully cleared out. | 501 | * speed transactions until that state is fully cleared out. |
497 | */ | 502 | */ |
498 | void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | 503 | int usb_hub_clear_tt_buffer(struct urb *urb) |
499 | { | 504 | { |
505 | struct usb_device *udev = urb->dev; | ||
506 | int pipe = urb->pipe; | ||
500 | struct usb_tt *tt = udev->tt; | 507 | struct usb_tt *tt = udev->tt; |
501 | unsigned long flags; | 508 | unsigned long flags; |
502 | struct usb_tt_clear *clear; | 509 | struct usb_tt_clear *clear; |
@@ -508,7 +515,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | |||
508 | if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { | 515 | if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { |
509 | dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); | 516 | dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); |
510 | /* FIXME recover somehow ... RESET_TT? */ | 517 | /* FIXME recover somehow ... RESET_TT? */ |
511 | return; | 518 | return -ENOMEM; |
512 | } | 519 | } |
513 | 520 | ||
514 | /* info that CLEAR_TT_BUFFER needs */ | 521 | /* info that CLEAR_TT_BUFFER needs */ |
@@ -520,14 +527,19 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | |||
520 | : (USB_ENDPOINT_XFER_BULK << 11); | 527 | : (USB_ENDPOINT_XFER_BULK << 11); |
521 | if (usb_pipein (pipe)) | 528 | if (usb_pipein (pipe)) |
522 | clear->devinfo |= 1 << 15; | 529 | clear->devinfo |= 1 << 15; |
523 | 530 | ||
531 | /* info for completion callback */ | ||
532 | clear->hcd = bus_to_hcd(udev->bus); | ||
533 | clear->ep = urb->ep; | ||
534 | |||
524 | /* tell keventd to clear state for this TT */ | 535 | /* tell keventd to clear state for this TT */ |
525 | spin_lock_irqsave (&tt->lock, flags); | 536 | spin_lock_irqsave (&tt->lock, flags); |
526 | list_add_tail (&clear->clear_list, &tt->clear_list); | 537 | list_add_tail (&clear->clear_list, &tt->clear_list); |
527 | schedule_work (&tt->kevent); | 538 | schedule_work(&tt->clear_work); |
528 | spin_unlock_irqrestore (&tt->lock, flags); | 539 | spin_unlock_irqrestore (&tt->lock, flags); |
540 | return 0; | ||
529 | } | 541 | } |
530 | EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer); | 542 | EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer); |
531 | 543 | ||
532 | /* If do_delay is false, return the number of milliseconds the caller | 544 | /* If do_delay is false, return the number of milliseconds the caller |
533 | * needs to delay. | 545 | * needs to delay. |
@@ -818,7 +830,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) | |||
818 | if (hub->has_indicators) | 830 | if (hub->has_indicators) |
819 | cancel_delayed_work_sync(&hub->leds); | 831 | cancel_delayed_work_sync(&hub->leds); |
820 | if (hub->tt.hub) | 832 | if (hub->tt.hub) |
821 | cancel_work_sync(&hub->tt.kevent); | 833 | cancel_work_sync(&hub->tt.clear_work); |
822 | } | 834 | } |
823 | 835 | ||
824 | /* caller has locked the hub device */ | 836 | /* caller has locked the hub device */ |
@@ -935,7 +947,7 @@ static int hub_configure(struct usb_hub *hub, | |||
935 | 947 | ||
936 | spin_lock_init (&hub->tt.lock); | 948 | spin_lock_init (&hub->tt.lock); |
937 | INIT_LIST_HEAD (&hub->tt.clear_list); | 949 | INIT_LIST_HEAD (&hub->tt.clear_list); |
938 | INIT_WORK (&hub->tt.kevent, hub_tt_kevent); | 950 | INIT_WORK(&hub->tt.clear_work, hub_tt_work); |
939 | switch (hdev->descriptor.bDeviceProtocol) { | 951 | switch (hdev->descriptor.bDeviceProtocol) { |
940 | case 0: | 952 | case 0: |
941 | break; | 953 | break; |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 889c0f32a40b..de8081f065ed 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
@@ -188,16 +188,18 @@ struct usb_tt { | |||
188 | /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ | 188 | /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ |
189 | spinlock_t lock; | 189 | spinlock_t lock; |
190 | struct list_head clear_list; /* of usb_tt_clear */ | 190 | struct list_head clear_list; /* of usb_tt_clear */ |
191 | struct work_struct kevent; | 191 | struct work_struct clear_work; |
192 | }; | 192 | }; |
193 | 193 | ||
194 | struct usb_tt_clear { | 194 | struct usb_tt_clear { |
195 | struct list_head clear_list; | 195 | struct list_head clear_list; |
196 | unsigned tt; | 196 | unsigned tt; |
197 | u16 devinfo; | 197 | u16 devinfo; |
198 | struct usb_hcd *hcd; | ||
199 | struct usb_host_endpoint *ep; | ||
198 | }; | 200 | }; |
199 | 201 | ||
200 | extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe); | 202 | extern int usb_hub_clear_tt_buffer(struct urb *urb); |
201 | extern void usb_ep0_reinit(struct usb_device *); | 203 | extern void usb_ep0_reinit(struct usb_device *); |
202 | 204 | ||
203 | #endif /* __LINUX_HUB_H */ | 205 | #endif /* __LINUX_HUB_H */ |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 2bed83caacb1..9720e699f472 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid, | |||
806 | return rc; | 806 | return rc; |
807 | } | 807 | } |
808 | 808 | ||
809 | static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf) | ||
810 | { | ||
811 | int err; | ||
812 | |||
813 | if (dev->have_langid) | ||
814 | return 0; | ||
815 | |||
816 | if (dev->string_langid < 0) | ||
817 | return -EPIPE; | ||
818 | |||
819 | err = usb_string_sub(dev, 0, 0, tbuf); | ||
820 | |||
821 | /* If the string was reported but is malformed, default to english | ||
822 | * (0x0409) */ | ||
823 | if (err == -ENODATA || (err > 0 && err < 4)) { | ||
824 | dev->string_langid = 0x0409; | ||
825 | dev->have_langid = 1; | ||
826 | dev_err(&dev->dev, | ||
827 | "string descriptor 0 malformed (err = %d), " | ||
828 | "defaulting to 0x%04x\n", | ||
829 | err, dev->string_langid); | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | /* In case of all other errors, we assume the device is not able to | ||
834 | * deal with strings at all. Set string_langid to -1 in order to | ||
835 | * prevent any string to be retrieved from the device */ | ||
836 | if (err < 0) { | ||
837 | dev_err(&dev->dev, "string descriptor 0 read error: %d\n", | ||
838 | err); | ||
839 | dev->string_langid = -1; | ||
840 | return -EPIPE; | ||
841 | } | ||
842 | |||
843 | /* always use the first langid listed */ | ||
844 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | ||
845 | dev->have_langid = 1; | ||
846 | dev_dbg(&dev->dev, "default language 0x%04x\n", | ||
847 | dev->string_langid); | ||
848 | return 0; | ||
849 | } | ||
850 | |||
809 | /** | 851 | /** |
810 | * usb_string - returns UTF-8 version of a string descriptor | 852 | * usb_string - returns UTF-8 version of a string descriptor |
811 | * @dev: the device whose string descriptor is being retrieved | 853 | * @dev: the device whose string descriptor is being retrieved |
@@ -837,24 +879,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
837 | if (!tbuf) | 879 | if (!tbuf) |
838 | return -ENOMEM; | 880 | return -ENOMEM; |
839 | 881 | ||
840 | /* get langid for strings if it's not yet known */ | 882 | err = usb_get_langid(dev, tbuf); |
841 | if (!dev->have_langid) { | 883 | if (err < 0) |
842 | err = usb_string_sub(dev, 0, 0, tbuf); | 884 | goto errout; |
843 | if (err < 0) { | ||
844 | dev_err(&dev->dev, | ||
845 | "string descriptor 0 read error: %d\n", | ||
846 | err); | ||
847 | } else if (err < 4) { | ||
848 | dev_err(&dev->dev, "string descriptor 0 too short\n"); | ||
849 | } else { | ||
850 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | ||
851 | /* always use the first langid listed */ | ||
852 | dev_dbg(&dev->dev, "default language 0x%04x\n", | ||
853 | dev->string_langid); | ||
854 | } | ||
855 | |||
856 | dev->have_langid = 1; | ||
857 | } | ||
858 | 885 | ||
859 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); | 886 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); |
860 | if (err < 0) | 887 | if (err < 0) |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 5d1ddf485d1e..7f8e83a954ac 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -286,6 +286,27 @@ config USB_S3C_HSOTG | |||
286 | default USB_GADGET | 286 | default USB_GADGET |
287 | select USB_GADGET_SELECTED | 287 | select USB_GADGET_SELECTED |
288 | 288 | ||
289 | config USB_GADGET_IMX | ||
290 | boolean "Freescale IMX USB Peripheral Controller" | ||
291 | depends on ARCH_MX1 | ||
292 | help | ||
293 | Freescale's IMX series include an integrated full speed | ||
294 | USB 1.1 device controller. The controller in the IMX series | ||
295 | is register-compatible. | ||
296 | |||
297 | It has Six fixed-function endpoints, as well as endpoint | ||
298 | zero (for control transfers). | ||
299 | |||
300 | Say "y" to link the driver statically, or "m" to build a | ||
301 | dynamically linked module called "imx_udc" and force all | ||
302 | gadget drivers to also be dynamically linked. | ||
303 | |||
304 | config USB_IMX | ||
305 | tristate | ||
306 | depends on USB_GADGET_IMX | ||
307 | default USB_GADGET | ||
308 | select USB_GADGET_SELECTED | ||
309 | |||
289 | config USB_GADGET_S3C2410 | 310 | config USB_GADGET_S3C2410 |
290 | boolean "S3C2410 USB Device Controller" | 311 | boolean "S3C2410 USB Device Controller" |
291 | depends on ARCH_S3C2410 | 312 | depends on ARCH_S3C2410 |
@@ -321,27 +342,6 @@ config USB_GADGET_MUSB_HDRC | |||
321 | This OTG-capable silicon IP is used in dual designs including | 342 | This OTG-capable silicon IP is used in dual designs including |
322 | the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin | 343 | the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin |
323 | 344 | ||
324 | config USB_GADGET_IMX | ||
325 | boolean "Freescale IMX USB Peripheral Controller" | ||
326 | depends on ARCH_MX1 | ||
327 | help | ||
328 | Freescale's IMX series include an integrated full speed | ||
329 | USB 1.1 device controller. The controller in the IMX series | ||
330 | is register-compatible. | ||
331 | |||
332 | It has Six fixed-function endpoints, as well as endpoint | ||
333 | zero (for control transfers). | ||
334 | |||
335 | Say "y" to link the driver statically, or "m" to build a | ||
336 | dynamically linked module called "imx_udc" and force all | ||
337 | gadget drivers to also be dynamically linked. | ||
338 | |||
339 | config USB_IMX | ||
340 | tristate | ||
341 | depends on USB_GADGET_IMX | ||
342 | default USB_GADGET | ||
343 | select USB_GADGET_SELECTED | ||
344 | |||
345 | config USB_GADGET_M66592 | 345 | config USB_GADGET_M66592 |
346 | boolean "Renesas M66592 USB Peripheral Controller" | 346 | boolean "Renesas M66592 USB Peripheral Controller" |
347 | select USB_GADGET_DUALSPEED | 347 | select USB_GADGET_DUALSPEED |
@@ -604,6 +604,7 @@ config USB_ZERO_HNPTEST | |||
604 | config USB_AUDIO | 604 | config USB_AUDIO |
605 | tristate "Audio Gadget (EXPERIMENTAL)" | 605 | tristate "Audio Gadget (EXPERIMENTAL)" |
606 | depends on SND | 606 | depends on SND |
607 | select SND_PCM | ||
607 | help | 608 | help |
608 | Gadget Audio is compatible with USB Audio Class specification 1.0. | 609 | Gadget Audio is compatible with USB Audio Class specification 1.0. |
609 | It will include at least one AudioControl interface, zero or more | 610 | It will include at least one AudioControl interface, zero or more |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 826f3adde5d8..77352ccc245e 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <linux/ioport.h> | 48 | #include <linux/ioport.h> |
49 | #include <linux/sched.h> | 49 | #include <linux/sched.h> |
50 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
51 | #include <linux/smp_lock.h> | ||
52 | #include <linux/errno.h> | 51 | #include <linux/errno.h> |
53 | #include <linux/init.h> | 52 | #include <linux/init.h> |
54 | #include <linux/timer.h> | 53 | #include <linux/timer.h> |
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 94de7e864614..9f80f4e970bd 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c | |||
@@ -42,9 +42,9 @@ | |||
42 | * Instead: allocate your own, using normal USB-IF procedures. | 42 | * Instead: allocate your own, using normal USB-IF procedures. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | /* Thanks to NetChip Technologies for donating this product ID. */ | 45 | /* Thanks to Linux Foundation for donating this product ID. */ |
46 | #define AUDIO_VENDOR_NUM 0x0525 /* NetChip */ | 46 | #define AUDIO_VENDOR_NUM 0x1d6b /* Linux Foundation */ |
47 | #define AUDIO_PRODUCT_NUM 0xa4a1 /* Linux-USB Audio Gadget */ | 47 | #define AUDIO_PRODUCT_NUM 0x0101 /* Linux-USB Audio Gadget */ |
48 | 48 | ||
49 | /*-------------------------------------------------------------------------*/ | 49 | /*-------------------------------------------------------------------------*/ |
50 | 50 | ||
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index d006dc652e02..bd102f5052ba 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -293,15 +293,16 @@ static int __init eth_bind(struct usb_composite_dev *cdev) | |||
293 | /* CDC Subset */ | 293 | /* CDC Subset */ |
294 | eth_config_driver.label = "CDC Subset/SAFE"; | 294 | eth_config_driver.label = "CDC Subset/SAFE"; |
295 | 295 | ||
296 | device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM), | 296 | device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM); |
297 | device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM), | 297 | device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM); |
298 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | 298 | if (!has_rndis()) |
299 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | ||
299 | } | 300 | } |
300 | 301 | ||
301 | if (has_rndis()) { | 302 | if (has_rndis()) { |
302 | /* RNDIS plus ECM-or-Subset */ | 303 | /* RNDIS plus ECM-or-Subset */ |
303 | device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM), | 304 | device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM); |
304 | device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM), | 305 | device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM); |
305 | device_desc.bNumConfigurations = 2; | 306 | device_desc.bNumConfigurations = 2; |
306 | } | 307 | } |
307 | 308 | ||
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index 6829d5961359..a3913519fd58 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/ioport.h> | 34 | #include <linux/ioport.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/errno.h> | 37 | #include <linux/errno.h> |
39 | #include <linux/init.h> | 38 | #include <linux/init.h> |
40 | #include <linux/timer.h> | 39 | #include <linux/timer.h> |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 0ce4e2819847..ed21e263f832 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -139,7 +139,7 @@ static int is_vbus_present(void) | |||
139 | { | 139 | { |
140 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 140 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
141 | 141 | ||
142 | if (mach->gpio_vbus) { | 142 | if (gpio_is_valid(mach->gpio_vbus)) { |
143 | int value = gpio_get_value(mach->gpio_vbus); | 143 | int value = gpio_get_value(mach->gpio_vbus); |
144 | 144 | ||
145 | if (mach->gpio_vbus_inverted) | 145 | if (mach->gpio_vbus_inverted) |
@@ -158,7 +158,7 @@ static void pullup_off(void) | |||
158 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 158 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
159 | int off_level = mach->gpio_pullup_inverted; | 159 | int off_level = mach->gpio_pullup_inverted; |
160 | 160 | ||
161 | if (mach->gpio_pullup) | 161 | if (gpio_is_valid(mach->gpio_pullup)) |
162 | gpio_set_value(mach->gpio_pullup, off_level); | 162 | gpio_set_value(mach->gpio_pullup, off_level); |
163 | else if (mach->udc_command) | 163 | else if (mach->udc_command) |
164 | mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | 164 | mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); |
@@ -169,7 +169,7 @@ static void pullup_on(void) | |||
169 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 169 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
170 | int on_level = !mach->gpio_pullup_inverted; | 170 | int on_level = !mach->gpio_pullup_inverted; |
171 | 171 | ||
172 | if (mach->gpio_pullup) | 172 | if (gpio_is_valid(mach->gpio_pullup)) |
173 | gpio_set_value(mach->gpio_pullup, on_level); | 173 | gpio_set_value(mach->gpio_pullup, on_level); |
174 | else if (mach->udc_command) | 174 | else if (mach->udc_command) |
175 | mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | 175 | mach->udc_command(PXA2XX_UDC_CMD_CONNECT); |
@@ -1000,7 +1000,7 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active) | |||
1000 | udc = container_of(_gadget, struct pxa25x_udc, gadget); | 1000 | udc = container_of(_gadget, struct pxa25x_udc, gadget); |
1001 | 1001 | ||
1002 | /* not all boards support pullup control */ | 1002 | /* not all boards support pullup control */ |
1003 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) | 1003 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) |
1004 | return -EOPNOTSUPP; | 1004 | return -EOPNOTSUPP; |
1005 | 1005 | ||
1006 | udc->pullup = (is_active != 0); | 1006 | udc->pullup = (is_active != 0); |
@@ -1802,11 +1802,13 @@ pxa25x_udc_irq(int irq, void *_dev) | |||
1802 | USIR0 |= tmp; | 1802 | USIR0 |= tmp; |
1803 | handled = 1; | 1803 | handled = 1; |
1804 | } | 1804 | } |
1805 | #ifndef CONFIG_USB_PXA25X_SMALL | ||
1805 | if (usir1 & tmp) { | 1806 | if (usir1 & tmp) { |
1806 | handle_ep(&dev->ep[i+8]); | 1807 | handle_ep(&dev->ep[i+8]); |
1807 | USIR1 |= tmp; | 1808 | USIR1 |= tmp; |
1808 | handled = 1; | 1809 | handled = 1; |
1809 | } | 1810 | } |
1811 | #endif | ||
1810 | } | 1812 | } |
1811 | } | 1813 | } |
1812 | 1814 | ||
@@ -2160,7 +2162,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2160 | dev->dev = &pdev->dev; | 2162 | dev->dev = &pdev->dev; |
2161 | dev->mach = pdev->dev.platform_data; | 2163 | dev->mach = pdev->dev.platform_data; |
2162 | 2164 | ||
2163 | if (dev->mach->gpio_vbus) { | 2165 | if (gpio_is_valid(dev->mach->gpio_vbus)) { |
2164 | if ((retval = gpio_request(dev->mach->gpio_vbus, | 2166 | if ((retval = gpio_request(dev->mach->gpio_vbus, |
2165 | "pxa25x_udc GPIO VBUS"))) { | 2167 | "pxa25x_udc GPIO VBUS"))) { |
2166 | dev_dbg(&pdev->dev, | 2168 | dev_dbg(&pdev->dev, |
@@ -2173,7 +2175,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2173 | } else | 2175 | } else |
2174 | vbus_irq = 0; | 2176 | vbus_irq = 0; |
2175 | 2177 | ||
2176 | if (dev->mach->gpio_pullup) { | 2178 | if (gpio_is_valid(dev->mach->gpio_pullup)) { |
2177 | if ((retval = gpio_request(dev->mach->gpio_pullup, | 2179 | if ((retval = gpio_request(dev->mach->gpio_pullup, |
2178 | "pca25x_udc GPIO PULLUP"))) { | 2180 | "pca25x_udc GPIO PULLUP"))) { |
2179 | dev_dbg(&pdev->dev, | 2181 | dev_dbg(&pdev->dev, |
@@ -2256,10 +2258,10 @@ lubbock_fail0: | |||
2256 | #endif | 2258 | #endif |
2257 | free_irq(irq, dev); | 2259 | free_irq(irq, dev); |
2258 | err_irq1: | 2260 | err_irq1: |
2259 | if (dev->mach->gpio_pullup) | 2261 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
2260 | gpio_free(dev->mach->gpio_pullup); | 2262 | gpio_free(dev->mach->gpio_pullup); |
2261 | err_gpio_pullup: | 2263 | err_gpio_pullup: |
2262 | if (dev->mach->gpio_vbus) | 2264 | if (gpio_is_valid(dev->mach->gpio_vbus)) |
2263 | gpio_free(dev->mach->gpio_vbus); | 2265 | gpio_free(dev->mach->gpio_vbus); |
2264 | err_gpio_vbus: | 2266 | err_gpio_vbus: |
2265 | clk_put(dev->clk); | 2267 | clk_put(dev->clk); |
@@ -2294,11 +2296,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) | |||
2294 | free_irq(LUBBOCK_USB_IRQ, dev); | 2296 | free_irq(LUBBOCK_USB_IRQ, dev); |
2295 | } | 2297 | } |
2296 | #endif | 2298 | #endif |
2297 | if (dev->mach->gpio_vbus) { | 2299 | if (gpio_is_valid(dev->mach->gpio_vbus)) { |
2298 | free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); | 2300 | free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); |
2299 | gpio_free(dev->mach->gpio_vbus); | 2301 | gpio_free(dev->mach->gpio_vbus); |
2300 | } | 2302 | } |
2301 | if (dev->mach->gpio_pullup) | 2303 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
2302 | gpio_free(dev->mach->gpio_pullup); | 2304 | gpio_free(dev->mach->gpio_pullup); |
2303 | 2305 | ||
2304 | clk_put(dev->clk); | 2306 | clk_put(dev->clk); |
@@ -2329,7 +2331,7 @@ static int pxa25x_udc_suspend(struct platform_device *dev, pm_message_t state) | |||
2329 | struct pxa25x_udc *udc = platform_get_drvdata(dev); | 2331 | struct pxa25x_udc *udc = platform_get_drvdata(dev); |
2330 | unsigned long flags; | 2332 | unsigned long flags; |
2331 | 2333 | ||
2332 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) | 2334 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) |
2333 | WARNING("USB host won't detect disconnect!\n"); | 2335 | WARNING("USB host won't detect disconnect!\n"); |
2334 | udc->suspended = 1; | 2336 | udc->suspended = 1; |
2335 | 2337 | ||
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 2b4660e08c4d..ca41b0b5afb3 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -442,6 +442,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
442 | 442 | ||
443 | case OID_802_3_MAC_OPTIONS: | 443 | case OID_802_3_MAC_OPTIONS: |
444 | pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); | 444 | pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); |
445 | *outbuf = cpu_to_le32(0); | ||
446 | retval = 0; | ||
445 | break; | 447 | break; |
446 | 448 | ||
447 | /* ieee802.3 statistics OIDs (table 4-4) */ | 449 | /* ieee802.3 statistics OIDs (table 4-4) */ |
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 9a2b8920532d..a9b452fe6221 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
33 | #include <linux/init.h> | 32 | #include <linux/init.h> |
34 | #include <linux/timer.h> | 33 | #include <linux/timer.h> |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 0c03471f0d41..1a920c70b5a1 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -181,26 +181,27 @@ config USB_OHCI_HCD_PPC_SOC | |||
181 | Enables support for the USB controller on the MPC52xx or | 181 | Enables support for the USB controller on the MPC52xx or |
182 | STB03xxx processor chip. If unsure, say Y. | 182 | STB03xxx processor chip. If unsure, say Y. |
183 | 183 | ||
184 | config USB_OHCI_HCD_PPC_OF | ||
185 | bool "OHCI support for PPC USB controller on OF platform bus" | ||
186 | depends on USB_OHCI_HCD && PPC_OF | ||
187 | default y | ||
188 | ---help--- | ||
189 | Enables support for the USB controller PowerPC present on the | ||
190 | OpenFirmware platform bus. | ||
191 | |||
192 | config USB_OHCI_HCD_PPC_OF_BE | 184 | config USB_OHCI_HCD_PPC_OF_BE |
193 | bool "Support big endian HC" | 185 | bool "OHCI support for OF platform bus (big endian)" |
194 | depends on USB_OHCI_HCD_PPC_OF | 186 | depends on USB_OHCI_HCD && PPC_OF |
195 | default y | ||
196 | select USB_OHCI_BIG_ENDIAN_DESC | 187 | select USB_OHCI_BIG_ENDIAN_DESC |
197 | select USB_OHCI_BIG_ENDIAN_MMIO | 188 | select USB_OHCI_BIG_ENDIAN_MMIO |
189 | ---help--- | ||
190 | Enables support for big-endian USB controllers present on the | ||
191 | OpenFirmware platform bus. | ||
198 | 192 | ||
199 | config USB_OHCI_HCD_PPC_OF_LE | 193 | config USB_OHCI_HCD_PPC_OF_LE |
200 | bool "Support little endian HC" | 194 | bool "OHCI support for OF platform bus (little endian)" |
201 | depends on USB_OHCI_HCD_PPC_OF | 195 | depends on USB_OHCI_HCD && PPC_OF |
202 | default n | ||
203 | select USB_OHCI_LITTLE_ENDIAN | 196 | select USB_OHCI_LITTLE_ENDIAN |
197 | ---help--- | ||
198 | Enables support for little-endian USB controllers present on the | ||
199 | OpenFirmware platform bus. | ||
200 | |||
201 | config USB_OHCI_HCD_PPC_OF | ||
202 | bool | ||
203 | depends on USB_OHCI_HCD && PPC_OF | ||
204 | default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE | ||
204 | 205 | ||
205 | config USB_OHCI_HCD_PCI | 206 | config USB_OHCI_HCD_PCI |
206 | bool "OHCI support for PCI-bus USB controllers" | 207 | bool "OHCI support for PCI-bus USB controllers" |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index c3a778bd359c..59d208d94d4e 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -113,6 +113,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { | |||
113 | .bus_resume = ehci_bus_resume, | 113 | .bus_resume = ehci_bus_resume, |
114 | .relinquish_port = ehci_relinquish_port, | 114 | .relinquish_port = ehci_relinquish_port, |
115 | .port_handed_over = ehci_port_handed_over, | 115 | .port_handed_over = ehci_port_handed_over, |
116 | |||
117 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
116 | }; | 118 | }; |
117 | 119 | ||
118 | static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | 120 | static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index bf86809c5120..991174937db3 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -325,6 +325,8 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
325 | .bus_resume = ehci_bus_resume, | 325 | .bus_resume = ehci_bus_resume, |
326 | .relinquish_port = ehci_relinquish_port, | 326 | .relinquish_port = ehci_relinquish_port, |
327 | .port_handed_over = ehci_port_handed_over, | 327 | .port_handed_over = ehci_port_handed_over, |
328 | |||
329 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
328 | }; | 330 | }; |
329 | 331 | ||
330 | static int ehci_fsl_drv_probe(struct platform_device *pdev) | 332 | static int ehci_fsl_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2b72473544d3..7d03549c3339 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -1003,6 +1003,8 @@ idle_timeout: | |||
1003 | schedule_timeout_uninterruptible(1); | 1003 | schedule_timeout_uninterruptible(1); |
1004 | goto rescan; | 1004 | goto rescan; |
1005 | case QH_STATE_IDLE: /* fully unlinked */ | 1005 | case QH_STATE_IDLE: /* fully unlinked */ |
1006 | if (qh->clearing_tt) | ||
1007 | goto idle_timeout; | ||
1006 | if (list_empty (&qh->qtd_list)) { | 1008 | if (list_empty (&qh->qtd_list)) { |
1007 | qh_put (qh); | 1009 | qh_put (qh); |
1008 | break; | 1010 | break; |
@@ -1030,12 +1032,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) | |||
1030 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 1032 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
1031 | struct ehci_qh *qh; | 1033 | struct ehci_qh *qh; |
1032 | int eptype = usb_endpoint_type(&ep->desc); | 1034 | int eptype = usb_endpoint_type(&ep->desc); |
1035 | int epnum = usb_endpoint_num(&ep->desc); | ||
1036 | int is_out = usb_endpoint_dir_out(&ep->desc); | ||
1037 | unsigned long flags; | ||
1033 | 1038 | ||
1034 | if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT) | 1039 | if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT) |
1035 | return; | 1040 | return; |
1036 | 1041 | ||
1037 | rescan: | 1042 | spin_lock_irqsave(&ehci->lock, flags); |
1038 | spin_lock_irq(&ehci->lock); | ||
1039 | qh = ep->hcpriv; | 1043 | qh = ep->hcpriv; |
1040 | 1044 | ||
1041 | /* For Bulk and Interrupt endpoints we maintain the toggle state | 1045 | /* For Bulk and Interrupt endpoints we maintain the toggle state |
@@ -1044,29 +1048,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) | |||
1044 | * the toggle bit in the QH. | 1048 | * the toggle bit in the QH. |
1045 | */ | 1049 | */ |
1046 | if (qh) { | 1050 | if (qh) { |
1051 | usb_settoggle(qh->dev, epnum, is_out, 0); | ||
1047 | if (!list_empty(&qh->qtd_list)) { | 1052 | if (!list_empty(&qh->qtd_list)) { |
1048 | WARN_ONCE(1, "clear_halt for a busy endpoint\n"); | 1053 | WARN_ONCE(1, "clear_halt for a busy endpoint\n"); |
1049 | } else if (qh->qh_state == QH_STATE_IDLE) { | 1054 | } else if (qh->qh_state == QH_STATE_LINKED) { |
1050 | qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); | 1055 | |
1051 | } else { | 1056 | /* The toggle value in the QH can't be updated |
1052 | /* It's not safe to write into the overlay area | 1057 | * while the QH is active. Unlink it now; |
1053 | * while the QH is active. Unlink it first and | 1058 | * re-linking will call qh_refresh(). |
1054 | * wait for the unlink to complete. | ||
1055 | */ | 1059 | */ |
1056 | if (qh->qh_state == QH_STATE_LINKED) { | 1060 | if (eptype == USB_ENDPOINT_XFER_BULK) { |
1057 | if (eptype == USB_ENDPOINT_XFER_BULK) { | 1061 | unlink_async(ehci, qh); |
1058 | unlink_async(ehci, qh); | 1062 | } else { |
1059 | } else { | 1063 | intr_deschedule(ehci, qh); |
1060 | intr_deschedule(ehci, qh); | 1064 | (void) qh_schedule(ehci, qh); |
1061 | (void) qh_schedule(ehci, qh); | ||
1062 | } | ||
1063 | } | 1065 | } |
1064 | spin_unlock_irq(&ehci->lock); | ||
1065 | schedule_timeout_uninterruptible(1); | ||
1066 | goto rescan; | ||
1067 | } | 1066 | } |
1068 | } | 1067 | } |
1069 | spin_unlock_irq(&ehci->lock); | 1068 | spin_unlock_irqrestore(&ehci->lock, flags); |
1070 | } | 1069 | } |
1071 | 1070 | ||
1072 | static int ehci_get_frame (struct usb_hcd *hcd) | 1071 | static int ehci_get_frame (struct usb_hcd *hcd) |
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c index a44bb4a94954..89b7c70c6ed6 100644 --- a/drivers/usb/host/ehci-ixp4xx.c +++ b/drivers/usb/host/ehci-ixp4xx.c | |||
@@ -61,6 +61,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = { | |||
61 | #endif | 61 | #endif |
62 | .relinquish_port = ehci_relinquish_port, | 62 | .relinquish_port = ehci_relinquish_port, |
63 | .port_handed_over = ehci_port_handed_over, | 63 | .port_handed_over = ehci_port_handed_over, |
64 | |||
65 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
64 | }; | 66 | }; |
65 | 67 | ||
66 | static int ixp4xx_ehci_probe(struct platform_device *pdev) | 68 | static int ixp4xx_ehci_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 770dd9aba62a..1d283e1b2b8d 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c | |||
@@ -105,6 +105,7 @@ static int ehci_orion_setup(struct usb_hcd *hcd) | |||
105 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 105 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
106 | int retval; | 106 | int retval; |
107 | 107 | ||
108 | ehci_reset(ehci); | ||
108 | retval = ehci_halt(ehci); | 109 | retval = ehci_halt(ehci); |
109 | if (retval) | 110 | if (retval) |
110 | return retval; | 111 | return retval; |
@@ -118,7 +119,6 @@ static int ehci_orion_setup(struct usb_hcd *hcd) | |||
118 | 119 | ||
119 | hcd->has_tt = 1; | 120 | hcd->has_tt = 1; |
120 | 121 | ||
121 | ehci_reset(ehci); | ||
122 | ehci_port_power(ehci, 0); | 122 | ehci_port_power(ehci, 0); |
123 | 123 | ||
124 | return retval; | 124 | return retval; |
@@ -165,6 +165,8 @@ static const struct hc_driver ehci_orion_hc_driver = { | |||
165 | .bus_resume = ehci_bus_resume, | 165 | .bus_resume = ehci_bus_resume, |
166 | .relinquish_port = ehci_relinquish_port, | 166 | .relinquish_port = ehci_relinquish_port, |
167 | .port_handed_over = ehci_port_handed_over, | 167 | .port_handed_over = ehci_port_handed_over, |
168 | |||
169 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
168 | }; | 170 | }; |
169 | 171 | ||
170 | static void __init | 172 | static void __init |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index f3683e1da161..c2f1b7df918c 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -404,6 +404,8 @@ static const struct hc_driver ehci_pci_hc_driver = { | |||
404 | .bus_resume = ehci_bus_resume, | 404 | .bus_resume = ehci_bus_resume, |
405 | .relinquish_port = ehci_relinquish_port, | 405 | .relinquish_port = ehci_relinquish_port, |
406 | .port_handed_over = ehci_port_handed_over, | 406 | .port_handed_over = ehci_port_handed_over, |
407 | |||
408 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
407 | }; | 409 | }; |
408 | 410 | ||
409 | /*-------------------------------------------------------------------------*/ | 411 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index fbd272288fc2..36f96da129f5 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c | |||
@@ -79,6 +79,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { | |||
79 | #endif | 79 | #endif |
80 | .relinquish_port = ehci_relinquish_port, | 80 | .relinquish_port = ehci_relinquish_port, |
81 | .port_handed_over = ehci_port_handed_over, | 81 | .port_handed_over = ehci_port_handed_over, |
82 | |||
83 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
82 | }; | 84 | }; |
83 | 85 | ||
84 | 86 | ||
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 93f7035d00a1..1dee33b9139e 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -75,6 +75,8 @@ static const struct hc_driver ps3_ehci_hc_driver = { | |||
75 | #endif | 75 | #endif |
76 | .relinquish_port = ehci_relinquish_port, | 76 | .relinquish_port = ehci_relinquish_port, |
77 | .port_handed_over = ehci_port_handed_over, | 77 | .port_handed_over = ehci_port_handed_over, |
78 | |||
79 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
78 | }; | 80 | }; |
79 | 81 | ||
80 | static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev) | 82 | static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev) |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 3192f683f807..9a1384747f3b 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -93,6 +93,22 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) | |||
93 | qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); | 93 | qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); |
94 | qh->hw_alt_next = EHCI_LIST_END(ehci); | 94 | qh->hw_alt_next = EHCI_LIST_END(ehci); |
95 | 95 | ||
96 | /* Except for control endpoints, we make hardware maintain data | ||
97 | * toggle (like OHCI) ... here (re)initialize the toggle in the QH, | ||
98 | * and set the pseudo-toggle in udev. Only usb_clear_halt() will | ||
99 | * ever clear it. | ||
100 | */ | ||
101 | if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { | ||
102 | unsigned is_out, epnum; | ||
103 | |||
104 | is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); | ||
105 | epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f; | ||
106 | if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { | ||
107 | qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); | ||
108 | usb_settoggle (qh->dev, epnum, is_out, 1); | ||
109 | } | ||
110 | } | ||
111 | |||
96 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ | 112 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ |
97 | wmb (); | 113 | wmb (); |
98 | qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); | 114 | qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); |
@@ -123,6 +139,55 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
123 | 139 | ||
124 | /*-------------------------------------------------------------------------*/ | 140 | /*-------------------------------------------------------------------------*/ |
125 | 141 | ||
142 | static void qh_link_async(struct ehci_hcd *ehci, struct ehci_qh *qh); | ||
143 | |||
144 | static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd, | ||
145 | struct usb_host_endpoint *ep) | ||
146 | { | ||
147 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
148 | struct ehci_qh *qh = ep->hcpriv; | ||
149 | unsigned long flags; | ||
150 | |||
151 | spin_lock_irqsave(&ehci->lock, flags); | ||
152 | qh->clearing_tt = 0; | ||
153 | if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list) | ||
154 | && HC_IS_RUNNING(hcd->state)) | ||
155 | qh_link_async(ehci, qh); | ||
156 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
157 | } | ||
158 | |||
159 | static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, struct ehci_qh *qh, | ||
160 | struct urb *urb, u32 token) | ||
161 | { | ||
162 | |||
163 | /* If an async split transaction gets an error or is unlinked, | ||
164 | * the TT buffer may be left in an indeterminate state. We | ||
165 | * have to clear the TT buffer. | ||
166 | * | ||
167 | * Note: this routine is never called for Isochronous transfers. | ||
168 | */ | ||
169 | if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) { | ||
170 | #ifdef DEBUG | ||
171 | struct usb_device *tt = urb->dev->tt->hub; | ||
172 | dev_dbg(&tt->dev, | ||
173 | "clear tt buffer port %d, a%d ep%d t%08x\n", | ||
174 | urb->dev->ttport, urb->dev->devnum, | ||
175 | usb_pipeendpoint(urb->pipe), token); | ||
176 | #endif /* DEBUG */ | ||
177 | if (!ehci_is_TDI(ehci) | ||
178 | || urb->dev->tt->hub != | ||
179 | ehci_to_hcd(ehci)->self.root_hub) { | ||
180 | if (usb_hub_clear_tt_buffer(urb) == 0) | ||
181 | qh->clearing_tt = 1; | ||
182 | } else { | ||
183 | |||
184 | /* REVISIT ARC-derived cores don't clear the root | ||
185 | * hub TT buffer in this way... | ||
186 | */ | ||
187 | } | ||
188 | } | ||
189 | } | ||
190 | |||
126 | static int qtd_copy_status ( | 191 | static int qtd_copy_status ( |
127 | struct ehci_hcd *ehci, | 192 | struct ehci_hcd *ehci, |
128 | struct urb *urb, | 193 | struct urb *urb, |
@@ -149,6 +214,14 @@ static int qtd_copy_status ( | |||
149 | if (token & QTD_STS_BABBLE) { | 214 | if (token & QTD_STS_BABBLE) { |
150 | /* FIXME "must" disable babbling device's port too */ | 215 | /* FIXME "must" disable babbling device's port too */ |
151 | status = -EOVERFLOW; | 216 | status = -EOVERFLOW; |
217 | /* CERR nonzero + halt --> stall */ | ||
218 | } else if (QTD_CERR(token)) { | ||
219 | status = -EPIPE; | ||
220 | |||
221 | /* In theory, more than one of the following bits can be set | ||
222 | * since they are sticky and the transaction is retried. | ||
223 | * Which to test first is rather arbitrary. | ||
224 | */ | ||
152 | } else if (token & QTD_STS_MMF) { | 225 | } else if (token & QTD_STS_MMF) { |
153 | /* fs/ls interrupt xfer missed the complete-split */ | 226 | /* fs/ls interrupt xfer missed the complete-split */ |
154 | status = -EPROTO; | 227 | status = -EPROTO; |
@@ -157,21 +230,15 @@ static int qtd_copy_status ( | |||
157 | ? -ENOSR /* hc couldn't read data */ | 230 | ? -ENOSR /* hc couldn't read data */ |
158 | : -ECOMM; /* hc couldn't write data */ | 231 | : -ECOMM; /* hc couldn't write data */ |
159 | } else if (token & QTD_STS_XACT) { | 232 | } else if (token & QTD_STS_XACT) { |
160 | /* timeout, bad crc, wrong PID, etc; retried */ | 233 | /* timeout, bad CRC, wrong PID, etc */ |
161 | if (QTD_CERR (token)) | 234 | ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n", |
162 | status = -EPIPE; | 235 | urb->dev->devpath, |
163 | else { | 236 | usb_pipeendpoint(urb->pipe), |
164 | ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n", | 237 | usb_pipein(urb->pipe) ? "in" : "out"); |
165 | urb->dev->devpath, | 238 | status = -EPROTO; |
166 | usb_pipeendpoint (urb->pipe), | 239 | } else { /* unknown */ |
167 | usb_pipein (urb->pipe) ? "in" : "out"); | ||
168 | status = -EPROTO; | ||
169 | } | ||
170 | /* CERR nonzero + no errors + halt --> stall */ | ||
171 | } else if (QTD_CERR (token)) | ||
172 | status = -EPIPE; | ||
173 | else /* unknown */ | ||
174 | status = -EPROTO; | 240 | status = -EPROTO; |
241 | } | ||
175 | 242 | ||
176 | ehci_vdbg (ehci, | 243 | ehci_vdbg (ehci, |
177 | "dev%d ep%d%s qtd token %08x --> status %d\n", | 244 | "dev%d ep%d%s qtd token %08x --> status %d\n", |
@@ -179,28 +246,6 @@ static int qtd_copy_status ( | |||
179 | usb_pipeendpoint (urb->pipe), | 246 | usb_pipeendpoint (urb->pipe), |
180 | usb_pipein (urb->pipe) ? "in" : "out", | 247 | usb_pipein (urb->pipe) ? "in" : "out", |
181 | token, status); | 248 | token, status); |
182 | |||
183 | /* if async CSPLIT failed, try cleaning out the TT buffer */ | ||
184 | if (status != -EPIPE | ||
185 | && urb->dev->tt | ||
186 | && !usb_pipeint(urb->pipe) | ||
187 | && ((token & QTD_STS_MMF) != 0 | ||
188 | || QTD_CERR(token) == 0) | ||
189 | && (!ehci_is_TDI(ehci) | ||
190 | || urb->dev->tt->hub != | ||
191 | ehci_to_hcd(ehci)->self.root_hub)) { | ||
192 | #ifdef DEBUG | ||
193 | struct usb_device *tt = urb->dev->tt->hub; | ||
194 | dev_dbg (&tt->dev, | ||
195 | "clear tt buffer port %d, a%d ep%d t%08x\n", | ||
196 | urb->dev->ttport, urb->dev->devnum, | ||
197 | usb_pipeendpoint (urb->pipe), token); | ||
198 | #endif /* DEBUG */ | ||
199 | /* REVISIT ARC-derived cores don't clear the root | ||
200 | * hub TT buffer in this way... | ||
201 | */ | ||
202 | usb_hub_tt_clear_buffer (urb->dev, urb->pipe); | ||
203 | } | ||
204 | } | 249 | } |
205 | 250 | ||
206 | return status; | 251 | return status; |
@@ -391,9 +436,16 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
391 | /* qh unlinked; token in overlay may be most current */ | 436 | /* qh unlinked; token in overlay may be most current */ |
392 | if (state == QH_STATE_IDLE | 437 | if (state == QH_STATE_IDLE |
393 | && cpu_to_hc32(ehci, qtd->qtd_dma) | 438 | && cpu_to_hc32(ehci, qtd->qtd_dma) |
394 | == qh->hw_current) | 439 | == qh->hw_current) { |
395 | token = hc32_to_cpu(ehci, qh->hw_token); | 440 | token = hc32_to_cpu(ehci, qh->hw_token); |
396 | 441 | ||
442 | /* An unlink may leave an incomplete | ||
443 | * async transaction in the TT buffer. | ||
444 | * We have to clear it. | ||
445 | */ | ||
446 | ehci_clear_tt_buffer(ehci, qh, urb, token); | ||
447 | } | ||
448 | |||
397 | /* force halt for unlinked or blocked qh, so we'll | 449 | /* force halt for unlinked or blocked qh, so we'll |
398 | * patch the qh later and so that completions can't | 450 | * patch the qh later and so that completions can't |
399 | * activate it while we "know" it's stopped. | 451 | * activate it while we "know" it's stopped. |
@@ -419,6 +471,13 @@ halt: | |||
419 | && (qtd->hw_alt_next | 471 | && (qtd->hw_alt_next |
420 | & EHCI_LIST_END(ehci))) | 472 | & EHCI_LIST_END(ehci))) |
421 | last_status = -EINPROGRESS; | 473 | last_status = -EINPROGRESS; |
474 | |||
475 | /* As part of low/full-speed endpoint-halt processing | ||
476 | * we must clear the TT buffer (11.17.5). | ||
477 | */ | ||
478 | if (unlikely(last_status != -EINPROGRESS && | ||
479 | last_status != -EREMOTEIO)) | ||
480 | ehci_clear_tt_buffer(ehci, qh, urb, token); | ||
422 | } | 481 | } |
423 | 482 | ||
424 | /* if we're removing something not at the queue head, | 483 | /* if we're removing something not at the queue head, |
@@ -834,6 +893,7 @@ done: | |||
834 | qh->qh_state = QH_STATE_IDLE; | 893 | qh->qh_state = QH_STATE_IDLE; |
835 | qh->hw_info1 = cpu_to_hc32(ehci, info1); | 894 | qh->hw_info1 = cpu_to_hc32(ehci, info1); |
836 | qh->hw_info2 = cpu_to_hc32(ehci, info2); | 895 | qh->hw_info2 = cpu_to_hc32(ehci, info2); |
896 | usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); | ||
837 | qh_refresh (ehci, qh); | 897 | qh_refresh (ehci, qh); |
838 | return qh; | 898 | return qh; |
839 | } | 899 | } |
@@ -847,6 +907,10 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
847 | __hc32 dma = QH_NEXT(ehci, qh->qh_dma); | 907 | __hc32 dma = QH_NEXT(ehci, qh->qh_dma); |
848 | struct ehci_qh *head; | 908 | struct ehci_qh *head; |
849 | 909 | ||
910 | /* Don't link a QH if there's a Clear-TT-Buffer pending */ | ||
911 | if (unlikely(qh->clearing_tt)) | ||
912 | return; | ||
913 | |||
850 | /* (re)start the async schedule? */ | 914 | /* (re)start the async schedule? */ |
851 | head = ehci->async; | 915 | head = ehci->async; |
852 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 916 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
@@ -864,7 +928,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
864 | } | 928 | } |
865 | } | 929 | } |
866 | 930 | ||
867 | /* clear halt and maybe recover from silicon quirk */ | 931 | /* clear halt and/or toggle; and maybe recover from silicon quirk */ |
868 | if (qh->qh_state == QH_STATE_IDLE) | 932 | if (qh->qh_state == QH_STATE_IDLE) |
869 | qh_refresh (ehci, qh); | 933 | qh_refresh (ehci, qh); |
870 | 934 | ||
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 9d1babc7ff65..74f7f83b29ad 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1619,11 +1619,14 @@ itd_complete ( | |||
1619 | desc->status = -EPROTO; | 1619 | desc->status = -EPROTO; |
1620 | 1620 | ||
1621 | /* HC need not update length with this error */ | 1621 | /* HC need not update length with this error */ |
1622 | if (!(t & EHCI_ISOC_BABBLE)) | 1622 | if (!(t & EHCI_ISOC_BABBLE)) { |
1623 | desc->actual_length = EHCI_ITD_LENGTH (t); | 1623 | desc->actual_length = EHCI_ITD_LENGTH(t); |
1624 | urb->actual_length += desc->actual_length; | ||
1625 | } | ||
1624 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { | 1626 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { |
1625 | desc->status = 0; | 1627 | desc->status = 0; |
1626 | desc->actual_length = EHCI_ITD_LENGTH (t); | 1628 | desc->actual_length = EHCI_ITD_LENGTH(t); |
1629 | urb->actual_length += desc->actual_length; | ||
1627 | } else { | 1630 | } else { |
1628 | /* URB was too late */ | 1631 | /* URB was too late */ |
1629 | desc->status = -EXDEV; | 1632 | desc->status = -EXDEV; |
@@ -2014,7 +2017,8 @@ sitd_complete ( | |||
2014 | desc->status = -EPROTO; | 2017 | desc->status = -EPROTO; |
2015 | } else { | 2018 | } else { |
2016 | desc->status = 0; | 2019 | desc->status = 0; |
2017 | desc->actual_length = desc->length - SITD_LENGTH (t); | 2020 | desc->actual_length = desc->length - SITD_LENGTH(t); |
2021 | urb->actual_length += desc->actual_length; | ||
2018 | } | 2022 | } |
2019 | stream->depth -= stream->interval << 3; | 2023 | stream->depth -= stream->interval << 3; |
2020 | 2024 | ||
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 90ad3395bb21..2bfff30f4704 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -354,7 +354,9 @@ struct ehci_qh { | |||
354 | unsigned short period; /* polling interval */ | 354 | unsigned short period; /* polling interval */ |
355 | unsigned short start; /* where polling starts */ | 355 | unsigned short start; /* where polling starts */ |
356 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ | 356 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ |
357 | |||
357 | struct usb_device *dev; /* access to TT */ | 358 | struct usb_device *dev; /* access to TT */ |
359 | unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ | ||
358 | } __attribute__ ((aligned (32))); | 360 | } __attribute__ ((aligned (32))); |
359 | 361 | ||
360 | /*-------------------------------------------------------------------------*/ | 362 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index bb63b68ddb77..62a226b61670 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c | |||
@@ -576,9 +576,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) | |||
576 | out_be16(&usb->fhci->regs->usb_event, | 576 | out_be16(&usb->fhci->regs->usb_event, |
577 | usb->saved_msk); | 577 | usb->saved_msk); |
578 | } else if (usb->port_status == FHCI_PORT_DISABLED) { | 578 | } else if (usb->port_status == FHCI_PORT_DISABLED) { |
579 | if (fhci_ioports_check_bus_state(fhci) == 1 && | 579 | if (fhci_ioports_check_bus_state(fhci) == 1) |
580 | usb->port_status != FHCI_PORT_LOW && | ||
581 | usb->port_status != FHCI_PORT_FULL) | ||
582 | fhci_device_connected_interrupt(fhci); | 580 | fhci_device_connected_interrupt(fhci); |
583 | } | 581 | } |
584 | usb_er &= ~USB_E_RESET_MASK; | 582 | usb_er &= ~USB_E_RESET_MASK; |
@@ -605,9 +603,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) | |||
605 | } | 603 | } |
606 | 604 | ||
607 | if (usb_er & USB_E_IDLE_MASK) { | 605 | if (usb_er & USB_E_IDLE_MASK) { |
608 | if (usb->port_status == FHCI_PORT_DISABLED && | 606 | if (usb->port_status == FHCI_PORT_DISABLED) { |
609 | usb->port_status != FHCI_PORT_LOW && | ||
610 | usb->port_status != FHCI_PORT_FULL) { | ||
611 | usb_er &= ~USB_E_RESET_MASK; | 607 | usb_er &= ~USB_E_RESET_MASK; |
612 | fhci_device_connected_interrupt(fhci); | 608 | fhci_device_connected_interrupt(fhci); |
613 | } else if (usb->port_status == | 609 | } else if (usb->port_status == |
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 3fa3a1702796..d4feebfc63bd 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
@@ -361,7 +361,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev) | |||
361 | 361 | ||
362 | static struct platform_driver isp1760_plat_driver = { | 362 | static struct platform_driver isp1760_plat_driver = { |
363 | .probe = isp1760_plat_probe, | 363 | .probe = isp1760_plat_probe, |
364 | .remove = isp1760_plat_remove, | 364 | .remove = __devexit_p(isp1760_plat_remove), |
365 | .driver = { | 365 | .driver = { |
366 | .name = "isp1760", | 366 | .name = "isp1760", |
367 | }, | 367 | }, |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index f3aaba35e912..83cbecd2a1ed 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -282,6 +282,7 @@ static int ohci_omap_init(struct usb_hcd *hcd) | |||
282 | static void ohci_omap_stop(struct usb_hcd *hcd) | 282 | static void ohci_omap_stop(struct usb_hcd *hcd) |
283 | { | 283 | { |
284 | dev_dbg(hcd->self.controller, "stopping USB Controller\n"); | 284 | dev_dbg(hcd->self.controller, "stopping USB Controller\n"); |
285 | ohci_stop(hcd); | ||
285 | omap_ohci_clock_power(0); | 286 | omap_ohci_clock_power(0); |
286 | } | 287 | } |
287 | 288 | ||
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 56976cc0352a..e18f74946e68 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
32 | #include <linux/timer.h> | 31 | #include <linux/timer.h> |
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 2501c571f855..705e34324156 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c | |||
@@ -173,6 +173,7 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int | |||
173 | { | 173 | { |
174 | void *addr; | 174 | void *addr; |
175 | u32 temp; | 175 | u32 temp; |
176 | u64 temp_64; | ||
176 | 177 | ||
177 | addr = &ir_set->irq_pending; | 178 | addr = &ir_set->irq_pending; |
178 | temp = xhci_readl(xhci, addr); | 179 | temp = xhci_readl(xhci, addr); |
@@ -200,25 +201,15 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int | |||
200 | xhci_dbg(xhci, " WARN: %p: ir_set.rsvd = 0x%x\n", | 201 | xhci_dbg(xhci, " WARN: %p: ir_set.rsvd = 0x%x\n", |
201 | addr, (unsigned int)temp); | 202 | addr, (unsigned int)temp); |
202 | 203 | ||
203 | addr = &ir_set->erst_base[0]; | 204 | addr = &ir_set->erst_base; |
204 | temp = xhci_readl(xhci, addr); | 205 | temp_64 = xhci_read_64(xhci, addr); |
205 | xhci_dbg(xhci, " %p: ir_set.erst_base[0] = 0x%x\n", | 206 | xhci_dbg(xhci, " %p: ir_set.erst_base = @%08llx\n", |
206 | addr, (unsigned int) temp); | 207 | addr, temp_64); |
207 | |||
208 | addr = &ir_set->erst_base[1]; | ||
209 | temp = xhci_readl(xhci, addr); | ||
210 | xhci_dbg(xhci, " %p: ir_set.erst_base[1] = 0x%x\n", | ||
211 | addr, (unsigned int) temp); | ||
212 | 208 | ||
213 | addr = &ir_set->erst_dequeue[0]; | 209 | addr = &ir_set->erst_dequeue; |
214 | temp = xhci_readl(xhci, addr); | 210 | temp_64 = xhci_read_64(xhci, addr); |
215 | xhci_dbg(xhci, " %p: ir_set.erst_dequeue[0] = 0x%x\n", | 211 | xhci_dbg(xhci, " %p: ir_set.erst_dequeue = @%08llx\n", |
216 | addr, (unsigned int) temp); | 212 | addr, temp_64); |
217 | |||
218 | addr = &ir_set->erst_dequeue[1]; | ||
219 | temp = xhci_readl(xhci, addr); | ||
220 | xhci_dbg(xhci, " %p: ir_set.erst_dequeue[1] = 0x%x\n", | ||
221 | addr, (unsigned int) temp); | ||
222 | } | 213 | } |
223 | 214 | ||
224 | void xhci_print_run_regs(struct xhci_hcd *xhci) | 215 | void xhci_print_run_regs(struct xhci_hcd *xhci) |
@@ -268,8 +259,7 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb) | |||
268 | xhci_dbg(xhci, "Link TRB:\n"); | 259 | xhci_dbg(xhci, "Link TRB:\n"); |
269 | xhci_print_trb_offsets(xhci, trb); | 260 | xhci_print_trb_offsets(xhci, trb); |
270 | 261 | ||
271 | address = trb->link.segment_ptr[0] + | 262 | address = trb->link.segment_ptr; |
272 | (((u64) trb->link.segment_ptr[1]) << 32); | ||
273 | xhci_dbg(xhci, "Next ring segment DMA address = 0x%llx\n", address); | 263 | xhci_dbg(xhci, "Next ring segment DMA address = 0x%llx\n", address); |
274 | 264 | ||
275 | xhci_dbg(xhci, "Interrupter target = 0x%x\n", | 265 | xhci_dbg(xhci, "Interrupter target = 0x%x\n", |
@@ -282,8 +272,7 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb) | |||
282 | (unsigned int) (trb->link.control & TRB_NO_SNOOP)); | 272 | (unsigned int) (trb->link.control & TRB_NO_SNOOP)); |
283 | break; | 273 | break; |
284 | case TRB_TYPE(TRB_TRANSFER): | 274 | case TRB_TYPE(TRB_TRANSFER): |
285 | address = trb->trans_event.buffer[0] + | 275 | address = trb->trans_event.buffer; |
286 | (((u64) trb->trans_event.buffer[1]) << 32); | ||
287 | /* | 276 | /* |
288 | * FIXME: look at flags to figure out if it's an address or if | 277 | * FIXME: look at flags to figure out if it's an address or if |
289 | * the data is directly in the buffer field. | 278 | * the data is directly in the buffer field. |
@@ -291,8 +280,7 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb) | |||
291 | xhci_dbg(xhci, "DMA address or buffer contents= %llu\n", address); | 280 | xhci_dbg(xhci, "DMA address or buffer contents= %llu\n", address); |
292 | break; | 281 | break; |
293 | case TRB_TYPE(TRB_COMPLETION): | 282 | case TRB_TYPE(TRB_COMPLETION): |
294 | address = trb->event_cmd.cmd_trb[0] + | 283 | address = trb->event_cmd.cmd_trb; |
295 | (((u64) trb->event_cmd.cmd_trb[1]) << 32); | ||
296 | xhci_dbg(xhci, "Command TRB pointer = %llu\n", address); | 284 | xhci_dbg(xhci, "Command TRB pointer = %llu\n", address); |
297 | xhci_dbg(xhci, "Completion status = %u\n", | 285 | xhci_dbg(xhci, "Completion status = %u\n", |
298 | (unsigned int) GET_COMP_CODE(trb->event_cmd.status)); | 286 | (unsigned int) GET_COMP_CODE(trb->event_cmd.status)); |
@@ -328,8 +316,8 @@ void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg) | |||
328 | for (i = 0; i < TRBS_PER_SEGMENT; ++i) { | 316 | for (i = 0; i < TRBS_PER_SEGMENT; ++i) { |
329 | trb = &seg->trbs[i]; | 317 | trb = &seg->trbs[i]; |
330 | xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", addr, | 318 | xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", addr, |
331 | (unsigned int) trb->link.segment_ptr[0], | 319 | lower_32_bits(trb->link.segment_ptr), |
332 | (unsigned int) trb->link.segment_ptr[1], | 320 | upper_32_bits(trb->link.segment_ptr), |
333 | (unsigned int) trb->link.intr_target, | 321 | (unsigned int) trb->link.intr_target, |
334 | (unsigned int) trb->link.control); | 322 | (unsigned int) trb->link.control); |
335 | addr += sizeof(*trb); | 323 | addr += sizeof(*trb); |
@@ -386,8 +374,8 @@ void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst) | |||
386 | entry = &erst->entries[i]; | 374 | entry = &erst->entries[i]; |
387 | xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", | 375 | xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", |
388 | (unsigned int) addr, | 376 | (unsigned int) addr, |
389 | (unsigned int) entry->seg_addr[0], | 377 | lower_32_bits(entry->seg_addr), |
390 | (unsigned int) entry->seg_addr[1], | 378 | upper_32_bits(entry->seg_addr), |
391 | (unsigned int) entry->seg_size, | 379 | (unsigned int) entry->seg_size, |
392 | (unsigned int) entry->rsvd); | 380 | (unsigned int) entry->rsvd); |
393 | addr += sizeof(*entry); | 381 | addr += sizeof(*entry); |
@@ -396,90 +384,147 @@ void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst) | |||
396 | 384 | ||
397 | void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci) | 385 | void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci) |
398 | { | 386 | { |
399 | u32 val; | 387 | u64 val; |
400 | 388 | ||
401 | val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[0]); | 389 | val = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); |
402 | xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = 0x%x\n", val); | 390 | xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = @%08x\n", |
403 | val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[1]); | 391 | lower_32_bits(val)); |
404 | xhci_dbg(xhci, "// xHC command ring deq ptr high bits = 0x%x\n", val); | 392 | xhci_dbg(xhci, "// xHC command ring deq ptr high bits = @%08x\n", |
393 | upper_32_bits(val)); | ||
405 | } | 394 | } |
406 | 395 | ||
407 | void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep) | 396 | /* Print the last 32 bytes for 64-byte contexts */ |
397 | static void dbg_rsvd64(struct xhci_hcd *xhci, u64 *ctx, dma_addr_t dma) | ||
398 | { | ||
399 | int i; | ||
400 | for (i = 0; i < 4; ++i) { | ||
401 | xhci_dbg(xhci, "@%p (virt) @%08llx " | ||
402 | "(dma) %#08llx - rsvd64[%d]\n", | ||
403 | &ctx[4 + i], (unsigned long long)dma, | ||
404 | ctx[4 + i], i); | ||
405 | dma += 8; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx) | ||
408 | { | 410 | { |
409 | int i, j; | ||
410 | int last_ep_ctx = 31; | ||
411 | /* Fields are 32 bits wide, DMA addresses are in bytes */ | 411 | /* Fields are 32 bits wide, DMA addresses are in bytes */ |
412 | int field_size = 32 / 8; | 412 | int field_size = 32 / 8; |
413 | int i; | ||
413 | 414 | ||
414 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n", | 415 | struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx); |
415 | &ctx->drop_flags, (unsigned long long)dma, | 416 | dma_addr_t dma = ctx->dma + ((unsigned long)slot_ctx - (unsigned long)ctx); |
416 | ctx->drop_flags); | 417 | int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); |
417 | dma += field_size; | ||
418 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n", | ||
419 | &ctx->add_flags, (unsigned long long)dma, | ||
420 | ctx->add_flags); | ||
421 | dma += field_size; | ||
422 | for (i = 0; i > 6; ++i) { | ||
423 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", | ||
424 | &ctx->rsvd[i], (unsigned long long)dma, | ||
425 | ctx->rsvd[i], i); | ||
426 | dma += field_size; | ||
427 | } | ||
428 | 418 | ||
429 | xhci_dbg(xhci, "Slot Context:\n"); | 419 | xhci_dbg(xhci, "Slot Context:\n"); |
430 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n", | 420 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n", |
431 | &ctx->slot.dev_info, | 421 | &slot_ctx->dev_info, |
432 | (unsigned long long)dma, ctx->slot.dev_info); | 422 | (unsigned long long)dma, slot_ctx->dev_info); |
433 | dma += field_size; | 423 | dma += field_size; |
434 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n", | 424 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n", |
435 | &ctx->slot.dev_info2, | 425 | &slot_ctx->dev_info2, |
436 | (unsigned long long)dma, ctx->slot.dev_info2); | 426 | (unsigned long long)dma, slot_ctx->dev_info2); |
437 | dma += field_size; | 427 | dma += field_size; |
438 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n", | 428 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n", |
439 | &ctx->slot.tt_info, | 429 | &slot_ctx->tt_info, |
440 | (unsigned long long)dma, ctx->slot.tt_info); | 430 | (unsigned long long)dma, slot_ctx->tt_info); |
441 | dma += field_size; | 431 | dma += field_size; |
442 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n", | 432 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n", |
443 | &ctx->slot.dev_state, | 433 | &slot_ctx->dev_state, |
444 | (unsigned long long)dma, ctx->slot.dev_state); | 434 | (unsigned long long)dma, slot_ctx->dev_state); |
445 | dma += field_size; | 435 | dma += field_size; |
446 | for (i = 0; i > 4; ++i) { | 436 | for (i = 0; i < 4; ++i) { |
447 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", | 437 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", |
448 | &ctx->slot.reserved[i], (unsigned long long)dma, | 438 | &slot_ctx->reserved[i], (unsigned long long)dma, |
449 | ctx->slot.reserved[i], i); | 439 | slot_ctx->reserved[i], i); |
450 | dma += field_size; | 440 | dma += field_size; |
451 | } | 441 | } |
452 | 442 | ||
443 | if (csz) | ||
444 | dbg_rsvd64(xhci, (u64 *)slot_ctx, dma); | ||
445 | } | ||
446 | |||
447 | void xhci_dbg_ep_ctx(struct xhci_hcd *xhci, | ||
448 | struct xhci_container_ctx *ctx, | ||
449 | unsigned int last_ep) | ||
450 | { | ||
451 | int i, j; | ||
452 | int last_ep_ctx = 31; | ||
453 | /* Fields are 32 bits wide, DMA addresses are in bytes */ | ||
454 | int field_size = 32 / 8; | ||
455 | int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); | ||
456 | |||
453 | if (last_ep < 31) | 457 | if (last_ep < 31) |
454 | last_ep_ctx = last_ep + 1; | 458 | last_ep_ctx = last_ep + 1; |
455 | for (i = 0; i < last_ep_ctx; ++i) { | 459 | for (i = 0; i < last_ep_ctx; ++i) { |
460 | struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i); | ||
461 | dma_addr_t dma = ctx->dma + | ||
462 | ((unsigned long)ep_ctx - (unsigned long)ctx); | ||
463 | |||
456 | xhci_dbg(xhci, "Endpoint %02d Context:\n", i); | 464 | xhci_dbg(xhci, "Endpoint %02d Context:\n", i); |
457 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n", | 465 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n", |
458 | &ctx->ep[i].ep_info, | 466 | &ep_ctx->ep_info, |
459 | (unsigned long long)dma, ctx->ep[i].ep_info); | 467 | (unsigned long long)dma, ep_ctx->ep_info); |
460 | dma += field_size; | 468 | dma += field_size; |
461 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n", | 469 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n", |
462 | &ctx->ep[i].ep_info2, | 470 | &ep_ctx->ep_info2, |
463 | (unsigned long long)dma, ctx->ep[i].ep_info2); | 471 | (unsigned long long)dma, ep_ctx->ep_info2); |
464 | dma += field_size; | ||
465 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - deq[0]\n", | ||
466 | &ctx->ep[i].deq[0], | ||
467 | (unsigned long long)dma, ctx->ep[i].deq[0]); | ||
468 | dma += field_size; | ||
469 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - deq[1]\n", | ||
470 | &ctx->ep[i].deq[1], | ||
471 | (unsigned long long)dma, ctx->ep[i].deq[1]); | ||
472 | dma += field_size; | 472 | dma += field_size; |
473 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n", | ||
474 | &ep_ctx->deq, | ||
475 | (unsigned long long)dma, ep_ctx->deq); | ||
476 | dma += 2*field_size; | ||
473 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n", | 477 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n", |
474 | &ctx->ep[i].tx_info, | 478 | &ep_ctx->tx_info, |
475 | (unsigned long long)dma, ctx->ep[i].tx_info); | 479 | (unsigned long long)dma, ep_ctx->tx_info); |
476 | dma += field_size; | 480 | dma += field_size; |
477 | for (j = 0; j < 3; ++j) { | 481 | for (j = 0; j < 3; ++j) { |
478 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", | 482 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", |
479 | &ctx->ep[i].reserved[j], | 483 | &ep_ctx->reserved[j], |
480 | (unsigned long long)dma, | 484 | (unsigned long long)dma, |
481 | ctx->ep[i].reserved[j], j); | 485 | ep_ctx->reserved[j], j); |
486 | dma += field_size; | ||
487 | } | ||
488 | |||
489 | if (csz) | ||
490 | dbg_rsvd64(xhci, (u64 *)ep_ctx, dma); | ||
491 | } | ||
492 | } | ||
493 | |||
494 | void xhci_dbg_ctx(struct xhci_hcd *xhci, | ||
495 | struct xhci_container_ctx *ctx, | ||
496 | unsigned int last_ep) | ||
497 | { | ||
498 | int i; | ||
499 | /* Fields are 32 bits wide, DMA addresses are in bytes */ | ||
500 | int field_size = 32 / 8; | ||
501 | struct xhci_slot_ctx *slot_ctx; | ||
502 | dma_addr_t dma = ctx->dma; | ||
503 | int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); | ||
504 | |||
505 | if (ctx->type == XHCI_CTX_TYPE_INPUT) { | ||
506 | struct xhci_input_control_ctx *ctrl_ctx = | ||
507 | xhci_get_input_control_ctx(xhci, ctx); | ||
508 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n", | ||
509 | &ctrl_ctx->drop_flags, (unsigned long long)dma, | ||
510 | ctrl_ctx->drop_flags); | ||
511 | dma += field_size; | ||
512 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n", | ||
513 | &ctrl_ctx->add_flags, (unsigned long long)dma, | ||
514 | ctrl_ctx->add_flags); | ||
515 | dma += field_size; | ||
516 | for (i = 0; i < 6; ++i) { | ||
517 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd2[%d]\n", | ||
518 | &ctrl_ctx->rsvd2[i], (unsigned long long)dma, | ||
519 | ctrl_ctx->rsvd2[i], i); | ||
482 | dma += field_size; | 520 | dma += field_size; |
483 | } | 521 | } |
522 | |||
523 | if (csz) | ||
524 | dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma); | ||
484 | } | 525 | } |
526 | |||
527 | slot_ctx = xhci_get_slot_ctx(xhci, ctx); | ||
528 | xhci_dbg_slot_ctx(xhci, ctx); | ||
529 | xhci_dbg_ep_ctx(xhci, ctx, last_ep); | ||
485 | } | 530 | } |
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c index dba3e07ccd09..816c39caca1c 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci-hcd.c | |||
@@ -103,7 +103,10 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
103 | u32 state; | 103 | u32 state; |
104 | 104 | ||
105 | state = xhci_readl(xhci, &xhci->op_regs->status); | 105 | state = xhci_readl(xhci, &xhci->op_regs->status); |
106 | BUG_ON((state & STS_HALT) == 0); | 106 | if ((state & STS_HALT) == 0) { |
107 | xhci_warn(xhci, "Host controller not halted, aborting reset.\n"); | ||
108 | return 0; | ||
109 | } | ||
107 | 110 | ||
108 | xhci_dbg(xhci, "// Reset the HC\n"); | 111 | xhci_dbg(xhci, "// Reset the HC\n"); |
109 | command = xhci_readl(xhci, &xhci->op_regs->command); | 112 | command = xhci_readl(xhci, &xhci->op_regs->command); |
@@ -226,6 +229,7 @@ int xhci_init(struct usb_hcd *hcd) | |||
226 | static void xhci_work(struct xhci_hcd *xhci) | 229 | static void xhci_work(struct xhci_hcd *xhci) |
227 | { | 230 | { |
228 | u32 temp; | 231 | u32 temp; |
232 | u64 temp_64; | ||
229 | 233 | ||
230 | /* | 234 | /* |
231 | * Clear the op reg interrupt status first, | 235 | * Clear the op reg interrupt status first, |
@@ -248,9 +252,9 @@ static void xhci_work(struct xhci_hcd *xhci) | |||
248 | /* FIXME this should be a delayed service routine that clears the EHB */ | 252 | /* FIXME this should be a delayed service routine that clears the EHB */ |
249 | xhci_handle_event(xhci); | 253 | xhci_handle_event(xhci); |
250 | 254 | ||
251 | /* Clear the event handler busy flag; the event ring should be empty. */ | 255 | /* Clear the event handler busy flag (RW1C); the event ring should be empty. */ |
252 | temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); | 256 | temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
253 | xhci_writel(xhci, temp & ~ERST_EHB, &xhci->ir_set->erst_dequeue[0]); | 257 | xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); |
254 | /* Flush posted writes -- FIXME is this necessary? */ | 258 | /* Flush posted writes -- FIXME is this necessary? */ |
255 | xhci_readl(xhci, &xhci->ir_set->irq_pending); | 259 | xhci_readl(xhci, &xhci->ir_set->irq_pending); |
256 | } | 260 | } |
@@ -266,19 +270,34 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) | |||
266 | { | 270 | { |
267 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 271 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
268 | u32 temp, temp2; | 272 | u32 temp, temp2; |
273 | union xhci_trb *trb; | ||
269 | 274 | ||
270 | spin_lock(&xhci->lock); | 275 | spin_lock(&xhci->lock); |
276 | trb = xhci->event_ring->dequeue; | ||
271 | /* Check if the xHC generated the interrupt, or the irq is shared */ | 277 | /* Check if the xHC generated the interrupt, or the irq is shared */ |
272 | temp = xhci_readl(xhci, &xhci->op_regs->status); | 278 | temp = xhci_readl(xhci, &xhci->op_regs->status); |
273 | temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); | 279 | temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); |
280 | if (temp == 0xffffffff && temp2 == 0xffffffff) | ||
281 | goto hw_died; | ||
282 | |||
274 | if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { | 283 | if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { |
275 | spin_unlock(&xhci->lock); | 284 | spin_unlock(&xhci->lock); |
276 | return IRQ_NONE; | 285 | return IRQ_NONE; |
277 | } | 286 | } |
287 | xhci_dbg(xhci, "op reg status = %08x\n", temp); | ||
288 | xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2); | ||
289 | xhci_dbg(xhci, "Event ring dequeue ptr:\n"); | ||
290 | xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", | ||
291 | (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb), | ||
292 | lower_32_bits(trb->link.segment_ptr), | ||
293 | upper_32_bits(trb->link.segment_ptr), | ||
294 | (unsigned int) trb->link.intr_target, | ||
295 | (unsigned int) trb->link.control); | ||
278 | 296 | ||
279 | if (temp & STS_FATAL) { | 297 | if (temp & STS_FATAL) { |
280 | xhci_warn(xhci, "WARNING: Host System Error\n"); | 298 | xhci_warn(xhci, "WARNING: Host System Error\n"); |
281 | xhci_halt(xhci); | 299 | xhci_halt(xhci); |
300 | hw_died: | ||
282 | xhci_to_hcd(xhci)->state = HC_STATE_HALT; | 301 | xhci_to_hcd(xhci)->state = HC_STATE_HALT; |
283 | spin_unlock(&xhci->lock); | 302 | spin_unlock(&xhci->lock); |
284 | return -ESHUTDOWN; | 303 | return -ESHUTDOWN; |
@@ -295,6 +314,7 @@ void xhci_event_ring_work(unsigned long arg) | |||
295 | { | 314 | { |
296 | unsigned long flags; | 315 | unsigned long flags; |
297 | int temp; | 316 | int temp; |
317 | u64 temp_64; | ||
298 | struct xhci_hcd *xhci = (struct xhci_hcd *) arg; | 318 | struct xhci_hcd *xhci = (struct xhci_hcd *) arg; |
299 | int i, j; | 319 | int i, j; |
300 | 320 | ||
@@ -311,9 +331,9 @@ void xhci_event_ring_work(unsigned long arg) | |||
311 | xhci_dbg(xhci, "Event ring:\n"); | 331 | xhci_dbg(xhci, "Event ring:\n"); |
312 | xhci_debug_segment(xhci, xhci->event_ring->deq_seg); | 332 | xhci_debug_segment(xhci, xhci->event_ring->deq_seg); |
313 | xhci_dbg_ring_ptrs(xhci, xhci->event_ring); | 333 | xhci_dbg_ring_ptrs(xhci, xhci->event_ring); |
314 | temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); | 334 | temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
315 | temp &= ERST_PTR_MASK; | 335 | temp_64 &= ~ERST_PTR_MASK; |
316 | xhci_dbg(xhci, "ERST deq = 0x%x\n", temp); | 336 | xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); |
317 | xhci_dbg(xhci, "Command ring:\n"); | 337 | xhci_dbg(xhci, "Command ring:\n"); |
318 | xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); | 338 | xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); |
319 | xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); | 339 | xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); |
@@ -356,6 +376,7 @@ void xhci_event_ring_work(unsigned long arg) | |||
356 | int xhci_run(struct usb_hcd *hcd) | 376 | int xhci_run(struct usb_hcd *hcd) |
357 | { | 377 | { |
358 | u32 temp; | 378 | u32 temp; |
379 | u64 temp_64; | ||
359 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 380 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
360 | void (*doorbell)(struct xhci_hcd *) = NULL; | 381 | void (*doorbell)(struct xhci_hcd *) = NULL; |
361 | 382 | ||
@@ -382,6 +403,20 @@ int xhci_run(struct usb_hcd *hcd) | |||
382 | add_timer(&xhci->event_ring_timer); | 403 | add_timer(&xhci->event_ring_timer); |
383 | #endif | 404 | #endif |
384 | 405 | ||
406 | xhci_dbg(xhci, "Command ring memory map follows:\n"); | ||
407 | xhci_debug_ring(xhci, xhci->cmd_ring); | ||
408 | xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); | ||
409 | xhci_dbg_cmd_ptrs(xhci); | ||
410 | |||
411 | xhci_dbg(xhci, "ERST memory map follows:\n"); | ||
412 | xhci_dbg_erst(xhci, &xhci->erst); | ||
413 | xhci_dbg(xhci, "Event ring:\n"); | ||
414 | xhci_debug_ring(xhci, xhci->event_ring); | ||
415 | xhci_dbg_ring_ptrs(xhci, xhci->event_ring); | ||
416 | temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); | ||
417 | temp_64 &= ~ERST_PTR_MASK; | ||
418 | xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); | ||
419 | |||
385 | xhci_dbg(xhci, "// Set the interrupt modulation register\n"); | 420 | xhci_dbg(xhci, "// Set the interrupt modulation register\n"); |
386 | temp = xhci_readl(xhci, &xhci->ir_set->irq_control); | 421 | temp = xhci_readl(xhci, &xhci->ir_set->irq_control); |
387 | temp &= ~ER_IRQ_INTERVAL_MASK; | 422 | temp &= ~ER_IRQ_INTERVAL_MASK; |
@@ -406,22 +441,6 @@ int xhci_run(struct usb_hcd *hcd) | |||
406 | if (NUM_TEST_NOOPS > 0) | 441 | if (NUM_TEST_NOOPS > 0) |
407 | doorbell = xhci_setup_one_noop(xhci); | 442 | doorbell = xhci_setup_one_noop(xhci); |
408 | 443 | ||
409 | xhci_dbg(xhci, "Command ring memory map follows:\n"); | ||
410 | xhci_debug_ring(xhci, xhci->cmd_ring); | ||
411 | xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); | ||
412 | xhci_dbg_cmd_ptrs(xhci); | ||
413 | |||
414 | xhci_dbg(xhci, "ERST memory map follows:\n"); | ||
415 | xhci_dbg_erst(xhci, &xhci->erst); | ||
416 | xhci_dbg(xhci, "Event ring:\n"); | ||
417 | xhci_debug_ring(xhci, xhci->event_ring); | ||
418 | xhci_dbg_ring_ptrs(xhci, xhci->event_ring); | ||
419 | temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); | ||
420 | temp &= ERST_PTR_MASK; | ||
421 | xhci_dbg(xhci, "ERST deq = 0x%x\n", temp); | ||
422 | temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[1]); | ||
423 | xhci_dbg(xhci, "ERST deq upper = 0x%x\n", temp); | ||
424 | |||
425 | temp = xhci_readl(xhci, &xhci->op_regs->command); | 444 | temp = xhci_readl(xhci, &xhci->op_regs->command); |
426 | temp |= (CMD_RUN); | 445 | temp |= (CMD_RUN); |
427 | xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", | 446 | xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", |
@@ -601,10 +620,13 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) | |||
601 | goto exit; | 620 | goto exit; |
602 | } | 621 | } |
603 | if (usb_endpoint_xfer_control(&urb->ep->desc)) | 622 | if (usb_endpoint_xfer_control(&urb->ep->desc)) |
604 | ret = xhci_queue_ctrl_tx(xhci, mem_flags, urb, | 623 | /* We have a spinlock and interrupts disabled, so we must pass |
624 | * atomic context to this function, which may allocate memory. | ||
625 | */ | ||
626 | ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, | ||
605 | slot_id, ep_index); | 627 | slot_id, ep_index); |
606 | else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) | 628 | else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) |
607 | ret = xhci_queue_bulk_tx(xhci, mem_flags, urb, | 629 | ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, |
608 | slot_id, ep_index); | 630 | slot_id, ep_index); |
609 | else | 631 | else |
610 | ret = -EINVAL; | 632 | ret = -EINVAL; |
@@ -661,8 +683,12 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
661 | goto done; | 683 | goto done; |
662 | 684 | ||
663 | xhci_dbg(xhci, "Cancel URB %p\n", urb); | 685 | xhci_dbg(xhci, "Cancel URB %p\n", urb); |
686 | xhci_dbg(xhci, "Event ring:\n"); | ||
687 | xhci_debug_ring(xhci, xhci->event_ring); | ||
664 | ep_index = xhci_get_endpoint_index(&urb->ep->desc); | 688 | ep_index = xhci_get_endpoint_index(&urb->ep->desc); |
665 | ep_ring = xhci->devs[urb->dev->slot_id]->ep_rings[ep_index]; | 689 | ep_ring = xhci->devs[urb->dev->slot_id]->ep_rings[ep_index]; |
690 | xhci_dbg(xhci, "Endpoint ring:\n"); | ||
691 | xhci_debug_ring(xhci, ep_ring); | ||
666 | td = (struct xhci_td *) urb->hcpriv; | 692 | td = (struct xhci_td *) urb->hcpriv; |
667 | 693 | ||
668 | ep_ring->cancels_pending++; | 694 | ep_ring->cancels_pending++; |
@@ -696,7 +722,9 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
696 | struct usb_host_endpoint *ep) | 722 | struct usb_host_endpoint *ep) |
697 | { | 723 | { |
698 | struct xhci_hcd *xhci; | 724 | struct xhci_hcd *xhci; |
699 | struct xhci_device_control *in_ctx; | 725 | struct xhci_container_ctx *in_ctx, *out_ctx; |
726 | struct xhci_input_control_ctx *ctrl_ctx; | ||
727 | struct xhci_slot_ctx *slot_ctx; | ||
700 | unsigned int last_ctx; | 728 | unsigned int last_ctx; |
701 | unsigned int ep_index; | 729 | unsigned int ep_index; |
702 | struct xhci_ep_ctx *ep_ctx; | 730 | struct xhci_ep_ctx *ep_ctx; |
@@ -724,31 +752,34 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
724 | } | 752 | } |
725 | 753 | ||
726 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; | 754 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; |
755 | out_ctx = xhci->devs[udev->slot_id]->out_ctx; | ||
756 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | ||
727 | ep_index = xhci_get_endpoint_index(&ep->desc); | 757 | ep_index = xhci_get_endpoint_index(&ep->desc); |
728 | ep_ctx = &xhci->devs[udev->slot_id]->out_ctx->ep[ep_index]; | 758 | ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); |
729 | /* If the HC already knows the endpoint is disabled, | 759 | /* If the HC already knows the endpoint is disabled, |
730 | * or the HCD has noted it is disabled, ignore this request | 760 | * or the HCD has noted it is disabled, ignore this request |
731 | */ | 761 | */ |
732 | if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED || | 762 | if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED || |
733 | in_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) { | 763 | ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) { |
734 | xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", | 764 | xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", |
735 | __func__, ep); | 765 | __func__, ep); |
736 | return 0; | 766 | return 0; |
737 | } | 767 | } |
738 | 768 | ||
739 | in_ctx->drop_flags |= drop_flag; | 769 | ctrl_ctx->drop_flags |= drop_flag; |
740 | new_drop_flags = in_ctx->drop_flags; | 770 | new_drop_flags = ctrl_ctx->drop_flags; |
741 | 771 | ||
742 | in_ctx->add_flags = ~drop_flag; | 772 | ctrl_ctx->add_flags = ~drop_flag; |
743 | new_add_flags = in_ctx->add_flags; | 773 | new_add_flags = ctrl_ctx->add_flags; |
744 | 774 | ||
745 | last_ctx = xhci_last_valid_endpoint(in_ctx->add_flags); | 775 | last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); |
776 | slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); | ||
746 | /* Update the last valid endpoint context, if we deleted the last one */ | 777 | /* Update the last valid endpoint context, if we deleted the last one */ |
747 | if ((in_ctx->slot.dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) { | 778 | if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) { |
748 | in_ctx->slot.dev_info &= ~LAST_CTX_MASK; | 779 | slot_ctx->dev_info &= ~LAST_CTX_MASK; |
749 | in_ctx->slot.dev_info |= LAST_CTX(last_ctx); | 780 | slot_ctx->dev_info |= LAST_CTX(last_ctx); |
750 | } | 781 | } |
751 | new_slot_info = in_ctx->slot.dev_info; | 782 | new_slot_info = slot_ctx->dev_info; |
752 | 783 | ||
753 | xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); | 784 | xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); |
754 | 785 | ||
@@ -778,17 +809,22 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
778 | struct usb_host_endpoint *ep) | 809 | struct usb_host_endpoint *ep) |
779 | { | 810 | { |
780 | struct xhci_hcd *xhci; | 811 | struct xhci_hcd *xhci; |
781 | struct xhci_device_control *in_ctx; | 812 | struct xhci_container_ctx *in_ctx, *out_ctx; |
782 | unsigned int ep_index; | 813 | unsigned int ep_index; |
783 | struct xhci_ep_ctx *ep_ctx; | 814 | struct xhci_ep_ctx *ep_ctx; |
815 | struct xhci_slot_ctx *slot_ctx; | ||
816 | struct xhci_input_control_ctx *ctrl_ctx; | ||
784 | u32 added_ctxs; | 817 | u32 added_ctxs; |
785 | unsigned int last_ctx; | 818 | unsigned int last_ctx; |
786 | u32 new_add_flags, new_drop_flags, new_slot_info; | 819 | u32 new_add_flags, new_drop_flags, new_slot_info; |
787 | int ret = 0; | 820 | int ret = 0; |
788 | 821 | ||
789 | ret = xhci_check_args(hcd, udev, ep, 1, __func__); | 822 | ret = xhci_check_args(hcd, udev, ep, 1, __func__); |
790 | if (ret <= 0) | 823 | if (ret <= 0) { |
824 | /* So we won't queue a reset ep command for a root hub */ | ||
825 | ep->hcpriv = NULL; | ||
791 | return ret; | 826 | return ret; |
827 | } | ||
792 | xhci = hcd_to_xhci(hcd); | 828 | xhci = hcd_to_xhci(hcd); |
793 | 829 | ||
794 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); | 830 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); |
@@ -810,12 +846,14 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
810 | } | 846 | } |
811 | 847 | ||
812 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; | 848 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; |
849 | out_ctx = xhci->devs[udev->slot_id]->out_ctx; | ||
850 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | ||
813 | ep_index = xhci_get_endpoint_index(&ep->desc); | 851 | ep_index = xhci_get_endpoint_index(&ep->desc); |
814 | ep_ctx = &xhci->devs[udev->slot_id]->out_ctx->ep[ep_index]; | 852 | ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); |
815 | /* If the HCD has already noted the endpoint is enabled, | 853 | /* If the HCD has already noted the endpoint is enabled, |
816 | * ignore this request. | 854 | * ignore this request. |
817 | */ | 855 | */ |
818 | if (in_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) { | 856 | if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) { |
819 | xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", | 857 | xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", |
820 | __func__, ep); | 858 | __func__, ep); |
821 | return 0; | 859 | return 0; |
@@ -833,8 +871,8 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
833 | return -ENOMEM; | 871 | return -ENOMEM; |
834 | } | 872 | } |
835 | 873 | ||
836 | in_ctx->add_flags |= added_ctxs; | 874 | ctrl_ctx->add_flags |= added_ctxs; |
837 | new_add_flags = in_ctx->add_flags; | 875 | new_add_flags = ctrl_ctx->add_flags; |
838 | 876 | ||
839 | /* If xhci_endpoint_disable() was called for this endpoint, but the | 877 | /* If xhci_endpoint_disable() was called for this endpoint, but the |
840 | * xHC hasn't been notified yet through the check_bandwidth() call, | 878 | * xHC hasn't been notified yet through the check_bandwidth() call, |
@@ -842,14 +880,18 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
842 | * descriptors. We must drop and re-add this endpoint, so we leave the | 880 | * descriptors. We must drop and re-add this endpoint, so we leave the |
843 | * drop flags alone. | 881 | * drop flags alone. |
844 | */ | 882 | */ |
845 | new_drop_flags = in_ctx->drop_flags; | 883 | new_drop_flags = ctrl_ctx->drop_flags; |
846 | 884 | ||
885 | slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); | ||
847 | /* Update the last valid endpoint context, if we just added one past */ | 886 | /* Update the last valid endpoint context, if we just added one past */ |
848 | if ((in_ctx->slot.dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) { | 887 | if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) { |
849 | in_ctx->slot.dev_info &= ~LAST_CTX_MASK; | 888 | slot_ctx->dev_info &= ~LAST_CTX_MASK; |
850 | in_ctx->slot.dev_info |= LAST_CTX(last_ctx); | 889 | slot_ctx->dev_info |= LAST_CTX(last_ctx); |
851 | } | 890 | } |
852 | new_slot_info = in_ctx->slot.dev_info; | 891 | new_slot_info = slot_ctx->dev_info; |
892 | |||
893 | /* Store the usb_device pointer for later use */ | ||
894 | ep->hcpriv = udev; | ||
853 | 895 | ||
854 | xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", | 896 | xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", |
855 | (unsigned int) ep->desc.bEndpointAddress, | 897 | (unsigned int) ep->desc.bEndpointAddress, |
@@ -860,9 +902,11 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
860 | return 0; | 902 | return 0; |
861 | } | 903 | } |
862 | 904 | ||
863 | static void xhci_zero_in_ctx(struct xhci_virt_device *virt_dev) | 905 | static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev) |
864 | { | 906 | { |
907 | struct xhci_input_control_ctx *ctrl_ctx; | ||
865 | struct xhci_ep_ctx *ep_ctx; | 908 | struct xhci_ep_ctx *ep_ctx; |
909 | struct xhci_slot_ctx *slot_ctx; | ||
866 | int i; | 910 | int i; |
867 | 911 | ||
868 | /* When a device's add flag and drop flag are zero, any subsequent | 912 | /* When a device's add flag and drop flag are zero, any subsequent |
@@ -870,17 +914,18 @@ static void xhci_zero_in_ctx(struct xhci_virt_device *virt_dev) | |||
870 | * untouched. Make sure we don't leave any old state in the input | 914 | * untouched. Make sure we don't leave any old state in the input |
871 | * endpoint contexts. | 915 | * endpoint contexts. |
872 | */ | 916 | */ |
873 | virt_dev->in_ctx->drop_flags = 0; | 917 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); |
874 | virt_dev->in_ctx->add_flags = 0; | 918 | ctrl_ctx->drop_flags = 0; |
875 | virt_dev->in_ctx->slot.dev_info &= ~LAST_CTX_MASK; | 919 | ctrl_ctx->add_flags = 0; |
920 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); | ||
921 | slot_ctx->dev_info &= ~LAST_CTX_MASK; | ||
876 | /* Endpoint 0 is always valid */ | 922 | /* Endpoint 0 is always valid */ |
877 | virt_dev->in_ctx->slot.dev_info |= LAST_CTX(1); | 923 | slot_ctx->dev_info |= LAST_CTX(1); |
878 | for (i = 1; i < 31; ++i) { | 924 | for (i = 1; i < 31; ++i) { |
879 | ep_ctx = &virt_dev->in_ctx->ep[i]; | 925 | ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i); |
880 | ep_ctx->ep_info = 0; | 926 | ep_ctx->ep_info = 0; |
881 | ep_ctx->ep_info2 = 0; | 927 | ep_ctx->ep_info2 = 0; |
882 | ep_ctx->deq[0] = 0; | 928 | ep_ctx->deq = 0; |
883 | ep_ctx->deq[1] = 0; | ||
884 | ep_ctx->tx_info = 0; | 929 | ep_ctx->tx_info = 0; |
885 | } | 930 | } |
886 | } | 931 | } |
@@ -903,6 +948,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
903 | unsigned long flags; | 948 | unsigned long flags; |
904 | struct xhci_hcd *xhci; | 949 | struct xhci_hcd *xhci; |
905 | struct xhci_virt_device *virt_dev; | 950 | struct xhci_virt_device *virt_dev; |
951 | struct xhci_input_control_ctx *ctrl_ctx; | ||
952 | struct xhci_slot_ctx *slot_ctx; | ||
906 | 953 | ||
907 | ret = xhci_check_args(hcd, udev, NULL, 0, __func__); | 954 | ret = xhci_check_args(hcd, udev, NULL, 0, __func__); |
908 | if (ret <= 0) | 955 | if (ret <= 0) |
@@ -918,16 +965,18 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
918 | virt_dev = xhci->devs[udev->slot_id]; | 965 | virt_dev = xhci->devs[udev->slot_id]; |
919 | 966 | ||
920 | /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ | 967 | /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ |
921 | virt_dev->in_ctx->add_flags |= SLOT_FLAG; | 968 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); |
922 | virt_dev->in_ctx->add_flags &= ~EP0_FLAG; | 969 | ctrl_ctx->add_flags |= SLOT_FLAG; |
923 | virt_dev->in_ctx->drop_flags &= ~SLOT_FLAG; | 970 | ctrl_ctx->add_flags &= ~EP0_FLAG; |
924 | virt_dev->in_ctx->drop_flags &= ~EP0_FLAG; | 971 | ctrl_ctx->drop_flags &= ~SLOT_FLAG; |
972 | ctrl_ctx->drop_flags &= ~EP0_FLAG; | ||
925 | xhci_dbg(xhci, "New Input Control Context:\n"); | 973 | xhci_dbg(xhci, "New Input Control Context:\n"); |
926 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, virt_dev->in_ctx_dma, | 974 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); |
927 | LAST_CTX_TO_EP_NUM(virt_dev->in_ctx->slot.dev_info)); | 975 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, |
976 | LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); | ||
928 | 977 | ||
929 | spin_lock_irqsave(&xhci->lock, flags); | 978 | spin_lock_irqsave(&xhci->lock, flags); |
930 | ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx_dma, | 979 | ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma, |
931 | udev->slot_id); | 980 | udev->slot_id); |
932 | if (ret < 0) { | 981 | if (ret < 0) { |
933 | spin_unlock_irqrestore(&xhci->lock, flags); | 982 | spin_unlock_irqrestore(&xhci->lock, flags); |
@@ -982,10 +1031,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
982 | } | 1031 | } |
983 | 1032 | ||
984 | xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); | 1033 | xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); |
985 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, | 1034 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, |
986 | LAST_CTX_TO_EP_NUM(virt_dev->in_ctx->slot.dev_info)); | 1035 | LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); |
987 | 1036 | ||
988 | xhci_zero_in_ctx(virt_dev); | 1037 | xhci_zero_in_ctx(xhci, virt_dev); |
989 | /* Free any old rings */ | 1038 | /* Free any old rings */ |
990 | for (i = 1; i < 31; ++i) { | 1039 | for (i = 1; i < 31; ++i) { |
991 | if (virt_dev->new_ep_rings[i]) { | 1040 | if (virt_dev->new_ep_rings[i]) { |
@@ -1023,7 +1072,67 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1023 | virt_dev->new_ep_rings[i] = NULL; | 1072 | virt_dev->new_ep_rings[i] = NULL; |
1024 | } | 1073 | } |
1025 | } | 1074 | } |
1026 | xhci_zero_in_ctx(virt_dev); | 1075 | xhci_zero_in_ctx(xhci, virt_dev); |
1076 | } | ||
1077 | |||
1078 | /* Deal with stalled endpoints. The core should have sent the control message | ||
1079 | * to clear the halt condition. However, we need to make the xHCI hardware | ||
1080 | * reset its sequence number, since a device will expect a sequence number of | ||
1081 | * zero after the halt condition is cleared. | ||
1082 | * Context: in_interrupt | ||
1083 | */ | ||
1084 | void xhci_endpoint_reset(struct usb_hcd *hcd, | ||
1085 | struct usb_host_endpoint *ep) | ||
1086 | { | ||
1087 | struct xhci_hcd *xhci; | ||
1088 | struct usb_device *udev; | ||
1089 | unsigned int ep_index; | ||
1090 | unsigned long flags; | ||
1091 | int ret; | ||
1092 | struct xhci_dequeue_state deq_state; | ||
1093 | struct xhci_ring *ep_ring; | ||
1094 | |||
1095 | xhci = hcd_to_xhci(hcd); | ||
1096 | udev = (struct usb_device *) ep->hcpriv; | ||
1097 | /* Called with a root hub endpoint (or an endpoint that wasn't added | ||
1098 | * with xhci_add_endpoint() | ||
1099 | */ | ||
1100 | if (!ep->hcpriv) | ||
1101 | return; | ||
1102 | ep_index = xhci_get_endpoint_index(&ep->desc); | ||
1103 | ep_ring = xhci->devs[udev->slot_id]->ep_rings[ep_index]; | ||
1104 | if (!ep_ring->stopped_td) { | ||
1105 | xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n", | ||
1106 | ep->desc.bEndpointAddress); | ||
1107 | return; | ||
1108 | } | ||
1109 | |||
1110 | xhci_dbg(xhci, "Queueing reset endpoint command\n"); | ||
1111 | spin_lock_irqsave(&xhci->lock, flags); | ||
1112 | ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); | ||
1113 | /* | ||
1114 | * Can't change the ring dequeue pointer until it's transitioned to the | ||
1115 | * stopped state, which is only upon a successful reset endpoint | ||
1116 | * command. Better hope that last command worked! | ||
1117 | */ | ||
1118 | if (!ret) { | ||
1119 | xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n"); | ||
1120 | /* We need to move the HW's dequeue pointer past this TD, | ||
1121 | * or it will attempt to resend it on the next doorbell ring. | ||
1122 | */ | ||
1123 | xhci_find_new_dequeue_state(xhci, udev->slot_id, | ||
1124 | ep_index, ep_ring->stopped_td, &deq_state); | ||
1125 | xhci_dbg(xhci, "Queueing new dequeue state\n"); | ||
1126 | xhci_queue_new_dequeue_state(xhci, ep_ring, | ||
1127 | udev->slot_id, | ||
1128 | ep_index, &deq_state); | ||
1129 | kfree(ep_ring->stopped_td); | ||
1130 | xhci_ring_cmd_db(xhci); | ||
1131 | } | ||
1132 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1133 | |||
1134 | if (ret) | ||
1135 | xhci_warn(xhci, "FIXME allocate a new ring segment\n"); | ||
1027 | } | 1136 | } |
1028 | 1137 | ||
1029 | /* | 1138 | /* |
@@ -1120,7 +1229,9 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
1120 | struct xhci_virt_device *virt_dev; | 1229 | struct xhci_virt_device *virt_dev; |
1121 | int ret = 0; | 1230 | int ret = 0; |
1122 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 1231 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
1123 | u32 temp; | 1232 | struct xhci_slot_ctx *slot_ctx; |
1233 | struct xhci_input_control_ctx *ctrl_ctx; | ||
1234 | u64 temp_64; | ||
1124 | 1235 | ||
1125 | if (!udev->slot_id) { | 1236 | if (!udev->slot_id) { |
1126 | xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); | 1237 | xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); |
@@ -1133,10 +1244,12 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
1133 | if (!udev->config) | 1244 | if (!udev->config) |
1134 | xhci_setup_addressable_virt_dev(xhci, udev); | 1245 | xhci_setup_addressable_virt_dev(xhci, udev); |
1135 | /* Otherwise, assume the core has the device configured how it wants */ | 1246 | /* Otherwise, assume the core has the device configured how it wants */ |
1247 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); | ||
1248 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); | ||
1136 | 1249 | ||
1137 | spin_lock_irqsave(&xhci->lock, flags); | 1250 | spin_lock_irqsave(&xhci->lock, flags); |
1138 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx_dma, | 1251 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, |
1139 | udev->slot_id); | 1252 | udev->slot_id); |
1140 | if (ret) { | 1253 | if (ret) { |
1141 | spin_unlock_irqrestore(&xhci->lock, flags); | 1254 | spin_unlock_irqrestore(&xhci->lock, flags); |
1142 | xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); | 1255 | xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); |
@@ -1176,41 +1289,37 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
1176 | default: | 1289 | default: |
1177 | xhci_err(xhci, "ERROR: unexpected command completion " | 1290 | xhci_err(xhci, "ERROR: unexpected command completion " |
1178 | "code 0x%x.\n", virt_dev->cmd_status); | 1291 | "code 0x%x.\n", virt_dev->cmd_status); |
1292 | xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); | ||
1293 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); | ||
1179 | ret = -EINVAL; | 1294 | ret = -EINVAL; |
1180 | break; | 1295 | break; |
1181 | } | 1296 | } |
1182 | if (ret) { | 1297 | if (ret) { |
1183 | return ret; | 1298 | return ret; |
1184 | } | 1299 | } |
1185 | temp = xhci_readl(xhci, &xhci->op_regs->dcbaa_ptr[0]); | 1300 | temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); |
1186 | xhci_dbg(xhci, "Op regs DCBAA ptr[0] = %#08x\n", temp); | 1301 | xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64); |
1187 | temp = xhci_readl(xhci, &xhci->op_regs->dcbaa_ptr[1]); | 1302 | xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n", |
1188 | xhci_dbg(xhci, "Op regs DCBAA ptr[1] = %#08x\n", temp); | ||
1189 | xhci_dbg(xhci, "Slot ID %d dcbaa entry[0] @%p = %#08x\n", | ||
1190 | udev->slot_id, | ||
1191 | &xhci->dcbaa->dev_context_ptrs[2*udev->slot_id], | ||
1192 | xhci->dcbaa->dev_context_ptrs[2*udev->slot_id]); | ||
1193 | xhci_dbg(xhci, "Slot ID %d dcbaa entry[1] @%p = %#08x\n", | ||
1194 | udev->slot_id, | 1303 | udev->slot_id, |
1195 | &xhci->dcbaa->dev_context_ptrs[2*udev->slot_id+1], | 1304 | &xhci->dcbaa->dev_context_ptrs[udev->slot_id], |
1196 | xhci->dcbaa->dev_context_ptrs[2*udev->slot_id+1]); | 1305 | (unsigned long long) |
1306 | xhci->dcbaa->dev_context_ptrs[udev->slot_id]); | ||
1197 | xhci_dbg(xhci, "Output Context DMA address = %#08llx\n", | 1307 | xhci_dbg(xhci, "Output Context DMA address = %#08llx\n", |
1198 | (unsigned long long)virt_dev->out_ctx_dma); | 1308 | (unsigned long long)virt_dev->out_ctx->dma); |
1199 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); | 1309 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); |
1200 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, virt_dev->in_ctx_dma, 2); | 1310 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); |
1201 | xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); | 1311 | xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); |
1202 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, 2); | 1312 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); |
1203 | /* | 1313 | /* |
1204 | * USB core uses address 1 for the roothubs, so we add one to the | 1314 | * USB core uses address 1 for the roothubs, so we add one to the |
1205 | * address given back to us by the HC. | 1315 | * address given back to us by the HC. |
1206 | */ | 1316 | */ |
1207 | udev->devnum = (virt_dev->out_ctx->slot.dev_state & DEV_ADDR_MASK) + 1; | 1317 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); |
1318 | udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; | ||
1208 | /* Zero the input context control for later use */ | 1319 | /* Zero the input context control for later use */ |
1209 | virt_dev->in_ctx->add_flags = 0; | 1320 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); |
1210 | virt_dev->in_ctx->drop_flags = 0; | 1321 | ctrl_ctx->add_flags = 0; |
1211 | /* Mirror flags in the output context for future ep enable/disable */ | 1322 | ctrl_ctx->drop_flags = 0; |
1212 | virt_dev->out_ctx->add_flags = SLOT_FLAG | EP0_FLAG; | ||
1213 | virt_dev->out_ctx->drop_flags = 0; | ||
1214 | 1323 | ||
1215 | xhci_dbg(xhci, "Device address = %d\n", udev->devnum); | 1324 | xhci_dbg(xhci, "Device address = %d\n", udev->devnum); |
1216 | /* XXX Meh, not sure if anyone else but choose_address uses this. */ | 1325 | /* XXX Meh, not sure if anyone else but choose_address uses this. */ |
@@ -1252,7 +1361,6 @@ static int __init xhci_hcd_init(void) | |||
1252 | /* xhci_device_control has eight fields, and also | 1361 | /* xhci_device_control has eight fields, and also |
1253 | * embeds one xhci_slot_ctx and 31 xhci_ep_ctx | 1362 | * embeds one xhci_slot_ctx and 31 xhci_ep_ctx |
1254 | */ | 1363 | */ |
1255 | BUILD_BUG_ON(sizeof(struct xhci_device_control) != (8+8+8*31)*32/8); | ||
1256 | BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); | 1364 | BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); |
1257 | BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); | 1365 | BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); |
1258 | BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); | 1366 | BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index c8a72de1c508..e6b9a1c6002d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -88,7 +88,7 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, | |||
88 | return; | 88 | return; |
89 | prev->next = next; | 89 | prev->next = next; |
90 | if (link_trbs) { | 90 | if (link_trbs) { |
91 | prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr[0] = next->dma; | 91 | prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = next->dma; |
92 | 92 | ||
93 | /* Set the last TRB in the segment to have a TRB type ID of Link TRB */ | 93 | /* Set the last TRB in the segment to have a TRB type ID of Link TRB */ |
94 | val = prev->trbs[TRBS_PER_SEGMENT-1].link.control; | 94 | val = prev->trbs[TRBS_PER_SEGMENT-1].link.control; |
@@ -189,6 +189,63 @@ fail: | |||
189 | return 0; | 189 | return 0; |
190 | } | 190 | } |
191 | 191 | ||
192 | #define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32) | ||
193 | |||
194 | struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci, | ||
195 | int type, gfp_t flags) | ||
196 | { | ||
197 | struct xhci_container_ctx *ctx = kzalloc(sizeof(*ctx), flags); | ||
198 | if (!ctx) | ||
199 | return NULL; | ||
200 | |||
201 | BUG_ON((type != XHCI_CTX_TYPE_DEVICE) && (type != XHCI_CTX_TYPE_INPUT)); | ||
202 | ctx->type = type; | ||
203 | ctx->size = HCC_64BYTE_CONTEXT(xhci->hcc_params) ? 2048 : 1024; | ||
204 | if (type == XHCI_CTX_TYPE_INPUT) | ||
205 | ctx->size += CTX_SIZE(xhci->hcc_params); | ||
206 | |||
207 | ctx->bytes = dma_pool_alloc(xhci->device_pool, flags, &ctx->dma); | ||
208 | memset(ctx->bytes, 0, ctx->size); | ||
209 | return ctx; | ||
210 | } | ||
211 | |||
212 | void xhci_free_container_ctx(struct xhci_hcd *xhci, | ||
213 | struct xhci_container_ctx *ctx) | ||
214 | { | ||
215 | dma_pool_free(xhci->device_pool, ctx->bytes, ctx->dma); | ||
216 | kfree(ctx); | ||
217 | } | ||
218 | |||
219 | struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, | ||
220 | struct xhci_container_ctx *ctx) | ||
221 | { | ||
222 | BUG_ON(ctx->type != XHCI_CTX_TYPE_INPUT); | ||
223 | return (struct xhci_input_control_ctx *)ctx->bytes; | ||
224 | } | ||
225 | |||
226 | struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, | ||
227 | struct xhci_container_ctx *ctx) | ||
228 | { | ||
229 | if (ctx->type == XHCI_CTX_TYPE_DEVICE) | ||
230 | return (struct xhci_slot_ctx *)ctx->bytes; | ||
231 | |||
232 | return (struct xhci_slot_ctx *) | ||
233 | (ctx->bytes + CTX_SIZE(xhci->hcc_params)); | ||
234 | } | ||
235 | |||
236 | struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, | ||
237 | struct xhci_container_ctx *ctx, | ||
238 | unsigned int ep_index) | ||
239 | { | ||
240 | /* increment ep index by offset of start of ep ctx array */ | ||
241 | ep_index++; | ||
242 | if (ctx->type == XHCI_CTX_TYPE_INPUT) | ||
243 | ep_index++; | ||
244 | |||
245 | return (struct xhci_ep_ctx *) | ||
246 | (ctx->bytes + (ep_index * CTX_SIZE(xhci->hcc_params))); | ||
247 | } | ||
248 | |||
192 | /* All the xhci_tds in the ring's TD list should be freed at this point */ | 249 | /* All the xhci_tds in the ring's TD list should be freed at this point */ |
193 | void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) | 250 | void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) |
194 | { | 251 | { |
@@ -200,8 +257,7 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) | |||
200 | return; | 257 | return; |
201 | 258 | ||
202 | dev = xhci->devs[slot_id]; | 259 | dev = xhci->devs[slot_id]; |
203 | xhci->dcbaa->dev_context_ptrs[2*slot_id] = 0; | 260 | xhci->dcbaa->dev_context_ptrs[slot_id] = 0; |
204 | xhci->dcbaa->dev_context_ptrs[2*slot_id + 1] = 0; | ||
205 | if (!dev) | 261 | if (!dev) |
206 | return; | 262 | return; |
207 | 263 | ||
@@ -210,11 +266,10 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) | |||
210 | xhci_ring_free(xhci, dev->ep_rings[i]); | 266 | xhci_ring_free(xhci, dev->ep_rings[i]); |
211 | 267 | ||
212 | if (dev->in_ctx) | 268 | if (dev->in_ctx) |
213 | dma_pool_free(xhci->device_pool, | 269 | xhci_free_container_ctx(xhci, dev->in_ctx); |
214 | dev->in_ctx, dev->in_ctx_dma); | ||
215 | if (dev->out_ctx) | 270 | if (dev->out_ctx) |
216 | dma_pool_free(xhci->device_pool, | 271 | xhci_free_container_ctx(xhci, dev->out_ctx); |
217 | dev->out_ctx, dev->out_ctx_dma); | 272 | |
218 | kfree(xhci->devs[slot_id]); | 273 | kfree(xhci->devs[slot_id]); |
219 | xhci->devs[slot_id] = 0; | 274 | xhci->devs[slot_id] = 0; |
220 | } | 275 | } |
@@ -222,7 +277,6 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) | |||
222 | int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | 277 | int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, |
223 | struct usb_device *udev, gfp_t flags) | 278 | struct usb_device *udev, gfp_t flags) |
224 | { | 279 | { |
225 | dma_addr_t dma; | ||
226 | struct xhci_virt_device *dev; | 280 | struct xhci_virt_device *dev; |
227 | 281 | ||
228 | /* Slot ID 0 is reserved */ | 282 | /* Slot ID 0 is reserved */ |
@@ -236,23 +290,21 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | |||
236 | return 0; | 290 | return 0; |
237 | dev = xhci->devs[slot_id]; | 291 | dev = xhci->devs[slot_id]; |
238 | 292 | ||
239 | /* Allocate the (output) device context that will be used in the HC */ | 293 | /* Allocate the (output) device context that will be used in the HC. */ |
240 | dev->out_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma); | 294 | dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags); |
241 | if (!dev->out_ctx) | 295 | if (!dev->out_ctx) |
242 | goto fail; | 296 | goto fail; |
243 | dev->out_ctx_dma = dma; | 297 | |
244 | xhci_dbg(xhci, "Slot %d output ctx = 0x%llx (dma)\n", slot_id, | 298 | xhci_dbg(xhci, "Slot %d output ctx = 0x%llx (dma)\n", slot_id, |
245 | (unsigned long long)dma); | 299 | (unsigned long long)dev->out_ctx->dma); |
246 | memset(dev->out_ctx, 0, sizeof(*dev->out_ctx)); | ||
247 | 300 | ||
248 | /* Allocate the (input) device context for address device command */ | 301 | /* Allocate the (input) device context for address device command */ |
249 | dev->in_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma); | 302 | dev->in_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_INPUT, flags); |
250 | if (!dev->in_ctx) | 303 | if (!dev->in_ctx) |
251 | goto fail; | 304 | goto fail; |
252 | dev->in_ctx_dma = dma; | 305 | |
253 | xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id, | 306 | xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id, |
254 | (unsigned long long)dma); | 307 | (unsigned long long)dev->in_ctx->dma); |
255 | memset(dev->in_ctx, 0, sizeof(*dev->in_ctx)); | ||
256 | 308 | ||
257 | /* Allocate endpoint 0 ring */ | 309 | /* Allocate endpoint 0 ring */ |
258 | dev->ep_rings[0] = xhci_ring_alloc(xhci, 1, true, flags); | 310 | dev->ep_rings[0] = xhci_ring_alloc(xhci, 1, true, flags); |
@@ -261,17 +313,12 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | |||
261 | 313 | ||
262 | init_completion(&dev->cmd_completion); | 314 | init_completion(&dev->cmd_completion); |
263 | 315 | ||
264 | /* | 316 | /* Point to output device context in dcbaa. */ |
265 | * Point to output device context in dcbaa; skip the output control | 317 | xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx->dma; |
266 | * context, which is eight 32 bit fields (or 32 bytes long) | ||
267 | */ | ||
268 | xhci->dcbaa->dev_context_ptrs[2*slot_id] = | ||
269 | (u32) dev->out_ctx_dma + (32); | ||
270 | xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n", | 318 | xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n", |
271 | slot_id, | 319 | slot_id, |
272 | &xhci->dcbaa->dev_context_ptrs[2*slot_id], | 320 | &xhci->dcbaa->dev_context_ptrs[slot_id], |
273 | (unsigned long long)dev->out_ctx_dma); | 321 | (unsigned long long) xhci->dcbaa->dev_context_ptrs[slot_id]); |
274 | xhci->dcbaa->dev_context_ptrs[2*slot_id + 1] = 0; | ||
275 | 322 | ||
276 | return 1; | 323 | return 1; |
277 | fail: | 324 | fail: |
@@ -285,6 +332,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
285 | struct xhci_virt_device *dev; | 332 | struct xhci_virt_device *dev; |
286 | struct xhci_ep_ctx *ep0_ctx; | 333 | struct xhci_ep_ctx *ep0_ctx; |
287 | struct usb_device *top_dev; | 334 | struct usb_device *top_dev; |
335 | struct xhci_slot_ctx *slot_ctx; | ||
336 | struct xhci_input_control_ctx *ctrl_ctx; | ||
288 | 337 | ||
289 | dev = xhci->devs[udev->slot_id]; | 338 | dev = xhci->devs[udev->slot_id]; |
290 | /* Slot ID 0 is reserved */ | 339 | /* Slot ID 0 is reserved */ |
@@ -293,27 +342,29 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
293 | udev->slot_id); | 342 | udev->slot_id); |
294 | return -EINVAL; | 343 | return -EINVAL; |
295 | } | 344 | } |
296 | ep0_ctx = &dev->in_ctx->ep[0]; | 345 | ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0); |
346 | ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx); | ||
347 | slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx); | ||
297 | 348 | ||
298 | /* 2) New slot context and endpoint 0 context are valid*/ | 349 | /* 2) New slot context and endpoint 0 context are valid*/ |
299 | dev->in_ctx->add_flags = SLOT_FLAG | EP0_FLAG; | 350 | ctrl_ctx->add_flags = SLOT_FLAG | EP0_FLAG; |
300 | 351 | ||
301 | /* 3) Only the control endpoint is valid - one endpoint context */ | 352 | /* 3) Only the control endpoint is valid - one endpoint context */ |
302 | dev->in_ctx->slot.dev_info |= LAST_CTX(1); | 353 | slot_ctx->dev_info |= LAST_CTX(1); |
303 | 354 | ||
304 | switch (udev->speed) { | 355 | switch (udev->speed) { |
305 | case USB_SPEED_SUPER: | 356 | case USB_SPEED_SUPER: |
306 | dev->in_ctx->slot.dev_info |= (u32) udev->route; | 357 | slot_ctx->dev_info |= (u32) udev->route; |
307 | dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_SS; | 358 | slot_ctx->dev_info |= (u32) SLOT_SPEED_SS; |
308 | break; | 359 | break; |
309 | case USB_SPEED_HIGH: | 360 | case USB_SPEED_HIGH: |
310 | dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_HS; | 361 | slot_ctx->dev_info |= (u32) SLOT_SPEED_HS; |
311 | break; | 362 | break; |
312 | case USB_SPEED_FULL: | 363 | case USB_SPEED_FULL: |
313 | dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_FS; | 364 | slot_ctx->dev_info |= (u32) SLOT_SPEED_FS; |
314 | break; | 365 | break; |
315 | case USB_SPEED_LOW: | 366 | case USB_SPEED_LOW: |
316 | dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_LS; | 367 | slot_ctx->dev_info |= (u32) SLOT_SPEED_LS; |
317 | break; | 368 | break; |
318 | case USB_SPEED_VARIABLE: | 369 | case USB_SPEED_VARIABLE: |
319 | xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n"); | 370 | xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n"); |
@@ -327,7 +378,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
327 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; | 378 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; |
328 | top_dev = top_dev->parent) | 379 | top_dev = top_dev->parent) |
329 | /* Found device below root hub */; | 380 | /* Found device below root hub */; |
330 | dev->in_ctx->slot.dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum); | 381 | slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum); |
331 | xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); | 382 | xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); |
332 | 383 | ||
333 | /* Is this a LS/FS device under a HS hub? */ | 384 | /* Is this a LS/FS device under a HS hub? */ |
@@ -337,8 +388,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
337 | */ | 388 | */ |
338 | if ((udev->speed == USB_SPEED_LOW || udev->speed == USB_SPEED_FULL) && | 389 | if ((udev->speed == USB_SPEED_LOW || udev->speed == USB_SPEED_FULL) && |
339 | udev->tt) { | 390 | udev->tt) { |
340 | dev->in_ctx->slot.tt_info = udev->tt->hub->slot_id; | 391 | slot_ctx->tt_info = udev->tt->hub->slot_id; |
341 | dev->in_ctx->slot.tt_info |= udev->ttport << 8; | 392 | slot_ctx->tt_info |= udev->ttport << 8; |
342 | } | 393 | } |
343 | xhci_dbg(xhci, "udev->tt = %p\n", udev->tt); | 394 | xhci_dbg(xhci, "udev->tt = %p\n", udev->tt); |
344 | xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport); | 395 | xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport); |
@@ -360,10 +411,9 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
360 | ep0_ctx->ep_info2 |= MAX_BURST(0); | 411 | ep0_ctx->ep_info2 |= MAX_BURST(0); |
361 | ep0_ctx->ep_info2 |= ERROR_COUNT(3); | 412 | ep0_ctx->ep_info2 |= ERROR_COUNT(3); |
362 | 413 | ||
363 | ep0_ctx->deq[0] = | 414 | ep0_ctx->deq = |
364 | dev->ep_rings[0]->first_seg->dma; | 415 | dev->ep_rings[0]->first_seg->dma; |
365 | ep0_ctx->deq[0] |= dev->ep_rings[0]->cycle_state; | 416 | ep0_ctx->deq |= dev->ep_rings[0]->cycle_state; |
366 | ep0_ctx->deq[1] = 0; | ||
367 | 417 | ||
368 | /* Steps 7 and 8 were done in xhci_alloc_virt_device() */ | 418 | /* Steps 7 and 8 were done in xhci_alloc_virt_device() */ |
369 | 419 | ||
@@ -470,25 +520,26 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
470 | unsigned int max_burst; | 520 | unsigned int max_burst; |
471 | 521 | ||
472 | ep_index = xhci_get_endpoint_index(&ep->desc); | 522 | ep_index = xhci_get_endpoint_index(&ep->desc); |
473 | ep_ctx = &virt_dev->in_ctx->ep[ep_index]; | 523 | ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); |
474 | 524 | ||
475 | /* Set up the endpoint ring */ | 525 | /* Set up the endpoint ring */ |
476 | virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, mem_flags); | 526 | virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, mem_flags); |
477 | if (!virt_dev->new_ep_rings[ep_index]) | 527 | if (!virt_dev->new_ep_rings[ep_index]) |
478 | return -ENOMEM; | 528 | return -ENOMEM; |
479 | ep_ring = virt_dev->new_ep_rings[ep_index]; | 529 | ep_ring = virt_dev->new_ep_rings[ep_index]; |
480 | ep_ctx->deq[0] = ep_ring->first_seg->dma | ep_ring->cycle_state; | 530 | ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state; |
481 | ep_ctx->deq[1] = 0; | ||
482 | 531 | ||
483 | ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep); | 532 | ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep); |
484 | 533 | ||
485 | /* FIXME dig Mult and streams info out of ep companion desc */ | 534 | /* FIXME dig Mult and streams info out of ep companion desc */ |
486 | 535 | ||
487 | /* Allow 3 retries for everything but isoc */ | 536 | /* Allow 3 retries for everything but isoc; |
537 | * error count = 0 means infinite retries. | ||
538 | */ | ||
488 | if (!usb_endpoint_xfer_isoc(&ep->desc)) | 539 | if (!usb_endpoint_xfer_isoc(&ep->desc)) |
489 | ep_ctx->ep_info2 = ERROR_COUNT(3); | 540 | ep_ctx->ep_info2 = ERROR_COUNT(3); |
490 | else | 541 | else |
491 | ep_ctx->ep_info2 = ERROR_COUNT(0); | 542 | ep_ctx->ep_info2 = ERROR_COUNT(1); |
492 | 543 | ||
493 | ep_ctx->ep_info2 |= xhci_get_endpoint_type(udev, ep); | 544 | ep_ctx->ep_info2 |= xhci_get_endpoint_type(udev, ep); |
494 | 545 | ||
@@ -498,7 +549,12 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
498 | max_packet = ep->desc.wMaxPacketSize; | 549 | max_packet = ep->desc.wMaxPacketSize; |
499 | ep_ctx->ep_info2 |= MAX_PACKET(max_packet); | 550 | ep_ctx->ep_info2 |= MAX_PACKET(max_packet); |
500 | /* dig out max burst from ep companion desc */ | 551 | /* dig out max burst from ep companion desc */ |
501 | max_packet = ep->ss_ep_comp->desc.bMaxBurst; | 552 | if (!ep->ss_ep_comp) { |
553 | xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n"); | ||
554 | max_packet = 0; | ||
555 | } else { | ||
556 | max_packet = ep->ss_ep_comp->desc.bMaxBurst; | ||
557 | } | ||
502 | ep_ctx->ep_info2 |= MAX_BURST(max_packet); | 558 | ep_ctx->ep_info2 |= MAX_BURST(max_packet); |
503 | break; | 559 | break; |
504 | case USB_SPEED_HIGH: | 560 | case USB_SPEED_HIGH: |
@@ -531,18 +587,114 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci, | |||
531 | struct xhci_ep_ctx *ep_ctx; | 587 | struct xhci_ep_ctx *ep_ctx; |
532 | 588 | ||
533 | ep_index = xhci_get_endpoint_index(&ep->desc); | 589 | ep_index = xhci_get_endpoint_index(&ep->desc); |
534 | ep_ctx = &virt_dev->in_ctx->ep[ep_index]; | 590 | ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); |
535 | 591 | ||
536 | ep_ctx->ep_info = 0; | 592 | ep_ctx->ep_info = 0; |
537 | ep_ctx->ep_info2 = 0; | 593 | ep_ctx->ep_info2 = 0; |
538 | ep_ctx->deq[0] = 0; | 594 | ep_ctx->deq = 0; |
539 | ep_ctx->deq[1] = 0; | ||
540 | ep_ctx->tx_info = 0; | 595 | ep_ctx->tx_info = 0; |
541 | /* Don't free the endpoint ring until the set interface or configuration | 596 | /* Don't free the endpoint ring until the set interface or configuration |
542 | * request succeeds. | 597 | * request succeeds. |
543 | */ | 598 | */ |
544 | } | 599 | } |
545 | 600 | ||
601 | /* Set up the scratchpad buffer array and scratchpad buffers, if needed. */ | ||
602 | static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags) | ||
603 | { | ||
604 | int i; | ||
605 | struct device *dev = xhci_to_hcd(xhci)->self.controller; | ||
606 | int num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2); | ||
607 | |||
608 | xhci_dbg(xhci, "Allocating %d scratchpad buffers\n", num_sp); | ||
609 | |||
610 | if (!num_sp) | ||
611 | return 0; | ||
612 | |||
613 | xhci->scratchpad = kzalloc(sizeof(*xhci->scratchpad), flags); | ||
614 | if (!xhci->scratchpad) | ||
615 | goto fail_sp; | ||
616 | |||
617 | xhci->scratchpad->sp_array = | ||
618 | pci_alloc_consistent(to_pci_dev(dev), | ||
619 | num_sp * sizeof(u64), | ||
620 | &xhci->scratchpad->sp_dma); | ||
621 | if (!xhci->scratchpad->sp_array) | ||
622 | goto fail_sp2; | ||
623 | |||
624 | xhci->scratchpad->sp_buffers = kzalloc(sizeof(void *) * num_sp, flags); | ||
625 | if (!xhci->scratchpad->sp_buffers) | ||
626 | goto fail_sp3; | ||
627 | |||
628 | xhci->scratchpad->sp_dma_buffers = | ||
629 | kzalloc(sizeof(dma_addr_t) * num_sp, flags); | ||
630 | |||
631 | if (!xhci->scratchpad->sp_dma_buffers) | ||
632 | goto fail_sp4; | ||
633 | |||
634 | xhci->dcbaa->dev_context_ptrs[0] = xhci->scratchpad->sp_dma; | ||
635 | for (i = 0; i < num_sp; i++) { | ||
636 | dma_addr_t dma; | ||
637 | void *buf = pci_alloc_consistent(to_pci_dev(dev), | ||
638 | xhci->page_size, &dma); | ||
639 | if (!buf) | ||
640 | goto fail_sp5; | ||
641 | |||
642 | xhci->scratchpad->sp_array[i] = dma; | ||
643 | xhci->scratchpad->sp_buffers[i] = buf; | ||
644 | xhci->scratchpad->sp_dma_buffers[i] = dma; | ||
645 | } | ||
646 | |||
647 | return 0; | ||
648 | |||
649 | fail_sp5: | ||
650 | for (i = i - 1; i >= 0; i--) { | ||
651 | pci_free_consistent(to_pci_dev(dev), xhci->page_size, | ||
652 | xhci->scratchpad->sp_buffers[i], | ||
653 | xhci->scratchpad->sp_dma_buffers[i]); | ||
654 | } | ||
655 | kfree(xhci->scratchpad->sp_dma_buffers); | ||
656 | |||
657 | fail_sp4: | ||
658 | kfree(xhci->scratchpad->sp_buffers); | ||
659 | |||
660 | fail_sp3: | ||
661 | pci_free_consistent(to_pci_dev(dev), num_sp * sizeof(u64), | ||
662 | xhci->scratchpad->sp_array, | ||
663 | xhci->scratchpad->sp_dma); | ||
664 | |||
665 | fail_sp2: | ||
666 | kfree(xhci->scratchpad); | ||
667 | xhci->scratchpad = NULL; | ||
668 | |||
669 | fail_sp: | ||
670 | return -ENOMEM; | ||
671 | } | ||
672 | |||
673 | static void scratchpad_free(struct xhci_hcd *xhci) | ||
674 | { | ||
675 | int num_sp; | ||
676 | int i; | ||
677 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); | ||
678 | |||
679 | if (!xhci->scratchpad) | ||
680 | return; | ||
681 | |||
682 | num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2); | ||
683 | |||
684 | for (i = 0; i < num_sp; i++) { | ||
685 | pci_free_consistent(pdev, xhci->page_size, | ||
686 | xhci->scratchpad->sp_buffers[i], | ||
687 | xhci->scratchpad->sp_dma_buffers[i]); | ||
688 | } | ||
689 | kfree(xhci->scratchpad->sp_dma_buffers); | ||
690 | kfree(xhci->scratchpad->sp_buffers); | ||
691 | pci_free_consistent(pdev, num_sp * sizeof(u64), | ||
692 | xhci->scratchpad->sp_array, | ||
693 | xhci->scratchpad->sp_dma); | ||
694 | kfree(xhci->scratchpad); | ||
695 | xhci->scratchpad = NULL; | ||
696 | } | ||
697 | |||
546 | void xhci_mem_cleanup(struct xhci_hcd *xhci) | 698 | void xhci_mem_cleanup(struct xhci_hcd *xhci) |
547 | { | 699 | { |
548 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); | 700 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); |
@@ -551,10 +703,8 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
551 | 703 | ||
552 | /* Free the Event Ring Segment Table and the actual Event Ring */ | 704 | /* Free the Event Ring Segment Table and the actual Event Ring */ |
553 | xhci_writel(xhci, 0, &xhci->ir_set->erst_size); | 705 | xhci_writel(xhci, 0, &xhci->ir_set->erst_size); |
554 | xhci_writel(xhci, 0, &xhci->ir_set->erst_base[0]); | 706 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); |
555 | xhci_writel(xhci, 0, &xhci->ir_set->erst_base[1]); | 707 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); |
556 | xhci_writel(xhci, 0, &xhci->ir_set->erst_dequeue[0]); | ||
557 | xhci_writel(xhci, 0, &xhci->ir_set->erst_dequeue[1]); | ||
558 | size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); | 708 | size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); |
559 | if (xhci->erst.entries) | 709 | if (xhci->erst.entries) |
560 | pci_free_consistent(pdev, size, | 710 | pci_free_consistent(pdev, size, |
@@ -566,8 +716,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
566 | xhci->event_ring = NULL; | 716 | xhci->event_ring = NULL; |
567 | xhci_dbg(xhci, "Freed event ring\n"); | 717 | xhci_dbg(xhci, "Freed event ring\n"); |
568 | 718 | ||
569 | xhci_writel(xhci, 0, &xhci->op_regs->cmd_ring[0]); | 719 | xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring); |
570 | xhci_writel(xhci, 0, &xhci->op_regs->cmd_ring[1]); | ||
571 | if (xhci->cmd_ring) | 720 | if (xhci->cmd_ring) |
572 | xhci_ring_free(xhci, xhci->cmd_ring); | 721 | xhci_ring_free(xhci, xhci->cmd_ring); |
573 | xhci->cmd_ring = NULL; | 722 | xhci->cmd_ring = NULL; |
@@ -586,8 +735,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
586 | xhci->device_pool = NULL; | 735 | xhci->device_pool = NULL; |
587 | xhci_dbg(xhci, "Freed device context pool\n"); | 736 | xhci_dbg(xhci, "Freed device context pool\n"); |
588 | 737 | ||
589 | xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[0]); | 738 | xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr); |
590 | xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[1]); | ||
591 | if (xhci->dcbaa) | 739 | if (xhci->dcbaa) |
592 | pci_free_consistent(pdev, sizeof(*xhci->dcbaa), | 740 | pci_free_consistent(pdev, sizeof(*xhci->dcbaa), |
593 | xhci->dcbaa, xhci->dcbaa->dma); | 741 | xhci->dcbaa, xhci->dcbaa->dma); |
@@ -595,6 +743,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
595 | 743 | ||
596 | xhci->page_size = 0; | 744 | xhci->page_size = 0; |
597 | xhci->page_shift = 0; | 745 | xhci->page_shift = 0; |
746 | scratchpad_free(xhci); | ||
598 | } | 747 | } |
599 | 748 | ||
600 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | 749 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) |
@@ -602,6 +751,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
602 | dma_addr_t dma; | 751 | dma_addr_t dma; |
603 | struct device *dev = xhci_to_hcd(xhci)->self.controller; | 752 | struct device *dev = xhci_to_hcd(xhci)->self.controller; |
604 | unsigned int val, val2; | 753 | unsigned int val, val2; |
754 | u64 val_64; | ||
605 | struct xhci_segment *seg; | 755 | struct xhci_segment *seg; |
606 | u32 page_size; | 756 | u32 page_size; |
607 | int i; | 757 | int i; |
@@ -647,8 +797,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
647 | xhci->dcbaa->dma = dma; | 797 | xhci->dcbaa->dma = dma; |
648 | xhci_dbg(xhci, "// Device context base array address = 0x%llx (DMA), %p (virt)\n", | 798 | xhci_dbg(xhci, "// Device context base array address = 0x%llx (DMA), %p (virt)\n", |
649 | (unsigned long long)xhci->dcbaa->dma, xhci->dcbaa); | 799 | (unsigned long long)xhci->dcbaa->dma, xhci->dcbaa); |
650 | xhci_writel(xhci, dma, &xhci->op_regs->dcbaa_ptr[0]); | 800 | xhci_write_64(xhci, dma, &xhci->op_regs->dcbaa_ptr); |
651 | xhci_writel(xhci, (u32) 0, &xhci->op_regs->dcbaa_ptr[1]); | ||
652 | 801 | ||
653 | /* | 802 | /* |
654 | * Initialize the ring segment pool. The ring must be a contiguous | 803 | * Initialize the ring segment pool. The ring must be a contiguous |
@@ -658,11 +807,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
658 | */ | 807 | */ |
659 | xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, | 808 | xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, |
660 | SEGMENT_SIZE, 64, xhci->page_size); | 809 | SEGMENT_SIZE, 64, xhci->page_size); |
810 | |||
661 | /* See Table 46 and Note on Figure 55 */ | 811 | /* See Table 46 and Note on Figure 55 */ |
662 | /* FIXME support 64-byte contexts */ | ||
663 | xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, | 812 | xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, |
664 | sizeof(struct xhci_device_control), | 813 | 2112, 64, xhci->page_size); |
665 | 64, xhci->page_size); | ||
666 | if (!xhci->segment_pool || !xhci->device_pool) | 814 | if (!xhci->segment_pool || !xhci->device_pool) |
667 | goto fail; | 815 | goto fail; |
668 | 816 | ||
@@ -675,14 +823,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
675 | (unsigned long long)xhci->cmd_ring->first_seg->dma); | 823 | (unsigned long long)xhci->cmd_ring->first_seg->dma); |
676 | 824 | ||
677 | /* Set the address in the Command Ring Control register */ | 825 | /* Set the address in the Command Ring Control register */ |
678 | val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[0]); | 826 | val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); |
679 | val = (val & ~CMD_RING_ADDR_MASK) | | 827 | val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | |
680 | (xhci->cmd_ring->first_seg->dma & CMD_RING_ADDR_MASK) | | 828 | (xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) | |
681 | xhci->cmd_ring->cycle_state; | 829 | xhci->cmd_ring->cycle_state; |
682 | xhci_dbg(xhci, "// Setting command ring address low bits to 0x%x\n", val); | 830 | xhci_dbg(xhci, "// Setting command ring address to 0x%x\n", val); |
683 | xhci_writel(xhci, val, &xhci->op_regs->cmd_ring[0]); | 831 | xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); |
684 | xhci_dbg(xhci, "// Setting command ring address high bits to 0x0\n"); | ||
685 | xhci_writel(xhci, (u32) 0, &xhci->op_regs->cmd_ring[1]); | ||
686 | xhci_dbg_cmd_ptrs(xhci); | 832 | xhci_dbg_cmd_ptrs(xhci); |
687 | 833 | ||
688 | val = xhci_readl(xhci, &xhci->cap_regs->db_off); | 834 | val = xhci_readl(xhci, &xhci->cap_regs->db_off); |
@@ -722,8 +868,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
722 | /* set ring base address and size for each segment table entry */ | 868 | /* set ring base address and size for each segment table entry */ |
723 | for (val = 0, seg = xhci->event_ring->first_seg; val < ERST_NUM_SEGS; val++) { | 869 | for (val = 0, seg = xhci->event_ring->first_seg; val < ERST_NUM_SEGS; val++) { |
724 | struct xhci_erst_entry *entry = &xhci->erst.entries[val]; | 870 | struct xhci_erst_entry *entry = &xhci->erst.entries[val]; |
725 | entry->seg_addr[0] = seg->dma; | 871 | entry->seg_addr = seg->dma; |
726 | entry->seg_addr[1] = 0; | ||
727 | entry->seg_size = TRBS_PER_SEGMENT; | 872 | entry->seg_size = TRBS_PER_SEGMENT; |
728 | entry->rsvd = 0; | 873 | entry->rsvd = 0; |
729 | seg = seg->next; | 874 | seg = seg->next; |
@@ -741,11 +886,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
741 | /* set the segment table base address */ | 886 | /* set the segment table base address */ |
742 | xhci_dbg(xhci, "// Set ERST base address for ir_set 0 = 0x%llx\n", | 887 | xhci_dbg(xhci, "// Set ERST base address for ir_set 0 = 0x%llx\n", |
743 | (unsigned long long)xhci->erst.erst_dma_addr); | 888 | (unsigned long long)xhci->erst.erst_dma_addr); |
744 | val = xhci_readl(xhci, &xhci->ir_set->erst_base[0]); | 889 | val_64 = xhci_read_64(xhci, &xhci->ir_set->erst_base); |
745 | val &= ERST_PTR_MASK; | 890 | val_64 &= ERST_PTR_MASK; |
746 | val |= (xhci->erst.erst_dma_addr & ~ERST_PTR_MASK); | 891 | val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_PTR_MASK); |
747 | xhci_writel(xhci, val, &xhci->ir_set->erst_base[0]); | 892 | xhci_write_64(xhci, val_64, &xhci->ir_set->erst_base); |
748 | xhci_writel(xhci, 0, &xhci->ir_set->erst_base[1]); | ||
749 | 893 | ||
750 | /* Set the event ring dequeue address */ | 894 | /* Set the event ring dequeue address */ |
751 | xhci_set_hc_event_deq(xhci); | 895 | xhci_set_hc_event_deq(xhci); |
@@ -761,7 +905,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
761 | for (i = 0; i < MAX_HC_SLOTS; ++i) | 905 | for (i = 0; i < MAX_HC_SLOTS; ++i) |
762 | xhci->devs[i] = 0; | 906 | xhci->devs[i] = 0; |
763 | 907 | ||
908 | if (scratchpad_alloc(xhci, flags)) | ||
909 | goto fail; | ||
910 | |||
764 | return 0; | 911 | return 0; |
912 | |||
765 | fail: | 913 | fail: |
766 | xhci_warn(xhci, "Couldn't initialize memory\n"); | 914 | xhci_warn(xhci, "Couldn't initialize memory\n"); |
767 | xhci_mem_cleanup(xhci); | 915 | xhci_mem_cleanup(xhci); |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 1462709e26c0..592fe7e623f7 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -117,6 +117,7 @@ static const struct hc_driver xhci_pci_hc_driver = { | |||
117 | .free_dev = xhci_free_dev, | 117 | .free_dev = xhci_free_dev, |
118 | .add_endpoint = xhci_add_endpoint, | 118 | .add_endpoint = xhci_add_endpoint, |
119 | .drop_endpoint = xhci_drop_endpoint, | 119 | .drop_endpoint = xhci_drop_endpoint, |
120 | .endpoint_reset = xhci_endpoint_reset, | ||
120 | .check_bandwidth = xhci_check_bandwidth, | 121 | .check_bandwidth = xhci_check_bandwidth, |
121 | .reset_bandwidth = xhci_reset_bandwidth, | 122 | .reset_bandwidth = xhci_reset_bandwidth, |
122 | .address_device = xhci_address_device, | 123 | .address_device = xhci_address_device, |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 02d81985c454..aa88a067148b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -135,6 +135,7 @@ static void next_trb(struct xhci_hcd *xhci, | |||
135 | static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer) | 135 | static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer) |
136 | { | 136 | { |
137 | union xhci_trb *next = ++(ring->dequeue); | 137 | union xhci_trb *next = ++(ring->dequeue); |
138 | unsigned long long addr; | ||
138 | 139 | ||
139 | ring->deq_updates++; | 140 | ring->deq_updates++; |
140 | /* Update the dequeue pointer further if that was a link TRB or we're at | 141 | /* Update the dequeue pointer further if that was a link TRB or we're at |
@@ -152,6 +153,13 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer | |||
152 | ring->dequeue = ring->deq_seg->trbs; | 153 | ring->dequeue = ring->deq_seg->trbs; |
153 | next = ring->dequeue; | 154 | next = ring->dequeue; |
154 | } | 155 | } |
156 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); | ||
157 | if (ring == xhci->event_ring) | ||
158 | xhci_dbg(xhci, "Event ring deq = 0x%llx (DMA)\n", addr); | ||
159 | else if (ring == xhci->cmd_ring) | ||
160 | xhci_dbg(xhci, "Command ring deq = 0x%llx (DMA)\n", addr); | ||
161 | else | ||
162 | xhci_dbg(xhci, "Ring deq = 0x%llx (DMA)\n", addr); | ||
155 | } | 163 | } |
156 | 164 | ||
157 | /* | 165 | /* |
@@ -171,6 +179,7 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer | |||
171 | { | 179 | { |
172 | u32 chain; | 180 | u32 chain; |
173 | union xhci_trb *next; | 181 | union xhci_trb *next; |
182 | unsigned long long addr; | ||
174 | 183 | ||
175 | chain = ring->enqueue->generic.field[3] & TRB_CHAIN; | 184 | chain = ring->enqueue->generic.field[3] & TRB_CHAIN; |
176 | next = ++(ring->enqueue); | 185 | next = ++(ring->enqueue); |
@@ -204,6 +213,13 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer | |||
204 | ring->enqueue = ring->enq_seg->trbs; | 213 | ring->enqueue = ring->enq_seg->trbs; |
205 | next = ring->enqueue; | 214 | next = ring->enqueue; |
206 | } | 215 | } |
216 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); | ||
217 | if (ring == xhci->event_ring) | ||
218 | xhci_dbg(xhci, "Event ring enq = 0x%llx (DMA)\n", addr); | ||
219 | else if (ring == xhci->cmd_ring) | ||
220 | xhci_dbg(xhci, "Command ring enq = 0x%llx (DMA)\n", addr); | ||
221 | else | ||
222 | xhci_dbg(xhci, "Ring enq = 0x%llx (DMA)\n", addr); | ||
207 | } | 223 | } |
208 | 224 | ||
209 | /* | 225 | /* |
@@ -237,7 +253,7 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring, | |||
237 | 253 | ||
238 | void xhci_set_hc_event_deq(struct xhci_hcd *xhci) | 254 | void xhci_set_hc_event_deq(struct xhci_hcd *xhci) |
239 | { | 255 | { |
240 | u32 temp; | 256 | u64 temp; |
241 | dma_addr_t deq; | 257 | dma_addr_t deq; |
242 | 258 | ||
243 | deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, | 259 | deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, |
@@ -246,13 +262,15 @@ void xhci_set_hc_event_deq(struct xhci_hcd *xhci) | |||
246 | xhci_warn(xhci, "WARN something wrong with SW event ring " | 262 | xhci_warn(xhci, "WARN something wrong with SW event ring " |
247 | "dequeue ptr.\n"); | 263 | "dequeue ptr.\n"); |
248 | /* Update HC event ring dequeue pointer */ | 264 | /* Update HC event ring dequeue pointer */ |
249 | temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); | 265 | temp = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
250 | temp &= ERST_PTR_MASK; | 266 | temp &= ERST_PTR_MASK; |
251 | if (!in_interrupt()) | 267 | /* Don't clear the EHB bit (which is RW1C) because |
252 | xhci_dbg(xhci, "// Write event ring dequeue pointer\n"); | 268 | * there might be more events to service. |
253 | xhci_writel(xhci, 0, &xhci->ir_set->erst_dequeue[1]); | 269 | */ |
254 | xhci_writel(xhci, (deq & ~ERST_PTR_MASK) | temp, | 270 | temp &= ~ERST_EHB; |
255 | &xhci->ir_set->erst_dequeue[0]); | 271 | xhci_dbg(xhci, "// Write event ring dequeue pointer, preserving EHB bit\n"); |
272 | xhci_write_64(xhci, ((u64) deq & (u64) ~ERST_PTR_MASK) | temp, | ||
273 | &xhci->ir_set->erst_dequeue); | ||
256 | } | 274 | } |
257 | 275 | ||
258 | /* Ring the host controller doorbell after placing a command on the ring */ | 276 | /* Ring the host controller doorbell after placing a command on the ring */ |
@@ -279,7 +297,8 @@ static void ring_ep_doorbell(struct xhci_hcd *xhci, | |||
279 | /* Don't ring the doorbell for this endpoint if there are pending | 297 | /* Don't ring the doorbell for this endpoint if there are pending |
280 | * cancellations because the we don't want to interrupt processing. | 298 | * cancellations because the we don't want to interrupt processing. |
281 | */ | 299 | */ |
282 | if (!ep_ring->cancels_pending && !(ep_ring->state & SET_DEQ_PENDING)) { | 300 | if (!ep_ring->cancels_pending && !(ep_ring->state & SET_DEQ_PENDING) |
301 | && !(ep_ring->state & EP_HALTED)) { | ||
283 | field = xhci_readl(xhci, db_addr) & DB_MASK; | 302 | field = xhci_readl(xhci, db_addr) & DB_MASK; |
284 | xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr); | 303 | xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr); |
285 | /* Flush PCI posted writes - FIXME Matthew Wilcox says this | 304 | /* Flush PCI posted writes - FIXME Matthew Wilcox says this |
@@ -316,12 +335,6 @@ static struct xhci_segment *find_trb_seg( | |||
316 | return cur_seg; | 335 | return cur_seg; |
317 | } | 336 | } |
318 | 337 | ||
319 | struct dequeue_state { | ||
320 | struct xhci_segment *new_deq_seg; | ||
321 | union xhci_trb *new_deq_ptr; | ||
322 | int new_cycle_state; | ||
323 | }; | ||
324 | |||
325 | /* | 338 | /* |
326 | * Move the xHC's endpoint ring dequeue pointer past cur_td. | 339 | * Move the xHC's endpoint ring dequeue pointer past cur_td. |
327 | * Record the new state of the xHC's endpoint ring dequeue segment, | 340 | * Record the new state of the xHC's endpoint ring dequeue segment, |
@@ -336,24 +349,30 @@ struct dequeue_state { | |||
336 | * - Finally we move the dequeue state one TRB further, toggling the cycle bit | 349 | * - Finally we move the dequeue state one TRB further, toggling the cycle bit |
337 | * if we've moved it past a link TRB with the toggle cycle bit set. | 350 | * if we've moved it past a link TRB with the toggle cycle bit set. |
338 | */ | 351 | */ |
339 | static void find_new_dequeue_state(struct xhci_hcd *xhci, | 352 | void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, |
340 | unsigned int slot_id, unsigned int ep_index, | 353 | unsigned int slot_id, unsigned int ep_index, |
341 | struct xhci_td *cur_td, struct dequeue_state *state) | 354 | struct xhci_td *cur_td, struct xhci_dequeue_state *state) |
342 | { | 355 | { |
343 | struct xhci_virt_device *dev = xhci->devs[slot_id]; | 356 | struct xhci_virt_device *dev = xhci->devs[slot_id]; |
344 | struct xhci_ring *ep_ring = dev->ep_rings[ep_index]; | 357 | struct xhci_ring *ep_ring = dev->ep_rings[ep_index]; |
345 | struct xhci_generic_trb *trb; | 358 | struct xhci_generic_trb *trb; |
359 | struct xhci_ep_ctx *ep_ctx; | ||
360 | dma_addr_t addr; | ||
346 | 361 | ||
347 | state->new_cycle_state = 0; | 362 | state->new_cycle_state = 0; |
363 | xhci_dbg(xhci, "Finding segment containing stopped TRB.\n"); | ||
348 | state->new_deq_seg = find_trb_seg(cur_td->start_seg, | 364 | state->new_deq_seg = find_trb_seg(cur_td->start_seg, |
349 | ep_ring->stopped_trb, | 365 | ep_ring->stopped_trb, |
350 | &state->new_cycle_state); | 366 | &state->new_cycle_state); |
351 | if (!state->new_deq_seg) | 367 | if (!state->new_deq_seg) |
352 | BUG(); | 368 | BUG(); |
353 | /* Dig out the cycle state saved by the xHC during the stop ep cmd */ | 369 | /* Dig out the cycle state saved by the xHC during the stop ep cmd */ |
354 | state->new_cycle_state = 0x1 & dev->out_ctx->ep[ep_index].deq[0]; | 370 | xhci_dbg(xhci, "Finding endpoint context\n"); |
371 | ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); | ||
372 | state->new_cycle_state = 0x1 & ep_ctx->deq; | ||
355 | 373 | ||
356 | state->new_deq_ptr = cur_td->last_trb; | 374 | state->new_deq_ptr = cur_td->last_trb; |
375 | xhci_dbg(xhci, "Finding segment containing last TRB in TD.\n"); | ||
357 | state->new_deq_seg = find_trb_seg(state->new_deq_seg, | 376 | state->new_deq_seg = find_trb_seg(state->new_deq_seg, |
358 | state->new_deq_ptr, | 377 | state->new_deq_ptr, |
359 | &state->new_cycle_state); | 378 | &state->new_cycle_state); |
@@ -367,6 +386,12 @@ static void find_new_dequeue_state(struct xhci_hcd *xhci, | |||
367 | next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); | 386 | next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); |
368 | 387 | ||
369 | /* Don't update the ring cycle state for the producer (us). */ | 388 | /* Don't update the ring cycle state for the producer (us). */ |
389 | xhci_dbg(xhci, "New dequeue segment = %p (virtual)\n", | ||
390 | state->new_deq_seg); | ||
391 | addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr); | ||
392 | xhci_dbg(xhci, "New dequeue pointer = 0x%llx (DMA)\n", | ||
393 | (unsigned long long) addr); | ||
394 | xhci_dbg(xhci, "Setting dequeue pointer in internal ring state.\n"); | ||
370 | ep_ring->dequeue = state->new_deq_ptr; | 395 | ep_ring->dequeue = state->new_deq_ptr; |
371 | ep_ring->deq_seg = state->new_deq_seg; | 396 | ep_ring->deq_seg = state->new_deq_seg; |
372 | } | 397 | } |
@@ -416,6 +441,30 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id, | |||
416 | unsigned int ep_index, struct xhci_segment *deq_seg, | 441 | unsigned int ep_index, struct xhci_segment *deq_seg, |
417 | union xhci_trb *deq_ptr, u32 cycle_state); | 442 | union xhci_trb *deq_ptr, u32 cycle_state); |
418 | 443 | ||
444 | void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, | ||
445 | struct xhci_ring *ep_ring, unsigned int slot_id, | ||
446 | unsigned int ep_index, struct xhci_dequeue_state *deq_state) | ||
447 | { | ||
448 | xhci_dbg(xhci, "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), " | ||
449 | "new deq ptr = %p (0x%llx dma), new cycle = %u\n", | ||
450 | deq_state->new_deq_seg, | ||
451 | (unsigned long long)deq_state->new_deq_seg->dma, | ||
452 | deq_state->new_deq_ptr, | ||
453 | (unsigned long long)xhci_trb_virt_to_dma(deq_state->new_deq_seg, deq_state->new_deq_ptr), | ||
454 | deq_state->new_cycle_state); | ||
455 | queue_set_tr_deq(xhci, slot_id, ep_index, | ||
456 | deq_state->new_deq_seg, | ||
457 | deq_state->new_deq_ptr, | ||
458 | (u32) deq_state->new_cycle_state); | ||
459 | /* Stop the TD queueing code from ringing the doorbell until | ||
460 | * this command completes. The HC won't set the dequeue pointer | ||
461 | * if the ring is running, and ringing the doorbell starts the | ||
462 | * ring running. | ||
463 | */ | ||
464 | ep_ring->state |= SET_DEQ_PENDING; | ||
465 | xhci_ring_cmd_db(xhci); | ||
466 | } | ||
467 | |||
419 | /* | 468 | /* |
420 | * When we get a command completion for a Stop Endpoint Command, we need to | 469 | * When we get a command completion for a Stop Endpoint Command, we need to |
421 | * unlink any cancelled TDs from the ring. There are two ways to do that: | 470 | * unlink any cancelled TDs from the ring. There are two ways to do that: |
@@ -436,7 +485,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
436 | struct xhci_td *cur_td = 0; | 485 | struct xhci_td *cur_td = 0; |
437 | struct xhci_td *last_unlinked_td; | 486 | struct xhci_td *last_unlinked_td; |
438 | 487 | ||
439 | struct dequeue_state deq_state; | 488 | struct xhci_dequeue_state deq_state; |
440 | #ifdef CONFIG_USB_HCD_STAT | 489 | #ifdef CONFIG_USB_HCD_STAT |
441 | ktime_t stop_time = ktime_get(); | 490 | ktime_t stop_time = ktime_get(); |
442 | #endif | 491 | #endif |
@@ -464,7 +513,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
464 | * move the xHC endpoint ring dequeue pointer past this TD. | 513 | * move the xHC endpoint ring dequeue pointer past this TD. |
465 | */ | 514 | */ |
466 | if (cur_td == ep_ring->stopped_td) | 515 | if (cur_td == ep_ring->stopped_td) |
467 | find_new_dequeue_state(xhci, slot_id, ep_index, cur_td, | 516 | xhci_find_new_dequeue_state(xhci, slot_id, ep_index, cur_td, |
468 | &deq_state); | 517 | &deq_state); |
469 | else | 518 | else |
470 | td_to_noop(xhci, ep_ring, cur_td); | 519 | td_to_noop(xhci, ep_ring, cur_td); |
@@ -480,24 +529,8 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
480 | 529 | ||
481 | /* If necessary, queue a Set Transfer Ring Dequeue Pointer command */ | 530 | /* If necessary, queue a Set Transfer Ring Dequeue Pointer command */ |
482 | if (deq_state.new_deq_ptr && deq_state.new_deq_seg) { | 531 | if (deq_state.new_deq_ptr && deq_state.new_deq_seg) { |
483 | xhci_dbg(xhci, "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), " | 532 | xhci_queue_new_dequeue_state(xhci, ep_ring, |
484 | "new deq ptr = %p (0x%llx dma), new cycle = %u\n", | 533 | slot_id, ep_index, &deq_state); |
485 | deq_state.new_deq_seg, | ||
486 | (unsigned long long)deq_state.new_deq_seg->dma, | ||
487 | deq_state.new_deq_ptr, | ||
488 | (unsigned long long)xhci_trb_virt_to_dma(deq_state.new_deq_seg, deq_state.new_deq_ptr), | ||
489 | deq_state.new_cycle_state); | ||
490 | queue_set_tr_deq(xhci, slot_id, ep_index, | ||
491 | deq_state.new_deq_seg, | ||
492 | deq_state.new_deq_ptr, | ||
493 | (u32) deq_state.new_cycle_state); | ||
494 | /* Stop the TD queueing code from ringing the doorbell until | ||
495 | * this command completes. The HC won't set the dequeue pointer | ||
496 | * if the ring is running, and ringing the doorbell starts the | ||
497 | * ring running. | ||
498 | */ | ||
499 | ep_ring->state |= SET_DEQ_PENDING; | ||
500 | xhci_ring_cmd_db(xhci); | ||
501 | } else { | 534 | } else { |
502 | /* Otherwise just ring the doorbell to restart the ring */ | 535 | /* Otherwise just ring the doorbell to restart the ring */ |
503 | ring_ep_doorbell(xhci, slot_id, ep_index); | 536 | ring_ep_doorbell(xhci, slot_id, ep_index); |
@@ -551,11 +584,15 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci, | |||
551 | unsigned int ep_index; | 584 | unsigned int ep_index; |
552 | struct xhci_ring *ep_ring; | 585 | struct xhci_ring *ep_ring; |
553 | struct xhci_virt_device *dev; | 586 | struct xhci_virt_device *dev; |
587 | struct xhci_ep_ctx *ep_ctx; | ||
588 | struct xhci_slot_ctx *slot_ctx; | ||
554 | 589 | ||
555 | slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); | 590 | slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); |
556 | ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); | 591 | ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); |
557 | dev = xhci->devs[slot_id]; | 592 | dev = xhci->devs[slot_id]; |
558 | ep_ring = dev->ep_rings[ep_index]; | 593 | ep_ring = dev->ep_rings[ep_index]; |
594 | ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); | ||
595 | slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx); | ||
559 | 596 | ||
560 | if (GET_COMP_CODE(event->status) != COMP_SUCCESS) { | 597 | if (GET_COMP_CODE(event->status) != COMP_SUCCESS) { |
561 | unsigned int ep_state; | 598 | unsigned int ep_state; |
@@ -569,9 +606,9 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci, | |||
569 | case COMP_CTX_STATE: | 606 | case COMP_CTX_STATE: |
570 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed due " | 607 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed due " |
571 | "to incorrect slot or ep state.\n"); | 608 | "to incorrect slot or ep state.\n"); |
572 | ep_state = dev->out_ctx->ep[ep_index].ep_info; | 609 | ep_state = ep_ctx->ep_info; |
573 | ep_state &= EP_STATE_MASK; | 610 | ep_state &= EP_STATE_MASK; |
574 | slot_state = dev->out_ctx->slot.dev_state; | 611 | slot_state = slot_ctx->dev_state; |
575 | slot_state = GET_SLOT_STATE(slot_state); | 612 | slot_state = GET_SLOT_STATE(slot_state); |
576 | xhci_dbg(xhci, "Slot state = %u, EP state = %u\n", | 613 | xhci_dbg(xhci, "Slot state = %u, EP state = %u\n", |
577 | slot_state, ep_state); | 614 | slot_state, ep_state); |
@@ -593,16 +630,33 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci, | |||
593 | * cancelling URBs, which might not be an error... | 630 | * cancelling URBs, which might not be an error... |
594 | */ | 631 | */ |
595 | } else { | 632 | } else { |
596 | xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq[0] = 0x%x, " | 633 | xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq = @%08llx\n", |
597 | "deq[1] = 0x%x.\n", | 634 | ep_ctx->deq); |
598 | dev->out_ctx->ep[ep_index].deq[0], | ||
599 | dev->out_ctx->ep[ep_index].deq[1]); | ||
600 | } | 635 | } |
601 | 636 | ||
602 | ep_ring->state &= ~SET_DEQ_PENDING; | 637 | ep_ring->state &= ~SET_DEQ_PENDING; |
603 | ring_ep_doorbell(xhci, slot_id, ep_index); | 638 | ring_ep_doorbell(xhci, slot_id, ep_index); |
604 | } | 639 | } |
605 | 640 | ||
641 | static void handle_reset_ep_completion(struct xhci_hcd *xhci, | ||
642 | struct xhci_event_cmd *event, | ||
643 | union xhci_trb *trb) | ||
644 | { | ||
645 | int slot_id; | ||
646 | unsigned int ep_index; | ||
647 | |||
648 | slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); | ||
649 | ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); | ||
650 | /* This command will only fail if the endpoint wasn't halted, | ||
651 | * but we don't care. | ||
652 | */ | ||
653 | xhci_dbg(xhci, "Ignoring reset ep completion code of %u\n", | ||
654 | (unsigned int) GET_COMP_CODE(event->status)); | ||
655 | |||
656 | /* Clear our internal halted state and restart the ring */ | ||
657 | xhci->devs[slot_id]->ep_rings[ep_index]->state &= ~EP_HALTED; | ||
658 | ring_ep_doorbell(xhci, slot_id, ep_index); | ||
659 | } | ||
606 | 660 | ||
607 | static void handle_cmd_completion(struct xhci_hcd *xhci, | 661 | static void handle_cmd_completion(struct xhci_hcd *xhci, |
608 | struct xhci_event_cmd *event) | 662 | struct xhci_event_cmd *event) |
@@ -611,7 +665,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, | |||
611 | u64 cmd_dma; | 665 | u64 cmd_dma; |
612 | dma_addr_t cmd_dequeue_dma; | 666 | dma_addr_t cmd_dequeue_dma; |
613 | 667 | ||
614 | cmd_dma = (((u64) event->cmd_trb[1]) << 32) + event->cmd_trb[0]; | 668 | cmd_dma = event->cmd_trb; |
615 | cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, | 669 | cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, |
616 | xhci->cmd_ring->dequeue); | 670 | xhci->cmd_ring->dequeue); |
617 | /* Is the command ring deq ptr out of sync with the deq seg ptr? */ | 671 | /* Is the command ring deq ptr out of sync with the deq seg ptr? */ |
@@ -653,6 +707,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, | |||
653 | case TRB_TYPE(TRB_CMD_NOOP): | 707 | case TRB_TYPE(TRB_CMD_NOOP): |
654 | ++xhci->noops_handled; | 708 | ++xhci->noops_handled; |
655 | break; | 709 | break; |
710 | case TRB_TYPE(TRB_RESET_EP): | ||
711 | handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue); | ||
712 | break; | ||
656 | default: | 713 | default: |
657 | /* Skip over unknown commands on the event ring */ | 714 | /* Skip over unknown commands on the event ring */ |
658 | xhci->error_bitmask |= 1 << 6; | 715 | xhci->error_bitmask |= 1 << 6; |
@@ -756,7 +813,9 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
756 | union xhci_trb *event_trb; | 813 | union xhci_trb *event_trb; |
757 | struct urb *urb = 0; | 814 | struct urb *urb = 0; |
758 | int status = -EINPROGRESS; | 815 | int status = -EINPROGRESS; |
816 | struct xhci_ep_ctx *ep_ctx; | ||
759 | 817 | ||
818 | xhci_dbg(xhci, "In %s\n", __func__); | ||
760 | xdev = xhci->devs[TRB_TO_SLOT_ID(event->flags)]; | 819 | xdev = xhci->devs[TRB_TO_SLOT_ID(event->flags)]; |
761 | if (!xdev) { | 820 | if (!xdev) { |
762 | xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n"); | 821 | xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n"); |
@@ -765,17 +824,17 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
765 | 824 | ||
766 | /* Endpoint ID is 1 based, our index is zero based */ | 825 | /* Endpoint ID is 1 based, our index is zero based */ |
767 | ep_index = TRB_TO_EP_ID(event->flags) - 1; | 826 | ep_index = TRB_TO_EP_ID(event->flags) - 1; |
827 | xhci_dbg(xhci, "%s - ep index = %d\n", __func__, ep_index); | ||
768 | ep_ring = xdev->ep_rings[ep_index]; | 828 | ep_ring = xdev->ep_rings[ep_index]; |
769 | if (!ep_ring || (xdev->out_ctx->ep[ep_index].ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) { | 829 | ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); |
830 | if (!ep_ring || (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) { | ||
770 | xhci_err(xhci, "ERROR Transfer event pointed to disabled endpoint\n"); | 831 | xhci_err(xhci, "ERROR Transfer event pointed to disabled endpoint\n"); |
771 | return -ENODEV; | 832 | return -ENODEV; |
772 | } | 833 | } |
773 | 834 | ||
774 | event_dma = event->buffer[0]; | 835 | event_dma = event->buffer; |
775 | if (event->buffer[1] != 0) | ||
776 | xhci_warn(xhci, "WARN ignoring upper 32-bits of 64-bit TRB dma address\n"); | ||
777 | |||
778 | /* This TRB should be in the TD at the head of this ring's TD list */ | 836 | /* This TRB should be in the TD at the head of this ring's TD list */ |
837 | xhci_dbg(xhci, "%s - checking for list empty\n", __func__); | ||
779 | if (list_empty(&ep_ring->td_list)) { | 838 | if (list_empty(&ep_ring->td_list)) { |
780 | xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n", | 839 | xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n", |
781 | TRB_TO_SLOT_ID(event->flags), ep_index); | 840 | TRB_TO_SLOT_ID(event->flags), ep_index); |
@@ -785,11 +844,14 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
785 | urb = NULL; | 844 | urb = NULL; |
786 | goto cleanup; | 845 | goto cleanup; |
787 | } | 846 | } |
847 | xhci_dbg(xhci, "%s - getting list entry\n", __func__); | ||
788 | td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list); | 848 | td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list); |
789 | 849 | ||
790 | /* Is this a TRB in the currently executing TD? */ | 850 | /* Is this a TRB in the currently executing TD? */ |
851 | xhci_dbg(xhci, "%s - looking for TD\n", __func__); | ||
791 | event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, | 852 | event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, |
792 | td->last_trb, event_dma); | 853 | td->last_trb, event_dma); |
854 | xhci_dbg(xhci, "%s - found event_seg = %p\n", __func__, event_seg); | ||
793 | if (!event_seg) { | 855 | if (!event_seg) { |
794 | /* HC is busted, give up! */ | 856 | /* HC is busted, give up! */ |
795 | xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not part of current TD\n"); | 857 | xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not part of current TD\n"); |
@@ -798,10 +860,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
798 | event_trb = &event_seg->trbs[(event_dma - event_seg->dma) / sizeof(*event_trb)]; | 860 | event_trb = &event_seg->trbs[(event_dma - event_seg->dma) / sizeof(*event_trb)]; |
799 | xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", | 861 | xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", |
800 | (unsigned int) (event->flags & TRB_TYPE_BITMASK)>>10); | 862 | (unsigned int) (event->flags & TRB_TYPE_BITMASK)>>10); |
801 | xhci_dbg(xhci, "Offset 0x00 (buffer[0]) = 0x%x\n", | 863 | xhci_dbg(xhci, "Offset 0x00 (buffer lo) = 0x%x\n", |
802 | (unsigned int) event->buffer[0]); | 864 | lower_32_bits(event->buffer)); |
803 | xhci_dbg(xhci, "Offset 0x04 (buffer[0]) = 0x%x\n", | 865 | xhci_dbg(xhci, "Offset 0x04 (buffer hi) = 0x%x\n", |
804 | (unsigned int) event->buffer[1]); | 866 | upper_32_bits(event->buffer)); |
805 | xhci_dbg(xhci, "Offset 0x08 (transfer length) = 0x%x\n", | 867 | xhci_dbg(xhci, "Offset 0x08 (transfer length) = 0x%x\n", |
806 | (unsigned int) event->transfer_len); | 868 | (unsigned int) event->transfer_len); |
807 | xhci_dbg(xhci, "Offset 0x0C (flags) = 0x%x\n", | 869 | xhci_dbg(xhci, "Offset 0x0C (flags) = 0x%x\n", |
@@ -823,6 +885,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
823 | break; | 885 | break; |
824 | case COMP_STALL: | 886 | case COMP_STALL: |
825 | xhci_warn(xhci, "WARN: Stalled endpoint\n"); | 887 | xhci_warn(xhci, "WARN: Stalled endpoint\n"); |
888 | ep_ring->state |= EP_HALTED; | ||
826 | status = -EPIPE; | 889 | status = -EPIPE; |
827 | break; | 890 | break; |
828 | case COMP_TRB_ERR: | 891 | case COMP_TRB_ERR: |
@@ -833,6 +896,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
833 | xhci_warn(xhci, "WARN: transfer error on endpoint\n"); | 896 | xhci_warn(xhci, "WARN: transfer error on endpoint\n"); |
834 | status = -EPROTO; | 897 | status = -EPROTO; |
835 | break; | 898 | break; |
899 | case COMP_BABBLE: | ||
900 | xhci_warn(xhci, "WARN: babble error on endpoint\n"); | ||
901 | status = -EOVERFLOW; | ||
902 | break; | ||
836 | case COMP_DB_ERR: | 903 | case COMP_DB_ERR: |
837 | xhci_warn(xhci, "WARN: HC couldn't access mem fast enough\n"); | 904 | xhci_warn(xhci, "WARN: HC couldn't access mem fast enough\n"); |
838 | status = -ENOSR; | 905 | status = -ENOSR; |
@@ -874,15 +941,26 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
874 | if (event_trb != ep_ring->dequeue) { | 941 | if (event_trb != ep_ring->dequeue) { |
875 | /* The event was for the status stage */ | 942 | /* The event was for the status stage */ |
876 | if (event_trb == td->last_trb) { | 943 | if (event_trb == td->last_trb) { |
877 | td->urb->actual_length = | 944 | if (td->urb->actual_length != 0) { |
878 | td->urb->transfer_buffer_length; | 945 | /* Don't overwrite a previously set error code */ |
946 | if (status == -EINPROGRESS || status == 0) | ||
947 | /* Did we already see a short data stage? */ | ||
948 | status = -EREMOTEIO; | ||
949 | } else { | ||
950 | td->urb->actual_length = | ||
951 | td->urb->transfer_buffer_length; | ||
952 | } | ||
879 | } else { | 953 | } else { |
880 | /* Maybe the event was for the data stage? */ | 954 | /* Maybe the event was for the data stage? */ |
881 | if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL) | 955 | if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL) { |
882 | /* We didn't stop on a link TRB in the middle */ | 956 | /* We didn't stop on a link TRB in the middle */ |
883 | td->urb->actual_length = | 957 | td->urb->actual_length = |
884 | td->urb->transfer_buffer_length - | 958 | td->urb->transfer_buffer_length - |
885 | TRB_LEN(event->transfer_len); | 959 | TRB_LEN(event->transfer_len); |
960 | xhci_dbg(xhci, "Waiting for status stage event\n"); | ||
961 | urb = NULL; | ||
962 | goto cleanup; | ||
963 | } | ||
886 | } | 964 | } |
887 | } | 965 | } |
888 | } else { | 966 | } else { |
@@ -929,16 +1007,20 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
929 | TRB_LEN(event->transfer_len)); | 1007 | TRB_LEN(event->transfer_len)); |
930 | td->urb->actual_length = 0; | 1008 | td->urb->actual_length = 0; |
931 | } | 1009 | } |
932 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) | 1010 | /* Don't overwrite a previously set error code */ |
933 | status = -EREMOTEIO; | 1011 | if (status == -EINPROGRESS) { |
934 | else | 1012 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) |
935 | status = 0; | 1013 | status = -EREMOTEIO; |
1014 | else | ||
1015 | status = 0; | ||
1016 | } | ||
936 | } else { | 1017 | } else { |
937 | td->urb->actual_length = td->urb->transfer_buffer_length; | 1018 | td->urb->actual_length = td->urb->transfer_buffer_length; |
938 | /* Ignore a short packet completion if the | 1019 | /* Ignore a short packet completion if the |
939 | * untransferred length was zero. | 1020 | * untransferred length was zero. |
940 | */ | 1021 | */ |
941 | status = 0; | 1022 | if (status == -EREMOTEIO) |
1023 | status = 0; | ||
942 | } | 1024 | } |
943 | } else { | 1025 | } else { |
944 | /* Slow path - walk the list, starting from the dequeue | 1026 | /* Slow path - walk the list, starting from the dequeue |
@@ -965,19 +1047,30 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
965 | TRB_LEN(event->transfer_len); | 1047 | TRB_LEN(event->transfer_len); |
966 | } | 1048 | } |
967 | } | 1049 | } |
968 | /* The Endpoint Stop Command completion will take care of | ||
969 | * any stopped TDs. A stopped TD may be restarted, so don't update the | ||
970 | * ring dequeue pointer or take this TD off any lists yet. | ||
971 | */ | ||
972 | if (GET_COMP_CODE(event->transfer_len) == COMP_STOP_INVAL || | 1050 | if (GET_COMP_CODE(event->transfer_len) == COMP_STOP_INVAL || |
973 | GET_COMP_CODE(event->transfer_len) == COMP_STOP) { | 1051 | GET_COMP_CODE(event->transfer_len) == COMP_STOP) { |
1052 | /* The Endpoint Stop Command completion will take care of any | ||
1053 | * stopped TDs. A stopped TD may be restarted, so don't update | ||
1054 | * the ring dequeue pointer or take this TD off any lists yet. | ||
1055 | */ | ||
974 | ep_ring->stopped_td = td; | 1056 | ep_ring->stopped_td = td; |
975 | ep_ring->stopped_trb = event_trb; | 1057 | ep_ring->stopped_trb = event_trb; |
976 | } else { | 1058 | } else { |
977 | /* Update ring dequeue pointer */ | 1059 | if (GET_COMP_CODE(event->transfer_len) == COMP_STALL) { |
978 | while (ep_ring->dequeue != td->last_trb) | 1060 | /* The transfer is completed from the driver's |
1061 | * perspective, but we need to issue a set dequeue | ||
1062 | * command for this stalled endpoint to move the dequeue | ||
1063 | * pointer past the TD. We can't do that here because | ||
1064 | * the halt condition must be cleared first. | ||
1065 | */ | ||
1066 | ep_ring->stopped_td = td; | ||
1067 | ep_ring->stopped_trb = event_trb; | ||
1068 | } else { | ||
1069 | /* Update ring dequeue pointer */ | ||
1070 | while (ep_ring->dequeue != td->last_trb) | ||
1071 | inc_deq(xhci, ep_ring, false); | ||
979 | inc_deq(xhci, ep_ring, false); | 1072 | inc_deq(xhci, ep_ring, false); |
980 | inc_deq(xhci, ep_ring, false); | 1073 | } |
981 | 1074 | ||
982 | /* Clean up the endpoint's TD list */ | 1075 | /* Clean up the endpoint's TD list */ |
983 | urb = td->urb; | 1076 | urb = td->urb; |
@@ -987,7 +1080,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
987 | list_del(&td->cancelled_td_list); | 1080 | list_del(&td->cancelled_td_list); |
988 | ep_ring->cancels_pending--; | 1081 | ep_ring->cancels_pending--; |
989 | } | 1082 | } |
990 | kfree(td); | 1083 | /* Leave the TD around for the reset endpoint function to use */ |
1084 | if (GET_COMP_CODE(event->transfer_len) != COMP_STALL) { | ||
1085 | kfree(td); | ||
1086 | } | ||
991 | urb->hcpriv = NULL; | 1087 | urb->hcpriv = NULL; |
992 | } | 1088 | } |
993 | cleanup: | 1089 | cleanup: |
@@ -997,6 +1093,8 @@ cleanup: | |||
997 | /* FIXME for multi-TD URBs (who have buffers bigger than 64MB) */ | 1093 | /* FIXME for multi-TD URBs (who have buffers bigger than 64MB) */ |
998 | if (urb) { | 1094 | if (urb) { |
999 | usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), urb); | 1095 | usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), urb); |
1096 | xhci_dbg(xhci, "Giveback URB %p, len = %d, status = %d\n", | ||
1097 | urb, td->urb->actual_length, status); | ||
1000 | spin_unlock(&xhci->lock); | 1098 | spin_unlock(&xhci->lock); |
1001 | usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, status); | 1099 | usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, status); |
1002 | spin_lock(&xhci->lock); | 1100 | spin_lock(&xhci->lock); |
@@ -1014,6 +1112,7 @@ void xhci_handle_event(struct xhci_hcd *xhci) | |||
1014 | int update_ptrs = 1; | 1112 | int update_ptrs = 1; |
1015 | int ret; | 1113 | int ret; |
1016 | 1114 | ||
1115 | xhci_dbg(xhci, "In %s\n", __func__); | ||
1017 | if (!xhci->event_ring || !xhci->event_ring->dequeue) { | 1116 | if (!xhci->event_ring || !xhci->event_ring->dequeue) { |
1018 | xhci->error_bitmask |= 1 << 1; | 1117 | xhci->error_bitmask |= 1 << 1; |
1019 | return; | 1118 | return; |
@@ -1026,18 +1125,25 @@ void xhci_handle_event(struct xhci_hcd *xhci) | |||
1026 | xhci->error_bitmask |= 1 << 2; | 1125 | xhci->error_bitmask |= 1 << 2; |
1027 | return; | 1126 | return; |
1028 | } | 1127 | } |
1128 | xhci_dbg(xhci, "%s - OS owns TRB\n", __func__); | ||
1029 | 1129 | ||
1030 | /* FIXME: Handle more event types. */ | 1130 | /* FIXME: Handle more event types. */ |
1031 | switch ((event->event_cmd.flags & TRB_TYPE_BITMASK)) { | 1131 | switch ((event->event_cmd.flags & TRB_TYPE_BITMASK)) { |
1032 | case TRB_TYPE(TRB_COMPLETION): | 1132 | case TRB_TYPE(TRB_COMPLETION): |
1133 | xhci_dbg(xhci, "%s - calling handle_cmd_completion\n", __func__); | ||
1033 | handle_cmd_completion(xhci, &event->event_cmd); | 1134 | handle_cmd_completion(xhci, &event->event_cmd); |
1135 | xhci_dbg(xhci, "%s - returned from handle_cmd_completion\n", __func__); | ||
1034 | break; | 1136 | break; |
1035 | case TRB_TYPE(TRB_PORT_STATUS): | 1137 | case TRB_TYPE(TRB_PORT_STATUS): |
1138 | xhci_dbg(xhci, "%s - calling handle_port_status\n", __func__); | ||
1036 | handle_port_status(xhci, event); | 1139 | handle_port_status(xhci, event); |
1140 | xhci_dbg(xhci, "%s - returned from handle_port_status\n", __func__); | ||
1037 | update_ptrs = 0; | 1141 | update_ptrs = 0; |
1038 | break; | 1142 | break; |
1039 | case TRB_TYPE(TRB_TRANSFER): | 1143 | case TRB_TYPE(TRB_TRANSFER): |
1144 | xhci_dbg(xhci, "%s - calling handle_tx_event\n", __func__); | ||
1040 | ret = handle_tx_event(xhci, &event->trans_event); | 1145 | ret = handle_tx_event(xhci, &event->trans_event); |
1146 | xhci_dbg(xhci, "%s - returned from handle_tx_event\n", __func__); | ||
1041 | if (ret < 0) | 1147 | if (ret < 0) |
1042 | xhci->error_bitmask |= 1 << 9; | 1148 | xhci->error_bitmask |= 1 << 9; |
1043 | else | 1149 | else |
@@ -1093,13 +1199,13 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, | |||
1093 | */ | 1199 | */ |
1094 | xhci_warn(xhci, "WARN urb submitted to disabled ep\n"); | 1200 | xhci_warn(xhci, "WARN urb submitted to disabled ep\n"); |
1095 | return -ENOENT; | 1201 | return -ENOENT; |
1096 | case EP_STATE_HALTED: | ||
1097 | case EP_STATE_ERROR: | 1202 | case EP_STATE_ERROR: |
1098 | xhci_warn(xhci, "WARN waiting for halt or error on ep " | 1203 | xhci_warn(xhci, "WARN waiting for error on ep to be cleared\n"); |
1099 | "to be cleared\n"); | ||
1100 | /* FIXME event handling code for error needs to clear it */ | 1204 | /* FIXME event handling code for error needs to clear it */ |
1101 | /* XXX not sure if this should be -ENOENT or not */ | 1205 | /* XXX not sure if this should be -ENOENT or not */ |
1102 | return -EINVAL; | 1206 | return -EINVAL; |
1207 | case EP_STATE_HALTED: | ||
1208 | xhci_dbg(xhci, "WARN halted endpoint, queueing URB anyway.\n"); | ||
1103 | case EP_STATE_STOPPED: | 1209 | case EP_STATE_STOPPED: |
1104 | case EP_STATE_RUNNING: | 1210 | case EP_STATE_RUNNING: |
1105 | break; | 1211 | break; |
@@ -1128,9 +1234,9 @@ static int prepare_transfer(struct xhci_hcd *xhci, | |||
1128 | gfp_t mem_flags) | 1234 | gfp_t mem_flags) |
1129 | { | 1235 | { |
1130 | int ret; | 1236 | int ret; |
1131 | 1237 | struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); | |
1132 | ret = prepare_ring(xhci, xdev->ep_rings[ep_index], | 1238 | ret = prepare_ring(xhci, xdev->ep_rings[ep_index], |
1133 | xdev->out_ctx->ep[ep_index].ep_info & EP_STATE_MASK, | 1239 | ep_ctx->ep_info & EP_STATE_MASK, |
1134 | num_trbs, mem_flags); | 1240 | num_trbs, mem_flags); |
1135 | if (ret) | 1241 | if (ret) |
1136 | return ret; | 1242 | return ret; |
@@ -1285,6 +1391,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
1285 | /* Queue the first TRB, even if it's zero-length */ | 1391 | /* Queue the first TRB, even if it's zero-length */ |
1286 | do { | 1392 | do { |
1287 | u32 field = 0; | 1393 | u32 field = 0; |
1394 | u32 length_field = 0; | ||
1288 | 1395 | ||
1289 | /* Don't change the cycle bit of the first TRB until later */ | 1396 | /* Don't change the cycle bit of the first TRB until later */ |
1290 | if (first_trb) | 1397 | if (first_trb) |
@@ -1314,10 +1421,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
1314 | (unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1), | 1421 | (unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1), |
1315 | (unsigned int) addr + trb_buff_len); | 1422 | (unsigned int) addr + trb_buff_len); |
1316 | } | 1423 | } |
1424 | length_field = TRB_LEN(trb_buff_len) | | ||
1425 | TD_REMAINDER(urb->transfer_buffer_length - running_total) | | ||
1426 | TRB_INTR_TARGET(0); | ||
1317 | queue_trb(xhci, ep_ring, false, | 1427 | queue_trb(xhci, ep_ring, false, |
1318 | (u32) addr, | 1428 | lower_32_bits(addr), |
1319 | (u32) ((u64) addr >> 32), | 1429 | upper_32_bits(addr), |
1320 | TRB_LEN(trb_buff_len) | TRB_INTR_TARGET(0), | 1430 | length_field, |
1321 | /* We always want to know if the TRB was short, | 1431 | /* We always want to know if the TRB was short, |
1322 | * or we won't get an event when it completes. | 1432 | * or we won't get an event when it completes. |
1323 | * (Unless we use event data TRBs, which are a | 1433 | * (Unless we use event data TRBs, which are a |
@@ -1365,7 +1475,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
1365 | struct xhci_generic_trb *start_trb; | 1475 | struct xhci_generic_trb *start_trb; |
1366 | bool first_trb; | 1476 | bool first_trb; |
1367 | int start_cycle; | 1477 | int start_cycle; |
1368 | u32 field; | 1478 | u32 field, length_field; |
1369 | 1479 | ||
1370 | int running_total, trb_buff_len, ret; | 1480 | int running_total, trb_buff_len, ret; |
1371 | u64 addr; | 1481 | u64 addr; |
@@ -1443,10 +1553,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
1443 | td->last_trb = ep_ring->enqueue; | 1553 | td->last_trb = ep_ring->enqueue; |
1444 | field |= TRB_IOC; | 1554 | field |= TRB_IOC; |
1445 | } | 1555 | } |
1556 | length_field = TRB_LEN(trb_buff_len) | | ||
1557 | TD_REMAINDER(urb->transfer_buffer_length - running_total) | | ||
1558 | TRB_INTR_TARGET(0); | ||
1446 | queue_trb(xhci, ep_ring, false, | 1559 | queue_trb(xhci, ep_ring, false, |
1447 | (u32) addr, | 1560 | lower_32_bits(addr), |
1448 | (u32) ((u64) addr >> 32), | 1561 | upper_32_bits(addr), |
1449 | TRB_LEN(trb_buff_len) | TRB_INTR_TARGET(0), | 1562 | length_field, |
1450 | /* We always want to know if the TRB was short, | 1563 | /* We always want to know if the TRB was short, |
1451 | * or we won't get an event when it completes. | 1564 | * or we won't get an event when it completes. |
1452 | * (Unless we use event data TRBs, which are a | 1565 | * (Unless we use event data TRBs, which are a |
@@ -1478,7 +1591,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
1478 | struct usb_ctrlrequest *setup; | 1591 | struct usb_ctrlrequest *setup; |
1479 | struct xhci_generic_trb *start_trb; | 1592 | struct xhci_generic_trb *start_trb; |
1480 | int start_cycle; | 1593 | int start_cycle; |
1481 | u32 field; | 1594 | u32 field, length_field; |
1482 | struct xhci_td *td; | 1595 | struct xhci_td *td; |
1483 | 1596 | ||
1484 | ep_ring = xhci->devs[slot_id]->ep_rings[ep_index]; | 1597 | ep_ring = xhci->devs[slot_id]->ep_rings[ep_index]; |
@@ -1528,13 +1641,16 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
1528 | 1641 | ||
1529 | /* If there's data, queue data TRBs */ | 1642 | /* If there's data, queue data TRBs */ |
1530 | field = 0; | 1643 | field = 0; |
1644 | length_field = TRB_LEN(urb->transfer_buffer_length) | | ||
1645 | TD_REMAINDER(urb->transfer_buffer_length) | | ||
1646 | TRB_INTR_TARGET(0); | ||
1531 | if (urb->transfer_buffer_length > 0) { | 1647 | if (urb->transfer_buffer_length > 0) { |
1532 | if (setup->bRequestType & USB_DIR_IN) | 1648 | if (setup->bRequestType & USB_DIR_IN) |
1533 | field |= TRB_DIR_IN; | 1649 | field |= TRB_DIR_IN; |
1534 | queue_trb(xhci, ep_ring, false, | 1650 | queue_trb(xhci, ep_ring, false, |
1535 | lower_32_bits(urb->transfer_dma), | 1651 | lower_32_bits(urb->transfer_dma), |
1536 | upper_32_bits(urb->transfer_dma), | 1652 | upper_32_bits(urb->transfer_dma), |
1537 | TRB_LEN(urb->transfer_buffer_length) | TRB_INTR_TARGET(0), | 1653 | length_field, |
1538 | /* Event on short tx */ | 1654 | /* Event on short tx */ |
1539 | field | TRB_ISP | TRB_TYPE(TRB_DATA) | ep_ring->cycle_state); | 1655 | field | TRB_ISP | TRB_TYPE(TRB_DATA) | ep_ring->cycle_state); |
1540 | } | 1656 | } |
@@ -1603,7 +1719,8 @@ int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id) | |||
1603 | int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | 1719 | int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, |
1604 | u32 slot_id) | 1720 | u32 slot_id) |
1605 | { | 1721 | { |
1606 | return queue_command(xhci, in_ctx_ptr, 0, 0, | 1722 | return queue_command(xhci, lower_32_bits(in_ctx_ptr), |
1723 | upper_32_bits(in_ctx_ptr), 0, | ||
1607 | TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id)); | 1724 | TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id)); |
1608 | } | 1725 | } |
1609 | 1726 | ||
@@ -1611,7 +1728,8 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | |||
1611 | int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | 1728 | int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, |
1612 | u32 slot_id) | 1729 | u32 slot_id) |
1613 | { | 1730 | { |
1614 | return queue_command(xhci, in_ctx_ptr, 0, 0, | 1731 | return queue_command(xhci, lower_32_bits(in_ctx_ptr), |
1732 | upper_32_bits(in_ctx_ptr), 0, | ||
1615 | TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id)); | 1733 | TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id)); |
1616 | } | 1734 | } |
1617 | 1735 | ||
@@ -1639,10 +1757,23 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id, | |||
1639 | u32 type = TRB_TYPE(TRB_SET_DEQ); | 1757 | u32 type = TRB_TYPE(TRB_SET_DEQ); |
1640 | 1758 | ||
1641 | addr = xhci_trb_virt_to_dma(deq_seg, deq_ptr); | 1759 | addr = xhci_trb_virt_to_dma(deq_seg, deq_ptr); |
1642 | if (addr == 0) | 1760 | if (addr == 0) { |
1643 | xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n"); | 1761 | xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n"); |
1644 | xhci_warn(xhci, "WARN deq seg = %p, deq pt = %p\n", | 1762 | xhci_warn(xhci, "WARN deq seg = %p, deq pt = %p\n", |
1645 | deq_seg, deq_ptr); | 1763 | deq_seg, deq_ptr); |
1646 | return queue_command(xhci, (u32) addr | cycle_state, 0, 0, | 1764 | return 0; |
1765 | } | ||
1766 | return queue_command(xhci, lower_32_bits(addr) | cycle_state, | ||
1767 | upper_32_bits(addr), 0, | ||
1647 | trb_slot_id | trb_ep_index | type); | 1768 | trb_slot_id | trb_ep_index | type); |
1648 | } | 1769 | } |
1770 | |||
1771 | int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, | ||
1772 | unsigned int ep_index) | ||
1773 | { | ||
1774 | u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id); | ||
1775 | u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); | ||
1776 | u32 type = TRB_TYPE(TRB_RESET_EP); | ||
1777 | |||
1778 | return queue_command(xhci, 0, 0, 0, trb_slot_id | trb_ep_index | type); | ||
1779 | } | ||
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 8936eeb5588b..d31d32206ba3 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
27 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
28 | #include <linux/kernel.h> | ||
28 | 29 | ||
29 | #include "../core/hcd.h" | 30 | #include "../core/hcd.h" |
30 | /* Code sharing between pci-quirks and xhci hcd */ | 31 | /* Code sharing between pci-quirks and xhci hcd */ |
@@ -42,14 +43,6 @@ | |||
42 | * xHCI register interface. | 43 | * xHCI register interface. |
43 | * This corresponds to the eXtensible Host Controller Interface (xHCI) | 44 | * This corresponds to the eXtensible Host Controller Interface (xHCI) |
44 | * Revision 0.95 specification | 45 | * Revision 0.95 specification |
45 | * | ||
46 | * Registers should always be accessed with double word or quad word accesses. | ||
47 | * | ||
48 | * Some xHCI implementations may support 64-bit address pointers. Registers | ||
49 | * with 64-bit address pointers should be written to with dword accesses by | ||
50 | * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second. | ||
51 | * xHCI implementations that do not support 64-bit address pointers will ignore | ||
52 | * the high dword, and write order is irrelevant. | ||
53 | */ | 46 | */ |
54 | 47 | ||
55 | /** | 48 | /** |
@@ -96,6 +89,7 @@ struct xhci_cap_regs { | |||
96 | #define HCS_ERST_MAX(p) (((p) >> 4) & 0xf) | 89 | #define HCS_ERST_MAX(p) (((p) >> 4) & 0xf) |
97 | /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */ | 90 | /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */ |
98 | /* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */ | 91 | /* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */ |
92 | #define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f) | ||
99 | 93 | ||
100 | /* HCSPARAMS3 - hcs_params3 - bitmasks */ | 94 | /* HCSPARAMS3 - hcs_params3 - bitmasks */ |
101 | /* bits 0:7, Max U1 to U0 latency for the roothub ports */ | 95 | /* bits 0:7, Max U1 to U0 latency for the roothub ports */ |
@@ -166,10 +160,10 @@ struct xhci_op_regs { | |||
166 | u32 reserved1; | 160 | u32 reserved1; |
167 | u32 reserved2; | 161 | u32 reserved2; |
168 | u32 dev_notification; | 162 | u32 dev_notification; |
169 | u32 cmd_ring[2]; | 163 | u64 cmd_ring; |
170 | /* rsvd: offset 0x20-2F */ | 164 | /* rsvd: offset 0x20-2F */ |
171 | u32 reserved3[4]; | 165 | u32 reserved3[4]; |
172 | u32 dcbaa_ptr[2]; | 166 | u64 dcbaa_ptr; |
173 | u32 config_reg; | 167 | u32 config_reg; |
174 | /* rsvd: offset 0x3C-3FF */ | 168 | /* rsvd: offset 0x3C-3FF */ |
175 | u32 reserved4[241]; | 169 | u32 reserved4[241]; |
@@ -254,7 +248,7 @@ struct xhci_op_regs { | |||
254 | #define CMD_RING_RUNNING (1 << 3) | 248 | #define CMD_RING_RUNNING (1 << 3) |
255 | /* bits 4:5 reserved and should be preserved */ | 249 | /* bits 4:5 reserved and should be preserved */ |
256 | /* Command Ring pointer - bit mask for the lower 32 bits. */ | 250 | /* Command Ring pointer - bit mask for the lower 32 bits. */ |
257 | #define CMD_RING_ADDR_MASK (0xffffffc0) | 251 | #define CMD_RING_RSVD_BITS (0x3f) |
258 | 252 | ||
259 | /* CONFIG - Configure Register - config_reg bitmasks */ | 253 | /* CONFIG - Configure Register - config_reg bitmasks */ |
260 | /* bits 0:7 - maximum number of device slots enabled (NumSlotsEn) */ | 254 | /* bits 0:7 - maximum number of device slots enabled (NumSlotsEn) */ |
@@ -382,8 +376,8 @@ struct xhci_intr_reg { | |||
382 | u32 irq_control; | 376 | u32 irq_control; |
383 | u32 erst_size; | 377 | u32 erst_size; |
384 | u32 rsvd; | 378 | u32 rsvd; |
385 | u32 erst_base[2]; | 379 | u64 erst_base; |
386 | u32 erst_dequeue[2]; | 380 | u64 erst_dequeue; |
387 | }; | 381 | }; |
388 | 382 | ||
389 | /* irq_pending bitmasks */ | 383 | /* irq_pending bitmasks */ |
@@ -453,6 +447,27 @@ struct xhci_doorbell_array { | |||
453 | 447 | ||
454 | 448 | ||
455 | /** | 449 | /** |
450 | * struct xhci_container_ctx | ||
451 | * @type: Type of context. Used to calculated offsets to contained contexts. | ||
452 | * @size: Size of the context data | ||
453 | * @bytes: The raw context data given to HW | ||
454 | * @dma: dma address of the bytes | ||
455 | * | ||
456 | * Represents either a Device or Input context. Holds a pointer to the raw | ||
457 | * memory used for the context (bytes) and dma address of it (dma). | ||
458 | */ | ||
459 | struct xhci_container_ctx { | ||
460 | unsigned type; | ||
461 | #define XHCI_CTX_TYPE_DEVICE 0x1 | ||
462 | #define XHCI_CTX_TYPE_INPUT 0x2 | ||
463 | |||
464 | int size; | ||
465 | |||
466 | u8 *bytes; | ||
467 | dma_addr_t dma; | ||
468 | }; | ||
469 | |||
470 | /** | ||
456 | * struct xhci_slot_ctx | 471 | * struct xhci_slot_ctx |
457 | * @dev_info: Route string, device speed, hub info, and last valid endpoint | 472 | * @dev_info: Route string, device speed, hub info, and last valid endpoint |
458 | * @dev_info2: Max exit latency for device number, root hub port number | 473 | * @dev_info2: Max exit latency for device number, root hub port number |
@@ -538,7 +553,7 @@ struct xhci_slot_ctx { | |||
538 | struct xhci_ep_ctx { | 553 | struct xhci_ep_ctx { |
539 | u32 ep_info; | 554 | u32 ep_info; |
540 | u32 ep_info2; | 555 | u32 ep_info2; |
541 | u32 deq[2]; | 556 | u64 deq; |
542 | u32 tx_info; | 557 | u32 tx_info; |
543 | /* offset 0x14 - 0x1f reserved for HC internal use */ | 558 | /* offset 0x14 - 0x1f reserved for HC internal use */ |
544 | u32 reserved[3]; | 559 | u32 reserved[3]; |
@@ -589,18 +604,16 @@ struct xhci_ep_ctx { | |||
589 | 604 | ||
590 | 605 | ||
591 | /** | 606 | /** |
592 | * struct xhci_device_control | 607 | * struct xhci_input_control_context |
593 | * Input/Output context; see section 6.2.5. | 608 | * Input control context; see section 6.2.5. |
594 | * | 609 | * |
595 | * @drop_context: set the bit of the endpoint context you want to disable | 610 | * @drop_context: set the bit of the endpoint context you want to disable |
596 | * @add_context: set the bit of the endpoint context you want to enable | 611 | * @add_context: set the bit of the endpoint context you want to enable |
597 | */ | 612 | */ |
598 | struct xhci_device_control { | 613 | struct xhci_input_control_ctx { |
599 | u32 drop_flags; | 614 | u32 drop_flags; |
600 | u32 add_flags; | 615 | u32 add_flags; |
601 | u32 rsvd[6]; | 616 | u32 rsvd2[6]; |
602 | struct xhci_slot_ctx slot; | ||
603 | struct xhci_ep_ctx ep[31]; | ||
604 | }; | 617 | }; |
605 | 618 | ||
606 | /* drop context bitmasks */ | 619 | /* drop context bitmasks */ |
@@ -608,7 +621,6 @@ struct xhci_device_control { | |||
608 | /* add context bitmasks */ | 621 | /* add context bitmasks */ |
609 | #define ADD_EP(x) (0x1 << x) | 622 | #define ADD_EP(x) (0x1 << x) |
610 | 623 | ||
611 | |||
612 | struct xhci_virt_device { | 624 | struct xhci_virt_device { |
613 | /* | 625 | /* |
614 | * Commands to the hardware are passed an "input context" that | 626 | * Commands to the hardware are passed an "input context" that |
@@ -618,11 +630,10 @@ struct xhci_virt_device { | |||
618 | * track of input and output contexts separately because | 630 | * track of input and output contexts separately because |
619 | * these commands might fail and we don't trust the hardware. | 631 | * these commands might fail and we don't trust the hardware. |
620 | */ | 632 | */ |
621 | struct xhci_device_control *out_ctx; | 633 | struct xhci_container_ctx *out_ctx; |
622 | dma_addr_t out_ctx_dma; | ||
623 | /* Used for addressing devices and configuration changes */ | 634 | /* Used for addressing devices and configuration changes */ |
624 | struct xhci_device_control *in_ctx; | 635 | struct xhci_container_ctx *in_ctx; |
625 | dma_addr_t in_ctx_dma; | 636 | |
626 | /* FIXME when stream support is added */ | 637 | /* FIXME when stream support is added */ |
627 | struct xhci_ring *ep_rings[31]; | 638 | struct xhci_ring *ep_rings[31]; |
628 | /* Temporary storage in case the configure endpoint command fails and we | 639 | /* Temporary storage in case the configure endpoint command fails and we |
@@ -641,7 +652,7 @@ struct xhci_virt_device { | |||
641 | */ | 652 | */ |
642 | struct xhci_device_context_array { | 653 | struct xhci_device_context_array { |
643 | /* 64-bit device addresses; we only write 32-bit addresses */ | 654 | /* 64-bit device addresses; we only write 32-bit addresses */ |
644 | u32 dev_context_ptrs[2*MAX_HC_SLOTS]; | 655 | u64 dev_context_ptrs[MAX_HC_SLOTS]; |
645 | /* private xHCD pointers */ | 656 | /* private xHCD pointers */ |
646 | dma_addr_t dma; | 657 | dma_addr_t dma; |
647 | }; | 658 | }; |
@@ -654,7 +665,7 @@ struct xhci_device_context_array { | |||
654 | 665 | ||
655 | struct xhci_stream_ctx { | 666 | struct xhci_stream_ctx { |
656 | /* 64-bit stream ring address, cycle state, and stream type */ | 667 | /* 64-bit stream ring address, cycle state, and stream type */ |
657 | u32 stream_ring[2]; | 668 | u64 stream_ring; |
658 | /* offset 0x14 - 0x1f reserved for HC internal use */ | 669 | /* offset 0x14 - 0x1f reserved for HC internal use */ |
659 | u32 reserved[2]; | 670 | u32 reserved[2]; |
660 | }; | 671 | }; |
@@ -662,7 +673,7 @@ struct xhci_stream_ctx { | |||
662 | 673 | ||
663 | struct xhci_transfer_event { | 674 | struct xhci_transfer_event { |
664 | /* 64-bit buffer address, or immediate data */ | 675 | /* 64-bit buffer address, or immediate data */ |
665 | u32 buffer[2]; | 676 | u64 buffer; |
666 | u32 transfer_len; | 677 | u32 transfer_len; |
667 | /* This field is interpreted differently based on the type of TRB */ | 678 | /* This field is interpreted differently based on the type of TRB */ |
668 | u32 flags; | 679 | u32 flags; |
@@ -744,7 +755,7 @@ struct xhci_transfer_event { | |||
744 | 755 | ||
745 | struct xhci_link_trb { | 756 | struct xhci_link_trb { |
746 | /* 64-bit segment pointer*/ | 757 | /* 64-bit segment pointer*/ |
747 | u32 segment_ptr[2]; | 758 | u64 segment_ptr; |
748 | u32 intr_target; | 759 | u32 intr_target; |
749 | u32 control; | 760 | u32 control; |
750 | }; | 761 | }; |
@@ -755,7 +766,7 @@ struct xhci_link_trb { | |||
755 | /* Command completion event TRB */ | 766 | /* Command completion event TRB */ |
756 | struct xhci_event_cmd { | 767 | struct xhci_event_cmd { |
757 | /* Pointer to command TRB, or the value passed by the event data trb */ | 768 | /* Pointer to command TRB, or the value passed by the event data trb */ |
758 | u32 cmd_trb[2]; | 769 | u64 cmd_trb; |
759 | u32 status; | 770 | u32 status; |
760 | u32 flags; | 771 | u32 flags; |
761 | }; | 772 | }; |
@@ -848,8 +859,8 @@ union xhci_trb { | |||
848 | #define TRB_CONFIG_EP 12 | 859 | #define TRB_CONFIG_EP 12 |
849 | /* Evaluate Context Command */ | 860 | /* Evaluate Context Command */ |
850 | #define TRB_EVAL_CONTEXT 13 | 861 | #define TRB_EVAL_CONTEXT 13 |
851 | /* Reset Transfer Ring Command */ | 862 | /* Reset Endpoint Command */ |
852 | #define TRB_RESET_RING 14 | 863 | #define TRB_RESET_EP 14 |
853 | /* Stop Transfer Ring Command */ | 864 | /* Stop Transfer Ring Command */ |
854 | #define TRB_STOP_RING 15 | 865 | #define TRB_STOP_RING 15 |
855 | /* Set Transfer Ring Dequeue Pointer Command */ | 866 | /* Set Transfer Ring Dequeue Pointer Command */ |
@@ -929,6 +940,7 @@ struct xhci_ring { | |||
929 | unsigned int cancels_pending; | 940 | unsigned int cancels_pending; |
930 | unsigned int state; | 941 | unsigned int state; |
931 | #define SET_DEQ_PENDING (1 << 0) | 942 | #define SET_DEQ_PENDING (1 << 0) |
943 | #define EP_HALTED (1 << 1) | ||
932 | /* The TRB that was last reported in a stopped endpoint ring */ | 944 | /* The TRB that was last reported in a stopped endpoint ring */ |
933 | union xhci_trb *stopped_trb; | 945 | union xhci_trb *stopped_trb; |
934 | struct xhci_td *stopped_td; | 946 | struct xhci_td *stopped_td; |
@@ -940,9 +952,15 @@ struct xhci_ring { | |||
940 | u32 cycle_state; | 952 | u32 cycle_state; |
941 | }; | 953 | }; |
942 | 954 | ||
955 | struct xhci_dequeue_state { | ||
956 | struct xhci_segment *new_deq_seg; | ||
957 | union xhci_trb *new_deq_ptr; | ||
958 | int new_cycle_state; | ||
959 | }; | ||
960 | |||
943 | struct xhci_erst_entry { | 961 | struct xhci_erst_entry { |
944 | /* 64-bit event ring segment address */ | 962 | /* 64-bit event ring segment address */ |
945 | u32 seg_addr[2]; | 963 | u64 seg_addr; |
946 | u32 seg_size; | 964 | u32 seg_size; |
947 | /* Set to zero */ | 965 | /* Set to zero */ |
948 | u32 rsvd; | 966 | u32 rsvd; |
@@ -957,6 +975,13 @@ struct xhci_erst { | |||
957 | unsigned int erst_size; | 975 | unsigned int erst_size; |
958 | }; | 976 | }; |
959 | 977 | ||
978 | struct xhci_scratchpad { | ||
979 | u64 *sp_array; | ||
980 | dma_addr_t sp_dma; | ||
981 | void **sp_buffers; | ||
982 | dma_addr_t *sp_dma_buffers; | ||
983 | }; | ||
984 | |||
960 | /* | 985 | /* |
961 | * Each segment table entry is 4*32bits long. 1K seems like an ok size: | 986 | * Each segment table entry is 4*32bits long. 1K seems like an ok size: |
962 | * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table, | 987 | * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table, |
@@ -1011,6 +1036,9 @@ struct xhci_hcd { | |||
1011 | struct xhci_ring *cmd_ring; | 1036 | struct xhci_ring *cmd_ring; |
1012 | struct xhci_ring *event_ring; | 1037 | struct xhci_ring *event_ring; |
1013 | struct xhci_erst erst; | 1038 | struct xhci_erst erst; |
1039 | /* Scratchpad */ | ||
1040 | struct xhci_scratchpad *scratchpad; | ||
1041 | |||
1014 | /* slot enabling and address device helpers */ | 1042 | /* slot enabling and address device helpers */ |
1015 | struct completion addr_dev; | 1043 | struct completion addr_dev; |
1016 | int slot_id; | 1044 | int slot_id; |
@@ -1071,13 +1099,43 @@ static inline unsigned int xhci_readl(const struct xhci_hcd *xhci, | |||
1071 | static inline void xhci_writel(struct xhci_hcd *xhci, | 1099 | static inline void xhci_writel(struct xhci_hcd *xhci, |
1072 | const unsigned int val, __u32 __iomem *regs) | 1100 | const unsigned int val, __u32 __iomem *regs) |
1073 | { | 1101 | { |
1074 | if (!in_interrupt()) | 1102 | xhci_dbg(xhci, |
1075 | xhci_dbg(xhci, | 1103 | "`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n", |
1076 | "`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n", | 1104 | regs, val); |
1077 | regs, val); | ||
1078 | writel(val, regs); | 1105 | writel(val, regs); |
1079 | } | 1106 | } |
1080 | 1107 | ||
1108 | /* | ||
1109 | * Registers should always be accessed with double word or quad word accesses. | ||
1110 | * | ||
1111 | * Some xHCI implementations may support 64-bit address pointers. Registers | ||
1112 | * with 64-bit address pointers should be written to with dword accesses by | ||
1113 | * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second. | ||
1114 | * xHCI implementations that do not support 64-bit address pointers will ignore | ||
1115 | * the high dword, and write order is irrelevant. | ||
1116 | */ | ||
1117 | static inline u64 xhci_read_64(const struct xhci_hcd *xhci, | ||
1118 | __u64 __iomem *regs) | ||
1119 | { | ||
1120 | __u32 __iomem *ptr = (__u32 __iomem *) regs; | ||
1121 | u64 val_lo = readl(ptr); | ||
1122 | u64 val_hi = readl(ptr + 1); | ||
1123 | return val_lo + (val_hi << 32); | ||
1124 | } | ||
1125 | static inline void xhci_write_64(struct xhci_hcd *xhci, | ||
1126 | const u64 val, __u64 __iomem *regs) | ||
1127 | { | ||
1128 | __u32 __iomem *ptr = (__u32 __iomem *) regs; | ||
1129 | u32 val_lo = lower_32_bits(val); | ||
1130 | u32 val_hi = upper_32_bits(val); | ||
1131 | |||
1132 | xhci_dbg(xhci, | ||
1133 | "`MEM_WRITE_DWORD(3'b000, 64'h%p, 64'h%0lx, 4'hf);\n", | ||
1134 | regs, (long unsigned int) val); | ||
1135 | writel(val_lo, ptr); | ||
1136 | writel(val_hi, ptr + 1); | ||
1137 | } | ||
1138 | |||
1081 | /* xHCI debugging */ | 1139 | /* xHCI debugging */ |
1082 | void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num); | 1140 | void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num); |
1083 | void xhci_print_registers(struct xhci_hcd *xhci); | 1141 | void xhci_print_registers(struct xhci_hcd *xhci); |
@@ -1090,7 +1148,7 @@ void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring); | |||
1090 | void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst); | 1148 | void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst); |
1091 | void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci); | 1149 | void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci); |
1092 | void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring); | 1150 | void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring); |
1093 | void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep); | 1151 | void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep); |
1094 | 1152 | ||
1095 | /* xHCI memory managment */ | 1153 | /* xHCI memory managment */ |
1096 | void xhci_mem_cleanup(struct xhci_hcd *xhci); | 1154 | void xhci_mem_cleanup(struct xhci_hcd *xhci); |
@@ -1128,6 +1186,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags); | |||
1128 | int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); | 1186 | int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); |
1129 | int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); | 1187 | int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); |
1130 | int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); | 1188 | int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); |
1189 | void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep); | ||
1131 | int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); | 1190 | int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); |
1132 | void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); | 1191 | void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); |
1133 | 1192 | ||
@@ -1148,10 +1207,23 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, | |||
1148 | int slot_id, unsigned int ep_index); | 1207 | int slot_id, unsigned int ep_index); |
1149 | int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | 1208 | int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, |
1150 | u32 slot_id); | 1209 | u32 slot_id); |
1210 | int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, | ||
1211 | unsigned int ep_index); | ||
1212 | void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, | ||
1213 | unsigned int slot_id, unsigned int ep_index, | ||
1214 | struct xhci_td *cur_td, struct xhci_dequeue_state *state); | ||
1215 | void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, | ||
1216 | struct xhci_ring *ep_ring, unsigned int slot_id, | ||
1217 | unsigned int ep_index, struct xhci_dequeue_state *deq_state); | ||
1151 | 1218 | ||
1152 | /* xHCI roothub code */ | 1219 | /* xHCI roothub code */ |
1153 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, | 1220 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, |
1154 | char *buf, u16 wLength); | 1221 | char *buf, u16 wLength); |
1155 | int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); | 1222 | int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); |
1156 | 1223 | ||
1224 | /* xHCI contexts */ | ||
1225 | struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); | ||
1226 | struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); | ||
1227 | struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); | ||
1228 | |||
1157 | #endif /* __LINUX_XHCI_HCD_H */ | 1229 | #endif /* __LINUX_XHCI_HCD_H */ |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index a68d91a11bee..abe3aa67ed00 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -220,7 +220,7 @@ config USB_IOWARRIOR | |||
220 | 220 | ||
221 | config USB_TEST | 221 | config USB_TEST |
222 | tristate "USB testing driver" | 222 | tristate "USB testing driver" |
223 | depends on USB && USB_DEVICEFS | 223 | depends on USB |
224 | help | 224 | help |
225 | This driver is for testing host controller software. It is used | 225 | This driver is for testing host controller software. It is used |
226 | with specialized device firmware for regression and stress testing, | 226 | with specialized device firmware for regression and stress testing, |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 3c5fe5cee05a..90e1a8dedfa9 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/smp_lock.h> | ||
21 | #include <linux/poll.h> | 22 | #include <linux/poll.h> |
22 | #include <linux/usb/iowarrior.h> | 23 | #include <linux/usb/iowarrior.h> |
23 | 24 | ||
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index deb95bb49fd1..d645f3899fe1 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/signal.h> | 33 | #include <linux/signal.h> |
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/smp_lock.h> | ||
35 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
36 | #include <linux/random.h> | 37 | #include <linux/random.h> |
37 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index e0ff9ccd866b..29092b8e59ce 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/smp_lock.h> | ||
19 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
20 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h index 8a39de3e6e47..59bf949e589b 100644 --- a/drivers/usb/musb/cppi_dma.h +++ b/drivers/usb/musb/cppi_dma.h | |||
@@ -5,7 +5,6 @@ | |||
5 | 5 | ||
6 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
7 | #include <linux/list.h> | 7 | #include <linux/list.h> |
8 | #include <linux/smp_lock.h> | ||
9 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
10 | #include <linux/dmapool.h> | 9 | #include <linux/dmapool.h> |
11 | 10 | ||
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 180d7daa4099..e16ff605c458 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -35,13 +35,14 @@ | |||
35 | #include <mach/hardware.h> | 35 | #include <mach/hardware.h> |
36 | #include <mach/memory.h> | 36 | #include <mach/memory.h> |
37 | #include <mach/gpio.h> | 37 | #include <mach/gpio.h> |
38 | #include <mach/cputype.h> | ||
38 | 39 | ||
39 | #include <asm/mach-types.h> | 40 | #include <asm/mach-types.h> |
40 | 41 | ||
41 | #include "musb_core.h" | 42 | #include "musb_core.h" |
42 | 43 | ||
43 | #ifdef CONFIG_MACH_DAVINCI_EVM | 44 | #ifdef CONFIG_MACH_DAVINCI_EVM |
44 | #define GPIO_nVBUS_DRV 87 | 45 | #define GPIO_nVBUS_DRV 144 |
45 | #endif | 46 | #endif |
46 | 47 | ||
47 | #include "davinci.h" | 48 | #include "davinci.h" |
@@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
329 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | 330 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); |
330 | WARNING("VBUS error workaround (delay coming)\n"); | 331 | WARNING("VBUS error workaround (delay coming)\n"); |
331 | } else if (is_host_enabled(musb) && drvvbus) { | 332 | } else if (is_host_enabled(musb) && drvvbus) { |
332 | musb->is_active = 1; | ||
333 | MUSB_HST_MODE(musb); | 333 | MUSB_HST_MODE(musb); |
334 | musb->xceiv->default_a = 1; | 334 | musb->xceiv->default_a = 1; |
335 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | 335 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; |
@@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
343 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); | 343 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); |
344 | } | 344 | } |
345 | 345 | ||
346 | /* NOTE: this must complete poweron within 100 msec */ | 346 | /* NOTE: this must complete poweron within 100 msec |
347 | * (OTG_TIME_A_WAIT_VRISE) but we don't check for that. | ||
348 | */ | ||
347 | davinci_source_power(musb, drvvbus, 0); | 349 | davinci_source_power(musb, drvvbus, 0); |
348 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", | 350 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", |
349 | drvvbus ? "on" : "off", | 351 | drvvbus ? "on" : "off", |
@@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb) | |||
411 | __raw_writel(phy_ctrl, USB_PHY_CTRL); | 413 | __raw_writel(phy_ctrl, USB_PHY_CTRL); |
412 | } | 414 | } |
413 | 415 | ||
416 | /* On dm355, the default-A state machine needs DRVVBUS control. | ||
417 | * If we won't be a host, there's no need to turn it on. | ||
418 | */ | ||
419 | if (cpu_is_davinci_dm355()) { | ||
420 | u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); | ||
421 | |||
422 | if (is_host_enabled(musb)) { | ||
423 | deepsleep &= ~DRVVBUS_OVERRIDE; | ||
424 | } else { | ||
425 | deepsleep &= ~DRVVBUS_FORCE; | ||
426 | deepsleep |= DRVVBUS_OVERRIDE; | ||
427 | } | ||
428 | __raw_writel(deepsleep, DM355_DEEPSLEEP); | ||
429 | } | ||
430 | |||
414 | /* reset the controller */ | 431 | /* reset the controller */ |
415 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); | 432 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); |
416 | 433 | ||
@@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb) | |||
437 | if (is_host_enabled(musb)) | 454 | if (is_host_enabled(musb)) |
438 | del_timer_sync(&otg_workaround); | 455 | del_timer_sync(&otg_workaround); |
439 | 456 | ||
457 | /* force VBUS off */ | ||
458 | if (cpu_is_davinci_dm355()) { | ||
459 | u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); | ||
460 | |||
461 | deepsleep &= ~DRVVBUS_FORCE; | ||
462 | deepsleep |= DRVVBUS_OVERRIDE; | ||
463 | __raw_writel(deepsleep, DM355_DEEPSLEEP); | ||
464 | } | ||
465 | |||
440 | davinci_source_power(musb, 0 /*off*/, 1); | 466 | davinci_source_power(musb, 0 /*off*/, 1); |
441 | 467 | ||
442 | /* delay, to avoid problems with module reload */ | 468 | /* delay, to avoid problems with module reload */ |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 554a414f65d1..c7c1ca0494cd 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -1326,7 +1326,6 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1326 | int i; | 1326 | int i; |
1327 | 1327 | ||
1328 | /* log core options (read using indexed model) */ | 1328 | /* log core options (read using indexed model) */ |
1329 | musb_ep_select(mbase, 0); | ||
1330 | reg = musb_read_configdata(mbase); | 1329 | reg = musb_read_configdata(mbase); |
1331 | 1330 | ||
1332 | strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8"); | 1331 | strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8"); |
@@ -1990,7 +1989,7 @@ bad_config: | |||
1990 | if (status < 0) | 1989 | if (status < 0) |
1991 | goto fail2; | 1990 | goto fail2; |
1992 | 1991 | ||
1993 | #ifdef CONFIG_USB_OTG | 1992 | #ifdef CONFIG_USB_MUSB_OTG |
1994 | setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); | 1993 | setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); |
1995 | #endif | 1994 | #endif |
1996 | 1995 | ||
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index f3772ca3b2cf..381d648a36b8 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/list.h> | 39 | #include <linux/list.h> |
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <linux/smp_lock.h> | ||
42 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
43 | #include <linux/timer.h> | 42 | #include <linux/timer.h> |
44 | #include <linux/clk.h> | 43 | #include <linux/clk.h> |
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 40ed50ecedff..7a6778675ad3 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c | |||
@@ -407,7 +407,7 @@ stall: | |||
407 | csr |= MUSB_RXCSR_P_SENDSTALL | 407 | csr |= MUSB_RXCSR_P_SENDSTALL |
408 | | MUSB_RXCSR_FLUSHFIFO | 408 | | MUSB_RXCSR_FLUSHFIFO |
409 | | MUSB_RXCSR_CLRDATATOG | 409 | | MUSB_RXCSR_CLRDATATOG |
410 | | MUSB_TXCSR_P_WZC_BITS; | 410 | | MUSB_RXCSR_P_WZC_BITS; |
411 | musb_writew(regs, MUSB_RXCSR, | 411 | musb_writew(regs, MUSB_RXCSR, |
412 | csr); | 412 | csr); |
413 | } | 413 | } |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 94a2a350a414..cf94511485f2 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -373,7 +373,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, | |||
373 | musb_save_toggle(qh, is_in, urb); | 373 | musb_save_toggle(qh, is_in, urb); |
374 | break; | 374 | break; |
375 | case USB_ENDPOINT_XFER_ISOC: | 375 | case USB_ENDPOINT_XFER_ISOC: |
376 | if (urb->error_count) | 376 | if (status == 0 && urb->error_count) |
377 | status = -EXDEV; | 377 | status = -EXDEV; |
378 | break; | 378 | break; |
379 | } | 379 | } |
@@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd) | |||
2235 | static int musb_bus_suspend(struct usb_hcd *hcd) | 2235 | static int musb_bus_suspend(struct usb_hcd *hcd) |
2236 | { | 2236 | { |
2237 | struct musb *musb = hcd_to_musb(hcd); | 2237 | struct musb *musb = hcd_to_musb(hcd); |
2238 | u8 devctl; | ||
2238 | 2239 | ||
2239 | if (musb->xceiv->state == OTG_STATE_A_SUSPEND) | 2240 | if (!is_host_active(musb)) |
2240 | return 0; | 2241 | return 0; |
2241 | 2242 | ||
2242 | if (is_host_active(musb) && musb->is_active) { | 2243 | switch (musb->xceiv->state) { |
2243 | WARNING("trying to suspend as %s is_active=%i\n", | 2244 | case OTG_STATE_A_SUSPEND: |
2244 | otg_state_string(musb), musb->is_active); | 2245 | return 0; |
2246 | case OTG_STATE_A_WAIT_VRISE: | ||
2247 | /* ID could be grounded even if there's no device | ||
2248 | * on the other end of the cable. NOTE that the | ||
2249 | * A_WAIT_VRISE timers are messy with MUSB... | ||
2250 | */ | ||
2251 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
2252 | if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) | ||
2253 | musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | ||
2254 | break; | ||
2255 | default: | ||
2256 | break; | ||
2257 | } | ||
2258 | |||
2259 | if (musb->is_active) { | ||
2260 | WARNING("trying to suspend as %s while active\n", | ||
2261 | otg_state_string(musb)); | ||
2245 | return -EBUSY; | 2262 | return -EBUSY; |
2246 | } else | 2263 | } else |
2247 | return 0; | 2264 | return 0; |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index de3b2f18db44..fbfd3fd9ce1f 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
@@ -323,6 +323,7 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | |||
323 | 323 | ||
324 | static inline u8 musb_read_configdata(void __iomem *mbase) | 324 | static inline u8 musb_read_configdata(void __iomem *mbase) |
325 | { | 325 | { |
326 | musb_writeb(mbase, MUSB_INDEX, 0); | ||
326 | return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA); | 327 | return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA); |
327 | } | 328 | } |
328 | 329 | ||
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index 69feeec1628c..aa884d072f0b 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
@@ -59,18 +59,4 @@ config NOP_USB_XCEIV | |||
59 | built-in with usb ip or which are autonomous and doesn't require any | 59 | built-in with usb ip or which are autonomous and doesn't require any |
60 | phy programming such as ISP1x04 etc. | 60 | phy programming such as ISP1x04 etc. |
61 | 61 | ||
62 | config USB_LANGWELL_OTG | ||
63 | tristate "Intel Langwell USB OTG dual-role support" | ||
64 | depends on USB && MRST | ||
65 | select USB_OTG | ||
66 | select USB_OTG_UTILS | ||
67 | help | ||
68 | Say Y here if you want to build Intel Langwell USB OTG | ||
69 | transciever driver in kernel. This driver implements role | ||
70 | switch between EHCI host driver and Langwell USB OTG | ||
71 | client driver. | ||
72 | |||
73 | To compile this driver as a module, choose M here: the | ||
74 | module will be called langwell_otg. | ||
75 | |||
76 | endif # USB || OTG | 62 | endif # USB || OTG |
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index 6d1abdd3c0ac..208167856529 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile | |||
@@ -9,7 +9,6 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o | |||
9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o | 9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o |
10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o | 10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o |
11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o | 11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o |
12 | obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o | ||
13 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o | 12 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o |
14 | 13 | ||
15 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG | 14 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG |
diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c deleted file mode 100644 index 6f628d0e9f39..000000000000 --- a/drivers/usb/otg/langwell_otg.c +++ /dev/null | |||
@@ -1,1915 +0,0 @@ | |||
1 | /* | ||
2 | * Intel Langwell USB OTG transceiver driver | ||
3 | * Copyright (C) 2008 - 2009, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | */ | ||
19 | /* This driver helps to switch Langwell OTG controller function between host | ||
20 | * and peripheral. It works with EHCI driver and Langwell client controller | ||
21 | * driver together. | ||
22 | */ | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/pci.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/moduleparam.h> | ||
31 | #include <linux/usb/ch9.h> | ||
32 | #include <linux/usb/gadget.h> | ||
33 | #include <linux/usb.h> | ||
34 | #include <linux/usb/otg.h> | ||
35 | #include <linux/notifier.h> | ||
36 | #include <asm/ipc_defs.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include "../core/hcd.h" | ||
39 | |||
40 | #include <linux/usb/langwell_otg.h> | ||
41 | |||
42 | #define DRIVER_DESC "Intel Langwell USB OTG transceiver driver" | ||
43 | #define DRIVER_VERSION "3.0.0.32L.0002" | ||
44 | |||
45 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
46 | MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>"); | ||
47 | MODULE_VERSION(DRIVER_VERSION); | ||
48 | MODULE_LICENSE("GPL"); | ||
49 | |||
50 | static const char driver_name[] = "langwell_otg"; | ||
51 | |||
52 | static int langwell_otg_probe(struct pci_dev *pdev, | ||
53 | const struct pci_device_id *id); | ||
54 | static void langwell_otg_remove(struct pci_dev *pdev); | ||
55 | static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message); | ||
56 | static int langwell_otg_resume(struct pci_dev *pdev); | ||
57 | |||
58 | static int langwell_otg_set_host(struct otg_transceiver *otg, | ||
59 | struct usb_bus *host); | ||
60 | static int langwell_otg_set_peripheral(struct otg_transceiver *otg, | ||
61 | struct usb_gadget *gadget); | ||
62 | static int langwell_otg_start_srp(struct otg_transceiver *otg); | ||
63 | |||
64 | static const struct pci_device_id pci_ids[] = {{ | ||
65 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
66 | .class_mask = ~0, | ||
67 | .vendor = 0x8086, | ||
68 | .device = 0x0811, | ||
69 | .subvendor = PCI_ANY_ID, | ||
70 | .subdevice = PCI_ANY_ID, | ||
71 | }, { /* end: all zeroes */ } | ||
72 | }; | ||
73 | |||
74 | static struct pci_driver otg_pci_driver = { | ||
75 | .name = (char *) driver_name, | ||
76 | .id_table = pci_ids, | ||
77 | |||
78 | .probe = langwell_otg_probe, | ||
79 | .remove = langwell_otg_remove, | ||
80 | |||
81 | .suspend = langwell_otg_suspend, | ||
82 | .resume = langwell_otg_resume, | ||
83 | }; | ||
84 | |||
85 | static const char *state_string(enum usb_otg_state state) | ||
86 | { | ||
87 | switch (state) { | ||
88 | case OTG_STATE_A_IDLE: | ||
89 | return "a_idle"; | ||
90 | case OTG_STATE_A_WAIT_VRISE: | ||
91 | return "a_wait_vrise"; | ||
92 | case OTG_STATE_A_WAIT_BCON: | ||
93 | return "a_wait_bcon"; | ||
94 | case OTG_STATE_A_HOST: | ||
95 | return "a_host"; | ||
96 | case OTG_STATE_A_SUSPEND: | ||
97 | return "a_suspend"; | ||
98 | case OTG_STATE_A_PERIPHERAL: | ||
99 | return "a_peripheral"; | ||
100 | case OTG_STATE_A_WAIT_VFALL: | ||
101 | return "a_wait_vfall"; | ||
102 | case OTG_STATE_A_VBUS_ERR: | ||
103 | return "a_vbus_err"; | ||
104 | case OTG_STATE_B_IDLE: | ||
105 | return "b_idle"; | ||
106 | case OTG_STATE_B_SRP_INIT: | ||
107 | return "b_srp_init"; | ||
108 | case OTG_STATE_B_PERIPHERAL: | ||
109 | return "b_peripheral"; | ||
110 | case OTG_STATE_B_WAIT_ACON: | ||
111 | return "b_wait_acon"; | ||
112 | case OTG_STATE_B_HOST: | ||
113 | return "b_host"; | ||
114 | default: | ||
115 | return "UNDEFINED"; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /* HSM timers */ | ||
120 | static inline struct langwell_otg_timer *otg_timer_initializer | ||
121 | (void (*function)(unsigned long), unsigned long expires, unsigned long data) | ||
122 | { | ||
123 | struct langwell_otg_timer *timer; | ||
124 | timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL); | ||
125 | timer->function = function; | ||
126 | timer->expires = expires; | ||
127 | timer->data = data; | ||
128 | return timer; | ||
129 | } | ||
130 | |||
131 | static struct langwell_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, | ||
132 | *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_res_tmr, | ||
133 | *b_bus_suspend_tmr; | ||
134 | |||
135 | static struct list_head active_timers; | ||
136 | |||
137 | static struct langwell_otg *the_transceiver; | ||
138 | |||
139 | /* host/client notify transceiver when event affects HNP state */ | ||
140 | void langwell_update_transceiver() | ||
141 | { | ||
142 | otg_dbg("transceiver driver is notified\n"); | ||
143 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
144 | } | ||
145 | EXPORT_SYMBOL(langwell_update_transceiver); | ||
146 | |||
147 | static int langwell_otg_set_host(struct otg_transceiver *otg, | ||
148 | struct usb_bus *host) | ||
149 | { | ||
150 | otg->host = host; | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int langwell_otg_set_peripheral(struct otg_transceiver *otg, | ||
156 | struct usb_gadget *gadget) | ||
157 | { | ||
158 | otg->gadget = gadget; | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int langwell_otg_set_power(struct otg_transceiver *otg, | ||
164 | unsigned mA) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | /* A-device drives vbus, controlled through PMIC CHRGCNTL register*/ | ||
170 | static void langwell_otg_drv_vbus(int on) | ||
171 | { | ||
172 | struct ipc_pmic_reg_data pmic_data = {0}; | ||
173 | struct ipc_pmic_reg_data battery_data; | ||
174 | |||
175 | /* Check if battery is attached or not */ | ||
176 | battery_data.pmic_reg_data[0].register_address = 0xd2; | ||
177 | battery_data.ioc = 0; | ||
178 | battery_data.num_entries = 1; | ||
179 | if (ipc_pmic_register_read(&battery_data)) { | ||
180 | otg_dbg("Failed to read PMIC register 0xd2.\n"); | ||
181 | return; | ||
182 | } | ||
183 | |||
184 | if ((battery_data.pmic_reg_data[0].value & 0x20) == 0) { | ||
185 | otg_dbg("no battery attached\n"); | ||
186 | return; | ||
187 | } | ||
188 | |||
189 | /* Workaround for battery attachment issue */ | ||
190 | if (battery_data.pmic_reg_data[0].value == 0x34) { | ||
191 | otg_dbg("battery \n"); | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | otg_dbg("battery attached\n"); | ||
196 | |||
197 | pmic_data.ioc = 0; | ||
198 | pmic_data.pmic_reg_data[0].register_address = 0xD4; | ||
199 | pmic_data.num_entries = 1; | ||
200 | if (on) | ||
201 | pmic_data.pmic_reg_data[0].value = 0x20; | ||
202 | else | ||
203 | pmic_data.pmic_reg_data[0].value = 0xc0; | ||
204 | |||
205 | if (ipc_pmic_register_write(&pmic_data, TRUE)) | ||
206 | otg_dbg("Failed to write PMIC.\n"); | ||
207 | |||
208 | } | ||
209 | |||
210 | /* charge vbus or discharge vbus through a resistor to ground */ | ||
211 | static void langwell_otg_chrg_vbus(int on) | ||
212 | { | ||
213 | |||
214 | u32 val; | ||
215 | |||
216 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
217 | |||
218 | if (on) | ||
219 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC, | ||
220 | the_transceiver->regs + CI_OTGSC); | ||
221 | else | ||
222 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD, | ||
223 | the_transceiver->regs + CI_OTGSC); | ||
224 | |||
225 | } | ||
226 | |||
227 | /* Start SRP */ | ||
228 | static int langwell_otg_start_srp(struct otg_transceiver *otg) | ||
229 | { | ||
230 | u32 val; | ||
231 | |||
232 | otg_dbg("Start SRP ->\n"); | ||
233 | |||
234 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
235 | |||
236 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP, | ||
237 | the_transceiver->regs + CI_OTGSC); | ||
238 | |||
239 | /* Check if the data plus is finished or not */ | ||
240 | msleep(8); | ||
241 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
242 | if (val & (OTGSC_HADP | OTGSC_DP)) | ||
243 | otg_dbg("DataLine SRP Error\n"); | ||
244 | |||
245 | /* FIXME: VBus SRP */ | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | |||
251 | /* stop SOF via bus_suspend */ | ||
252 | static void langwell_otg_loc_sof(int on) | ||
253 | { | ||
254 | struct usb_hcd *hcd; | ||
255 | int err; | ||
256 | |||
257 | otg_dbg("loc_sof -> %d\n", on); | ||
258 | |||
259 | hcd = bus_to_hcd(the_transceiver->otg.host); | ||
260 | if (on) | ||
261 | err = hcd->driver->bus_resume(hcd); | ||
262 | else | ||
263 | err = hcd->driver->bus_suspend(hcd); | ||
264 | |||
265 | if (err) | ||
266 | otg_dbg("Failed to resume/suspend bus - %d\n", err); | ||
267 | } | ||
268 | |||
269 | static void langwell_otg_phy_low_power(int on) | ||
270 | { | ||
271 | u32 val; | ||
272 | |||
273 | otg_dbg("phy low power mode-> %d\n", on); | ||
274 | |||
275 | val = readl(the_transceiver->regs + CI_HOSTPC1); | ||
276 | if (on) | ||
277 | writel(val | HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1); | ||
278 | else | ||
279 | writel(val & ~HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1); | ||
280 | } | ||
281 | |||
282 | /* Enable/Disable OTG interrupt */ | ||
283 | static void langwell_otg_intr(int on) | ||
284 | { | ||
285 | u32 val; | ||
286 | |||
287 | otg_dbg("interrupt -> %d\n", on); | ||
288 | |||
289 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
290 | if (on) { | ||
291 | val = val | (OTGSC_INTEN_MASK | OTGSC_IDPU); | ||
292 | writel(val, the_transceiver->regs + CI_OTGSC); | ||
293 | } else { | ||
294 | val = val & ~(OTGSC_INTEN_MASK | OTGSC_IDPU); | ||
295 | writel(val, the_transceiver->regs + CI_OTGSC); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | /* set HAAR: Hardware Assist Auto-Reset */ | ||
300 | static void langwell_otg_HAAR(int on) | ||
301 | { | ||
302 | u32 val; | ||
303 | |||
304 | otg_dbg("HAAR -> %d\n", on); | ||
305 | |||
306 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
307 | if (on) | ||
308 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR, | ||
309 | the_transceiver->regs + CI_OTGSC); | ||
310 | else | ||
311 | writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR, | ||
312 | the_transceiver->regs + CI_OTGSC); | ||
313 | } | ||
314 | |||
315 | /* set HABA: Hardware Assist B-Disconnect to A-Connect */ | ||
316 | static void langwell_otg_HABA(int on) | ||
317 | { | ||
318 | u32 val; | ||
319 | |||
320 | otg_dbg("HABA -> %d\n", on); | ||
321 | |||
322 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
323 | if (on) | ||
324 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA, | ||
325 | the_transceiver->regs + CI_OTGSC); | ||
326 | else | ||
327 | writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA, | ||
328 | the_transceiver->regs + CI_OTGSC); | ||
329 | } | ||
330 | |||
331 | static int langwell_otg_check_se0_srp(int on) | ||
332 | { | ||
333 | u32 val; | ||
334 | |||
335 | int delay_time = TB_SE0_SRP * 10; /* step is 100us */ | ||
336 | |||
337 | otg_dbg("check_se0_srp -> \n"); | ||
338 | |||
339 | do { | ||
340 | udelay(100); | ||
341 | if (!delay_time--) | ||
342 | break; | ||
343 | val = readl(the_transceiver->regs + CI_PORTSC1); | ||
344 | val &= PORTSC_LS; | ||
345 | } while (!val); | ||
346 | |||
347 | otg_dbg("check_se0_srp <- \n"); | ||
348 | return val; | ||
349 | } | ||
350 | |||
351 | /* The timeout callback function to set time out bit */ | ||
352 | static void set_tmout(unsigned long indicator) | ||
353 | { | ||
354 | *(int *)indicator = 1; | ||
355 | } | ||
356 | |||
357 | void langwell_otg_nsf_msg(unsigned long indicator) | ||
358 | { | ||
359 | switch (indicator) { | ||
360 | case 2: | ||
361 | case 4: | ||
362 | case 6: | ||
363 | case 7: | ||
364 | printk(KERN_ERR "OTG:NSF-%lu - deivce not responding\n", | ||
365 | indicator); | ||
366 | break; | ||
367 | case 3: | ||
368 | printk(KERN_ERR "OTG:NSF-%lu - deivce not supported\n", | ||
369 | indicator); | ||
370 | break; | ||
371 | default: | ||
372 | printk(KERN_ERR "Do not have this kind of NSF\n"); | ||
373 | break; | ||
374 | } | ||
375 | } | ||
376 | |||
377 | /* Initialize timers */ | ||
378 | static void langwell_otg_init_timers(struct otg_hsm *hsm) | ||
379 | { | ||
380 | /* HSM used timers */ | ||
381 | a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, | ||
382 | (unsigned long)&hsm->a_wait_vrise_tmout); | ||
383 | a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON, | ||
384 | (unsigned long)&hsm->a_wait_bcon_tmout); | ||
385 | a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, | ||
386 | (unsigned long)&hsm->a_aidl_bdis_tmout); | ||
387 | b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST, | ||
388 | (unsigned long)&hsm->b_ase0_brst_tmout); | ||
389 | b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, | ||
390 | (unsigned long)&hsm->b_se0_srp); | ||
391 | b_srp_res_tmr = otg_timer_initializer(&set_tmout, TB_SRP_RES, | ||
392 | (unsigned long)&hsm->b_srp_res_tmout); | ||
393 | b_bus_suspend_tmr = otg_timer_initializer(&set_tmout, TB_BUS_SUSPEND, | ||
394 | (unsigned long)&hsm->b_bus_suspend_tmout); | ||
395 | } | ||
396 | |||
397 | /* Free timers */ | ||
398 | static void langwell_otg_free_timers(void) | ||
399 | { | ||
400 | kfree(a_wait_vrise_tmr); | ||
401 | kfree(a_wait_bcon_tmr); | ||
402 | kfree(a_aidl_bdis_tmr); | ||
403 | kfree(b_ase0_brst_tmr); | ||
404 | kfree(b_se0_srp_tmr); | ||
405 | kfree(b_srp_res_tmr); | ||
406 | kfree(b_bus_suspend_tmr); | ||
407 | } | ||
408 | |||
409 | /* Add timer to timer list */ | ||
410 | static void langwell_otg_add_timer(void *gtimer) | ||
411 | { | ||
412 | struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; | ||
413 | struct langwell_otg_timer *tmp_timer; | ||
414 | u32 val32; | ||
415 | |||
416 | /* Check if the timer is already in the active list, | ||
417 | * if so update timer count | ||
418 | */ | ||
419 | list_for_each_entry(tmp_timer, &active_timers, list) | ||
420 | if (tmp_timer == timer) { | ||
421 | timer->count = timer->expires; | ||
422 | return; | ||
423 | } | ||
424 | timer->count = timer->expires; | ||
425 | |||
426 | if (list_empty(&active_timers)) { | ||
427 | val32 = readl(the_transceiver->regs + CI_OTGSC); | ||
428 | writel(val32 | OTGSC_1MSE, the_transceiver->regs + CI_OTGSC); | ||
429 | } | ||
430 | |||
431 | list_add_tail(&timer->list, &active_timers); | ||
432 | } | ||
433 | |||
434 | /* Remove timer from the timer list; clear timeout status */ | ||
435 | static void langwell_otg_del_timer(void *gtimer) | ||
436 | { | ||
437 | struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; | ||
438 | struct langwell_otg_timer *tmp_timer, *del_tmp; | ||
439 | u32 val32; | ||
440 | |||
441 | list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) | ||
442 | if (tmp_timer == timer) | ||
443 | list_del(&timer->list); | ||
444 | |||
445 | if (list_empty(&active_timers)) { | ||
446 | val32 = readl(the_transceiver->regs + CI_OTGSC); | ||
447 | writel(val32 & ~OTGSC_1MSE, the_transceiver->regs + CI_OTGSC); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | /* Reduce timer count by 1, and find timeout conditions.*/ | ||
452 | static int langwell_otg_tick_timer(u32 *int_sts) | ||
453 | { | ||
454 | struct langwell_otg_timer *tmp_timer, *del_tmp; | ||
455 | int expired = 0; | ||
456 | |||
457 | list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { | ||
458 | tmp_timer->count--; | ||
459 | /* check if timer expires */ | ||
460 | if (!tmp_timer->count) { | ||
461 | list_del(&tmp_timer->list); | ||
462 | tmp_timer->function(tmp_timer->data); | ||
463 | expired = 1; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | if (list_empty(&active_timers)) { | ||
468 | otg_dbg("tick timer: disable 1ms int\n"); | ||
469 | *int_sts = *int_sts & ~OTGSC_1MSE; | ||
470 | } | ||
471 | return expired; | ||
472 | } | ||
473 | |||
474 | static void reset_otg(void) | ||
475 | { | ||
476 | u32 val; | ||
477 | int delay_time = 1000; | ||
478 | |||
479 | otg_dbg("reseting OTG controller ...\n"); | ||
480 | val = readl(the_transceiver->regs + CI_USBCMD); | ||
481 | writel(val | USBCMD_RST, the_transceiver->regs + CI_USBCMD); | ||
482 | do { | ||
483 | udelay(100); | ||
484 | if (!delay_time--) | ||
485 | otg_dbg("reset timeout\n"); | ||
486 | val = readl(the_transceiver->regs + CI_USBCMD); | ||
487 | val &= USBCMD_RST; | ||
488 | } while (val != 0); | ||
489 | otg_dbg("reset done.\n"); | ||
490 | } | ||
491 | |||
492 | static void set_host_mode(void) | ||
493 | { | ||
494 | u32 val; | ||
495 | |||
496 | reset_otg(); | ||
497 | val = readl(the_transceiver->regs + CI_USBMODE); | ||
498 | val = (val & (~USBMODE_CM)) | USBMODE_HOST; | ||
499 | writel(val, the_transceiver->regs + CI_USBMODE); | ||
500 | } | ||
501 | |||
502 | static void set_client_mode(void) | ||
503 | { | ||
504 | u32 val; | ||
505 | |||
506 | reset_otg(); | ||
507 | val = readl(the_transceiver->regs + CI_USBMODE); | ||
508 | val = (val & (~USBMODE_CM)) | USBMODE_DEVICE; | ||
509 | writel(val, the_transceiver->regs + CI_USBMODE); | ||
510 | } | ||
511 | |||
512 | static void init_hsm(void) | ||
513 | { | ||
514 | struct langwell_otg *langwell = the_transceiver; | ||
515 | u32 val32; | ||
516 | |||
517 | /* read OTGSC after reset */ | ||
518 | val32 = readl(langwell->regs + CI_OTGSC); | ||
519 | otg_dbg("%s: OTGSC init value = 0x%x\n", __func__, val32); | ||
520 | |||
521 | /* set init state */ | ||
522 | if (val32 & OTGSC_ID) { | ||
523 | langwell->hsm.id = 1; | ||
524 | langwell->otg.default_a = 0; | ||
525 | set_client_mode(); | ||
526 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
527 | langwell_otg_drv_vbus(0); | ||
528 | } else { | ||
529 | langwell->hsm.id = 0; | ||
530 | langwell->otg.default_a = 1; | ||
531 | set_host_mode(); | ||
532 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
533 | } | ||
534 | |||
535 | /* set session indicator */ | ||
536 | if (val32 & OTGSC_BSE) | ||
537 | langwell->hsm.b_sess_end = 1; | ||
538 | if (val32 & OTGSC_BSV) | ||
539 | langwell->hsm.b_sess_vld = 1; | ||
540 | if (val32 & OTGSC_ASV) | ||
541 | langwell->hsm.a_sess_vld = 1; | ||
542 | if (val32 & OTGSC_AVV) | ||
543 | langwell->hsm.a_vbus_vld = 1; | ||
544 | |||
545 | /* defautly power the bus */ | ||
546 | langwell->hsm.a_bus_req = 1; | ||
547 | langwell->hsm.a_bus_drop = 0; | ||
548 | /* defautly don't request bus as B device */ | ||
549 | langwell->hsm.b_bus_req = 0; | ||
550 | /* no system error */ | ||
551 | langwell->hsm.a_clr_err = 0; | ||
552 | } | ||
553 | |||
554 | static irqreturn_t otg_dummy_irq(int irq, void *_dev) | ||
555 | { | ||
556 | void __iomem *reg_base = _dev; | ||
557 | u32 val; | ||
558 | u32 int_mask = 0; | ||
559 | |||
560 | val = readl(reg_base + CI_USBMODE); | ||
561 | if ((val & USBMODE_CM) != USBMODE_DEVICE) | ||
562 | return IRQ_NONE; | ||
563 | |||
564 | val = readl(reg_base + CI_USBSTS); | ||
565 | int_mask = val & INTR_DUMMY_MASK; | ||
566 | |||
567 | if (int_mask == 0) | ||
568 | return IRQ_NONE; | ||
569 | |||
570 | /* clear hsm.b_conn here since host driver can't detect it | ||
571 | * otg_dummy_irq called means B-disconnect happened. | ||
572 | */ | ||
573 | if (the_transceiver->hsm.b_conn) { | ||
574 | the_transceiver->hsm.b_conn = 0; | ||
575 | if (spin_trylock(&the_transceiver->wq_lock)) { | ||
576 | queue_work(the_transceiver->qwork, | ||
577 | &the_transceiver->work); | ||
578 | spin_unlock(&the_transceiver->wq_lock); | ||
579 | } | ||
580 | } | ||
581 | /* Clear interrupts */ | ||
582 | writel(int_mask, reg_base + CI_USBSTS); | ||
583 | return IRQ_HANDLED; | ||
584 | } | ||
585 | |||
586 | static irqreturn_t otg_irq(int irq, void *_dev) | ||
587 | { | ||
588 | struct langwell_otg *langwell = _dev; | ||
589 | u32 int_sts, int_en; | ||
590 | u32 int_mask = 0; | ||
591 | int flag = 0; | ||
592 | |||
593 | int_sts = readl(langwell->regs + CI_OTGSC); | ||
594 | int_en = (int_sts & OTGSC_INTEN_MASK) >> 8; | ||
595 | int_mask = int_sts & int_en; | ||
596 | if (int_mask == 0) | ||
597 | return IRQ_NONE; | ||
598 | |||
599 | if (int_mask & OTGSC_IDIS) { | ||
600 | otg_dbg("%s: id change int\n", __func__); | ||
601 | langwell->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0; | ||
602 | flag = 1; | ||
603 | } | ||
604 | if (int_mask & OTGSC_DPIS) { | ||
605 | otg_dbg("%s: data pulse int\n", __func__); | ||
606 | langwell->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0; | ||
607 | flag = 1; | ||
608 | } | ||
609 | if (int_mask & OTGSC_BSEIS) { | ||
610 | otg_dbg("%s: b session end int\n", __func__); | ||
611 | langwell->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0; | ||
612 | flag = 1; | ||
613 | } | ||
614 | if (int_mask & OTGSC_BSVIS) { | ||
615 | otg_dbg("%s: b session valid int\n", __func__); | ||
616 | langwell->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0; | ||
617 | flag = 1; | ||
618 | } | ||
619 | if (int_mask & OTGSC_ASVIS) { | ||
620 | otg_dbg("%s: a session valid int\n", __func__); | ||
621 | langwell->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0; | ||
622 | flag = 1; | ||
623 | } | ||
624 | if (int_mask & OTGSC_AVVIS) { | ||
625 | otg_dbg("%s: a vbus valid int\n", __func__); | ||
626 | langwell->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0; | ||
627 | flag = 1; | ||
628 | } | ||
629 | |||
630 | if (int_mask & OTGSC_1MSS) { | ||
631 | /* need to schedule otg_work if any timer is expired */ | ||
632 | if (langwell_otg_tick_timer(&int_sts)) | ||
633 | flag = 1; | ||
634 | } | ||
635 | |||
636 | writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask, | ||
637 | langwell->regs + CI_OTGSC); | ||
638 | if (flag) | ||
639 | queue_work(langwell->qwork, &langwell->work); | ||
640 | |||
641 | return IRQ_HANDLED; | ||
642 | } | ||
643 | |||
644 | static void langwell_otg_work(struct work_struct *work) | ||
645 | { | ||
646 | struct langwell_otg *langwell = container_of(work, | ||
647 | struct langwell_otg, work); | ||
648 | int retval; | ||
649 | |||
650 | otg_dbg("%s: old state = %s\n", __func__, | ||
651 | state_string(langwell->otg.state)); | ||
652 | |||
653 | switch (langwell->otg.state) { | ||
654 | case OTG_STATE_UNDEFINED: | ||
655 | case OTG_STATE_B_IDLE: | ||
656 | if (!langwell->hsm.id) { | ||
657 | langwell_otg_del_timer(b_srp_res_tmr); | ||
658 | langwell->otg.default_a = 1; | ||
659 | langwell->hsm.a_srp_det = 0; | ||
660 | |||
661 | langwell_otg_chrg_vbus(0); | ||
662 | langwell_otg_drv_vbus(0); | ||
663 | |||
664 | set_host_mode(); | ||
665 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
666 | queue_work(langwell->qwork, &langwell->work); | ||
667 | } else if (langwell->hsm.b_srp_res_tmout) { | ||
668 | langwell->hsm.b_srp_res_tmout = 0; | ||
669 | langwell->hsm.b_bus_req = 0; | ||
670 | langwell_otg_nsf_msg(6); | ||
671 | } else if (langwell->hsm.b_sess_vld) { | ||
672 | langwell_otg_del_timer(b_srp_res_tmr); | ||
673 | langwell->hsm.b_sess_end = 0; | ||
674 | langwell->hsm.a_bus_suspend = 0; | ||
675 | |||
676 | langwell_otg_chrg_vbus(0); | ||
677 | if (langwell->client_ops) { | ||
678 | langwell->client_ops->resume(langwell->pdev); | ||
679 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
680 | } else | ||
681 | otg_dbg("client driver not loaded.\n"); | ||
682 | |||
683 | } else if (langwell->hsm.b_bus_req && | ||
684 | (langwell->hsm.b_sess_end)) { | ||
685 | /* workaround for b_se0_srp detection */ | ||
686 | retval = langwell_otg_check_se0_srp(0); | ||
687 | if (retval) { | ||
688 | langwell->hsm.b_bus_req = 0; | ||
689 | otg_dbg("LS is not SE0, try again later\n"); | ||
690 | } else { | ||
691 | /* Start SRP */ | ||
692 | langwell_otg_start_srp(&langwell->otg); | ||
693 | langwell_otg_add_timer(b_srp_res_tmr); | ||
694 | } | ||
695 | } | ||
696 | break; | ||
697 | case OTG_STATE_B_SRP_INIT: | ||
698 | if (!langwell->hsm.id) { | ||
699 | langwell->otg.default_a = 1; | ||
700 | langwell->hsm.a_srp_det = 0; | ||
701 | |||
702 | langwell_otg_drv_vbus(0); | ||
703 | langwell_otg_chrg_vbus(0); | ||
704 | |||
705 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
706 | queue_work(langwell->qwork, &langwell->work); | ||
707 | } else if (langwell->hsm.b_sess_vld) { | ||
708 | langwell_otg_chrg_vbus(0); | ||
709 | if (langwell->client_ops) { | ||
710 | langwell->client_ops->resume(langwell->pdev); | ||
711 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
712 | } else | ||
713 | otg_dbg("client driver not loaded.\n"); | ||
714 | } | ||
715 | break; | ||
716 | case OTG_STATE_B_PERIPHERAL: | ||
717 | if (!langwell->hsm.id) { | ||
718 | langwell->otg.default_a = 1; | ||
719 | langwell->hsm.a_srp_det = 0; | ||
720 | |||
721 | langwell_otg_drv_vbus(0); | ||
722 | langwell_otg_chrg_vbus(0); | ||
723 | set_host_mode(); | ||
724 | |||
725 | if (langwell->client_ops) { | ||
726 | langwell->client_ops->suspend(langwell->pdev, | ||
727 | PMSG_FREEZE); | ||
728 | } else | ||
729 | otg_dbg("client driver has been removed.\n"); | ||
730 | |||
731 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
732 | queue_work(langwell->qwork, &langwell->work); | ||
733 | } else if (!langwell->hsm.b_sess_vld) { | ||
734 | langwell->hsm.b_hnp_enable = 0; | ||
735 | |||
736 | if (langwell->client_ops) { | ||
737 | langwell->client_ops->suspend(langwell->pdev, | ||
738 | PMSG_FREEZE); | ||
739 | } else | ||
740 | otg_dbg("client driver has been removed.\n"); | ||
741 | |||
742 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
743 | } else if (langwell->hsm.b_bus_req && langwell->hsm.b_hnp_enable | ||
744 | && langwell->hsm.a_bus_suspend) { | ||
745 | |||
746 | if (langwell->client_ops) { | ||
747 | langwell->client_ops->suspend(langwell->pdev, | ||
748 | PMSG_FREEZE); | ||
749 | } else | ||
750 | otg_dbg("client driver has been removed.\n"); | ||
751 | |||
752 | langwell_otg_HAAR(1); | ||
753 | langwell->hsm.a_conn = 0; | ||
754 | |||
755 | if (langwell->host_ops) { | ||
756 | langwell->host_ops->probe(langwell->pdev, | ||
757 | langwell->host_ops->id_table); | ||
758 | langwell->otg.state = OTG_STATE_B_WAIT_ACON; | ||
759 | } else | ||
760 | otg_dbg("host driver not loaded.\n"); | ||
761 | |||
762 | langwell->hsm.a_bus_resume = 0; | ||
763 | langwell->hsm.b_ase0_brst_tmout = 0; | ||
764 | langwell_otg_add_timer(b_ase0_brst_tmr); | ||
765 | } | ||
766 | break; | ||
767 | |||
768 | case OTG_STATE_B_WAIT_ACON: | ||
769 | if (!langwell->hsm.id) { | ||
770 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
771 | langwell->otg.default_a = 1; | ||
772 | langwell->hsm.a_srp_det = 0; | ||
773 | |||
774 | langwell_otg_drv_vbus(0); | ||
775 | langwell_otg_chrg_vbus(0); | ||
776 | set_host_mode(); | ||
777 | |||
778 | langwell_otg_HAAR(0); | ||
779 | if (langwell->host_ops) | ||
780 | langwell->host_ops->remove(langwell->pdev); | ||
781 | else | ||
782 | otg_dbg("host driver has been removed.\n"); | ||
783 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
784 | queue_work(langwell->qwork, &langwell->work); | ||
785 | } else if (!langwell->hsm.b_sess_vld) { | ||
786 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
787 | langwell->hsm.b_hnp_enable = 0; | ||
788 | langwell->hsm.b_bus_req = 0; | ||
789 | langwell_otg_chrg_vbus(0); | ||
790 | langwell_otg_HAAR(0); | ||
791 | |||
792 | if (langwell->host_ops) | ||
793 | langwell->host_ops->remove(langwell->pdev); | ||
794 | else | ||
795 | otg_dbg("host driver has been removed.\n"); | ||
796 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
797 | } else if (langwell->hsm.a_conn) { | ||
798 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
799 | langwell_otg_HAAR(0); | ||
800 | langwell->otg.state = OTG_STATE_B_HOST; | ||
801 | queue_work(langwell->qwork, &langwell->work); | ||
802 | } else if (langwell->hsm.a_bus_resume || | ||
803 | langwell->hsm.b_ase0_brst_tmout) { | ||
804 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
805 | langwell_otg_HAAR(0); | ||
806 | langwell_otg_nsf_msg(7); | ||
807 | |||
808 | if (langwell->host_ops) | ||
809 | langwell->host_ops->remove(langwell->pdev); | ||
810 | else | ||
811 | otg_dbg("host driver has been removed.\n"); | ||
812 | |||
813 | langwell->hsm.a_bus_suspend = 0; | ||
814 | langwell->hsm.b_bus_req = 0; | ||
815 | |||
816 | if (langwell->client_ops) | ||
817 | langwell->client_ops->resume(langwell->pdev); | ||
818 | else | ||
819 | otg_dbg("client driver not loaded.\n"); | ||
820 | |||
821 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
822 | } | ||
823 | break; | ||
824 | |||
825 | case OTG_STATE_B_HOST: | ||
826 | if (!langwell->hsm.id) { | ||
827 | langwell->otg.default_a = 1; | ||
828 | langwell->hsm.a_srp_det = 0; | ||
829 | |||
830 | langwell_otg_drv_vbus(0); | ||
831 | langwell_otg_chrg_vbus(0); | ||
832 | set_host_mode(); | ||
833 | if (langwell->host_ops) | ||
834 | langwell->host_ops->remove(langwell->pdev); | ||
835 | else | ||
836 | otg_dbg("host driver has been removed.\n"); | ||
837 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
838 | queue_work(langwell->qwork, &langwell->work); | ||
839 | } else if (!langwell->hsm.b_sess_vld) { | ||
840 | langwell->hsm.b_hnp_enable = 0; | ||
841 | langwell->hsm.b_bus_req = 0; | ||
842 | langwell_otg_chrg_vbus(0); | ||
843 | if (langwell->host_ops) | ||
844 | langwell->host_ops->remove(langwell->pdev); | ||
845 | else | ||
846 | otg_dbg("host driver has been removed.\n"); | ||
847 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
848 | } else if ((!langwell->hsm.b_bus_req) || | ||
849 | (!langwell->hsm.a_conn)) { | ||
850 | langwell->hsm.b_bus_req = 0; | ||
851 | langwell_otg_loc_sof(0); | ||
852 | if (langwell->host_ops) | ||
853 | langwell->host_ops->remove(langwell->pdev); | ||
854 | else | ||
855 | otg_dbg("host driver has been removed.\n"); | ||
856 | |||
857 | langwell->hsm.a_bus_suspend = 0; | ||
858 | |||
859 | if (langwell->client_ops) | ||
860 | langwell->client_ops->resume(langwell->pdev); | ||
861 | else | ||
862 | otg_dbg("client driver not loaded.\n"); | ||
863 | |||
864 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
865 | } | ||
866 | break; | ||
867 | |||
868 | case OTG_STATE_A_IDLE: | ||
869 | langwell->otg.default_a = 1; | ||
870 | if (langwell->hsm.id) { | ||
871 | langwell->otg.default_a = 0; | ||
872 | langwell->hsm.b_bus_req = 0; | ||
873 | langwell_otg_drv_vbus(0); | ||
874 | langwell_otg_chrg_vbus(0); | ||
875 | |||
876 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
877 | queue_work(langwell->qwork, &langwell->work); | ||
878 | } else if (langwell->hsm.a_sess_vld) { | ||
879 | langwell_otg_drv_vbus(1); | ||
880 | langwell->hsm.a_srp_det = 1; | ||
881 | langwell->hsm.a_wait_vrise_tmout = 0; | ||
882 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
883 | langwell->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
884 | queue_work(langwell->qwork, &langwell->work); | ||
885 | } else if (!langwell->hsm.a_bus_drop && | ||
886 | (langwell->hsm.a_srp_det || langwell->hsm.a_bus_req)) { | ||
887 | langwell_otg_drv_vbus(1); | ||
888 | langwell->hsm.a_wait_vrise_tmout = 0; | ||
889 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
890 | langwell->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
891 | queue_work(langwell->qwork, &langwell->work); | ||
892 | } | ||
893 | break; | ||
894 | case OTG_STATE_A_WAIT_VRISE: | ||
895 | if (langwell->hsm.id) { | ||
896 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
897 | langwell->hsm.b_bus_req = 0; | ||
898 | langwell->otg.default_a = 0; | ||
899 | langwell_otg_drv_vbus(0); | ||
900 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
901 | } else if (langwell->hsm.a_vbus_vld) { | ||
902 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
903 | if (langwell->host_ops) | ||
904 | langwell->host_ops->probe(langwell->pdev, | ||
905 | langwell->host_ops->id_table); | ||
906 | else | ||
907 | otg_dbg("host driver not loaded.\n"); | ||
908 | langwell->hsm.b_conn = 0; | ||
909 | langwell->hsm.a_set_b_hnp_en = 0; | ||
910 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
911 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
912 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
913 | } else if (langwell->hsm.a_wait_vrise_tmout) { | ||
914 | if (langwell->hsm.a_vbus_vld) { | ||
915 | if (langwell->host_ops) | ||
916 | langwell->host_ops->probe( | ||
917 | langwell->pdev, | ||
918 | langwell->host_ops->id_table); | ||
919 | else | ||
920 | otg_dbg("host driver not loaded.\n"); | ||
921 | langwell->hsm.b_conn = 0; | ||
922 | langwell->hsm.a_set_b_hnp_en = 0; | ||
923 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
924 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
925 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
926 | } else { | ||
927 | langwell_otg_drv_vbus(0); | ||
928 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
929 | } | ||
930 | } | ||
931 | break; | ||
932 | case OTG_STATE_A_WAIT_BCON: | ||
933 | if (langwell->hsm.id) { | ||
934 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
935 | |||
936 | langwell->otg.default_a = 0; | ||
937 | langwell->hsm.b_bus_req = 0; | ||
938 | if (langwell->host_ops) | ||
939 | langwell->host_ops->remove(langwell->pdev); | ||
940 | else | ||
941 | otg_dbg("host driver has been removed.\n"); | ||
942 | langwell_otg_drv_vbus(0); | ||
943 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
944 | queue_work(langwell->qwork, &langwell->work); | ||
945 | } else if (!langwell->hsm.a_vbus_vld) { | ||
946 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
947 | |||
948 | if (langwell->host_ops) | ||
949 | langwell->host_ops->remove(langwell->pdev); | ||
950 | else | ||
951 | otg_dbg("host driver has been removed.\n"); | ||
952 | langwell_otg_drv_vbus(0); | ||
953 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
954 | } else if (langwell->hsm.a_bus_drop || | ||
955 | (langwell->hsm.a_wait_bcon_tmout && | ||
956 | !langwell->hsm.a_bus_req)) { | ||
957 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
958 | |||
959 | if (langwell->host_ops) | ||
960 | langwell->host_ops->remove(langwell->pdev); | ||
961 | else | ||
962 | otg_dbg("host driver has been removed.\n"); | ||
963 | langwell_otg_drv_vbus(0); | ||
964 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
965 | } else if (langwell->hsm.b_conn) { | ||
966 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
967 | |||
968 | langwell->hsm.a_suspend_req = 0; | ||
969 | langwell->otg.state = OTG_STATE_A_HOST; | ||
970 | if (!langwell->hsm.a_bus_req && | ||
971 | langwell->hsm.a_set_b_hnp_en) { | ||
972 | /* It is not safe enough to do a fast | ||
973 | * transistion from A_WAIT_BCON to | ||
974 | * A_SUSPEND */ | ||
975 | msleep(10000); | ||
976 | if (langwell->hsm.a_bus_req) | ||
977 | break; | ||
978 | |||
979 | if (request_irq(langwell->pdev->irq, | ||
980 | otg_dummy_irq, IRQF_SHARED, | ||
981 | driver_name, langwell->regs) != 0) { | ||
982 | otg_dbg("request interrupt %d fail\n", | ||
983 | langwell->pdev->irq); | ||
984 | } | ||
985 | |||
986 | langwell_otg_HABA(1); | ||
987 | langwell->hsm.b_bus_resume = 0; | ||
988 | langwell->hsm.a_aidl_bdis_tmout = 0; | ||
989 | langwell_otg_add_timer(a_aidl_bdis_tmr); | ||
990 | |||
991 | langwell_otg_loc_sof(0); | ||
992 | langwell->otg.state = OTG_STATE_A_SUSPEND; | ||
993 | } else if (!langwell->hsm.a_bus_req && | ||
994 | !langwell->hsm.a_set_b_hnp_en) { | ||
995 | struct pci_dev *pdev = langwell->pdev; | ||
996 | if (langwell->host_ops) | ||
997 | langwell->host_ops->remove(pdev); | ||
998 | else | ||
999 | otg_dbg("host driver removed.\n"); | ||
1000 | langwell_otg_drv_vbus(0); | ||
1001 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1002 | } | ||
1003 | } | ||
1004 | break; | ||
1005 | case OTG_STATE_A_HOST: | ||
1006 | if (langwell->hsm.id) { | ||
1007 | langwell->otg.default_a = 0; | ||
1008 | langwell->hsm.b_bus_req = 0; | ||
1009 | if (langwell->host_ops) | ||
1010 | langwell->host_ops->remove(langwell->pdev); | ||
1011 | else | ||
1012 | otg_dbg("host driver has been removed.\n"); | ||
1013 | langwell_otg_drv_vbus(0); | ||
1014 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1015 | queue_work(langwell->qwork, &langwell->work); | ||
1016 | } else if (langwell->hsm.a_bus_drop || | ||
1017 | (!langwell->hsm.a_set_b_hnp_en && !langwell->hsm.a_bus_req)) { | ||
1018 | if (langwell->host_ops) | ||
1019 | langwell->host_ops->remove(langwell->pdev); | ||
1020 | else | ||
1021 | otg_dbg("host driver has been removed.\n"); | ||
1022 | langwell_otg_drv_vbus(0); | ||
1023 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1024 | } else if (!langwell->hsm.a_vbus_vld) { | ||
1025 | if (langwell->host_ops) | ||
1026 | langwell->host_ops->remove(langwell->pdev); | ||
1027 | else | ||
1028 | otg_dbg("host driver has been removed.\n"); | ||
1029 | langwell_otg_drv_vbus(0); | ||
1030 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1031 | } else if (langwell->hsm.a_set_b_hnp_en | ||
1032 | && !langwell->hsm.a_bus_req) { | ||
1033 | /* Set HABA to enable hardware assistance to signal | ||
1034 | * A-connect after receiver B-disconnect. Hardware | ||
1035 | * will then set client mode and enable URE, SLE and | ||
1036 | * PCE after the assistance. otg_dummy_irq is used to | ||
1037 | * clean these ints when client driver is not resumed. | ||
1038 | */ | ||
1039 | if (request_irq(langwell->pdev->irq, | ||
1040 | otg_dummy_irq, IRQF_SHARED, driver_name, | ||
1041 | langwell->regs) != 0) { | ||
1042 | otg_dbg("request interrupt %d failed\n", | ||
1043 | langwell->pdev->irq); | ||
1044 | } | ||
1045 | |||
1046 | /* set HABA */ | ||
1047 | langwell_otg_HABA(1); | ||
1048 | langwell->hsm.b_bus_resume = 0; | ||
1049 | langwell->hsm.a_aidl_bdis_tmout = 0; | ||
1050 | langwell_otg_add_timer(a_aidl_bdis_tmr); | ||
1051 | langwell_otg_loc_sof(0); | ||
1052 | langwell->otg.state = OTG_STATE_A_SUSPEND; | ||
1053 | } else if (!langwell->hsm.b_conn || !langwell->hsm.a_bus_req) { | ||
1054 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
1055 | langwell->hsm.a_set_b_hnp_en = 0; | ||
1056 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
1057 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1058 | } | ||
1059 | break; | ||
1060 | case OTG_STATE_A_SUSPEND: | ||
1061 | if (langwell->hsm.id) { | ||
1062 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1063 | langwell_otg_HABA(0); | ||
1064 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1065 | langwell->otg.default_a = 0; | ||
1066 | langwell->hsm.b_bus_req = 0; | ||
1067 | if (langwell->host_ops) | ||
1068 | langwell->host_ops->remove(langwell->pdev); | ||
1069 | else | ||
1070 | otg_dbg("host driver has been removed.\n"); | ||
1071 | langwell_otg_drv_vbus(0); | ||
1072 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1073 | queue_work(langwell->qwork, &langwell->work); | ||
1074 | } else if (langwell->hsm.a_bus_req || | ||
1075 | langwell->hsm.b_bus_resume) { | ||
1076 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1077 | langwell_otg_HABA(0); | ||
1078 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1079 | langwell->hsm.a_suspend_req = 0; | ||
1080 | langwell_otg_loc_sof(1); | ||
1081 | langwell->otg.state = OTG_STATE_A_HOST; | ||
1082 | } else if (langwell->hsm.a_aidl_bdis_tmout || | ||
1083 | langwell->hsm.a_bus_drop) { | ||
1084 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1085 | langwell_otg_HABA(0); | ||
1086 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1087 | if (langwell->host_ops) | ||
1088 | langwell->host_ops->remove(langwell->pdev); | ||
1089 | else | ||
1090 | otg_dbg("host driver has been removed.\n"); | ||
1091 | langwell_otg_drv_vbus(0); | ||
1092 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1093 | } else if (!langwell->hsm.b_conn && | ||
1094 | langwell->hsm.a_set_b_hnp_en) { | ||
1095 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1096 | langwell_otg_HABA(0); | ||
1097 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1098 | |||
1099 | if (langwell->host_ops) | ||
1100 | langwell->host_ops->remove(langwell->pdev); | ||
1101 | else | ||
1102 | otg_dbg("host driver has been removed.\n"); | ||
1103 | |||
1104 | langwell->hsm.b_bus_suspend = 0; | ||
1105 | langwell->hsm.b_bus_suspend_vld = 0; | ||
1106 | langwell->hsm.b_bus_suspend_tmout = 0; | ||
1107 | |||
1108 | /* msleep(200); */ | ||
1109 | if (langwell->client_ops) | ||
1110 | langwell->client_ops->resume(langwell->pdev); | ||
1111 | else | ||
1112 | otg_dbg("client driver not loaded.\n"); | ||
1113 | |||
1114 | langwell_otg_add_timer(b_bus_suspend_tmr); | ||
1115 | langwell->otg.state = OTG_STATE_A_PERIPHERAL; | ||
1116 | break; | ||
1117 | } else if (!langwell->hsm.a_vbus_vld) { | ||
1118 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1119 | langwell_otg_HABA(0); | ||
1120 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1121 | if (langwell->host_ops) | ||
1122 | langwell->host_ops->remove(langwell->pdev); | ||
1123 | else | ||
1124 | otg_dbg("host driver has been removed.\n"); | ||
1125 | langwell_otg_drv_vbus(0); | ||
1126 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1127 | } | ||
1128 | break; | ||
1129 | case OTG_STATE_A_PERIPHERAL: | ||
1130 | if (langwell->hsm.id) { | ||
1131 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
1132 | langwell->otg.default_a = 0; | ||
1133 | langwell->hsm.b_bus_req = 0; | ||
1134 | if (langwell->client_ops) | ||
1135 | langwell->client_ops->suspend(langwell->pdev, | ||
1136 | PMSG_FREEZE); | ||
1137 | else | ||
1138 | otg_dbg("client driver has been removed.\n"); | ||
1139 | langwell_otg_drv_vbus(0); | ||
1140 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1141 | queue_work(langwell->qwork, &langwell->work); | ||
1142 | } else if (!langwell->hsm.a_vbus_vld) { | ||
1143 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
1144 | if (langwell->client_ops) | ||
1145 | langwell->client_ops->suspend(langwell->pdev, | ||
1146 | PMSG_FREEZE); | ||
1147 | else | ||
1148 | otg_dbg("client driver has been removed.\n"); | ||
1149 | langwell_otg_drv_vbus(0); | ||
1150 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1151 | } else if (langwell->hsm.a_bus_drop) { | ||
1152 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
1153 | if (langwell->client_ops) | ||
1154 | langwell->client_ops->suspend(langwell->pdev, | ||
1155 | PMSG_FREEZE); | ||
1156 | else | ||
1157 | otg_dbg("client driver has been removed.\n"); | ||
1158 | langwell_otg_drv_vbus(0); | ||
1159 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1160 | } else if (langwell->hsm.b_bus_suspend) { | ||
1161 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
1162 | if (langwell->client_ops) | ||
1163 | langwell->client_ops->suspend(langwell->pdev, | ||
1164 | PMSG_FREEZE); | ||
1165 | else | ||
1166 | otg_dbg("client driver has been removed.\n"); | ||
1167 | |||
1168 | if (langwell->host_ops) | ||
1169 | langwell->host_ops->probe(langwell->pdev, | ||
1170 | langwell->host_ops->id_table); | ||
1171 | else | ||
1172 | otg_dbg("host driver not loaded.\n"); | ||
1173 | langwell->hsm.a_set_b_hnp_en = 0; | ||
1174 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
1175 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
1176 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1177 | } else if (langwell->hsm.b_bus_suspend_tmout) { | ||
1178 | u32 val; | ||
1179 | val = readl(langwell->regs + CI_PORTSC1); | ||
1180 | if (!(val & PORTSC_SUSP)) | ||
1181 | break; | ||
1182 | if (langwell->client_ops) | ||
1183 | langwell->client_ops->suspend(langwell->pdev, | ||
1184 | PMSG_FREEZE); | ||
1185 | else | ||
1186 | otg_dbg("client driver has been removed.\n"); | ||
1187 | if (langwell->host_ops) | ||
1188 | langwell->host_ops->probe(langwell->pdev, | ||
1189 | langwell->host_ops->id_table); | ||
1190 | else | ||
1191 | otg_dbg("host driver not loaded.\n"); | ||
1192 | langwell->hsm.a_set_b_hnp_en = 0; | ||
1193 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
1194 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
1195 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1196 | } | ||
1197 | break; | ||
1198 | case OTG_STATE_A_VBUS_ERR: | ||
1199 | if (langwell->hsm.id) { | ||
1200 | langwell->otg.default_a = 0; | ||
1201 | langwell->hsm.a_clr_err = 0; | ||
1202 | langwell->hsm.a_srp_det = 0; | ||
1203 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1204 | queue_work(langwell->qwork, &langwell->work); | ||
1205 | } else if (langwell->hsm.a_clr_err) { | ||
1206 | langwell->hsm.a_clr_err = 0; | ||
1207 | langwell->hsm.a_srp_det = 0; | ||
1208 | reset_otg(); | ||
1209 | init_hsm(); | ||
1210 | if (langwell->otg.state == OTG_STATE_A_IDLE) | ||
1211 | queue_work(langwell->qwork, &langwell->work); | ||
1212 | } | ||
1213 | break; | ||
1214 | case OTG_STATE_A_WAIT_VFALL: | ||
1215 | if (langwell->hsm.id) { | ||
1216 | langwell->otg.default_a = 0; | ||
1217 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1218 | queue_work(langwell->qwork, &langwell->work); | ||
1219 | } else if (langwell->hsm.a_bus_req) { | ||
1220 | langwell_otg_drv_vbus(1); | ||
1221 | langwell->hsm.a_wait_vrise_tmout = 0; | ||
1222 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
1223 | langwell->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
1224 | } else if (!langwell->hsm.a_sess_vld) { | ||
1225 | langwell->hsm.a_srp_det = 0; | ||
1226 | langwell_otg_drv_vbus(0); | ||
1227 | set_host_mode(); | ||
1228 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
1229 | } | ||
1230 | break; | ||
1231 | default: | ||
1232 | ; | ||
1233 | } | ||
1234 | |||
1235 | otg_dbg("%s: new state = %s\n", __func__, | ||
1236 | state_string(langwell->otg.state)); | ||
1237 | } | ||
1238 | |||
1239 | static ssize_t | ||
1240 | show_registers(struct device *_dev, struct device_attribute *attr, char *buf) | ||
1241 | { | ||
1242 | struct langwell_otg *langwell; | ||
1243 | char *next; | ||
1244 | unsigned size; | ||
1245 | unsigned t; | ||
1246 | |||
1247 | langwell = the_transceiver; | ||
1248 | next = buf; | ||
1249 | size = PAGE_SIZE; | ||
1250 | |||
1251 | t = scnprintf(next, size, | ||
1252 | "\n" | ||
1253 | "USBCMD = 0x%08x \n" | ||
1254 | "USBSTS = 0x%08x \n" | ||
1255 | "USBINTR = 0x%08x \n" | ||
1256 | "ASYNCLISTADDR = 0x%08x \n" | ||
1257 | "PORTSC1 = 0x%08x \n" | ||
1258 | "HOSTPC1 = 0x%08x \n" | ||
1259 | "OTGSC = 0x%08x \n" | ||
1260 | "USBMODE = 0x%08x \n", | ||
1261 | readl(langwell->regs + 0x30), | ||
1262 | readl(langwell->regs + 0x34), | ||
1263 | readl(langwell->regs + 0x38), | ||
1264 | readl(langwell->regs + 0x48), | ||
1265 | readl(langwell->regs + 0x74), | ||
1266 | readl(langwell->regs + 0xb4), | ||
1267 | readl(langwell->regs + 0xf4), | ||
1268 | readl(langwell->regs + 0xf8) | ||
1269 | ); | ||
1270 | size -= t; | ||
1271 | next += t; | ||
1272 | |||
1273 | return PAGE_SIZE - size; | ||
1274 | } | ||
1275 | static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL); | ||
1276 | |||
1277 | static ssize_t | ||
1278 | show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) | ||
1279 | { | ||
1280 | struct langwell_otg *langwell; | ||
1281 | char *next; | ||
1282 | unsigned size; | ||
1283 | unsigned t; | ||
1284 | |||
1285 | langwell = the_transceiver; | ||
1286 | next = buf; | ||
1287 | size = PAGE_SIZE; | ||
1288 | |||
1289 | t = scnprintf(next, size, | ||
1290 | "\n" | ||
1291 | "current state = %s\n" | ||
1292 | "a_bus_resume = \t%d\n" | ||
1293 | "a_bus_suspend = \t%d\n" | ||
1294 | "a_conn = \t%d\n" | ||
1295 | "a_sess_vld = \t%d\n" | ||
1296 | "a_srp_det = \t%d\n" | ||
1297 | "a_vbus_vld = \t%d\n" | ||
1298 | "b_bus_resume = \t%d\n" | ||
1299 | "b_bus_suspend = \t%d\n" | ||
1300 | "b_conn = \t%d\n" | ||
1301 | "b_se0_srp = \t%d\n" | ||
1302 | "b_sess_end = \t%d\n" | ||
1303 | "b_sess_vld = \t%d\n" | ||
1304 | "id = \t%d\n" | ||
1305 | "a_set_b_hnp_en = \t%d\n" | ||
1306 | "b_srp_done = \t%d\n" | ||
1307 | "b_hnp_enable = \t%d\n" | ||
1308 | "a_wait_vrise_tmout = \t%d\n" | ||
1309 | "a_wait_bcon_tmout = \t%d\n" | ||
1310 | "a_aidl_bdis_tmout = \t%d\n" | ||
1311 | "b_ase0_brst_tmout = \t%d\n" | ||
1312 | "a_bus_drop = \t%d\n" | ||
1313 | "a_bus_req = \t%d\n" | ||
1314 | "a_clr_err = \t%d\n" | ||
1315 | "a_suspend_req = \t%d\n" | ||
1316 | "b_bus_req = \t%d\n" | ||
1317 | "b_bus_suspend_tmout = \t%d\n" | ||
1318 | "b_bus_suspend_vld = \t%d\n", | ||
1319 | state_string(langwell->otg.state), | ||
1320 | langwell->hsm.a_bus_resume, | ||
1321 | langwell->hsm.a_bus_suspend, | ||
1322 | langwell->hsm.a_conn, | ||
1323 | langwell->hsm.a_sess_vld, | ||
1324 | langwell->hsm.a_srp_det, | ||
1325 | langwell->hsm.a_vbus_vld, | ||
1326 | langwell->hsm.b_bus_resume, | ||
1327 | langwell->hsm.b_bus_suspend, | ||
1328 | langwell->hsm.b_conn, | ||
1329 | langwell->hsm.b_se0_srp, | ||
1330 | langwell->hsm.b_sess_end, | ||
1331 | langwell->hsm.b_sess_vld, | ||
1332 | langwell->hsm.id, | ||
1333 | langwell->hsm.a_set_b_hnp_en, | ||
1334 | langwell->hsm.b_srp_done, | ||
1335 | langwell->hsm.b_hnp_enable, | ||
1336 | langwell->hsm.a_wait_vrise_tmout, | ||
1337 | langwell->hsm.a_wait_bcon_tmout, | ||
1338 | langwell->hsm.a_aidl_bdis_tmout, | ||
1339 | langwell->hsm.b_ase0_brst_tmout, | ||
1340 | langwell->hsm.a_bus_drop, | ||
1341 | langwell->hsm.a_bus_req, | ||
1342 | langwell->hsm.a_clr_err, | ||
1343 | langwell->hsm.a_suspend_req, | ||
1344 | langwell->hsm.b_bus_req, | ||
1345 | langwell->hsm.b_bus_suspend_tmout, | ||
1346 | langwell->hsm.b_bus_suspend_vld | ||
1347 | ); | ||
1348 | size -= t; | ||
1349 | next += t; | ||
1350 | |||
1351 | return PAGE_SIZE - size; | ||
1352 | } | ||
1353 | static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL); | ||
1354 | |||
1355 | static ssize_t | ||
1356 | get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) | ||
1357 | { | ||
1358 | struct langwell_otg *langwell; | ||
1359 | char *next; | ||
1360 | unsigned size; | ||
1361 | unsigned t; | ||
1362 | |||
1363 | langwell = the_transceiver; | ||
1364 | next = buf; | ||
1365 | size = PAGE_SIZE; | ||
1366 | |||
1367 | t = scnprintf(next, size, "%d", langwell->hsm.a_bus_req); | ||
1368 | size -= t; | ||
1369 | next += t; | ||
1370 | |||
1371 | return PAGE_SIZE - size; | ||
1372 | } | ||
1373 | |||
1374 | static ssize_t | ||
1375 | set_a_bus_req(struct device *dev, struct device_attribute *attr, | ||
1376 | const char *buf, size_t count) | ||
1377 | { | ||
1378 | struct langwell_otg *langwell; | ||
1379 | langwell = the_transceiver; | ||
1380 | if (!langwell->otg.default_a) | ||
1381 | return -1; | ||
1382 | if (count > 2) | ||
1383 | return -1; | ||
1384 | |||
1385 | if (buf[0] == '0') { | ||
1386 | langwell->hsm.a_bus_req = 0; | ||
1387 | otg_dbg("a_bus_req = 0\n"); | ||
1388 | } else if (buf[0] == '1') { | ||
1389 | /* If a_bus_drop is TRUE, a_bus_req can't be set */ | ||
1390 | if (langwell->hsm.a_bus_drop) | ||
1391 | return -1; | ||
1392 | langwell->hsm.a_bus_req = 1; | ||
1393 | otg_dbg("a_bus_req = 1\n"); | ||
1394 | } | ||
1395 | if (spin_trylock(&langwell->wq_lock)) { | ||
1396 | queue_work(langwell->qwork, &langwell->work); | ||
1397 | spin_unlock(&langwell->wq_lock); | ||
1398 | } | ||
1399 | return count; | ||
1400 | } | ||
1401 | static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req); | ||
1402 | |||
1403 | static ssize_t | ||
1404 | get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) | ||
1405 | { | ||
1406 | struct langwell_otg *langwell; | ||
1407 | char *next; | ||
1408 | unsigned size; | ||
1409 | unsigned t; | ||
1410 | |||
1411 | langwell = the_transceiver; | ||
1412 | next = buf; | ||
1413 | size = PAGE_SIZE; | ||
1414 | |||
1415 | t = scnprintf(next, size, "%d", langwell->hsm.a_bus_drop); | ||
1416 | size -= t; | ||
1417 | next += t; | ||
1418 | |||
1419 | return PAGE_SIZE - size; | ||
1420 | } | ||
1421 | |||
1422 | static ssize_t | ||
1423 | set_a_bus_drop(struct device *dev, struct device_attribute *attr, | ||
1424 | const char *buf, size_t count) | ||
1425 | { | ||
1426 | struct langwell_otg *langwell; | ||
1427 | langwell = the_transceiver; | ||
1428 | if (!langwell->otg.default_a) | ||
1429 | return -1; | ||
1430 | if (count > 2) | ||
1431 | return -1; | ||
1432 | |||
1433 | if (buf[0] == '0') { | ||
1434 | langwell->hsm.a_bus_drop = 0; | ||
1435 | otg_dbg("a_bus_drop = 0\n"); | ||
1436 | } else if (buf[0] == '1') { | ||
1437 | langwell->hsm.a_bus_drop = 1; | ||
1438 | langwell->hsm.a_bus_req = 0; | ||
1439 | otg_dbg("a_bus_drop = 1, then a_bus_req = 0\n"); | ||
1440 | } | ||
1441 | if (spin_trylock(&langwell->wq_lock)) { | ||
1442 | queue_work(langwell->qwork, &langwell->work); | ||
1443 | spin_unlock(&langwell->wq_lock); | ||
1444 | } | ||
1445 | return count; | ||
1446 | } | ||
1447 | static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO, | ||
1448 | get_a_bus_drop, set_a_bus_drop); | ||
1449 | |||
1450 | static ssize_t | ||
1451 | get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) | ||
1452 | { | ||
1453 | struct langwell_otg *langwell; | ||
1454 | char *next; | ||
1455 | unsigned size; | ||
1456 | unsigned t; | ||
1457 | |||
1458 | langwell = the_transceiver; | ||
1459 | next = buf; | ||
1460 | size = PAGE_SIZE; | ||
1461 | |||
1462 | t = scnprintf(next, size, "%d", langwell->hsm.b_bus_req); | ||
1463 | size -= t; | ||
1464 | next += t; | ||
1465 | |||
1466 | return PAGE_SIZE - size; | ||
1467 | } | ||
1468 | |||
1469 | static ssize_t | ||
1470 | set_b_bus_req(struct device *dev, struct device_attribute *attr, | ||
1471 | const char *buf, size_t count) | ||
1472 | { | ||
1473 | struct langwell_otg *langwell; | ||
1474 | langwell = the_transceiver; | ||
1475 | |||
1476 | if (langwell->otg.default_a) | ||
1477 | return -1; | ||
1478 | |||
1479 | if (count > 2) | ||
1480 | return -1; | ||
1481 | |||
1482 | if (buf[0] == '0') { | ||
1483 | langwell->hsm.b_bus_req = 0; | ||
1484 | otg_dbg("b_bus_req = 0\n"); | ||
1485 | } else if (buf[0] == '1') { | ||
1486 | langwell->hsm.b_bus_req = 1; | ||
1487 | otg_dbg("b_bus_req = 1\n"); | ||
1488 | } | ||
1489 | if (spin_trylock(&langwell->wq_lock)) { | ||
1490 | queue_work(langwell->qwork, &langwell->work); | ||
1491 | spin_unlock(&langwell->wq_lock); | ||
1492 | } | ||
1493 | return count; | ||
1494 | } | ||
1495 | static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req); | ||
1496 | |||
1497 | static ssize_t | ||
1498 | set_a_clr_err(struct device *dev, struct device_attribute *attr, | ||
1499 | const char *buf, size_t count) | ||
1500 | { | ||
1501 | struct langwell_otg *langwell; | ||
1502 | langwell = the_transceiver; | ||
1503 | |||
1504 | if (!langwell->otg.default_a) | ||
1505 | return -1; | ||
1506 | if (count > 2) | ||
1507 | return -1; | ||
1508 | |||
1509 | if (buf[0] == '1') { | ||
1510 | langwell->hsm.a_clr_err = 1; | ||
1511 | otg_dbg("a_clr_err = 1\n"); | ||
1512 | } | ||
1513 | if (spin_trylock(&langwell->wq_lock)) { | ||
1514 | queue_work(langwell->qwork, &langwell->work); | ||
1515 | spin_unlock(&langwell->wq_lock); | ||
1516 | } | ||
1517 | return count; | ||
1518 | } | ||
1519 | static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err); | ||
1520 | |||
1521 | static struct attribute *inputs_attrs[] = { | ||
1522 | &dev_attr_a_bus_req.attr, | ||
1523 | &dev_attr_a_bus_drop.attr, | ||
1524 | &dev_attr_b_bus_req.attr, | ||
1525 | &dev_attr_a_clr_err.attr, | ||
1526 | NULL, | ||
1527 | }; | ||
1528 | |||
1529 | static struct attribute_group debug_dev_attr_group = { | ||
1530 | .name = "inputs", | ||
1531 | .attrs = inputs_attrs, | ||
1532 | }; | ||
1533 | |||
1534 | int langwell_register_host(struct pci_driver *host_driver) | ||
1535 | { | ||
1536 | int ret = 0; | ||
1537 | |||
1538 | the_transceiver->host_ops = host_driver; | ||
1539 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
1540 | otg_dbg("host controller driver is registered\n"); | ||
1541 | |||
1542 | return ret; | ||
1543 | } | ||
1544 | EXPORT_SYMBOL(langwell_register_host); | ||
1545 | |||
1546 | void langwell_unregister_host(struct pci_driver *host_driver) | ||
1547 | { | ||
1548 | if (the_transceiver->host_ops) | ||
1549 | the_transceiver->host_ops->remove(the_transceiver->pdev); | ||
1550 | the_transceiver->host_ops = NULL; | ||
1551 | the_transceiver->hsm.a_bus_drop = 1; | ||
1552 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
1553 | otg_dbg("host controller driver is unregistered\n"); | ||
1554 | } | ||
1555 | EXPORT_SYMBOL(langwell_unregister_host); | ||
1556 | |||
1557 | int langwell_register_peripheral(struct pci_driver *client_driver) | ||
1558 | { | ||
1559 | int ret = 0; | ||
1560 | |||
1561 | if (client_driver) | ||
1562 | ret = client_driver->probe(the_transceiver->pdev, | ||
1563 | client_driver->id_table); | ||
1564 | if (!ret) { | ||
1565 | the_transceiver->client_ops = client_driver; | ||
1566 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
1567 | otg_dbg("client controller driver is registered\n"); | ||
1568 | } | ||
1569 | |||
1570 | return ret; | ||
1571 | } | ||
1572 | EXPORT_SYMBOL(langwell_register_peripheral); | ||
1573 | |||
1574 | void langwell_unregister_peripheral(struct pci_driver *client_driver) | ||
1575 | { | ||
1576 | if (the_transceiver->client_ops) | ||
1577 | the_transceiver->client_ops->remove(the_transceiver->pdev); | ||
1578 | the_transceiver->client_ops = NULL; | ||
1579 | the_transceiver->hsm.b_bus_req = 0; | ||
1580 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
1581 | otg_dbg("client controller driver is unregistered\n"); | ||
1582 | } | ||
1583 | EXPORT_SYMBOL(langwell_unregister_peripheral); | ||
1584 | |||
1585 | static int langwell_otg_probe(struct pci_dev *pdev, | ||
1586 | const struct pci_device_id *id) | ||
1587 | { | ||
1588 | unsigned long resource, len; | ||
1589 | void __iomem *base = NULL; | ||
1590 | int retval; | ||
1591 | u32 val32; | ||
1592 | struct langwell_otg *langwell; | ||
1593 | char qname[] = "langwell_otg_queue"; | ||
1594 | |||
1595 | retval = 0; | ||
1596 | otg_dbg("\notg controller is detected.\n"); | ||
1597 | if (pci_enable_device(pdev) < 0) { | ||
1598 | retval = -ENODEV; | ||
1599 | goto done; | ||
1600 | } | ||
1601 | |||
1602 | langwell = kzalloc(sizeof *langwell, GFP_KERNEL); | ||
1603 | if (langwell == NULL) { | ||
1604 | retval = -ENOMEM; | ||
1605 | goto done; | ||
1606 | } | ||
1607 | the_transceiver = langwell; | ||
1608 | |||
1609 | /* control register: BAR 0 */ | ||
1610 | resource = pci_resource_start(pdev, 0); | ||
1611 | len = pci_resource_len(pdev, 0); | ||
1612 | if (!request_mem_region(resource, len, driver_name)) { | ||
1613 | retval = -EBUSY; | ||
1614 | goto err; | ||
1615 | } | ||
1616 | langwell->region = 1; | ||
1617 | |||
1618 | base = ioremap_nocache(resource, len); | ||
1619 | if (base == NULL) { | ||
1620 | retval = -EFAULT; | ||
1621 | goto err; | ||
1622 | } | ||
1623 | langwell->regs = base; | ||
1624 | |||
1625 | if (!pdev->irq) { | ||
1626 | otg_dbg("No IRQ.\n"); | ||
1627 | retval = -ENODEV; | ||
1628 | goto err; | ||
1629 | } | ||
1630 | |||
1631 | langwell->qwork = create_workqueue(qname); | ||
1632 | if (!langwell->qwork) { | ||
1633 | otg_dbg("cannot create workqueue %s\n", qname); | ||
1634 | retval = -ENOMEM; | ||
1635 | goto err; | ||
1636 | } | ||
1637 | INIT_WORK(&langwell->work, langwell_otg_work); | ||
1638 | |||
1639 | /* OTG common part */ | ||
1640 | langwell->pdev = pdev; | ||
1641 | langwell->otg.dev = &pdev->dev; | ||
1642 | langwell->otg.label = driver_name; | ||
1643 | langwell->otg.set_host = langwell_otg_set_host; | ||
1644 | langwell->otg.set_peripheral = langwell_otg_set_peripheral; | ||
1645 | langwell->otg.set_power = langwell_otg_set_power; | ||
1646 | langwell->otg.start_srp = langwell_otg_start_srp; | ||
1647 | langwell->otg.state = OTG_STATE_UNDEFINED; | ||
1648 | if (otg_set_transceiver(&langwell->otg)) { | ||
1649 | otg_dbg("can't set transceiver\n"); | ||
1650 | retval = -EBUSY; | ||
1651 | goto err; | ||
1652 | } | ||
1653 | |||
1654 | reset_otg(); | ||
1655 | init_hsm(); | ||
1656 | |||
1657 | spin_lock_init(&langwell->lock); | ||
1658 | spin_lock_init(&langwell->wq_lock); | ||
1659 | INIT_LIST_HEAD(&active_timers); | ||
1660 | langwell_otg_init_timers(&langwell->hsm); | ||
1661 | |||
1662 | if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, | ||
1663 | driver_name, langwell) != 0) { | ||
1664 | otg_dbg("request interrupt %d failed\n", pdev->irq); | ||
1665 | retval = -EBUSY; | ||
1666 | goto err; | ||
1667 | } | ||
1668 | |||
1669 | /* enable OTGSC int */ | ||
1670 | val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE | | ||
1671 | OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU; | ||
1672 | writel(val32, langwell->regs + CI_OTGSC); | ||
1673 | |||
1674 | retval = device_create_file(&pdev->dev, &dev_attr_registers); | ||
1675 | if (retval < 0) { | ||
1676 | otg_dbg("Can't register sysfs attribute: %d\n", retval); | ||
1677 | goto err; | ||
1678 | } | ||
1679 | |||
1680 | retval = device_create_file(&pdev->dev, &dev_attr_hsm); | ||
1681 | if (retval < 0) { | ||
1682 | otg_dbg("Can't hsm sysfs attribute: %d\n", retval); | ||
1683 | goto err; | ||
1684 | } | ||
1685 | |||
1686 | retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group); | ||
1687 | if (retval < 0) { | ||
1688 | otg_dbg("Can't register sysfs attr group: %d\n", retval); | ||
1689 | goto err; | ||
1690 | } | ||
1691 | |||
1692 | if (langwell->otg.state == OTG_STATE_A_IDLE) | ||
1693 | queue_work(langwell->qwork, &langwell->work); | ||
1694 | |||
1695 | return 0; | ||
1696 | |||
1697 | err: | ||
1698 | if (the_transceiver) | ||
1699 | langwell_otg_remove(pdev); | ||
1700 | done: | ||
1701 | return retval; | ||
1702 | } | ||
1703 | |||
1704 | static void langwell_otg_remove(struct pci_dev *pdev) | ||
1705 | { | ||
1706 | struct langwell_otg *langwell; | ||
1707 | |||
1708 | langwell = the_transceiver; | ||
1709 | |||
1710 | if (langwell->qwork) { | ||
1711 | flush_workqueue(langwell->qwork); | ||
1712 | destroy_workqueue(langwell->qwork); | ||
1713 | } | ||
1714 | langwell_otg_free_timers(); | ||
1715 | |||
1716 | /* disable OTGSC interrupt as OTGSC doesn't change in reset */ | ||
1717 | writel(0, langwell->regs + CI_OTGSC); | ||
1718 | |||
1719 | if (pdev->irq) | ||
1720 | free_irq(pdev->irq, langwell); | ||
1721 | if (langwell->regs) | ||
1722 | iounmap(langwell->regs); | ||
1723 | if (langwell->region) | ||
1724 | release_mem_region(pci_resource_start(pdev, 0), | ||
1725 | pci_resource_len(pdev, 0)); | ||
1726 | |||
1727 | otg_set_transceiver(NULL); | ||
1728 | pci_disable_device(pdev); | ||
1729 | sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group); | ||
1730 | device_remove_file(&pdev->dev, &dev_attr_hsm); | ||
1731 | device_remove_file(&pdev->dev, &dev_attr_registers); | ||
1732 | kfree(langwell); | ||
1733 | langwell = NULL; | ||
1734 | } | ||
1735 | |||
1736 | static void transceiver_suspend(struct pci_dev *pdev) | ||
1737 | { | ||
1738 | pci_save_state(pdev); | ||
1739 | pci_set_power_state(pdev, PCI_D3hot); | ||
1740 | langwell_otg_phy_low_power(1); | ||
1741 | } | ||
1742 | |||
1743 | static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message) | ||
1744 | { | ||
1745 | int ret = 0; | ||
1746 | struct langwell_otg *langwell; | ||
1747 | |||
1748 | langwell = the_transceiver; | ||
1749 | |||
1750 | /* Disbale OTG interrupts */ | ||
1751 | langwell_otg_intr(0); | ||
1752 | |||
1753 | if (pdev->irq) | ||
1754 | free_irq(pdev->irq, langwell); | ||
1755 | |||
1756 | /* Prevent more otg_work */ | ||
1757 | flush_workqueue(langwell->qwork); | ||
1758 | spin_lock(&langwell->wq_lock); | ||
1759 | |||
1760 | /* start actions */ | ||
1761 | switch (langwell->otg.state) { | ||
1762 | case OTG_STATE_A_IDLE: | ||
1763 | case OTG_STATE_B_IDLE: | ||
1764 | case OTG_STATE_A_WAIT_VFALL: | ||
1765 | case OTG_STATE_A_VBUS_ERR: | ||
1766 | transceiver_suspend(pdev); | ||
1767 | break; | ||
1768 | case OTG_STATE_A_WAIT_VRISE: | ||
1769 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
1770 | langwell->hsm.a_srp_det = 0; | ||
1771 | langwell_otg_drv_vbus(0); | ||
1772 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
1773 | transceiver_suspend(pdev); | ||
1774 | break; | ||
1775 | case OTG_STATE_A_WAIT_BCON: | ||
1776 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
1777 | if (langwell->host_ops) | ||
1778 | ret = langwell->host_ops->suspend(pdev, message); | ||
1779 | langwell_otg_drv_vbus(0); | ||
1780 | break; | ||
1781 | case OTG_STATE_A_HOST: | ||
1782 | if (langwell->host_ops) | ||
1783 | ret = langwell->host_ops->suspend(pdev, message); | ||
1784 | langwell_otg_drv_vbus(0); | ||
1785 | langwell_otg_phy_low_power(1); | ||
1786 | break; | ||
1787 | case OTG_STATE_A_SUSPEND: | ||
1788 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1789 | langwell_otg_HABA(0); | ||
1790 | if (langwell->host_ops) | ||
1791 | langwell->host_ops->remove(pdev); | ||
1792 | else | ||
1793 | otg_dbg("host driver has been removed.\n"); | ||
1794 | langwell_otg_drv_vbus(0); | ||
1795 | transceiver_suspend(pdev); | ||
1796 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1797 | break; | ||
1798 | case OTG_STATE_A_PERIPHERAL: | ||
1799 | if (langwell->client_ops) | ||
1800 | ret = langwell->client_ops->suspend(pdev, message); | ||
1801 | else | ||
1802 | otg_dbg("client driver has been removed.\n"); | ||
1803 | langwell_otg_drv_vbus(0); | ||
1804 | transceiver_suspend(pdev); | ||
1805 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1806 | break; | ||
1807 | case OTG_STATE_B_HOST: | ||
1808 | if (langwell->host_ops) | ||
1809 | langwell->host_ops->remove(pdev); | ||
1810 | else | ||
1811 | otg_dbg("host driver has been removed.\n"); | ||
1812 | langwell->hsm.b_bus_req = 0; | ||
1813 | transceiver_suspend(pdev); | ||
1814 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1815 | break; | ||
1816 | case OTG_STATE_B_PERIPHERAL: | ||
1817 | if (langwell->client_ops) | ||
1818 | ret = langwell->client_ops->suspend(pdev, message); | ||
1819 | else | ||
1820 | otg_dbg("client driver has been removed.\n"); | ||
1821 | break; | ||
1822 | case OTG_STATE_B_WAIT_ACON: | ||
1823 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
1824 | langwell_otg_HAAR(0); | ||
1825 | if (langwell->host_ops) | ||
1826 | langwell->host_ops->remove(pdev); | ||
1827 | else | ||
1828 | otg_dbg("host driver has been removed.\n"); | ||
1829 | langwell->hsm.b_bus_req = 0; | ||
1830 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1831 | transceiver_suspend(pdev); | ||
1832 | break; | ||
1833 | default: | ||
1834 | otg_dbg("error state before suspend\n "); | ||
1835 | break; | ||
1836 | } | ||
1837 | spin_unlock(&langwell->wq_lock); | ||
1838 | |||
1839 | return ret; | ||
1840 | } | ||
1841 | |||
1842 | static void transceiver_resume(struct pci_dev *pdev) | ||
1843 | { | ||
1844 | pci_restore_state(pdev); | ||
1845 | pci_set_power_state(pdev, PCI_D0); | ||
1846 | langwell_otg_phy_low_power(0); | ||
1847 | } | ||
1848 | |||
1849 | static int langwell_otg_resume(struct pci_dev *pdev) | ||
1850 | { | ||
1851 | int ret = 0; | ||
1852 | struct langwell_otg *langwell; | ||
1853 | |||
1854 | langwell = the_transceiver; | ||
1855 | |||
1856 | spin_lock(&langwell->wq_lock); | ||
1857 | |||
1858 | switch (langwell->otg.state) { | ||
1859 | case OTG_STATE_A_IDLE: | ||
1860 | case OTG_STATE_B_IDLE: | ||
1861 | case OTG_STATE_A_WAIT_VFALL: | ||
1862 | case OTG_STATE_A_VBUS_ERR: | ||
1863 | transceiver_resume(pdev); | ||
1864 | break; | ||
1865 | case OTG_STATE_A_WAIT_BCON: | ||
1866 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
1867 | langwell_otg_drv_vbus(1); | ||
1868 | if (langwell->host_ops) | ||
1869 | ret = langwell->host_ops->resume(pdev); | ||
1870 | break; | ||
1871 | case OTG_STATE_A_HOST: | ||
1872 | langwell_otg_drv_vbus(1); | ||
1873 | langwell_otg_phy_low_power(0); | ||
1874 | if (langwell->host_ops) | ||
1875 | ret = langwell->host_ops->resume(pdev); | ||
1876 | break; | ||
1877 | case OTG_STATE_B_PERIPHERAL: | ||
1878 | if (langwell->client_ops) | ||
1879 | ret = langwell->client_ops->resume(pdev); | ||
1880 | else | ||
1881 | otg_dbg("client driver not loaded.\n"); | ||
1882 | break; | ||
1883 | default: | ||
1884 | otg_dbg("error state before suspend\n "); | ||
1885 | break; | ||
1886 | } | ||
1887 | |||
1888 | if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, | ||
1889 | driver_name, the_transceiver) != 0) { | ||
1890 | otg_dbg("request interrupt %d failed\n", pdev->irq); | ||
1891 | ret = -EBUSY; | ||
1892 | } | ||
1893 | |||
1894 | /* enable OTG interrupts */ | ||
1895 | langwell_otg_intr(1); | ||
1896 | |||
1897 | spin_unlock(&langwell->wq_lock); | ||
1898 | |||
1899 | queue_work(langwell->qwork, &langwell->work); | ||
1900 | |||
1901 | |||
1902 | return ret; | ||
1903 | } | ||
1904 | |||
1905 | static int __init langwell_otg_init(void) | ||
1906 | { | ||
1907 | return pci_register_driver(&otg_pci_driver); | ||
1908 | } | ||
1909 | module_init(langwell_otg_init); | ||
1910 | |||
1911 | static void __exit langwell_otg_cleanup(void) | ||
1912 | { | ||
1913 | pci_unregister_driver(&otg_pci_driver); | ||
1914 | } | ||
1915 | module_exit(langwell_otg_cleanup); | ||
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 9ed5ea568679..af456b48985f 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c | |||
@@ -53,6 +53,7 @@ EXPORT_SYMBOL(usb_nop_xceiv_register); | |||
53 | void usb_nop_xceiv_unregister(void) | 53 | void usb_nop_xceiv_unregister(void) |
54 | { | 54 | { |
55 | platform_device_unregister(pd); | 55 | platform_device_unregister(pd); |
56 | pd = NULL; | ||
56 | } | 57 | } |
57 | EXPORT_SYMBOL(usb_nop_xceiv_unregister); | 58 | EXPORT_SYMBOL(usb_nop_xceiv_unregister); |
58 | 59 | ||
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 247b61bfb7f4..0e4f2e41ace5 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options) | |||
169 | kfree(tty); | 169 | kfree(tty); |
170 | } | 170 | } |
171 | } | 171 | } |
172 | /* So we know not to kill the hardware on a hangup on this | 172 | /* Now that any required fake tty operations are completed restore |
173 | port. We have also bumped the use count by one so it won't go | 173 | * the tty port count */ |
174 | idle */ | 174 | --port->port.count; |
175 | /* The console is special in terms of closing the device so | ||
176 | * indicate this port is now acting as a system console. */ | ||
175 | port->console = 1; | 177 | port->console = 1; |
176 | retval = 0; | 178 | retval = 0; |
177 | 179 | ||
@@ -204,7 +206,7 @@ static void usb_console_write(struct console *co, | |||
204 | 206 | ||
205 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); | 207 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); |
206 | 208 | ||
207 | if (!port->port.count) { | 209 | if (!port->console) { |
208 | dbg("%s - port not opened", __func__); | 210 | dbg("%s - port not opened", __func__); |
209 | return; | 211 | return; |
210 | } | 212 | } |
@@ -300,8 +302,7 @@ void usb_serial_console_exit(void) | |||
300 | { | 302 | { |
301 | if (usbcons_info.port) { | 303 | if (usbcons_info.port) { |
302 | unregister_console(&usbcons); | 304 | unregister_console(&usbcons); |
303 | if (usbcons_info.port->port.count) | 305 | usbcons_info.port->console = 0; |
304 | usbcons_info.port->port.count--; | ||
305 | usbcons_info.port = NULL; | 306 | usbcons_info.port = NULL; |
306 | } | 307 | } |
307 | } | 308 | } |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 2b9eeda62bfe..985cbcf48bda 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -67,6 +67,8 @@ static struct usb_device_id id_table [] = { | |||
67 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 67 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
68 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ | 68 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ |
69 | { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */ | 69 | { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */ |
70 | { USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */ | ||
71 | { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */ | ||
70 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ | 72 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ |
71 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ | 73 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ |
72 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ | 74 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ |
@@ -78,6 +80,7 @@ static struct usb_device_id id_table [] = { | |||
78 | { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ | 80 | { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ |
79 | { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ | 81 | { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ |
80 | { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ | 82 | { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ |
83 | { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ | ||
81 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ | 84 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ |
82 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ | 85 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ |
83 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ | 86 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ |
@@ -94,7 +97,9 @@ static struct usb_device_id id_table [] = { | |||
94 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ | 97 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ |
95 | { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ | 98 | { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ |
96 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ | 99 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ |
100 | { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ | ||
97 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ | 101 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ |
102 | { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ | ||
98 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ | 103 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ |
99 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 104 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
100 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 105 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 9734085fd2fe..59adfe123110 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1228 | /* precursor to disconnect so just go away */ | 1228 | /* precursor to disconnect so just go away */ |
1229 | return; | 1229 | return; |
1230 | case -EPIPE: | 1230 | case -EPIPE: |
1231 | usb_clear_halt(port->serial->dev, 0x81); | 1231 | /* Can't call usb_clear_halt while in_interrupt */ |
1232 | break; | 1232 | /* FALLS THROUGH */ |
1233 | default: | 1233 | default: |
1234 | /* something ugly is going on... */ | 1234 | /* something ugly is going on... */ |
1235 | dev_err(&urb->dev->dev, | 1235 | dev_err(&urb->dev->dev, |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 3dc3768ca71c..b574878c78b2 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/smp_lock.h> | ||
36 | #include <linux/tty.h> | 37 | #include <linux/tty.h> |
37 | #include <linux/tty_driver.h> | 38 | #include <linux/tty_driver.h> |
38 | #include <linux/tty_flip.h> | 39 | #include <linux/tty_flip.h> |
@@ -107,6 +108,7 @@ struct ftdi_sio_quirk { | |||
107 | 108 | ||
108 | static int ftdi_jtag_probe(struct usb_serial *serial); | 109 | static int ftdi_jtag_probe(struct usb_serial *serial); |
109 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); | 110 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); |
111 | static int ftdi_NDI_device_setup(struct usb_serial *serial); | ||
110 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); | 112 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); |
111 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); | 113 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); |
112 | 114 | ||
@@ -118,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { | |||
118 | .probe = ftdi_mtxorb_hack_setup, | 120 | .probe = ftdi_mtxorb_hack_setup, |
119 | }; | 121 | }; |
120 | 122 | ||
123 | static struct ftdi_sio_quirk ftdi_NDI_device_quirk = { | ||
124 | .probe = ftdi_NDI_device_setup, | ||
125 | }; | ||
126 | |||
121 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { | 127 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { |
122 | .port_probe = ftdi_USB_UIRT_setup, | 128 | .port_probe = ftdi_USB_UIRT_setup, |
123 | }; | 129 | }; |
@@ -191,6 +197,7 @@ static struct usb_device_id id_table_combined [] = { | |||
191 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, | 197 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, |
192 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, | 198 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, |
193 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, | 199 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, |
200 | { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) }, | ||
194 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, | 201 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, |
195 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, | 202 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, |
196 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, | 203 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, |
@@ -579,6 +586,9 @@ static struct usb_device_id id_table_combined [] = { | |||
579 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, | 586 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, |
580 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, | 587 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, |
581 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, | 588 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, |
589 | { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) }, | ||
590 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) }, | ||
591 | { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) }, | ||
582 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, | 592 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, |
583 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, | 593 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, |
584 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, | 594 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, |
@@ -644,6 +654,16 @@ static struct usb_device_id id_table_combined [] = { | |||
644 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, | 654 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, |
645 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, | 655 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, |
646 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, | 656 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, |
657 | { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID), | ||
658 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
659 | { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID), | ||
660 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
661 | { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID), | ||
662 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
663 | { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID), | ||
664 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
665 | { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), | ||
666 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
647 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, | 667 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, |
648 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, | 668 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, |
649 | { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, | 669 | { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, |
@@ -660,6 +680,8 @@ static struct usb_device_id id_table_combined [] = { | |||
660 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 680 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
661 | { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), | 681 | { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), |
662 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 682 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
683 | { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), | ||
684 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
663 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | 685 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, |
664 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, | 686 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, |
665 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, | 687 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, |
@@ -667,7 +689,6 @@ static struct usb_device_id id_table_combined [] = { | |||
667 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, | 689 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, |
668 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, | 690 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, |
669 | { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, | 691 | { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, |
670 | { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) }, | ||
671 | { USB_DEVICE(ATMEL_VID, STK541_PID) }, | 692 | { USB_DEVICE(ATMEL_VID, STK541_PID) }, |
672 | { USB_DEVICE(DE_VID, STB_PID) }, | 693 | { USB_DEVICE(DE_VID, STB_PID) }, |
673 | { USB_DEVICE(DE_VID, WHT_PID) }, | 694 | { USB_DEVICE(DE_VID, WHT_PID) }, |
@@ -677,6 +698,7 @@ static struct usb_device_id id_table_combined [] = { | |||
677 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | 698 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), |
678 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 699 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
679 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, | 700 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, |
701 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, | ||
680 | { }, /* Optional parameter entry */ | 702 | { }, /* Optional parameter entry */ |
681 | { } /* Terminating entry */ | 703 | { } /* Terminating entry */ |
682 | }; | 704 | }; |
@@ -1023,6 +1045,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
1023 | case FT2232C: /* FT2232C chip */ | 1045 | case FT2232C: /* FT2232C chip */ |
1024 | case FT232RL: | 1046 | case FT232RL: |
1025 | if (baud <= 3000000) { | 1047 | if (baud <= 3000000) { |
1048 | __u16 product_id = le16_to_cpu( | ||
1049 | port->serial->dev->descriptor.idProduct); | ||
1050 | if (((FTDI_NDI_HUC_PID == product_id) || | ||
1051 | (FTDI_NDI_SPECTRA_SCU_PID == product_id) || | ||
1052 | (FTDI_NDI_FUTURE_2_PID == product_id) || | ||
1053 | (FTDI_NDI_FUTURE_3_PID == product_id) || | ||
1054 | (FTDI_NDI_AURORA_SCU_PID == product_id)) && | ||
1055 | (baud == 19200)) { | ||
1056 | baud = 1200000; | ||
1057 | } | ||
1026 | div_value = ftdi_232bm_baud_to_divisor(baud); | 1058 | div_value = ftdi_232bm_baud_to_divisor(baud); |
1027 | } else { | 1059 | } else { |
1028 | dbg("%s - Baud rate too high!", __func__); | 1060 | dbg("%s - Baud rate too high!", __func__); |
@@ -1554,6 +1586,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) | |||
1554 | } /* ftdi_HE_TIRA1_setup */ | 1586 | } /* ftdi_HE_TIRA1_setup */ |
1555 | 1587 | ||
1556 | /* | 1588 | /* |
1589 | * Module parameter to control latency timer for NDI FTDI-based USB devices. | ||
1590 | * If this value is not set in modprobe.conf.local its value will be set to 1ms. | ||
1591 | */ | ||
1592 | static int ndi_latency_timer = 1; | ||
1593 | |||
1594 | /* Setup for the NDI FTDI-based USB devices, which requires hardwired | ||
1595 | * baudrate (19200 gets mapped to 1200000). | ||
1596 | * | ||
1597 | * Called from usbserial:serial_probe. | ||
1598 | */ | ||
1599 | static int ftdi_NDI_device_setup(struct usb_serial *serial) | ||
1600 | { | ||
1601 | struct usb_device *udev = serial->dev; | ||
1602 | int latency = ndi_latency_timer; | ||
1603 | int rv = 0; | ||
1604 | char buf[1]; | ||
1605 | |||
1606 | if (latency == 0) | ||
1607 | latency = 1; | ||
1608 | if (latency > 99) | ||
1609 | latency = 99; | ||
1610 | |||
1611 | dbg("%s setting NDI device latency to %d", __func__, latency); | ||
1612 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); | ||
1613 | |||
1614 | rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
1615 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | ||
1616 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | ||
1617 | latency, 0, buf, 0, WDR_TIMEOUT); | ||
1618 | return 0; | ||
1619 | } | ||
1620 | |||
1621 | /* | ||
1557 | * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko | 1622 | * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko |
1558 | * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from | 1623 | * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from |
1559 | * userspace using openocd. | 1624 | * userspace using openocd. |
@@ -2121,7 +2186,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
2121 | /* Note that the error flag is duplicated for | 2186 | /* Note that the error flag is duplicated for |
2122 | every character received since we don't know | 2187 | every character received since we don't know |
2123 | which character it applied to */ | 2188 | which character it applied to */ |
2124 | if (!usb_serial_handle_sysrq_char(port, | 2189 | if (!usb_serial_handle_sysrq_char(tty, port, |
2125 | data[packet_offset + i])) | 2190 | data[packet_offset + i])) |
2126 | tty_insert_flip_char(tty, | 2191 | tty_insert_flip_char(tty, |
2127 | data[packet_offset + i], | 2192 | data[packet_offset + i], |
@@ -2622,3 +2687,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default=" | |||
2622 | module_param(product, ushort, 0); | 2687 | module_param(product, ushort, 0); |
2623 | MODULE_PARM_DESC(product, "User specified product ID"); | 2688 | MODULE_PARM_DESC(product, "User specified product ID"); |
2624 | 2689 | ||
2690 | module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR); | ||
2691 | MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override"); | ||
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index f1d440a728a3..24dbd99e87d7 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -506,6 +506,7 @@ | |||
506 | * | 506 | * |
507 | * Armin Laeuger originally sent the PID for the UM 100 module. | 507 | * Armin Laeuger originally sent the PID for the UM 100 module. |
508 | */ | 508 | */ |
509 | #define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */ | ||
509 | #define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ | 510 | #define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ |
510 | #define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ | 511 | #define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ |
511 | #define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ | 512 | #define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ |
@@ -614,6 +615,9 @@ | |||
614 | #define FTDI_CCSICDU20_0_PID 0xF9D0 | 615 | #define FTDI_CCSICDU20_0_PID 0xF9D0 |
615 | #define FTDI_CCSICDU40_1_PID 0xF9D1 | 616 | #define FTDI_CCSICDU40_1_PID 0xF9D1 |
616 | #define FTDI_CCSMACHX_2_PID 0xF9D2 | 617 | #define FTDI_CCSMACHX_2_PID 0xF9D2 |
618 | #define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 | ||
619 | #define FTDI_CCSICDU64_4_PID 0xF9D4 | ||
620 | #define FTDI_CCSPRIME8_5_PID 0xF9D5 | ||
617 | 621 | ||
618 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ | 622 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ |
619 | #define INSIDE_ACCESSO 0xFAD0 | 623 | #define INSIDE_ACCESSO 0xFAD0 |
@@ -736,6 +740,15 @@ | |||
736 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | 740 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ |
737 | 741 | ||
738 | /* | 742 | /* |
743 | * NDI (www.ndigital.com) product ids | ||
744 | */ | ||
745 | #define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ | ||
746 | #define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ | ||
747 | #define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ | ||
748 | #define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ | ||
749 | #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ | ||
750 | |||
751 | /* | ||
739 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) | 752 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) |
740 | */ | 753 | */ |
741 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ | 754 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ |
@@ -848,9 +861,6 @@ | |||
848 | #define TML_VID 0x1B91 /* Vendor ID */ | 861 | #define TML_VID 0x1B91 /* Vendor ID */ |
849 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ | 862 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ |
850 | 863 | ||
851 | /* NDI Polaris System */ | ||
852 | #define FTDI_NDI_HUC_PID 0xDA70 | ||
853 | |||
854 | /* Propox devices */ | 864 | /* Propox devices */ |
855 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | 865 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 |
856 | 866 | ||
@@ -934,6 +944,15 @@ | |||
934 | #define MARVELL_VID 0x9e88 | 944 | #define MARVELL_VID 0x9e88 |
935 | #define MARVELL_SHEEVAPLUG_PID 0x9e8f | 945 | #define MARVELL_SHEEVAPLUG_PID 0x9e8f |
936 | 946 | ||
947 | #define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ | ||
948 | |||
949 | /* | ||
950 | * GN Otometrics (http://www.otometrics.com) | ||
951 | * Submitted by Ville Sundberg. | ||
952 | */ | ||
953 | #define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ | ||
954 | #define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ | ||
955 | |||
937 | /* | 956 | /* |
938 | * BmRequestType: 1100 0000b | 957 | * BmRequestType: 1100 0000b |
939 | * bRequest: FTDI_E2_READ | 958 | * bRequest: FTDI_E2_READ |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 932d6241b787..ce57f6a32bdf 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -424,10 +424,17 @@ static void flush_and_resubmit_read_urb(struct usb_serial_port *port) | |||
424 | if (!tty) | 424 | if (!tty) |
425 | goto done; | 425 | goto done; |
426 | 426 | ||
427 | /* Push data to tty */ | 427 | /* The per character mucking around with sysrq path it too slow for |
428 | for (i = 0; i < urb->actual_length; i++, ch++) { | 428 | stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases |
429 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 429 | where the USB serial is not a console anyway */ |
430 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | 430 | if (!port->console || !port->sysrq) |
431 | tty_insert_flip_string(tty, ch, urb->actual_length); | ||
432 | else { | ||
433 | /* Push data to tty */ | ||
434 | for (i = 0; i < urb->actual_length; i++, ch++) { | ||
435 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | ||
436 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | ||
437 | } | ||
431 | } | 438 | } |
432 | tty_flip_buffer_push(tty); | 439 | tty_flip_buffer_push(tty); |
433 | tty_kref_put(tty); | 440 | tty_kref_put(tty); |
@@ -527,11 +534,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) | |||
527 | } | 534 | } |
528 | } | 535 | } |
529 | 536 | ||
530 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) | 537 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, |
538 | struct usb_serial_port *port, unsigned int ch) | ||
531 | { | 539 | { |
532 | if (port->sysrq && port->console) { | 540 | if (port->sysrq && port->console) { |
533 | if (ch && time_before(jiffies, port->sysrq)) { | 541 | if (ch && time_before(jiffies, port->sysrq)) { |
534 | handle_sysrq(ch, tty_port_tty_get(&port->port)); | 542 | handle_sysrq(ch, tty); |
535 | port->sysrq = 0; | 543 | port->sysrq = 0; |
536 | return 1; | 544 | return 1; |
537 | } | 545 | } |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index bfc5ce000ef9..ccd4dd340d2c 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -521,7 +521,7 @@ static int mos7720_chars_in_buffer(struct tty_struct *tty) | |||
521 | mos7720_port = usb_get_serial_port_data(port); | 521 | mos7720_port = usb_get_serial_port_data(port); |
522 | if (mos7720_port == NULL) { | 522 | if (mos7720_port == NULL) { |
523 | dbg("%s:leaving ...........", __func__); | 523 | dbg("%s:leaving ...........", __func__); |
524 | return -ENODEV; | 524 | return 0; |
525 | } | 525 | } |
526 | 526 | ||
527 | for (i = 0; i < NUM_URBS; ++i) { | 527 | for (i = 0; i < NUM_URBS; ++i) { |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index c40f95c1951c..270009afdf77 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
29 | #include <linux/tty.h> | 30 | #include <linux/tty.h> |
30 | #include <linux/tty_driver.h> | 31 | #include <linux/tty_driver.h> |
31 | #include <linux/tty_flip.h> | 32 | #include <linux/tty_flip.h> |
@@ -123,10 +124,13 @@ | |||
123 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | 124 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 |
124 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 | 125 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 |
125 | 126 | ||
126 | /* This driver also supports the ATEN UC2324 device since it is mos7840 based | 127 | /* This driver also supports |
127 | * - if I knew the device id it would also support the ATEN UC2322 */ | 128 | * ATEN UC2324 device using Moschip MCS7840 |
129 | * ATEN UC2322 device using Moschip MCS7820 | ||
130 | */ | ||
128 | #define USB_VENDOR_ID_ATENINTL 0x0557 | 131 | #define USB_VENDOR_ID_ATENINTL 0x0557 |
129 | #define ATENINTL_DEVICE_ID_UC2324 0x2011 | 132 | #define ATENINTL_DEVICE_ID_UC2324 0x2011 |
133 | #define ATENINTL_DEVICE_ID_UC2322 0x7820 | ||
130 | 134 | ||
131 | /* Interrupt Routine Defines */ | 135 | /* Interrupt Routine Defines */ |
132 | 136 | ||
@@ -176,6 +180,7 @@ static struct usb_device_id moschip_port_id_table[] = { | |||
176 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 180 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
177 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 181 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
178 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 182 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
183 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | ||
179 | {} /* terminating entry */ | 184 | {} /* terminating entry */ |
180 | }; | 185 | }; |
181 | 186 | ||
@@ -185,6 +190,7 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = { | |||
185 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 190 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
186 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 191 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
187 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 192 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
193 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | ||
188 | {} /* terminating entry */ | 194 | {} /* terminating entry */ |
189 | }; | 195 | }; |
190 | 196 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 575816e6ba37..c784ddbe7b61 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -66,8 +66,10 @@ static int option_tiocmget(struct tty_struct *tty, struct file *file); | |||
66 | static int option_tiocmset(struct tty_struct *tty, struct file *file, | 66 | static int option_tiocmset(struct tty_struct *tty, struct file *file, |
67 | unsigned int set, unsigned int clear); | 67 | unsigned int set, unsigned int clear); |
68 | static int option_send_setup(struct usb_serial_port *port); | 68 | static int option_send_setup(struct usb_serial_port *port); |
69 | #ifdef CONFIG_PM | ||
69 | static int option_suspend(struct usb_serial *serial, pm_message_t message); | 70 | static int option_suspend(struct usb_serial *serial, pm_message_t message); |
70 | static int option_resume(struct usb_serial *serial); | 71 | static int option_resume(struct usb_serial *serial); |
72 | #endif | ||
71 | 73 | ||
72 | /* Vendor and product IDs */ | 74 | /* Vendor and product IDs */ |
73 | #define OPTION_VENDOR_ID 0x0AF0 | 75 | #define OPTION_VENDOR_ID 0x0AF0 |
@@ -205,7 +207,9 @@ static int option_resume(struct usb_serial *serial); | |||
205 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 | 207 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 |
206 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 | 208 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 |
207 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | 209 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 |
210 | #define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100 | ||
208 | #define NOVATELWIRELESS_PRODUCT_MC760 0x6000 | 211 | #define NOVATELWIRELESS_PRODUCT_MC760 0x6000 |
212 | #define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 | ||
209 | 213 | ||
210 | /* FUTURE NOVATEL PRODUCTS */ | 214 | /* FUTURE NOVATEL PRODUCTS */ |
211 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 | 215 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 |
@@ -258,11 +262,6 @@ static int option_resume(struct usb_serial *serial); | |||
258 | #define AXESSTEL_VENDOR_ID 0x1726 | 262 | #define AXESSTEL_VENDOR_ID 0x1726 |
259 | #define AXESSTEL_PRODUCT_MV110H 0x1000 | 263 | #define AXESSTEL_PRODUCT_MV110H 0x1000 |
260 | 264 | ||
261 | #define ONDA_VENDOR_ID 0x19d2 | ||
262 | #define ONDA_PRODUCT_MSA501HS 0x0001 | ||
263 | #define ONDA_PRODUCT_ET502HS 0x0002 | ||
264 | #define ONDA_PRODUCT_MT503HS 0x2000 | ||
265 | |||
266 | #define BANDRICH_VENDOR_ID 0x1A8D | 265 | #define BANDRICH_VENDOR_ID 0x1A8D |
267 | #define BANDRICH_PRODUCT_C100_1 0x1002 | 266 | #define BANDRICH_PRODUCT_C100_1 0x1002 |
268 | #define BANDRICH_PRODUCT_C100_2 0x1003 | 267 | #define BANDRICH_PRODUCT_C100_2 0x1003 |
@@ -300,6 +299,7 @@ static int option_resume(struct usb_serial *serial); | |||
300 | #define ZTE_PRODUCT_MF628 0x0015 | 299 | #define ZTE_PRODUCT_MF628 0x0015 |
301 | #define ZTE_PRODUCT_MF626 0x0031 | 300 | #define ZTE_PRODUCT_MF626 0x0031 |
302 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe | 301 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe |
302 | #define ZTE_PRODUCT_AC8710 0xfff1 | ||
303 | 303 | ||
304 | #define BENQ_VENDOR_ID 0x04a5 | 304 | #define BENQ_VENDOR_ID 0x04a5 |
305 | #define BENQ_PRODUCT_H10 0x4068 | 305 | #define BENQ_PRODUCT_H10 0x4068 |
@@ -307,11 +307,25 @@ static int option_resume(struct usb_serial *serial); | |||
307 | #define DLINK_VENDOR_ID 0x1186 | 307 | #define DLINK_VENDOR_ID 0x1186 |
308 | #define DLINK_PRODUCT_DWM_652 0x3e04 | 308 | #define DLINK_PRODUCT_DWM_652 0x3e04 |
309 | 309 | ||
310 | #define QISDA_VENDOR_ID 0x1da5 | ||
311 | #define QISDA_PRODUCT_H21_4512 0x4512 | ||
312 | #define QISDA_PRODUCT_H21_4523 0x4523 | ||
313 | #define QISDA_PRODUCT_H20_4515 0x4515 | ||
314 | #define QISDA_PRODUCT_H20_4519 0x4519 | ||
315 | |||
310 | 316 | ||
311 | /* TOSHIBA PRODUCTS */ | 317 | /* TOSHIBA PRODUCTS */ |
312 | #define TOSHIBA_VENDOR_ID 0x0930 | 318 | #define TOSHIBA_VENDOR_ID 0x0930 |
313 | #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 | 319 | #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 |
314 | 320 | ||
321 | #define ALINK_VENDOR_ID 0x1e0e | ||
322 | #define ALINK_PRODUCT_3GU 0x9200 | ||
323 | |||
324 | /* ALCATEL PRODUCTS */ | ||
325 | #define ALCATEL_VENDOR_ID 0x1bbb | ||
326 | #define ALCATEL_PRODUCT_X060S 0x0000 | ||
327 | |||
328 | |||
315 | static struct usb_device_id option_ids[] = { | 329 | static struct usb_device_id option_ids[] = { |
316 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 330 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
317 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 331 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -428,8 +442,10 @@ static struct usb_device_id option_ids[] = { | |||
428 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ | 442 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ |
429 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ | 443 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ |
430 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ | 444 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ |
445 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727_NEW) }, /* Novatel MC727/U727/USB727 refresh */ | ||
431 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ | 446 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ |
432 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ | 447 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ |
448 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */ | ||
433 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ | 449 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ |
434 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ | 450 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ |
435 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ | 451 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ |
@@ -463,42 +479,6 @@ static struct usb_device_id option_ids[] = { | |||
463 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 479 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
464 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, | 480 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, |
465 | { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, | 481 | { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, |
466 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) }, | ||
467 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, | ||
468 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0003) }, | ||
469 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0004) }, | ||
470 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0005) }, | ||
471 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0006) }, | ||
472 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0007) }, | ||
473 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0008) }, | ||
474 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0009) }, | ||
475 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000a) }, | ||
476 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000b) }, | ||
477 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000c) }, | ||
478 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000d) }, | ||
479 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000e) }, | ||
480 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000f) }, | ||
481 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0010) }, | ||
482 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0011) }, | ||
483 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0012) }, | ||
484 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0013) }, | ||
485 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0014) }, | ||
486 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0015) }, | ||
487 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0016) }, | ||
488 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0017) }, | ||
489 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0018) }, | ||
490 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0019) }, | ||
491 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0020) }, | ||
492 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0021) }, | ||
493 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0022) }, | ||
494 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0023) }, | ||
495 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0024) }, | ||
496 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0025) }, | ||
497 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0026) }, | ||
498 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0027) }, | ||
499 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0028) }, | ||
500 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0029) }, | ||
501 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MT503HS) }, | ||
502 | { USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) }, | 482 | { USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) }, |
503 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, | 483 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, |
504 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, | 484 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, |
@@ -523,14 +503,85 @@ static struct usb_device_id option_ids[] = { | |||
523 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 503 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
524 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ | 504 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ |
525 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, | 505 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, |
526 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) }, | 506 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
527 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, | 507 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, |
528 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, | 508 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, |
529 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, | 509 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) }, |
510 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) }, | ||
511 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0006, 0xff, 0xff, 0xff) }, | ||
512 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0007, 0xff, 0xff, 0xff) }, | ||
513 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0008, 0xff, 0xff, 0xff) }, | ||
514 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0009, 0xff, 0xff, 0xff) }, | ||
515 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000a, 0xff, 0xff, 0xff) }, | ||
516 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000b, 0xff, 0xff, 0xff) }, | ||
517 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000c, 0xff, 0xff, 0xff) }, | ||
518 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000d, 0xff, 0xff, 0xff) }, | ||
519 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000e, 0xff, 0xff, 0xff) }, | ||
520 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000f, 0xff, 0xff, 0xff) }, | ||
521 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) }, | ||
522 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, | ||
523 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff) }, | ||
524 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, | ||
525 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, | ||
526 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, | ||
527 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff) }, | ||
528 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, | ||
529 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) }, | ||
530 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, | ||
531 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff) }, | ||
532 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) }, | ||
533 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, | ||
534 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, | ||
535 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff) }, | ||
536 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, | ||
537 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, | ||
538 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, | ||
539 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, | ||
540 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff) }, | ||
541 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, | ||
542 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, | ||
543 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff) }, | ||
544 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, | ||
545 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff) }, | ||
546 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, | ||
547 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, | ||
548 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff) }, | ||
549 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, | ||
550 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff) }, | ||
551 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, | ||
552 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff) }, | ||
553 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, | ||
554 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff) }, | ||
555 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, | ||
556 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, | ||
557 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff) }, | ||
558 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, | ||
559 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, | ||
560 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) }, | ||
561 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) }, | ||
562 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) }, | ||
563 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0082, 0xff, 0xff, 0xff) }, | ||
564 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, | ||
565 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, | ||
566 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, | ||
567 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ | ||
568 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, | ||
569 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, | ||
570 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, | ||
571 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, | ||
572 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, | ||
573 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, | ||
574 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, | ||
530 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 575 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
531 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 576 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
532 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ | 577 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, |
578 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, | ||
579 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, | ||
580 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, | ||
533 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ | 581 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ |
582 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, | ||
583 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, | ||
584 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, | ||
534 | { } /* Terminating entry */ | 585 | { } /* Terminating entry */ |
535 | }; | 586 | }; |
536 | MODULE_DEVICE_TABLE(usb, option_ids); | 587 | MODULE_DEVICE_TABLE(usb, option_ids); |
@@ -539,8 +590,10 @@ static struct usb_driver option_driver = { | |||
539 | .name = "option", | 590 | .name = "option", |
540 | .probe = usb_serial_probe, | 591 | .probe = usb_serial_probe, |
541 | .disconnect = usb_serial_disconnect, | 592 | .disconnect = usb_serial_disconnect, |
593 | #ifdef CONFIG_PM | ||
542 | .suspend = usb_serial_suspend, | 594 | .suspend = usb_serial_suspend, |
543 | .resume = usb_serial_resume, | 595 | .resume = usb_serial_resume, |
596 | #endif | ||
544 | .id_table = option_ids, | 597 | .id_table = option_ids, |
545 | .no_dynamic_id = 1, | 598 | .no_dynamic_id = 1, |
546 | }; | 599 | }; |
@@ -572,8 +625,10 @@ static struct usb_serial_driver option_1port_device = { | |||
572 | .disconnect = option_disconnect, | 625 | .disconnect = option_disconnect, |
573 | .release = option_release, | 626 | .release = option_release, |
574 | .read_int_callback = option_instat_callback, | 627 | .read_int_callback = option_instat_callback, |
628 | #ifdef CONFIG_PM | ||
575 | .suspend = option_suspend, | 629 | .suspend = option_suspend, |
576 | .resume = option_resume, | 630 | .resume = option_resume, |
631 | #endif | ||
577 | }; | 632 | }; |
578 | 633 | ||
579 | static int debug; | 634 | static int debug; |
@@ -732,7 +787,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
732 | memcpy(this_urb->transfer_buffer, buf, todo); | 787 | memcpy(this_urb->transfer_buffer, buf, todo); |
733 | this_urb->transfer_buffer_length = todo; | 788 | this_urb->transfer_buffer_length = todo; |
734 | 789 | ||
735 | this_urb->dev = port->serial->dev; | ||
736 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | 790 | err = usb_submit_urb(this_urb, GFP_ATOMIC); |
737 | if (err) { | 791 | if (err) { |
738 | dbg("usb_submit_urb %p (write bulk) failed " | 792 | dbg("usb_submit_urb %p (write bulk) failed " |
@@ -816,7 +870,6 @@ static void option_instat_callback(struct urb *urb) | |||
816 | int status = urb->status; | 870 | int status = urb->status; |
817 | struct usb_serial_port *port = urb->context; | 871 | struct usb_serial_port *port = urb->context; |
818 | struct option_port_private *portdata = usb_get_serial_port_data(port); | 872 | struct option_port_private *portdata = usb_get_serial_port_data(port); |
819 | struct usb_serial *serial = port->serial; | ||
820 | 873 | ||
821 | dbg("%s", __func__); | 874 | dbg("%s", __func__); |
822 | dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); | 875 | dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); |
@@ -860,7 +913,6 @@ static void option_instat_callback(struct urb *urb) | |||
860 | 913 | ||
861 | /* Resubmit urb so we continue receiving IRQ data */ | 914 | /* Resubmit urb so we continue receiving IRQ data */ |
862 | if (status != -ESHUTDOWN && status != -ENOENT) { | 915 | if (status != -ESHUTDOWN && status != -ENOENT) { |
863 | urb->dev = serial->dev; | ||
864 | err = usb_submit_urb(urb, GFP_ATOMIC); | 916 | err = usb_submit_urb(urb, GFP_ATOMIC); |
865 | if (err) | 917 | if (err) |
866 | dbg("%s: resubmit intr urb failed. (%d)", | 918 | dbg("%s: resubmit intr urb failed. (%d)", |
@@ -913,7 +965,6 @@ static int option_open(struct tty_struct *tty, | |||
913 | struct usb_serial_port *port, struct file *filp) | 965 | struct usb_serial_port *port, struct file *filp) |
914 | { | 966 | { |
915 | struct option_port_private *portdata; | 967 | struct option_port_private *portdata; |
916 | struct usb_serial *serial = port->serial; | ||
917 | int i, err; | 968 | int i, err; |
918 | struct urb *urb; | 969 | struct urb *urb; |
919 | 970 | ||
@@ -921,23 +972,11 @@ static int option_open(struct tty_struct *tty, | |||
921 | 972 | ||
922 | dbg("%s", __func__); | 973 | dbg("%s", __func__); |
923 | 974 | ||
924 | /* Reset low level data toggle and start reading from endpoints */ | 975 | /* Start reading from the IN endpoint */ |
925 | for (i = 0; i < N_IN_URB; i++) { | 976 | for (i = 0; i < N_IN_URB; i++) { |
926 | urb = portdata->in_urbs[i]; | 977 | urb = portdata->in_urbs[i]; |
927 | if (!urb) | 978 | if (!urb) |
928 | continue; | 979 | continue; |
929 | if (urb->dev != serial->dev) { | ||
930 | dbg("%s: dev %p != %p", __func__, | ||
931 | urb->dev, serial->dev); | ||
932 | continue; | ||
933 | } | ||
934 | |||
935 | /* | ||
936 | * make sure endpoint data toggle is synchronized with the | ||
937 | * device | ||
938 | */ | ||
939 | usb_clear_halt(urb->dev, urb->pipe); | ||
940 | |||
941 | err = usb_submit_urb(urb, GFP_KERNEL); | 980 | err = usb_submit_urb(urb, GFP_KERNEL); |
942 | if (err) { | 981 | if (err) { |
943 | dbg("%s: submit urb %d failed (%d) %d", | 982 | dbg("%s: submit urb %d failed (%d) %d", |
@@ -946,16 +985,6 @@ static int option_open(struct tty_struct *tty, | |||
946 | } | 985 | } |
947 | } | 986 | } |
948 | 987 | ||
949 | /* Reset low level data toggle on out endpoints */ | ||
950 | for (i = 0; i < N_OUT_URB; i++) { | ||
951 | urb = portdata->out_urbs[i]; | ||
952 | if (!urb) | ||
953 | continue; | ||
954 | urb->dev = serial->dev; | ||
955 | /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | ||
956 | usb_pipeout(urb->pipe), 0); */ | ||
957 | } | ||
958 | |||
959 | option_send_setup(port); | 988 | option_send_setup(port); |
960 | 989 | ||
961 | return 0; | 990 | return 0; |
@@ -1195,6 +1224,7 @@ static void option_release(struct usb_serial *serial) | |||
1195 | } | 1224 | } |
1196 | } | 1225 | } |
1197 | 1226 | ||
1227 | #ifdef CONFIG_PM | ||
1198 | static int option_suspend(struct usb_serial *serial, pm_message_t message) | 1228 | static int option_suspend(struct usb_serial *serial, pm_message_t message) |
1199 | { | 1229 | { |
1200 | dbg("%s entered", __func__); | 1230 | dbg("%s entered", __func__); |
@@ -1218,7 +1248,6 @@ static int option_resume(struct usb_serial *serial) | |||
1218 | dbg("%s: No interrupt URB for port %d\n", __func__, i); | 1248 | dbg("%s: No interrupt URB for port %d\n", __func__, i); |
1219 | continue; | 1249 | continue; |
1220 | } | 1250 | } |
1221 | port->interrupt_in_urb->dev = serial->dev; | ||
1222 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); | 1251 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); |
1223 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); | 1252 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); |
1224 | if (err < 0) { | 1253 | if (err < 0) { |
@@ -1254,6 +1283,7 @@ static int option_resume(struct usb_serial *serial) | |||
1254 | } | 1283 | } |
1255 | return 0; | 1284 | return 0; |
1256 | } | 1285 | } |
1286 | #endif | ||
1257 | 1287 | ||
1258 | MODULE_AUTHOR(DRIVER_AUTHOR); | 1288 | MODULE_AUTHOR(DRIVER_AUTHOR); |
1259 | MODULE_DESCRIPTION(DRIVER_DESC); | 1289 | MODULE_DESCRIPTION(DRIVER_DESC); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ec6c132a25b5..7d15bfa7c2db 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = { | |||
94 | { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, | 94 | { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, |
95 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, | 95 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, |
96 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, | 96 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, |
97 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, | ||
97 | { } /* Terminating entry */ | 98 | { } /* Terminating entry */ |
98 | }; | 99 | }; |
99 | 100 | ||
@@ -971,18 +972,46 @@ exit: | |||
971 | __func__, retval); | 972 | __func__, retval); |
972 | } | 973 | } |
973 | 974 | ||
975 | static void pl2303_push_data(struct tty_struct *tty, | ||
976 | struct usb_serial_port *port, struct urb *urb, | ||
977 | u8 line_status) | ||
978 | { | ||
979 | unsigned char *data = urb->transfer_buffer; | ||
980 | /* get tty_flag from status */ | ||
981 | char tty_flag = TTY_NORMAL; | ||
982 | /* break takes precedence over parity, */ | ||
983 | /* which takes precedence over framing errors */ | ||
984 | if (line_status & UART_BREAK_ERROR) | ||
985 | tty_flag = TTY_BREAK; | ||
986 | else if (line_status & UART_PARITY_ERROR) | ||
987 | tty_flag = TTY_PARITY; | ||
988 | else if (line_status & UART_FRAME_ERROR) | ||
989 | tty_flag = TTY_FRAME; | ||
990 | dbg("%s - tty_flag = %d", __func__, tty_flag); | ||
991 | |||
992 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
993 | /* overrun is special, not associated with a char */ | ||
994 | if (line_status & UART_OVERRUN_ERROR) | ||
995 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
996 | if (port->console && port->sysrq) { | ||
997 | int i; | ||
998 | for (i = 0; i < urb->actual_length; ++i) | ||
999 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | ||
1000 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1001 | } else | ||
1002 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
1003 | tty_flip_buffer_push(tty); | ||
1004 | } | ||
1005 | |||
974 | static void pl2303_read_bulk_callback(struct urb *urb) | 1006 | static void pl2303_read_bulk_callback(struct urb *urb) |
975 | { | 1007 | { |
976 | struct usb_serial_port *port = urb->context; | 1008 | struct usb_serial_port *port = urb->context; |
977 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 1009 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
978 | struct tty_struct *tty; | 1010 | struct tty_struct *tty; |
979 | unsigned char *data = urb->transfer_buffer; | ||
980 | unsigned long flags; | 1011 | unsigned long flags; |
981 | int i; | ||
982 | int result; | 1012 | int result; |
983 | int status = urb->status; | 1013 | int status = urb->status; |
984 | u8 line_status; | 1014 | u8 line_status; |
985 | char tty_flag; | ||
986 | 1015 | ||
987 | dbg("%s - port %d", __func__, port->number); | 1016 | dbg("%s - port %d", __func__, port->number); |
988 | 1017 | ||
@@ -1010,10 +1039,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1010 | } | 1039 | } |
1011 | 1040 | ||
1012 | usb_serial_debug_data(debug, &port->dev, __func__, | 1041 | usb_serial_debug_data(debug, &port->dev, __func__, |
1013 | urb->actual_length, data); | 1042 | urb->actual_length, urb->transfer_buffer); |
1014 | |||
1015 | /* get tty_flag from status */ | ||
1016 | tty_flag = TTY_NORMAL; | ||
1017 | 1043 | ||
1018 | spin_lock_irqsave(&priv->lock, flags); | 1044 | spin_lock_irqsave(&priv->lock, flags); |
1019 | line_status = priv->line_status; | 1045 | line_status = priv->line_status; |
@@ -1021,26 +1047,9 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1021 | spin_unlock_irqrestore(&priv->lock, flags); | 1047 | spin_unlock_irqrestore(&priv->lock, flags); |
1022 | wake_up_interruptible(&priv->delta_msr_wait); | 1048 | wake_up_interruptible(&priv->delta_msr_wait); |
1023 | 1049 | ||
1024 | /* break takes precedence over parity, */ | ||
1025 | /* which takes precedence over framing errors */ | ||
1026 | if (line_status & UART_BREAK_ERROR) | ||
1027 | tty_flag = TTY_BREAK; | ||
1028 | else if (line_status & UART_PARITY_ERROR) | ||
1029 | tty_flag = TTY_PARITY; | ||
1030 | else if (line_status & UART_FRAME_ERROR) | ||
1031 | tty_flag = TTY_FRAME; | ||
1032 | dbg("%s - tty_flag = %d", __func__, tty_flag); | ||
1033 | |||
1034 | tty = tty_port_tty_get(&port->port); | 1050 | tty = tty_port_tty_get(&port->port); |
1035 | if (tty && urb->actual_length) { | 1051 | if (tty && urb->actual_length) { |
1036 | tty_buffer_request_room(tty, urb->actual_length + 1); | 1052 | pl2303_push_data(tty, port, urb, line_status); |
1037 | /* overrun is special, not associated with a char */ | ||
1038 | if (line_status & UART_OVERRUN_ERROR) | ||
1039 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
1040 | for (i = 0; i < urb->actual_length; ++i) | ||
1041 | if (!usb_serial_handle_sysrq_char(port, data[i])) | ||
1042 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1043 | tty_flip_buffer_push(tty); | ||
1044 | } | 1053 | } |
1045 | tty_kref_put(tty); | 1054 | tty_kref_put(tty); |
1046 | /* Schedule the next read _if_ we are still open */ | 1055 | /* Schedule the next read _if_ we are still open */ |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 1d7a22e3a9fd..12aac7d2462d 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -122,3 +122,7 @@ | |||
122 | /* Hewlett-Packard LD220-HP POS Pole Display */ | 122 | /* Hewlett-Packard LD220-HP POS Pole Display */ |
123 | #define HP_VENDOR_ID 0x03f0 | 123 | #define HP_VENDOR_ID 0x03f0 |
124 | #define HP_LD220_PRODUCT_ID 0x3524 | 124 | #define HP_LD220_PRODUCT_ID 0x3524 |
125 | |||
126 | /* Cressi Edy (diving computer) PC interface */ | ||
127 | #define CRESSI_VENDOR_ID 0x04b8 | ||
128 | #define CRESSI_EDY_PRODUCT_ID 0x0521 | ||
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 032f7aeb40a4..f48d05e0acc1 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -181,35 +181,50 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = { | |||
181 | }; | 181 | }; |
182 | 182 | ||
183 | static struct usb_device_id id_table [] = { | 183 | static struct usb_device_id id_table [] = { |
184 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ | ||
185 | { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ | ||
186 | { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ | ||
187 | |||
184 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | 188 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ |
185 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 189 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
186 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 190 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ |
187 | { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */ | ||
188 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 191 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
189 | { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ | ||
190 | { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ | 192 | { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ |
193 | { USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */ | ||
194 | { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ | ||
195 | { USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */ | ||
191 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 196 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
192 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ | 197 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
198 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | ||
193 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ | 199 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ |
194 | /* Sierra Wireless C597 */ | 200 | /* Sierra Wireless C597 */ |
195 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, | 201 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, |
196 | /* Sierra Wireless Device */ | 202 | /* Sierra Wireless T598 */ |
197 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, | 203 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, |
198 | { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */ | 204 | { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */ |
199 | { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */ | 205 | { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */ |
200 | { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */ | 206 | { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */ |
207 | { USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */ | ||
201 | 208 | ||
202 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 209 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
203 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
204 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 210 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
211 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
212 | { USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */ | ||
213 | { USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */ | ||
214 | { USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */ | ||
205 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ | 215 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ |
206 | { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */ | 216 | { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */ |
207 | { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ | 217 | { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ |
208 | { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */ | 218 | { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */ |
209 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 219 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
210 | { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ | 220 | { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ |
221 | { USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */ | ||
211 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ | 222 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ |
212 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ | 223 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ |
224 | { USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */ | ||
225 | { USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */ | ||
226 | { USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */ | ||
227 | { USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */ | ||
213 | { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ | 228 | { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ |
214 | { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ | 229 | { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ |
215 | /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ | 230 | /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ |
@@ -227,16 +242,13 @@ static struct usb_device_id id_table [] = { | |||
227 | { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ | 242 | { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ |
228 | /* Sierra Wireless C885 */ | 243 | /* Sierra Wireless C885 */ |
229 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, | 244 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, |
230 | /* Sierra Wireless Device */ | 245 | /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ |
231 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, | 246 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, |
232 | /* Sierra Wireless Device */ | 247 | /* Sierra Wireless C22/C33 */ |
233 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, | 248 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, |
234 | /* Sierra Wireless Device */ | 249 | /* Sierra Wireless HSPA Non-Composite Device */ |
235 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, | 250 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, |
236 | 251 | { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ | |
237 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | ||
238 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ | ||
239 | |||
240 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ | 252 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ |
241 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist | 253 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist |
242 | }, | 254 | }, |
@@ -814,7 +826,7 @@ static int sierra_startup(struct usb_serial *serial) | |||
814 | return 0; | 826 | return 0; |
815 | } | 827 | } |
816 | 828 | ||
817 | static void sierra_disconnect(struct usb_serial *serial) | 829 | static void sierra_release(struct usb_serial *serial) |
818 | { | 830 | { |
819 | int i; | 831 | int i; |
820 | struct usb_serial_port *port; | 832 | struct usb_serial_port *port; |
@@ -830,7 +842,6 @@ static void sierra_disconnect(struct usb_serial *serial) | |||
830 | if (!portdata) | 842 | if (!portdata) |
831 | continue; | 843 | continue; |
832 | kfree(portdata); | 844 | kfree(portdata); |
833 | usb_set_serial_port_data(port, NULL); | ||
834 | } | 845 | } |
835 | } | 846 | } |
836 | 847 | ||
@@ -853,7 +864,7 @@ static struct usb_serial_driver sierra_device = { | |||
853 | .tiocmget = sierra_tiocmget, | 864 | .tiocmget = sierra_tiocmget, |
854 | .tiocmset = sierra_tiocmset, | 865 | .tiocmset = sierra_tiocmset, |
855 | .attach = sierra_startup, | 866 | .attach = sierra_startup, |
856 | .disconnect = sierra_disconnect, | 867 | .release = sierra_release, |
857 | .read_int_callback = sierra_instat_callback, | 868 | .read_int_callback = sierra_instat_callback, |
858 | }; | 869 | }; |
859 | 870 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 991d8232e376..3bc609fe2242 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -191,7 +191,6 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { | |||
191 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, | 191 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, |
192 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, | 192 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, |
193 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, | 193 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, |
194 | { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, | ||
195 | }; | 194 | }; |
196 | 195 | ||
197 | static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { | 196 | static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { |
@@ -728,7 +727,7 @@ static int ti_write_room(struct tty_struct *tty) | |||
728 | dbg("%s - port %d", __func__, port->number); | 727 | dbg("%s - port %d", __func__, port->number); |
729 | 728 | ||
730 | if (tport == NULL) | 729 | if (tport == NULL) |
731 | return -ENODEV; | 730 | return 0; |
732 | 731 | ||
733 | spin_lock_irqsave(&tport->tp_lock, flags); | 732 | spin_lock_irqsave(&tport->tp_lock, flags); |
734 | room = ti_buf_space_avail(tport->tp_write_buf); | 733 | room = ti_buf_space_avail(tport->tp_write_buf); |
@@ -749,7 +748,7 @@ static int ti_chars_in_buffer(struct tty_struct *tty) | |||
749 | dbg("%s - port %d", __func__, port->number); | 748 | dbg("%s - port %d", __func__, port->number); |
750 | 749 | ||
751 | if (tport == NULL) | 750 | if (tport == NULL) |
752 | return -ENODEV; | 751 | return 0; |
753 | 752 | ||
754 | spin_lock_irqsave(&tport->tp_lock, flags); | 753 | spin_lock_irqsave(&tport->tp_lock, flags); |
755 | chars = ti_buf_data_avail(tport->tp_write_buf); | 754 | chars = ti_buf_data_avail(tport->tp_write_buf); |
@@ -1658,7 +1657,7 @@ static int ti_do_download(struct usb_device *dev, int pipe, | |||
1658 | u8 cs = 0; | 1657 | u8 cs = 0; |
1659 | int done; | 1658 | int done; |
1660 | struct ti_firmware_header *header; | 1659 | struct ti_firmware_header *header; |
1661 | int status; | 1660 | int status = 0; |
1662 | int len; | 1661 | int len; |
1663 | 1662 | ||
1664 | for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) | 1663 | for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a84216464ca0..99188c92068b 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/smp_lock.h> | ||
24 | #include <linux/tty.h> | 25 | #include <linux/tty.h> |
25 | #include <linux/tty_driver.h> | 26 | #include <linux/tty_driver.h> |
26 | #include <linux/tty_flip.h> | 27 | #include <linux/tty_flip.h> |
@@ -31,6 +32,7 @@ | |||
31 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
32 | #include <linux/list.h> | 33 | #include <linux/list.h> |
33 | #include <linux/uaccess.h> | 34 | #include <linux/uaccess.h> |
35 | #include <linux/serial.h> | ||
34 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
35 | #include <linux/usb/serial.h> | 37 | #include <linux/usb/serial.h> |
36 | #include "pl2303.h" | 38 | #include "pl2303.h" |
@@ -183,6 +185,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
183 | struct usb_serial_port *port; | 185 | struct usb_serial_port *port; |
184 | unsigned int portNumber; | 186 | unsigned int portNumber; |
185 | int retval = 0; | 187 | int retval = 0; |
188 | int first = 0; | ||
186 | 189 | ||
187 | dbg("%s", __func__); | 190 | dbg("%s", __func__); |
188 | 191 | ||
@@ -220,8 +223,9 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
220 | tty->driver_data = port; | 223 | tty->driver_data = port; |
221 | tty_port_tty_set(&port->port, tty); | 224 | tty_port_tty_set(&port->port, tty); |
222 | 225 | ||
223 | if (port->port.count == 1) { | 226 | /* If the console is attached, the device is already open */ |
224 | 227 | if (port->port.count == 1 && !port->console) { | |
228 | first = 1; | ||
225 | /* lock this module before we call it | 229 | /* lock this module before we call it |
226 | * this may fail, which means we must bail out, | 230 | * this may fail, which means we must bail out, |
227 | * safe because we are called with BKL held */ | 231 | * safe because we are called with BKL held */ |
@@ -244,13 +248,21 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
244 | if (retval) | 248 | if (retval) |
245 | goto bailout_interface_put; | 249 | goto bailout_interface_put; |
246 | mutex_unlock(&serial->disc_mutex); | 250 | mutex_unlock(&serial->disc_mutex); |
251 | set_bit(ASYNCB_INITIALIZED, &port->port.flags); | ||
247 | } | 252 | } |
248 | mutex_unlock(&port->mutex); | 253 | mutex_unlock(&port->mutex); |
249 | /* Now do the correct tty layer semantics */ | 254 | /* Now do the correct tty layer semantics */ |
250 | retval = tty_port_block_til_ready(&port->port, tty, filp); | 255 | retval = tty_port_block_til_ready(&port->port, tty, filp); |
251 | if (retval == 0) | 256 | if (retval == 0) { |
257 | if (!first) | ||
258 | usb_serial_put(serial); | ||
252 | return 0; | 259 | return 0; |
253 | 260 | } | |
261 | mutex_lock(&port->mutex); | ||
262 | if (first == 0) | ||
263 | goto bailout_mutex_unlock; | ||
264 | /* Undo the initial port actions */ | ||
265 | mutex_lock(&serial->disc_mutex); | ||
254 | bailout_interface_put: | 266 | bailout_interface_put: |
255 | usb_autopm_put_interface(serial->interface); | 267 | usb_autopm_put_interface(serial->interface); |
256 | bailout_module_put: | 268 | bailout_module_put: |
@@ -338,6 +350,22 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
338 | 350 | ||
339 | dbg("%s - port %d", __func__, port->number); | 351 | dbg("%s - port %d", __func__, port->number); |
340 | 352 | ||
353 | /* FIXME: | ||
354 | This leaves a very narrow race. Really we should do the | ||
355 | serial_do_free() on tty->shutdown(), but tty->shutdown can | ||
356 | be called from IRQ context and serial_do_free can sleep. | ||
357 | |||
358 | The right fix is probably to make the tty free (which is rare) | ||
359 | and thus tty->shutdown() occur via a work queue and simplify all | ||
360 | the drivers that use it. | ||
361 | */ | ||
362 | if (tty_hung_up_p(filp)) { | ||
363 | /* serial_hangup already called serial_down at this point. | ||
364 | Another user may have already reopened the port but | ||
365 | serial_do_free is refcounted */ | ||
366 | serial_do_free(port); | ||
367 | return; | ||
368 | } | ||
341 | 369 | ||
342 | if (tty_port_close_start(&port->port, tty, filp) == 0) | 370 | if (tty_port_close_start(&port->port, tty, filp) == 0) |
343 | return; | 371 | return; |
@@ -353,7 +381,8 @@ static void serial_hangup(struct tty_struct *tty) | |||
353 | struct usb_serial_port *port = tty->driver_data; | 381 | struct usb_serial_port *port = tty->driver_data; |
354 | serial_do_down(port); | 382 | serial_do_down(port); |
355 | tty_port_hangup(&port->port); | 383 | tty_port_hangup(&port->port); |
356 | serial_do_free(port); | 384 | /* We must not free port yet - the USB serial layer depends on it's |
385 | continued existence */ | ||
357 | } | 386 | } |
358 | 387 | ||
359 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, | 388 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, |
@@ -392,7 +421,6 @@ static int serial_chars_in_buffer(struct tty_struct *tty) | |||
392 | struct usb_serial_port *port = tty->driver_data; | 421 | struct usb_serial_port *port = tty->driver_data; |
393 | dbg("%s = port %d", __func__, port->number); | 422 | dbg("%s = port %d", __func__, port->number); |
394 | 423 | ||
395 | WARN_ON(!port->port.count); | ||
396 | /* if the device was unplugged then any remaining characters | 424 | /* if the device was unplugged then any remaining characters |
397 | fell out of the connector ;) */ | 425 | fell out of the connector ;) */ |
398 | if (port->serial->disconnected) | 426 | if (port->serial->disconnected) |
diff --git a/drivers/usb/storage/option_ms.c b/drivers/usb/storage/option_ms.c index d41cc0a970f7..773a5cd38c5a 100644 --- a/drivers/usb/storage/option_ms.c +++ b/drivers/usb/storage/option_ms.c | |||
@@ -118,6 +118,9 @@ static int option_inquiry(struct us_data *us) | |||
118 | 118 | ||
119 | result = memcmp(buffer+8, "Option", 6); | 119 | result = memcmp(buffer+8, "Option", 6); |
120 | 120 | ||
121 | if (result != 0) | ||
122 | result = memcmp(buffer+8, "ZCOPTION", 8); | ||
123 | |||
121 | /* Read the CSW */ | 124 | /* Read the CSW */ |
122 | usb_stor_bulk_transfer_buf(us, | 125 | usb_stor_bulk_transfer_buf(us, |
123 | us->recv_bulk_pipe, | 126 | us->recv_bulk_pipe, |
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index fcb320217218..e20dc525d177 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -961,7 +961,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us) | |||
961 | US_BULK_GET_MAX_LUN, | 961 | US_BULK_GET_MAX_LUN, |
962 | USB_DIR_IN | USB_TYPE_CLASS | | 962 | USB_DIR_IN | USB_TYPE_CLASS | |
963 | USB_RECIP_INTERFACE, | 963 | USB_RECIP_INTERFACE, |
964 | 0, us->ifnum, us->iobuf, 1, HZ); | 964 | 0, us->ifnum, us->iobuf, 1, 10*HZ); |
965 | 965 | ||
966 | US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", | 966 | US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", |
967 | result, us->iobuf[0]); | 967 | result, us->iobuf[0]); |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 8afcf08eba98..3b54b3940178 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -1119,12 +1119,13 @@ config FB_CARILLO_RANCH | |||
1119 | 1119 | ||
1120 | config FB_INTEL | 1120 | config FB_INTEL |
1121 | tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" | 1121 | tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" |
1122 | depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL | 1122 | depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL && EMBEDDED |
1123 | select FB_MODE_HELPERS | 1123 | select FB_MODE_HELPERS |
1124 | select FB_CFB_FILLRECT | 1124 | select FB_CFB_FILLRECT |
1125 | select FB_CFB_COPYAREA | 1125 | select FB_CFB_COPYAREA |
1126 | select FB_CFB_IMAGEBLIT | 1126 | select FB_CFB_IMAGEBLIT |
1127 | select FB_BOOT_VESA_SUPPORT if FB_INTEL = y | 1127 | select FB_BOOT_VESA_SUPPORT if FB_INTEL = y |
1128 | depends on !DRM_I915 | ||
1128 | help | 1129 | help |
1129 | This driver supports the on-board graphics built in to the Intel | 1130 | This driver supports the on-board graphics built in to the Intel |
1130 | 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. | 1131 | 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index cb88394ba995..da05f0801bb7 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -261,6 +261,9 @@ static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo) | |||
261 | /** | 261 | /** |
262 | * atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory | 262 | * atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory |
263 | * @sinfo: the frame buffer to allocate memory for | 263 | * @sinfo: the frame buffer to allocate memory for |
264 | * | ||
265 | * This function is called only from the atmel_lcdfb_probe() | ||
266 | * so no locking by fb_info->mm_lock around smem_len setting is needed. | ||
264 | */ | 267 | */ |
265 | static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) | 268 | static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) |
266 | { | 269 | { |
@@ -270,9 +273,7 @@ static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) | |||
270 | 273 | ||
271 | smem_len = (var->xres_virtual * var->yres_virtual | 274 | smem_len = (var->xres_virtual * var->yres_virtual |
272 | * ((var->bits_per_pixel + 7) / 8)); | 275 | * ((var->bits_per_pixel + 7) / 8)); |
273 | mutex_lock(&info->mm_lock); | ||
274 | info->fix.smem_len = max(smem_len, sinfo->smem_len); | 276 | info->fix.smem_len = max(smem_len, sinfo->smem_len); |
275 | mutex_unlock(&info->mm_lock); | ||
276 | 277 | ||
277 | info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len, | 278 | info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len, |
278 | (dma_addr_t *)&info->fix.smem_start, GFP_KERNEL); | 279 | (dma_addr_t *)&info->fix.smem_start, GFP_KERNEL); |
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index e641584e212e..887166267443 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c | |||
@@ -145,6 +145,8 @@ static int pwm_backlight_suspend(struct platform_device *pdev, | |||
145 | struct backlight_device *bl = platform_get_drvdata(pdev); | 145 | struct backlight_device *bl = platform_get_drvdata(pdev); |
146 | struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); | 146 | struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); |
147 | 147 | ||
148 | if (pb->notify) | ||
149 | pb->notify(0); | ||
148 | pwm_config(pb->pwm, 0, pb->period); | 150 | pwm_config(pb->pwm, 0, pb->period); |
149 | pwm_disable(pb->pwm); | 151 | pwm_disable(pb->pwm); |
150 | return 0; | 152 | return 0; |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 53ea05645ff8..a85c818be945 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/compat.h> | 16 | #include <linux/compat.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/major.h> | 20 | #include <linux/major.h> |
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 5c1a2c01778f..9ae9cd32bd06 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -256,8 +256,8 @@ static void fix_edid(unsigned char *edid, int fix) | |||
256 | 256 | ||
257 | static int edid_checksum(unsigned char *edid) | 257 | static int edid_checksum(unsigned char *edid) |
258 | { | 258 | { |
259 | unsigned char i, csum = 0, all_null = 0; | 259 | unsigned char csum = 0, all_null = 0; |
260 | int err = 0, fix = check_edid(edid); | 260 | int i, err = 0, fix = check_edid(edid); |
261 | 261 | ||
262 | if (fix) | 262 | if (fix) |
263 | fix_edid(edid, fix); | 263 | fix_edid(edid, fix); |
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 0bf2190928d0..72d68b3dc478 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
@@ -1223,12 +1223,6 @@ static int __devinit install_fb(struct fb_info *info) | |||
1223 | return -EINVAL; | 1223 | return -EINVAL; |
1224 | } | 1224 | } |
1225 | 1225 | ||
1226 | if (fsl_diu_set_par(info)) { | ||
1227 | printk(KERN_ERR "fb_set_par failed"); | ||
1228 | fb_dealloc_cmap(&info->cmap); | ||
1229 | return -EINVAL; | ||
1230 | } | ||
1231 | |||
1232 | if (register_framebuffer(info) < 0) { | 1226 | if (register_framebuffer(info) < 0) { |
1233 | printk(KERN_ERR "register_framebuffer failed"); | 1227 | printk(KERN_ERR "register_framebuffer failed"); |
1234 | unmap_video_memory(info); | 1228 | unmap_video_memory(info); |
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 567fb944bd2a..f8778cde2183 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c | |||
@@ -1365,11 +1365,6 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) | |||
1365 | init_completion(&mx3fbi->flip_cmpl); | 1365 | init_completion(&mx3fbi->flip_cmpl); |
1366 | disable_irq(ichan->eof_irq); | 1366 | disable_irq(ichan->eof_irq); |
1367 | dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); | 1367 | dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); |
1368 | ret = mx3fb_set_par(fbi); | ||
1369 | if (ret < 0) | ||
1370 | goto esetpar; | ||
1371 | |||
1372 | mx3fb_blank(FB_BLANK_UNBLANK, fbi); | ||
1373 | 1368 | ||
1374 | dev_info(dev, "registered, using mode %s\n", fb_mode); | 1369 | dev_info(dev, "registered, using mode %s\n", fb_mode); |
1375 | 1370 | ||
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 4ea99bfc37b4..8862233d57b6 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c | |||
@@ -1254,7 +1254,7 @@ static struct fb_ops omapfb_ops = { | |||
1254 | static ssize_t omapfb_show_caps_num(struct device *dev, | 1254 | static ssize_t omapfb_show_caps_num(struct device *dev, |
1255 | struct device_attribute *attr, char *buf) | 1255 | struct device_attribute *attr, char *buf) |
1256 | { | 1256 | { |
1257 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1257 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1258 | int plane; | 1258 | int plane; |
1259 | size_t size; | 1259 | size_t size; |
1260 | struct omapfb_caps caps; | 1260 | struct omapfb_caps caps; |
@@ -1274,7 +1274,7 @@ static ssize_t omapfb_show_caps_num(struct device *dev, | |||
1274 | static ssize_t omapfb_show_caps_text(struct device *dev, | 1274 | static ssize_t omapfb_show_caps_text(struct device *dev, |
1275 | struct device_attribute *attr, char *buf) | 1275 | struct device_attribute *attr, char *buf) |
1276 | { | 1276 | { |
1277 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1277 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1278 | int i; | 1278 | int i; |
1279 | struct omapfb_caps caps; | 1279 | struct omapfb_caps caps; |
1280 | int plane; | 1280 | int plane; |
@@ -1321,7 +1321,7 @@ static DEVICE_ATTR(caps_text, 0444, omapfb_show_caps_text, NULL); | |||
1321 | static ssize_t omapfb_show_panel_name(struct device *dev, | 1321 | static ssize_t omapfb_show_panel_name(struct device *dev, |
1322 | struct device_attribute *attr, char *buf) | 1322 | struct device_attribute *attr, char *buf) |
1323 | { | 1323 | { |
1324 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1324 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1325 | 1325 | ||
1326 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name); | 1326 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name); |
1327 | } | 1327 | } |
@@ -1330,7 +1330,7 @@ static ssize_t omapfb_show_bklight_level(struct device *dev, | |||
1330 | struct device_attribute *attr, | 1330 | struct device_attribute *attr, |
1331 | char *buf) | 1331 | char *buf) |
1332 | { | 1332 | { |
1333 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1333 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1334 | int r; | 1334 | int r; |
1335 | 1335 | ||
1336 | if (fbdev->panel->get_bklight_level) { | 1336 | if (fbdev->panel->get_bklight_level) { |
@@ -1345,7 +1345,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev, | |||
1345 | struct device_attribute *attr, | 1345 | struct device_attribute *attr, |
1346 | const char *buf, size_t size) | 1346 | const char *buf, size_t size) |
1347 | { | 1347 | { |
1348 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1348 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1349 | int r; | 1349 | int r; |
1350 | 1350 | ||
1351 | if (fbdev->panel->set_bklight_level) { | 1351 | if (fbdev->panel->set_bklight_level) { |
@@ -1364,7 +1364,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev, | |||
1364 | static ssize_t omapfb_show_bklight_max(struct device *dev, | 1364 | static ssize_t omapfb_show_bklight_max(struct device *dev, |
1365 | struct device_attribute *attr, char *buf) | 1365 | struct device_attribute *attr, char *buf) |
1366 | { | 1366 | { |
1367 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1367 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1368 | int r; | 1368 | int r; |
1369 | 1369 | ||
1370 | if (fbdev->panel->get_bklight_level) { | 1370 | if (fbdev->panel->get_bklight_level) { |
@@ -1397,7 +1397,7 @@ static struct attribute_group panel_attr_grp = { | |||
1397 | static ssize_t omapfb_show_ctrl_name(struct device *dev, | 1397 | static ssize_t omapfb_show_ctrl_name(struct device *dev, |
1398 | struct device_attribute *attr, char *buf) | 1398 | struct device_attribute *attr, char *buf) |
1399 | { | 1399 | { |
1400 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1400 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1401 | 1401 | ||
1402 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name); | 1402 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name); |
1403 | } | 1403 | } |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 16d4f4c7d52b..924d79462780 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -1540,9 +1540,6 @@ static int sm501fb_init_fb(struct fb_info *fb, | |||
1540 | if (ret) | 1540 | if (ret) |
1541 | dev_err(info->dev, "check_var() failed on initial setup?\n"); | 1541 | dev_err(info->dev, "check_var() failed on initial setup?\n"); |
1542 | 1542 | ||
1543 | /* ensure we've activated our new configuration */ | ||
1544 | (fb->fbops->fb_set_par)(fb); | ||
1545 | |||
1546 | return 0; | 1543 | return 0; |
1547 | } | 1544 | } |
1548 | 1545 | ||
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 193c8f0e5cc5..bcec78ffc765 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -669,7 +669,7 @@ static int __init virtio_pci_init(void) | |||
669 | 669 | ||
670 | err = pci_register_driver(&virtio_pci_driver); | 670 | err = pci_register_driver(&virtio_pci_driver); |
671 | if (err) | 671 | if (err) |
672 | device_unregister(virtio_pci_root); | 672 | root_device_unregister(virtio_pci_root); |
673 | 673 | ||
674 | return err; | 674 | return err; |
675 | } | 675 | } |
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index 5c7011cda6a6..751c003864ad 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c | |||
@@ -161,7 +161,7 @@ static long bcm47xx_wdt_ioctl(struct file *file, | |||
161 | { | 161 | { |
162 | void __user *argp = (void __user *)arg; | 162 | void __user *argp = (void __user *)arg; |
163 | int __user *p = argp; | 163 | int __user *p = argp; |
164 | int new_value, retval = -EINVAL;; | 164 | int new_value, retval = -EINVAL; |
165 | 165 | ||
166 | switch (cmd) { | 166 | switch (cmd) { |
167 | case WDIOC_GETSUPPORT: | 167 | case WDIOC_GETSUPPORT: |
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index e9f950ff86ea..cdd55e0d09f8 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/watchdog.h> | 29 | #include <linux/watchdog.h> |
30 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
31 | #include <linux/uaccess.h> | 31 | #include <linux/uaccess.h> |
32 | #include <linux/io.h> | ||
32 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
33 | 34 | ||
34 | #define WDT_VERSION "0.3" | 35 | #define WDT_VERSION "0.3" |
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index ee1caae4d33b..016245419fad 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | static unsigned long oscr_freq; | 39 | static unsigned long oscr_freq; |
40 | static unsigned long sa1100wdt_users; | 40 | static unsigned long sa1100wdt_users; |
41 | static int pre_margin; | 41 | static unsigned int pre_margin; |
42 | static int boot_status; | 42 | static int boot_status; |
43 | 43 | ||
44 | /* | 44 | /* |
@@ -84,6 +84,7 @@ static const struct watchdog_info ident = { | |||
84 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | 84 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
85 | | WDIOF_KEEPALIVEPING, | 85 | | WDIOF_KEEPALIVEPING, |
86 | .identity = "SA1100/PXA255 Watchdog", | 86 | .identity = "SA1100/PXA255 Watchdog", |
87 | .firmware_version = 1, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | static long sa1100dog_ioctl(struct file *file, unsigned int cmd, | 90 | static long sa1100dog_ioctl(struct file *file, unsigned int cmd, |
@@ -118,7 +119,7 @@ static long sa1100dog_ioctl(struct file *file, unsigned int cmd, | |||
118 | if (ret) | 119 | if (ret) |
119 | break; | 120 | break; |
120 | 121 | ||
121 | if (time <= 0 || time > 255) { | 122 | if (time <= 0 || (oscr_freq * (long long)time >= 0xffffffff)) { |
122 | ret = -EINVAL; | 123 | ret = -EINVAL; |
123 | break; | 124 | break; |
124 | } | 125 | } |
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index 916890abffdd..f201accc4e3d 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c | |||
@@ -89,6 +89,11 @@ static void w83627hf_select_wd_register(void) | |||
89 | c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */ | 89 | c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */ |
90 | outb_p(0x2b, WDT_EFER); | 90 | outb_p(0x2b, WDT_EFER); |
91 | outb_p(c, WDT_EFDR); /* set GPIO3 to WDT0 */ | 91 | outb_p(c, WDT_EFDR); /* set GPIO3 to WDT0 */ |
92 | } else if (c == 0x88) { /* W83627EHF */ | ||
93 | outb_p(0x2d, WDT_EFER); /* select GPIO5 */ | ||
94 | c = inb_p(WDT_EFDR) & ~0x01; /* PIN77 -> WDT0# */ | ||
95 | outb_p(0x2d, WDT_EFER); | ||
96 | outb_p(c, WDT_EFDR); /* set GPIO5 to WDT0 */ | ||
92 | } | 97 | } |
93 | 98 | ||
94 | outb_p(0x07, WDT_EFER); /* point to logical device number reg */ | 99 | outb_p(0x07, WDT_EFER); /* point to logical device number reg */ |
diff --git a/drivers/watchdog/w83697ug_wdt.c b/drivers/watchdog/w83697ug_wdt.c index 883b5f79673a..a6c12dec91a1 100644 --- a/drivers/watchdog/w83697ug_wdt.c +++ b/drivers/watchdog/w83697ug_wdt.c | |||
@@ -149,8 +149,10 @@ static void wdt_ctrl(int timeout) | |||
149 | { | 149 | { |
150 | spin_lock(&io_lock); | 150 | spin_lock(&io_lock); |
151 | 151 | ||
152 | if (w83697ug_select_wd_register() < 0) | 152 | if (w83697ug_select_wd_register() < 0) { |
153 | spin_unlock(&io_lock); | ||
153 | return; | 154 | return; |
155 | } | ||
154 | 156 | ||
155 | outb_p(0xF4, WDT_EFER); /* Select CRF4 */ | 157 | outb_p(0xF4, WDT_EFER); /* Select CRF4 */ |
156 | outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ | 158 | outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ |