diff options
Diffstat (limited to 'drivers')
51 files changed, 850 insertions, 249 deletions
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 0cded0468003..821c81e8cd38 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c | |||
@@ -1511,8 +1511,8 @@ static inline short setup_idle_tx_channel (hrz_dev * dev, hrz_vcc * vcc) { | |||
1511 | // a.k.a. prepare the channel and remember that we have done so. | 1511 | // a.k.a. prepare the channel and remember that we have done so. |
1512 | 1512 | ||
1513 | tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel]; | 1513 | tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel]; |
1514 | u16 rd_ptr; | 1514 | u32 rd_ptr; |
1515 | u16 wr_ptr; | 1515 | u32 wr_ptr; |
1516 | u16 channel = vcc->channel; | 1516 | u16 channel = vcc->channel; |
1517 | 1517 | ||
1518 | unsigned long flags; | 1518 | unsigned long flags; |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 4d5ed18dad00..27bca34b4a65 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -147,7 +147,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
147 | printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); | 147 | printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); |
148 | return -ENOMEM; | 148 | return -ENOMEM; |
149 | } | 149 | } |
150 | global_flush_tlb(); | 150 | flush_agp_mappings(); |
151 | 151 | ||
152 | bridge->scratch_page_real = virt_to_gart(addr); | 152 | bridge->scratch_page_real = virt_to_gart(addr); |
153 | bridge->scratch_page = | 153 | bridge->scratch_page = |
@@ -191,7 +191,7 @@ err_out: | |||
191 | if (bridge->driver->needs_scratch_page) { | 191 | if (bridge->driver->needs_scratch_page) { |
192 | bridge->driver->agp_destroy_page( | 192 | bridge->driver->agp_destroy_page( |
193 | gart_to_virt(bridge->scratch_page_real)); | 193 | gart_to_virt(bridge->scratch_page_real)); |
194 | global_flush_tlb(); | 194 | flush_agp_mappings(); |
195 | } | 195 | } |
196 | if (got_gatt) | 196 | if (got_gatt) |
197 | bridge->driver->free_gatt_table(bridge); | 197 | bridge->driver->free_gatt_table(bridge); |
@@ -217,7 +217,7 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) | |||
217 | bridge->driver->needs_scratch_page) { | 217 | bridge->driver->needs_scratch_page) { |
218 | bridge->driver->agp_destroy_page( | 218 | bridge->driver->agp_destroy_page( |
219 | gart_to_virt(bridge->scratch_page_real)); | 219 | gart_to_virt(bridge->scratch_page_real)); |
220 | global_flush_tlb(); | 220 | flush_agp_mappings(); |
221 | } | 221 | } |
222 | } | 222 | } |
223 | 223 | ||
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 19f242b50781..5567ce8d72b0 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -155,7 +155,7 @@ void agp_free_memory(struct agp_memory *curr) | |||
155 | for (i = 0; i < curr->page_count; i++) { | 155 | for (i = 0; i < curr->page_count; i++) { |
156 | curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); | 156 | curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); |
157 | } | 157 | } |
158 | global_flush_tlb(); | 158 | flush_agp_mappings(); |
159 | } | 159 | } |
160 | agp_free_key(curr->key); | 160 | agp_free_key(curr->key); |
161 | vfree(curr->memory); | 161 | vfree(curr->memory); |
@@ -213,8 +213,6 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, | |||
213 | new->memory[i] = virt_to_gart(addr); | 213 | new->memory[i] = virt_to_gart(addr); |
214 | new->page_count++; | 214 | new->page_count++; |
215 | } | 215 | } |
216 | global_flush_tlb(); | ||
217 | |||
218 | new->bridge = bridge; | 216 | new->bridge = bridge; |
219 | 217 | ||
220 | flush_agp_mappings(); | 218 | flush_agp_mappings(); |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 70ef926c3bd8..4e9a04e1f08e 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -180,11 +180,10 @@ superio_exit(void) | |||
180 | #define W83781D_REG_BANK 0x4E | 180 | #define W83781D_REG_BANK 0x4E |
181 | 181 | ||
182 | #define W83781D_REG_CONFIG 0x40 | 182 | #define W83781D_REG_CONFIG 0x40 |
183 | #define W83781D_REG_ALARM1 0x41 | 183 | #define W83781D_REG_ALARM1 0x459 |
184 | #define W83781D_REG_ALARM2 0x42 | 184 | #define W83781D_REG_ALARM2 0x45A |
185 | #define W83781D_REG_ALARM3 0x450 | 185 | #define W83781D_REG_ALARM3 0x45B |
186 | 186 | ||
187 | #define W83781D_REG_IRQ 0x4C | ||
188 | #define W83781D_REG_BEEP_CONFIG 0x4D | 187 | #define W83781D_REG_BEEP_CONFIG 0x4D |
189 | #define W83781D_REG_BEEP_INTS1 0x56 | 188 | #define W83781D_REG_BEEP_INTS1 0x56 |
190 | #define W83781D_REG_BEEP_INTS2 0x57 | 189 | #define W83781D_REG_BEEP_INTS2 0x57 |
@@ -1370,13 +1369,6 @@ static void w83627hf_init_client(struct i2c_client *client) | |||
1370 | W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); | 1369 | W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); |
1371 | } | 1370 | } |
1372 | } | 1371 | } |
1373 | |||
1374 | /* enable comparator mode for temp2 and temp3 so | ||
1375 | alarm indication will work correctly */ | ||
1376 | i = w83627hf_read_value(client, W83781D_REG_IRQ); | ||
1377 | if (!(i & 0x40)) | ||
1378 | w83627hf_write_value(client, W83781D_REG_IRQ, | ||
1379 | i | 0x40); | ||
1380 | } | 1372 | } |
1381 | 1373 | ||
1382 | /* Start monitoring */ | 1374 | /* Start monitoring */ |
@@ -1400,7 +1392,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1400 | /* skip missing sensors */ | 1392 | /* skip missing sensors */ |
1401 | if (((data->type == w83697hf) && (i == 1)) || | 1393 | if (((data->type == w83697hf) && (i == 1)) || |
1402 | ((data->type == w83627thf || data->type == w83637hf) | 1394 | ((data->type == w83627thf || data->type == w83637hf) |
1403 | && (i == 4 || i == 5))) | 1395 | && (i == 5 || i == 6))) |
1404 | continue; | 1396 | continue; |
1405 | data->in[i] = | 1397 | data->in[i] = |
1406 | w83627hf_read_value(client, W83781D_REG_IN(i)); | 1398 | w83627hf_read_value(client, W83781D_REG_IN(i)); |
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index c9366b504833..a2237d4b2cf2 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c | |||
@@ -142,19 +142,18 @@ static int vt596_transaction(u8 size) | |||
142 | /* Make sure the SMBus host is ready to start transmitting */ | 142 | /* Make sure the SMBus host is ready to start transmitting */ |
143 | if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { | 143 | if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { |
144 | dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " | 144 | dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " |
145 | "Resetting... ", temp); | 145 | "Resetting...\n", temp); |
146 | 146 | ||
147 | outb_p(temp, SMBHSTSTS); | 147 | outb_p(temp, SMBHSTSTS); |
148 | if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { | 148 | if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { |
149 | printk("Failed! (0x%02x)\n", temp); | 149 | dev_err(&vt596_adapter.dev, "SMBus reset failed! " |
150 | "(0x%02x)\n", temp); | ||
150 | return -1; | 151 | return -1; |
151 | } else { | ||
152 | printk("Successful!\n"); | ||
153 | } | 152 | } |
154 | } | 153 | } |
155 | 154 | ||
156 | /* Start the transaction by setting bit 6 */ | 155 | /* Start the transaction by setting bit 6 */ |
157 | outb_p(0x40 | (size & 0x3C), SMBHSTCNT); | 156 | outb_p(0x40 | size, SMBHSTCNT); |
158 | 157 | ||
159 | /* We will always wait for a fraction of a second */ | 158 | /* We will always wait for a fraction of a second */ |
160 | do { | 159 | do { |
@@ -171,7 +170,7 @@ static int vt596_transaction(u8 size) | |||
171 | if (temp & 0x10) { | 170 | if (temp & 0x10) { |
172 | result = -1; | 171 | result = -1; |
173 | dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", | 172 | dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", |
174 | inb_p(SMBHSTCNT) & 0x3C); | 173 | size); |
175 | } | 174 | } |
176 | 175 | ||
177 | if (temp & 0x08) { | 176 | if (temp & 0x08) { |
@@ -180,11 +179,13 @@ static int vt596_transaction(u8 size) | |||
180 | } | 179 | } |
181 | 180 | ||
182 | if (temp & 0x04) { | 181 | if (temp & 0x04) { |
182 | int read = inb_p(SMBHSTADD) & 0x01; | ||
183 | result = -1; | 183 | result = -1; |
184 | /* Quick commands are used to probe for chips, so | 184 | /* The quick and receive byte commands are used to probe |
185 | errors are expected, and we don't want to frighten the | 185 | for chips, so errors are expected, and we don't want |
186 | user. */ | 186 | to frighten the user. */ |
187 | if ((inb_p(SMBHSTCNT) & 0x3C) != VT596_QUICK) | 187 | if (!((size == VT596_QUICK && !read) || |
188 | (size == VT596_BYTE && read))) | ||
188 | dev_err(&vt596_adapter.dev, "Transaction error!\n"); | 189 | dev_err(&vt596_adapter.dev, "Transaction error!\n"); |
189 | } | 190 | } |
190 | 191 | ||
@@ -462,9 +463,9 @@ static void __exit i2c_vt596_exit(void) | |||
462 | } | 463 | } |
463 | } | 464 | } |
464 | 465 | ||
465 | MODULE_AUTHOR( | 466 | MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>, " |
466 | "Frodo Looijaard <frodol@dds.nl> and " | 467 | "Mark D. Studebaker <mdsxyz123@yahoo.com> and " |
467 | "Philip Edelbrock <phil@netroedge.com>"); | 468 | "Jean Delvare <khali@linux-fr.org>"); |
468 | MODULE_DESCRIPTION("vt82c596 SMBus driver"); | 469 | MODULE_DESCRIPTION("vt82c596 SMBus driver"); |
469 | MODULE_LICENSE("GPL"); | 470 | MODULE_LICENSE("GPL"); |
470 | 471 | ||
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c index 01b037007410..02682fb794c8 100644 --- a/drivers/i2c/chips/ds1337.c +++ b/drivers/i2c/chips/ds1337.c | |||
@@ -164,9 +164,9 @@ static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt) | |||
164 | buf[1] = BIN2BCD(dt->tm_sec); | 164 | buf[1] = BIN2BCD(dt->tm_sec); |
165 | buf[2] = BIN2BCD(dt->tm_min); | 165 | buf[2] = BIN2BCD(dt->tm_min); |
166 | buf[3] = BIN2BCD(dt->tm_hour); | 166 | buf[3] = BIN2BCD(dt->tm_hour); |
167 | buf[4] = BIN2BCD(dt->tm_wday) + 1; | 167 | buf[4] = BIN2BCD(dt->tm_wday + 1); |
168 | buf[5] = BIN2BCD(dt->tm_mday); | 168 | buf[5] = BIN2BCD(dt->tm_mday); |
169 | buf[6] = BIN2BCD(dt->tm_mon) + 1; | 169 | buf[6] = BIN2BCD(dt->tm_mon + 1); |
170 | val = dt->tm_year; | 170 | val = dt->tm_year; |
171 | if (val >= 100) { | 171 | if (val >= 100) { |
172 | val -= 100; | 172 | val -= 100; |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index a737886e39d1..42e5b8175cbf 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -539,6 +539,15 @@ config BLK_DEV_CS5530 | |||
539 | 539 | ||
540 | It is safe to say Y to this question. | 540 | It is safe to say Y to this question. |
541 | 541 | ||
542 | config BLK_DEV_CS5535 | ||
543 | tristate "AMD CS5535 chipset support" | ||
544 | depends on X86 && !X86_64 | ||
545 | help | ||
546 | Include support for UDMA on the NSC/AMD CS5535 companion chipset. | ||
547 | This will automatically be detected and configured if found. | ||
548 | |||
549 | It is safe to say Y to this question. | ||
550 | |||
542 | config BLK_DEV_HPT34X | 551 | config BLK_DEV_HPT34X |
543 | tristate "HPT34X chipset support" | 552 | tristate "HPT34X chipset support" |
544 | help | 553 | help |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index e83f54d37f96..f615ab759962 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -2038,11 +2038,9 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file, | |||
2038 | struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); | 2038 | struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); |
2039 | ide_drive_t *drive = floppy->drive; | 2039 | ide_drive_t *drive = floppy->drive; |
2040 | void __user *argp = (void __user *)arg; | 2040 | void __user *argp = (void __user *)arg; |
2041 | int err = generic_ide_ioctl(drive, file, bdev, cmd, arg); | 2041 | int err; |
2042 | int prevent = (arg) ? 1 : 0; | 2042 | int prevent = (arg) ? 1 : 0; |
2043 | idefloppy_pc_t pc; | 2043 | idefloppy_pc_t pc; |
2044 | if (err != -EINVAL) | ||
2045 | return err; | ||
2046 | 2044 | ||
2047 | switch (cmd) { | 2045 | switch (cmd) { |
2048 | case CDROMEJECT: | 2046 | case CDROMEJECT: |
@@ -2094,7 +2092,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file, | |||
2094 | case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: | 2092 | case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: |
2095 | return idefloppy_get_format_progress(drive, argp); | 2093 | return idefloppy_get_format_progress(drive, argp); |
2096 | } | 2094 | } |
2097 | return -EINVAL; | 2095 | return generic_ide_ioctl(drive, file, bdev, cmd, arg); |
2098 | } | 2096 | } |
2099 | 2097 | ||
2100 | static int idefloppy_media_changed(struct gendisk *disk) | 2098 | static int idefloppy_media_changed(struct gendisk *disk) |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 0b0aa4f51628..af7af958ab3e 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -104,8 +104,6 @@ void default_hwif_iops (ide_hwif_t *hwif) | |||
104 | hwif->INSL = ide_insl; | 104 | hwif->INSL = ide_insl; |
105 | } | 105 | } |
106 | 106 | ||
107 | EXPORT_SYMBOL(default_hwif_iops); | ||
108 | |||
109 | /* | 107 | /* |
110 | * MMIO operations, typically used for SATA controllers | 108 | * MMIO operations, typically used for SATA controllers |
111 | */ | 109 | */ |
@@ -329,8 +327,6 @@ void default_hwif_transport(ide_hwif_t *hwif) | |||
329 | hwif->atapi_output_bytes = atapi_output_bytes; | 327 | hwif->atapi_output_bytes = atapi_output_bytes; |
330 | } | 328 | } |
331 | 329 | ||
332 | EXPORT_SYMBOL(default_hwif_transport); | ||
333 | |||
334 | /* | 330 | /* |
335 | * Beginning of Taskfile OPCODE Library and feature sets. | 331 | * Beginning of Taskfile OPCODE Library and feature sets. |
336 | */ | 332 | */ |
@@ -529,8 +525,6 @@ int wait_for_ready (ide_drive_t *drive, int timeout) | |||
529 | return 0; | 525 | return 0; |
530 | } | 526 | } |
531 | 527 | ||
532 | EXPORT_SYMBOL(wait_for_ready); | ||
533 | |||
534 | /* | 528 | /* |
535 | * This routine busy-waits for the drive status to be not "busy". | 529 | * This routine busy-waits for the drive status to be not "busy". |
536 | * It then checks the status for all of the "good" bits and none | 530 | * It then checks the status for all of the "good" bits and none |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 7ec18fa3b5ff..54f9639c2a8c 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -161,8 +161,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
161 | return ide_stopped; | 161 | return ide_stopped; |
162 | } | 162 | } |
163 | 163 | ||
164 | EXPORT_SYMBOL(do_rw_taskfile); | ||
165 | |||
166 | /* | 164 | /* |
167 | * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. | 165 | * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. |
168 | */ | 166 | */ |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 9fe19808d815..8af179b531c3 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -803,6 +803,7 @@ found: | |||
803 | hwif->irq = hw->irq; | 803 | hwif->irq = hw->irq; |
804 | hwif->noprobe = 0; | 804 | hwif->noprobe = 0; |
805 | hwif->chipset = hw->chipset; | 805 | hwif->chipset = hw->chipset; |
806 | hwif->gendev.parent = hw->dev; | ||
806 | 807 | ||
807 | if (!initializing) { | 808 | if (!initializing) { |
808 | probe_hwif_init_with_fixup(hwif, fixup); | 809 | probe_hwif_init_with_fixup(hwif, fixup); |
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 1dafffa7e513..ef79805218e4 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -182,13 +182,14 @@ static void ide_detach(dev_link_t *link) | |||
182 | 182 | ||
183 | } /* ide_detach */ | 183 | } /* ide_detach */ |
184 | 184 | ||
185 | static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq) | 185 | static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) |
186 | { | 186 | { |
187 | hw_regs_t hw; | 187 | hw_regs_t hw; |
188 | memset(&hw, 0, sizeof(hw)); | 188 | memset(&hw, 0, sizeof(hw)); |
189 | ide_init_hwif_ports(&hw, io, ctl, NULL); | 189 | ide_init_hwif_ports(&hw, io, ctl, NULL); |
190 | hw.irq = irq; | 190 | hw.irq = irq; |
191 | hw.chipset = ide_pci; | 191 | hw.chipset = ide_pci; |
192 | hw.dev = &handle->dev; | ||
192 | return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); | 193 | return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); |
193 | } | 194 | } |
194 | 195 | ||
@@ -327,12 +328,12 @@ static void ide_config(dev_link_t *link) | |||
327 | 328 | ||
328 | /* retry registration in case device is still spinning up */ | 329 | /* retry registration in case device is still spinning up */ |
329 | for (hd = -1, i = 0; i < 10; i++) { | 330 | for (hd = -1, i = 0; i < 10; i++) { |
330 | hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ); | 331 | hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle); |
331 | if (hd >= 0) break; | 332 | if (hd >= 0) break; |
332 | if (link->io.NumPorts1 == 0x20) { | 333 | if (link->io.NumPorts1 == 0x20) { |
333 | outb(0x02, ctl_base + 0x10); | 334 | outb(0x02, ctl_base + 0x10); |
334 | hd = idecs_register(io_base + 0x10, ctl_base + 0x10, | 335 | hd = idecs_register(io_base + 0x10, ctl_base + 0x10, |
335 | link->irq.AssignedIRQ); | 336 | link->irq.AssignedIRQ, handle); |
336 | if (hd >= 0) { | 337 | if (hd >= 0) { |
337 | io_base += 0x10; | 338 | io_base += 0x10; |
338 | ctl_base += 0x10; | 339 | ctl_base += 0x10; |
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index af46226c1796..f35d684edc25 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile | |||
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o | |||
6 | obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o | 6 | obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o |
7 | obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o | 7 | obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o |
8 | obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o | 8 | obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o |
9 | obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o | ||
9 | obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o | 10 | obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o |
10 | obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o | 11 | obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o |
11 | obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o | 12 | obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o |
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 844a6c9fb949..21965e5ef25e 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
@@ -74,6 +74,7 @@ static struct amd_ide_chip { | |||
74 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, | 74 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, |
75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, | 75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, |
76 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, | 76 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, |
77 | { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, | ||
77 | { 0 } | 78 | { 0 } |
78 | }; | 79 | }; |
79 | 80 | ||
@@ -491,6 +492,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { | |||
491 | /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), | 492 | /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), |
492 | /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), | 493 | /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), |
493 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), | 494 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), |
495 | /* 17 */ DECLARE_AMD_DEV("AMD5536"), | ||
494 | }; | 496 | }; |
495 | 497 | ||
496 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) | 498 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) |
@@ -527,6 +529,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { | |||
527 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, | 529 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, |
528 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, | 530 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, |
529 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, | 531 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, |
532 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, | ||
530 | { 0, }, | 533 | { 0, }, |
531 | }; | 534 | }; |
532 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); | 535 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); |
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c new file mode 100644 index 000000000000..6eb305197f3c --- /dev/null +++ b/drivers/ide/pci/cs5535.c | |||
@@ -0,0 +1,305 @@ | |||
1 | /* | ||
2 | * linux/drivers/ide/pci/cs5535.c | ||
3 | * | ||
4 | * Copyright (C) 2004-2005 Advanced Micro Devices, Inc. | ||
5 | * | ||
6 | * History: | ||
7 | * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com> | ||
8 | * - Reworked tuneproc, set_drive, misc mods to prep for mainline | ||
9 | * - Work was sponsored by CIS (M) Sdn Bhd. | ||
10 | * Ported to Kernel 2.6.11 on June 26, 2005 by | ||
11 | * Wolfgang Zuleger <wolfgang.zuleger@gmx.de> | ||
12 | * Alexander Kiausch <alex.kiausch@t-online.de> | ||
13 | * Originally developed by AMD for 2.4/2.6 | ||
14 | * | ||
15 | * Development of this chipset driver was funded | ||
16 | * by the nice folks at National Semiconductor/AMD. | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or modify it | ||
19 | * under the terms of the GNU General Public License version 2 as published by | ||
20 | * the Free Software Foundation. | ||
21 | * | ||
22 | * Documentation: | ||
23 | * CS5535 documentation available from AMD | ||
24 | */ | ||
25 | |||
26 | #include <linux/config.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <linux/ide.h> | ||
30 | |||
31 | #include "ide-timing.h" | ||
32 | |||
33 | #define MSR_ATAC_BASE 0x51300000 | ||
34 | #define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0) | ||
35 | #define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01) | ||
36 | #define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02) | ||
37 | #define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03) | ||
38 | #define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04) | ||
39 | #define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05) | ||
40 | #define ATAC_IO_BAR (MSR_ATAC_BASE+0x08) | ||
41 | #define ATAC_RESET (MSR_ATAC_BASE+0x10) | ||
42 | #define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20) | ||
43 | #define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21) | ||
44 | #define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22) | ||
45 | #define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23) | ||
46 | #define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24) | ||
47 | #define ATAC_BM0_CMD_PRIM 0x00 | ||
48 | #define ATAC_BM0_STS_PRIM 0x02 | ||
49 | #define ATAC_BM0_PRD 0x04 | ||
50 | #define CS5535_CABLE_DETECT 0x48 | ||
51 | |||
52 | /* Format I PIO settings. We seperate out cmd and data for safer timings */ | ||
53 | |||
54 | static unsigned int cs5535_pio_cmd_timings[5] = | ||
55 | { 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 }; | ||
56 | static unsigned int cs5535_pio_dta_timings[5] = | ||
57 | { 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 }; | ||
58 | |||
59 | static unsigned int cs5535_mwdma_timings[3] = | ||
60 | { 0x7F0FFFF3, 0x7F035352, 0x7f024241 }; | ||
61 | |||
62 | static unsigned int cs5535_udma_timings[5] = | ||
63 | { 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 }; | ||
64 | |||
65 | /* Macros to check if the register is the reset value - reset value is an | ||
66 | invalid timing and indicates the register has not been set previously */ | ||
67 | |||
68 | #define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL) == 0x00009172 ) | ||
69 | #define CS5535_BAD_DMA(timings) ( (timings & 0x000FFFFF) == 0x00077771 ) | ||
70 | |||
71 | /**** | ||
72 | * cs5535_set_speed - Configure the chipset to the new speed | ||
73 | * @drive: Drive to set up | ||
74 | * @speed: desired speed | ||
75 | * | ||
76 | * cs5535_set_speed() configures the chipset to a new speed. | ||
77 | */ | ||
78 | static void cs5535_set_speed(ide_drive_t *drive, u8 speed) | ||
79 | { | ||
80 | |||
81 | u32 reg = 0, dummy; | ||
82 | int unit = drive->select.b.unit; | ||
83 | |||
84 | |||
85 | /* Set the PIO timings */ | ||
86 | if ((speed & XFER_MODE) == XFER_PIO) { | ||
87 | u8 pioa; | ||
88 | u8 piob; | ||
89 | u8 cmd; | ||
90 | |||
91 | pioa = speed - XFER_PIO_0; | ||
92 | piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]), | ||
93 | 255, 4, NULL); | ||
94 | cmd = pioa < piob ? pioa : piob; | ||
95 | |||
96 | /* Write the speed of the current drive */ | ||
97 | reg = (cs5535_pio_cmd_timings[cmd] << 16) | | ||
98 | cs5535_pio_dta_timings[pioa]; | ||
99 | wrmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0); | ||
100 | |||
101 | /* And if nessesary - change the speed of the other drive */ | ||
102 | rdmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, dummy); | ||
103 | |||
104 | if (((reg >> 16) & cs5535_pio_cmd_timings[cmd]) != | ||
105 | cs5535_pio_cmd_timings[cmd]) { | ||
106 | reg &= 0x0000FFFF; | ||
107 | reg |= cs5535_pio_cmd_timings[cmd] << 16; | ||
108 | wrmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, 0); | ||
109 | } | ||
110 | |||
111 | /* Set bit 31 of the DMA register for PIO format 1 timings */ | ||
112 | rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy); | ||
113 | wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, | ||
114 | reg | 0x80000000UL, 0); | ||
115 | } else { | ||
116 | rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy); | ||
117 | |||
118 | reg &= 0x80000000UL; /* Preserve the PIO format bit */ | ||
119 | |||
120 | if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7) | ||
121 | reg |= cs5535_udma_timings[speed - XFER_UDMA_0]; | ||
122 | else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) | ||
123 | reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0]; | ||
124 | else | ||
125 | return; | ||
126 | |||
127 | wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, 0); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static u8 cs5535_ratemask(ide_drive_t *drive) | ||
132 | { | ||
133 | /* eighty93 will return 1 if it's 80core and capable of | ||
134 | exceeding udma2, 0 otherwise. we need ratemask to set | ||
135 | the max speed and if we can > udma2 then we return 2 | ||
136 | which selects speed_max as udma4 which is the 5535's max | ||
137 | speed, and 1 selects udma2 which is the max for 40c */ | ||
138 | if (!eighty_ninty_three(drive)) | ||
139 | return 1; | ||
140 | |||
141 | return 2; | ||
142 | } | ||
143 | |||
144 | |||
145 | /**** | ||
146 | * cs5535_set_drive - Configure the drive to the new speed | ||
147 | * @drive: Drive to set up | ||
148 | * @speed: desired speed | ||
149 | * | ||
150 | * cs5535_set_drive() configures the drive and the chipset to a | ||
151 | * new speed. It also can be called by upper layers. | ||
152 | */ | ||
153 | static int cs5535_set_drive(ide_drive_t *drive, u8 speed) | ||
154 | { | ||
155 | speed = ide_rate_filter(cs5535_ratemask(drive), speed); | ||
156 | ide_config_drive_speed(drive, speed); | ||
157 | cs5535_set_speed(drive, speed); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | /**** | ||
163 | * cs5535_tuneproc - PIO setup | ||
164 | * @drive: drive to set up | ||
165 | * @pio: mode to use (255 for 'best possible') | ||
166 | * | ||
167 | * A callback from the upper layers for PIO-only tuning. | ||
168 | */ | ||
169 | static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed) | ||
170 | { | ||
171 | u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, | ||
172 | XFER_PIO_4 }; | ||
173 | |||
174 | /* cs5535 max pio is pio 4, best_pio will check the blacklist. | ||
175 | i think we don't need to rate_filter the incoming xferspeed | ||
176 | since we know we're only going to choose pio */ | ||
177 | xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL); | ||
178 | ide_config_drive_speed(drive, modes[xferspeed]); | ||
179 | cs5535_set_speed(drive, xferspeed); | ||
180 | } | ||
181 | |||
182 | static int cs5535_config_drive_for_dma(ide_drive_t *drive) | ||
183 | { | ||
184 | u8 speed; | ||
185 | |||
186 | speed = ide_dma_speed(drive, cs5535_ratemask(drive)); | ||
187 | |||
188 | /* If no DMA speed was available then let dma_check hit pio */ | ||
189 | if (!speed) { | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | cs5535_set_drive(drive, speed); | ||
194 | return ide_dma_enable(drive); | ||
195 | } | ||
196 | |||
197 | static int cs5535_dma_check(ide_drive_t *drive) | ||
198 | { | ||
199 | ide_hwif_t *hwif = drive->hwif; | ||
200 | struct hd_driveid *id = drive->id; | ||
201 | u8 speed; | ||
202 | |||
203 | drive->init_speed = 0; | ||
204 | |||
205 | if ((id->capability & 1) && drive->autodma) { | ||
206 | if (ide_use_dma(drive)) { | ||
207 | if (cs5535_config_drive_for_dma(drive)) | ||
208 | return hwif->ide_dma_on(drive); | ||
209 | } | ||
210 | |||
211 | goto fast_ata_pio; | ||
212 | |||
213 | } else if ((id->capability & 8) || (id->field_valid & 2)) { | ||
214 | fast_ata_pio: | ||
215 | speed = ide_get_best_pio_mode(drive, 255, 4, NULL); | ||
216 | cs5535_set_drive(drive, speed); | ||
217 | return hwif->ide_dma_off_quietly(drive); | ||
218 | } | ||
219 | /* IORDY not supported */ | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static u8 __devinit cs5535_cable_detect(struct pci_dev *dev) | ||
224 | { | ||
225 | u8 bit; | ||
226 | |||
227 | /* if a 80 wire cable was detected */ | ||
228 | pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit); | ||
229 | return (bit & 1); | ||
230 | } | ||
231 | |||
232 | /**** | ||
233 | * init_hwif_cs5535 - Initialize one ide cannel | ||
234 | * @hwif: Channel descriptor | ||
235 | * | ||
236 | * This gets invoked by the IDE driver once for each channel. It | ||
237 | * performs channel-specific pre-initialization before drive probing. | ||
238 | * | ||
239 | */ | ||
240 | static void __devinit init_hwif_cs5535(ide_hwif_t *hwif) | ||
241 | { | ||
242 | int i; | ||
243 | |||
244 | hwif->autodma = 0; | ||
245 | |||
246 | hwif->tuneproc = &cs5535_tuneproc; | ||
247 | hwif->speedproc = &cs5535_set_drive; | ||
248 | hwif->ide_dma_check = &cs5535_dma_check; | ||
249 | |||
250 | hwif->atapi_dma = 1; | ||
251 | hwif->ultra_mask = 0x1F; | ||
252 | hwif->mwdma_mask = 0x07; | ||
253 | |||
254 | |||
255 | hwif->udma_four = cs5535_cable_detect(hwif->pci_dev); | ||
256 | |||
257 | if (!noautodma) | ||
258 | hwif->autodma = 1; | ||
259 | |||
260 | /* just setting autotune and not worrying about bios timings */ | ||
261 | for (i = 0; i < 2; i++) { | ||
262 | hwif->drives[i].autotune = 1; | ||
263 | hwif->drives[i].autodma = hwif->autodma; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static ide_pci_device_t cs5535_chipset __devinitdata = { | ||
268 | .name = "CS5535", | ||
269 | .init_hwif = init_hwif_cs5535, | ||
270 | .channels = 1, | ||
271 | .autodma = AUTODMA, | ||
272 | .bootable = ON_BOARD, | ||
273 | }; | ||
274 | |||
275 | static int __devinit cs5535_init_one(struct pci_dev *dev, | ||
276 | const struct pci_device_id *id) | ||
277 | { | ||
278 | return ide_setup_pci_device(dev, &cs5535_chipset); | ||
279 | } | ||
280 | |||
281 | static struct pci_device_id cs5535_pci_tbl[] = | ||
282 | { | ||
283 | { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID, | ||
284 | PCI_ANY_ID, 0, 0, 0}, | ||
285 | { 0, }, | ||
286 | }; | ||
287 | |||
288 | MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl); | ||
289 | |||
290 | static struct pci_driver driver = { | ||
291 | .name = "CS5535_IDE", | ||
292 | .id_table = cs5535_pci_tbl, | ||
293 | .probe = cs5535_init_one, | ||
294 | }; | ||
295 | |||
296 | static int __init cs5535_ide_init(void) | ||
297 | { | ||
298 | return ide_pci_register_driver(&driver); | ||
299 | } | ||
300 | |||
301 | module_init(cs5535_ide_init); | ||
302 | |||
303 | MODULE_AUTHOR("AMD"); | ||
304 | MODULE_DESCRIPTION("PCI driver module for AMD/NS CS5535 IDE"); | ||
305 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 5a33513f3dd1..9f41ecd56338 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c | |||
@@ -469,7 +469,7 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) | |||
469 | 469 | ||
470 | static __devinitdata ide_hwif_t *primary; | 470 | static __devinitdata ide_hwif_t *primary; |
471 | 471 | ||
472 | void __devinit init_iops_cy82c693(ide_hwif_t *hwif) | 472 | static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) |
473 | { | 473 | { |
474 | if (PCI_FUNC(hwif->pci_dev->devfn) == 1) | 474 | if (PCI_FUNC(hwif->pci_dev->devfn) == 1) |
475 | primary = hwif; | 475 | primary = hwif; |
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 2b9961b88135..022d244f2eb0 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
@@ -701,6 +701,7 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name) | |||
701 | unsigned long barsize = pci_resource_len(dev, 5); | 701 | unsigned long barsize = pci_resource_len(dev, 5); |
702 | u8 tmpbyte = 0; | 702 | u8 tmpbyte = 0; |
703 | void __iomem *ioaddr; | 703 | void __iomem *ioaddr; |
704 | u32 tmp, irq_mask; | ||
704 | 705 | ||
705 | /* | 706 | /* |
706 | * Drop back to PIO if we can't map the mmio. Some | 707 | * Drop back to PIO if we can't map the mmio. Some |
@@ -726,6 +727,14 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name) | |||
726 | pci_set_drvdata(dev, (void *) ioaddr); | 727 | pci_set_drvdata(dev, (void *) ioaddr); |
727 | 728 | ||
728 | if (pdev_is_sata(dev)) { | 729 | if (pdev_is_sata(dev)) { |
730 | /* make sure IDE0/1 interrupts are not masked */ | ||
731 | irq_mask = (1 << 22) | (1 << 23); | ||
732 | tmp = readl(ioaddr + 0x48); | ||
733 | if (tmp & irq_mask) { | ||
734 | tmp &= ~irq_mask; | ||
735 | writel(tmp, ioaddr + 0x48); | ||
736 | readl(ioaddr + 0x48); /* flush */ | ||
737 | } | ||
729 | writel(0, ioaddr + 0x148); | 738 | writel(0, ioaddr + 0x148); |
730 | writel(0, ioaddr + 0x1C8); | 739 | writel(0, ioaddr + 0x1C8); |
731 | } | 740 | } |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index aed5ca23fb22..5ea741f47fc8 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -31,7 +31,7 @@ | |||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
32 | * SOFTWARE. | 32 | * SOFTWARE. |
33 | * | 33 | * |
34 | * $Id: user_mad.c 2814 2005-07-06 19:14:09Z halr $ | 34 | * $Id: user_mad.c 4010 2005-11-09 23:11:56Z roland $ |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
@@ -110,13 +110,13 @@ struct ib_umad_device { | |||
110 | }; | 110 | }; |
111 | 111 | ||
112 | struct ib_umad_file { | 112 | struct ib_umad_file { |
113 | struct ib_umad_port *port; | 113 | struct ib_umad_port *port; |
114 | struct list_head recv_list; | 114 | struct list_head recv_list; |
115 | struct list_head port_list; | 115 | struct list_head port_list; |
116 | spinlock_t recv_lock; | 116 | spinlock_t recv_lock; |
117 | wait_queue_head_t recv_wait; | 117 | wait_queue_head_t recv_wait; |
118 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; | 118 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; |
119 | struct ib_mr *mr[IB_UMAD_MAX_AGENTS]; | 119 | int agents_dead; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | struct ib_umad_packet { | 122 | struct ib_umad_packet { |
@@ -145,6 +145,12 @@ static void ib_umad_release_dev(struct kref *ref) | |||
145 | kfree(dev); | 145 | kfree(dev); |
146 | } | 146 | } |
147 | 147 | ||
148 | /* caller must hold port->mutex at least for reading */ | ||
149 | static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id) | ||
150 | { | ||
151 | return file->agents_dead ? NULL : file->agent[id]; | ||
152 | } | ||
153 | |||
148 | static int queue_packet(struct ib_umad_file *file, | 154 | static int queue_packet(struct ib_umad_file *file, |
149 | struct ib_mad_agent *agent, | 155 | struct ib_mad_agent *agent, |
150 | struct ib_umad_packet *packet) | 156 | struct ib_umad_packet *packet) |
@@ -152,10 +158,11 @@ static int queue_packet(struct ib_umad_file *file, | |||
152 | int ret = 1; | 158 | int ret = 1; |
153 | 159 | ||
154 | down_read(&file->port->mutex); | 160 | down_read(&file->port->mutex); |
161 | |||
155 | for (packet->mad.hdr.id = 0; | 162 | for (packet->mad.hdr.id = 0; |
156 | packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; | 163 | packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; |
157 | packet->mad.hdr.id++) | 164 | packet->mad.hdr.id++) |
158 | if (agent == file->agent[packet->mad.hdr.id]) { | 165 | if (agent == __get_agent(file, packet->mad.hdr.id)) { |
159 | spin_lock_irq(&file->recv_lock); | 166 | spin_lock_irq(&file->recv_lock); |
160 | list_add_tail(&packet->list, &file->recv_list); | 167 | list_add_tail(&packet->list, &file->recv_list); |
161 | spin_unlock_irq(&file->recv_lock); | 168 | spin_unlock_irq(&file->recv_lock); |
@@ -327,7 +334,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
327 | 334 | ||
328 | down_read(&file->port->mutex); | 335 | down_read(&file->port->mutex); |
329 | 336 | ||
330 | agent = file->agent[packet->mad.hdr.id]; | 337 | agent = __get_agent(file, packet->mad.hdr.id); |
331 | if (!agent) { | 338 | if (!agent) { |
332 | ret = -EINVAL; | 339 | ret = -EINVAL; |
333 | goto err_up; | 340 | goto err_up; |
@@ -481,7 +488,7 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg) | |||
481 | } | 488 | } |
482 | 489 | ||
483 | for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id) | 490 | for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id) |
484 | if (!file->agent[agent_id]) | 491 | if (!__get_agent(file, agent_id)) |
485 | goto found; | 492 | goto found; |
486 | 493 | ||
487 | ret = -ENOMEM; | 494 | ret = -ENOMEM; |
@@ -505,29 +512,15 @@ found: | |||
505 | goto out; | 512 | goto out; |
506 | } | 513 | } |
507 | 514 | ||
508 | file->agent[agent_id] = agent; | ||
509 | |||
510 | file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE); | ||
511 | if (IS_ERR(file->mr[agent_id])) { | ||
512 | ret = -ENOMEM; | ||
513 | goto err; | ||
514 | } | ||
515 | |||
516 | if (put_user(agent_id, | 515 | if (put_user(agent_id, |
517 | (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) { | 516 | (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) { |
518 | ret = -EFAULT; | 517 | ret = -EFAULT; |
519 | goto err_mr; | 518 | ib_unregister_mad_agent(agent); |
519 | goto out; | ||
520 | } | 520 | } |
521 | 521 | ||
522 | file->agent[agent_id] = agent; | ||
522 | ret = 0; | 523 | ret = 0; |
523 | goto out; | ||
524 | |||
525 | err_mr: | ||
526 | ib_dereg_mr(file->mr[agent_id]); | ||
527 | |||
528 | err: | ||
529 | file->agent[agent_id] = NULL; | ||
530 | ib_unregister_mad_agent(agent); | ||
531 | 524 | ||
532 | out: | 525 | out: |
533 | up_write(&file->port->mutex); | 526 | up_write(&file->port->mutex); |
@@ -536,27 +529,29 @@ out: | |||
536 | 529 | ||
537 | static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) | 530 | static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) |
538 | { | 531 | { |
532 | struct ib_mad_agent *agent = NULL; | ||
539 | u32 id; | 533 | u32 id; |
540 | int ret = 0; | 534 | int ret = 0; |
541 | 535 | ||
542 | down_write(&file->port->mutex); | 536 | if (get_user(id, (u32 __user *) arg)) |
537 | return -EFAULT; | ||
543 | 538 | ||
544 | if (get_user(id, (u32 __user *) arg)) { | 539 | down_write(&file->port->mutex); |
545 | ret = -EFAULT; | ||
546 | goto out; | ||
547 | } | ||
548 | 540 | ||
549 | if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) { | 541 | if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !__get_agent(file, id)) { |
550 | ret = -EINVAL; | 542 | ret = -EINVAL; |
551 | goto out; | 543 | goto out; |
552 | } | 544 | } |
553 | 545 | ||
554 | ib_dereg_mr(file->mr[id]); | 546 | agent = file->agent[id]; |
555 | ib_unregister_mad_agent(file->agent[id]); | ||
556 | file->agent[id] = NULL; | 547 | file->agent[id] = NULL; |
557 | 548 | ||
558 | out: | 549 | out: |
559 | up_write(&file->port->mutex); | 550 | up_write(&file->port->mutex); |
551 | |||
552 | if (agent) | ||
553 | ib_unregister_mad_agent(agent); | ||
554 | |||
560 | return ret; | 555 | return ret; |
561 | } | 556 | } |
562 | 557 | ||
@@ -621,23 +616,29 @@ static int ib_umad_close(struct inode *inode, struct file *filp) | |||
621 | struct ib_umad_file *file = filp->private_data; | 616 | struct ib_umad_file *file = filp->private_data; |
622 | struct ib_umad_device *dev = file->port->umad_dev; | 617 | struct ib_umad_device *dev = file->port->umad_dev; |
623 | struct ib_umad_packet *packet, *tmp; | 618 | struct ib_umad_packet *packet, *tmp; |
619 | int already_dead; | ||
624 | int i; | 620 | int i; |
625 | 621 | ||
626 | down_write(&file->port->mutex); | 622 | down_write(&file->port->mutex); |
627 | for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) | 623 | |
628 | if (file->agent[i]) { | 624 | already_dead = file->agents_dead; |
629 | ib_dereg_mr(file->mr[i]); | 625 | file->agents_dead = 1; |
630 | ib_unregister_mad_agent(file->agent[i]); | ||
631 | } | ||
632 | 626 | ||
633 | list_for_each_entry_safe(packet, tmp, &file->recv_list, list) | 627 | list_for_each_entry_safe(packet, tmp, &file->recv_list, list) |
634 | kfree(packet); | 628 | kfree(packet); |
635 | 629 | ||
636 | list_del(&file->port_list); | 630 | list_del(&file->port_list); |
637 | up_write(&file->port->mutex); | ||
638 | 631 | ||
639 | kfree(file); | 632 | downgrade_write(&file->port->mutex); |
633 | |||
634 | if (!already_dead) | ||
635 | for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) | ||
636 | if (file->agent[i]) | ||
637 | ib_unregister_mad_agent(file->agent[i]); | ||
638 | |||
639 | up_read(&file->port->mutex); | ||
640 | 640 | ||
641 | kfree(file); | ||
641 | kref_put(&dev->ref, ib_umad_release_dev); | 642 | kref_put(&dev->ref, ib_umad_release_dev); |
642 | 643 | ||
643 | return 0; | 644 | return 0; |
@@ -801,7 +802,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, | |||
801 | goto err_class; | 802 | goto err_class; |
802 | port->sm_dev->owner = THIS_MODULE; | 803 | port->sm_dev->owner = THIS_MODULE; |
803 | port->sm_dev->ops = &umad_sm_fops; | 804 | port->sm_dev->ops = &umad_sm_fops; |
804 | kobject_set_name(&port->dev->kobj, "issm%d", port->dev_num); | 805 | kobject_set_name(&port->sm_dev->kobj, "issm%d", port->dev_num); |
805 | if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) | 806 | if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) |
806 | goto err_sm_cdev; | 807 | goto err_sm_cdev; |
807 | 808 | ||
@@ -863,14 +864,36 @@ static void ib_umad_kill_port(struct ib_umad_port *port) | |||
863 | 864 | ||
864 | port->ib_dev = NULL; | 865 | port->ib_dev = NULL; |
865 | 866 | ||
866 | list_for_each_entry(file, &port->file_list, port_list) | 867 | /* |
867 | for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) { | 868 | * Now go through the list of files attached to this port and |
868 | if (!file->agent[id]) | 869 | * unregister all of their MAD agents. We need to hold |
869 | continue; | 870 | * port->mutex while doing this to avoid racing with |
870 | ib_dereg_mr(file->mr[id]); | 871 | * ib_umad_close(), but we can't hold the mutex for writing |
871 | ib_unregister_mad_agent(file->agent[id]); | 872 | * while calling ib_unregister_mad_agent(), since that might |
872 | file->agent[id] = NULL; | 873 | * deadlock by calling back into queue_packet(). So we |
873 | } | 874 | * downgrade our lock to a read lock, and then drop and |
875 | * reacquire the write lock for the next iteration. | ||
876 | * | ||
877 | * We do list_del_init() on the file's list_head so that the | ||
878 | * list_del in ib_umad_close() is still OK, even after the | ||
879 | * file is removed from the list. | ||
880 | */ | ||
881 | while (!list_empty(&port->file_list)) { | ||
882 | file = list_entry(port->file_list.next, struct ib_umad_file, | ||
883 | port_list); | ||
884 | |||
885 | file->agents_dead = 1; | ||
886 | list_del_init(&file->port_list); | ||
887 | |||
888 | downgrade_write(&port->mutex); | ||
889 | |||
890 | for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) | ||
891 | if (file->agent[id]) | ||
892 | ib_unregister_mad_agent(file->agent[id]); | ||
893 | |||
894 | up_read(&port->mutex); | ||
895 | down_write(&port->mutex); | ||
896 | } | ||
874 | 897 | ||
875 | up_write(&port->mutex); | 898 | up_write(&port->mutex); |
876 | 899 | ||
@@ -913,7 +936,7 @@ static void ib_umad_add_one(struct ib_device *device) | |||
913 | 936 | ||
914 | err: | 937 | err: |
915 | while (--i >= s) | 938 | while (--i >= s) |
916 | ib_umad_kill_port(&umad_dev->port[i]); | 939 | ib_umad_kill_port(&umad_dev->port[i - s]); |
917 | 940 | ||
918 | kref_put(&umad_dev->ref, ib_umad_release_dev); | 941 | kref_put(&umad_dev->ref, ib_umad_release_dev); |
919 | } | 942 | } |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 63a74151c60b..ed45da892b1c 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -708,7 +708,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, | |||
708 | resp->wc[i].opcode = wc[i].opcode; | 708 | resp->wc[i].opcode = wc[i].opcode; |
709 | resp->wc[i].vendor_err = wc[i].vendor_err; | 709 | resp->wc[i].vendor_err = wc[i].vendor_err; |
710 | resp->wc[i].byte_len = wc[i].byte_len; | 710 | resp->wc[i].byte_len = wc[i].byte_len; |
711 | resp->wc[i].imm_data = wc[i].imm_data; | 711 | resp->wc[i].imm_data = (__u32 __force) wc[i].imm_data; |
712 | resp->wc[i].qp_num = wc[i].qp_num; | 712 | resp->wc[i].qp_num = wc[i].qp_num; |
713 | resp->wc[i].src_qp = wc[i].src_qp; | 713 | resp->wc[i].src_qp = wc[i].src_qp; |
714 | resp->wc[i].wc_flags = wc[i].wc_flags; | 714 | resp->wc[i].wc_flags = wc[i].wc_flags; |
@@ -908,7 +908,12 @@ retry: | |||
908 | if (ret) | 908 | if (ret) |
909 | goto err_destroy; | 909 | goto err_destroy; |
910 | 910 | ||
911 | resp.qp_handle = uobj->uobject.id; | 911 | resp.qp_handle = uobj->uobject.id; |
912 | resp.max_recv_sge = attr.cap.max_recv_sge; | ||
913 | resp.max_send_sge = attr.cap.max_send_sge; | ||
914 | resp.max_recv_wr = attr.cap.max_recv_wr; | ||
915 | resp.max_send_wr = attr.cap.max_send_wr; | ||
916 | resp.max_inline_data = attr.cap.max_inline_data; | ||
912 | 917 | ||
913 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 918 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
914 | &resp, sizeof resp)) { | 919 | &resp, sizeof resp)) { |
@@ -1135,7 +1140,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, | |||
1135 | next->num_sge = user_wr->num_sge; | 1140 | next->num_sge = user_wr->num_sge; |
1136 | next->opcode = user_wr->opcode; | 1141 | next->opcode = user_wr->opcode; |
1137 | next->send_flags = user_wr->send_flags; | 1142 | next->send_flags = user_wr->send_flags; |
1138 | next->imm_data = user_wr->imm_data; | 1143 | next->imm_data = (__be32 __force) user_wr->imm_data; |
1139 | 1144 | ||
1140 | if (qp->qp_type == IB_QPT_UD) { | 1145 | if (qp->qp_type == IB_QPT_UD) { |
1141 | next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr, | 1146 | next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr, |
@@ -1701,7 +1706,6 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, | |||
1701 | } | 1706 | } |
1702 | 1707 | ||
1703 | attr.max_wr = cmd.max_wr; | 1708 | attr.max_wr = cmd.max_wr; |
1704 | attr.max_sge = cmd.max_sge; | ||
1705 | attr.srq_limit = cmd.srq_limit; | 1709 | attr.srq_limit = cmd.srq_limit; |
1706 | 1710 | ||
1707 | ret = ib_modify_srq(srq, &attr, cmd.attr_mask); | 1711 | ret = ib_modify_srq(srq, &attr, cmd.attr_mask); |
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 4186cc888ea5..4c15e112736c 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
@@ -325,16 +325,8 @@ EXPORT_SYMBOL(ib_destroy_cq); | |||
325 | int ib_resize_cq(struct ib_cq *cq, | 325 | int ib_resize_cq(struct ib_cq *cq, |
326 | int cqe) | 326 | int cqe) |
327 | { | 327 | { |
328 | int ret; | 328 | return cq->device->resize_cq ? |
329 | 329 | cq->device->resize_cq(cq, cqe) : -ENOSYS; | |
330 | if (!cq->device->resize_cq) | ||
331 | return -ENOSYS; | ||
332 | |||
333 | ret = cq->device->resize_cq(cq, &cqe); | ||
334 | if (!ret) | ||
335 | cq->cqe = cqe; | ||
336 | |||
337 | return ret; | ||
338 | } | 330 | } |
339 | EXPORT_SYMBOL(ib_resize_cq); | 331 | EXPORT_SYMBOL(ib_resize_cq); |
340 | 332 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c index 25ebab64bc42..c3bec7490f52 100644 --- a/drivers/infiniband/hw/mthca/mthca_catas.c +++ b/drivers/infiniband/hw/mthca/mthca_catas.c | |||
@@ -97,7 +97,7 @@ static void poll_catas(unsigned long dev_ptr) | |||
97 | } | 97 | } |
98 | 98 | ||
99 | spin_lock_irqsave(&catas_lock, flags); | 99 | spin_lock_irqsave(&catas_lock, flags); |
100 | if (dev->catas_err.stop) | 100 | if (!dev->catas_err.stop) |
101 | mod_timer(&dev->catas_err.timer, | 101 | mod_timer(&dev->catas_err.timer, |
102 | jiffies + MTHCA_CATAS_POLL_INTERVAL); | 102 | jiffies + MTHCA_CATAS_POLL_INTERVAL); |
103 | spin_unlock_irqrestore(&catas_lock, flags); | 103 | spin_unlock_irqrestore(&catas_lock, flags); |
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 49f211d55df7..9ed34587fc5c 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -1060,6 +1060,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, | |||
1060 | dev_lim->hca.arbel.resize_srq = field & 1; | 1060 | dev_lim->hca.arbel.resize_srq = field & 1; |
1061 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); | 1061 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); |
1062 | dev_lim->max_sg = min_t(int, field, dev_lim->max_sg); | 1062 | dev_lim->max_sg = min_t(int, field, dev_lim->max_sg); |
1063 | MTHCA_GET(size, outbox, QUERY_DEV_LIM_MAX_DESC_SZ_RQ_OFFSET); | ||
1064 | dev_lim->max_desc_sz = min_t(int, size, dev_lim->max_desc_sz); | ||
1063 | MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET); | 1065 | MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET); |
1064 | dev_lim->mpt_entry_sz = size; | 1066 | dev_lim->mpt_entry_sz = size; |
1065 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET); | 1067 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET); |
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index f98e23555826..4a8adcef2079 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c | |||
@@ -258,7 +258,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, | |||
258 | { | 258 | { |
259 | struct mthca_cq *cq; | 259 | struct mthca_cq *cq; |
260 | struct mthca_cqe *cqe; | 260 | struct mthca_cqe *cqe; |
261 | int prod_index; | 261 | u32 prod_index; |
262 | int nfreed = 0; | 262 | int nfreed = 0; |
263 | 263 | ||
264 | spin_lock_irq(&dev->cq_table.lock); | 264 | spin_lock_irq(&dev->cq_table.lock); |
@@ -293,19 +293,15 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, | |||
293 | * Now sweep backwards through the CQ, removing CQ entries | 293 | * Now sweep backwards through the CQ, removing CQ entries |
294 | * that match our QP by copying older entries on top of them. | 294 | * that match our QP by copying older entries on top of them. |
295 | */ | 295 | */ |
296 | while (prod_index > cq->cons_index) { | 296 | while ((int) --prod_index - (int) cq->cons_index >= 0) { |
297 | cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe); | 297 | cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); |
298 | if (cqe->my_qpn == cpu_to_be32(qpn)) { | 298 | if (cqe->my_qpn == cpu_to_be32(qpn)) { |
299 | if (srq) | 299 | if (srq) |
300 | mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); | 300 | mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); |
301 | ++nfreed; | 301 | ++nfreed; |
302 | } | 302 | } else if (nfreed) |
303 | else if (nfreed) | 303 | memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe), |
304 | memcpy(get_cqe(cq, (prod_index - 1 + nfreed) & | 304 | cqe, MTHCA_CQ_ENTRY_SIZE); |
305 | cq->ibcq.cqe), | ||
306 | cqe, | ||
307 | MTHCA_CQ_ENTRY_SIZE); | ||
308 | --prod_index; | ||
309 | } | 305 | } |
310 | 306 | ||
311 | if (nfreed) { | 307 | if (nfreed) { |
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index e7e5d3b4f004..497ff794ef6a 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h | |||
@@ -131,6 +131,7 @@ struct mthca_limits { | |||
131 | int max_sg; | 131 | int max_sg; |
132 | int num_qps; | 132 | int num_qps; |
133 | int max_wqes; | 133 | int max_wqes; |
134 | int max_desc_sz; | ||
134 | int max_qp_init_rdma; | 135 | int max_qp_init_rdma; |
135 | int reserved_qps; | 136 | int reserved_qps; |
136 | int num_srqs; | 137 | int num_srqs; |
@@ -154,6 +155,7 @@ struct mthca_limits { | |||
154 | int reserved_mcgs; | 155 | int reserved_mcgs; |
155 | int num_pds; | 156 | int num_pds; |
156 | int reserved_pds; | 157 | int reserved_pds; |
158 | u32 page_size_cap; | ||
157 | u32 flags; | 159 | u32 flags; |
158 | u8 port_width_cap; | 160 | u8 port_width_cap; |
159 | }; | 161 | }; |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 45c6328e780c..147f248a8073 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
@@ -168,6 +168,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim | |||
168 | mdev->limits.max_srq_wqes = dev_lim->max_srq_sz; | 168 | mdev->limits.max_srq_wqes = dev_lim->max_srq_sz; |
169 | mdev->limits.reserved_srqs = dev_lim->reserved_srqs; | 169 | mdev->limits.reserved_srqs = dev_lim->reserved_srqs; |
170 | mdev->limits.reserved_eecs = dev_lim->reserved_eecs; | 170 | mdev->limits.reserved_eecs = dev_lim->reserved_eecs; |
171 | mdev->limits.max_desc_sz = dev_lim->max_desc_sz; | ||
171 | /* | 172 | /* |
172 | * Subtract 1 from the limit because we need to allocate a | 173 | * Subtract 1 from the limit because we need to allocate a |
173 | * spare CQE so the HCA HW can tell the difference between an | 174 | * spare CQE so the HCA HW can tell the difference between an |
@@ -181,6 +182,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim | |||
181 | mdev->limits.reserved_uars = dev_lim->reserved_uars; | 182 | mdev->limits.reserved_uars = dev_lim->reserved_uars; |
182 | mdev->limits.reserved_pds = dev_lim->reserved_pds; | 183 | mdev->limits.reserved_pds = dev_lim->reserved_pds; |
183 | mdev->limits.port_width_cap = dev_lim->max_port_width; | 184 | mdev->limits.port_width_cap = dev_lim->max_port_width; |
185 | mdev->limits.page_size_cap = ~(u32) (dev_lim->min_page_sz - 1); | ||
184 | mdev->limits.flags = dev_lim->flags; | 186 | mdev->limits.flags = dev_lim->flags; |
185 | 187 | ||
186 | /* IB_DEVICE_RESIZE_MAX_WR not supported by driver. | 188 | /* IB_DEVICE_RESIZE_MAX_WR not supported by driver. |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 6b0166668269..4cc7e2846df1 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
@@ -90,6 +90,7 @@ static int mthca_query_device(struct ib_device *ibdev, | |||
90 | memcpy(&props->node_guid, out_mad->data + 12, 8); | 90 | memcpy(&props->node_guid, out_mad->data + 12, 8); |
91 | 91 | ||
92 | props->max_mr_size = ~0ull; | 92 | props->max_mr_size = ~0ull; |
93 | props->page_size_cap = mdev->limits.page_size_cap; | ||
93 | props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps; | 94 | props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps; |
94 | props->max_qp_wr = mdev->limits.max_wqes; | 95 | props->max_qp_wr = mdev->limits.max_wqes; |
95 | props->max_sge = mdev->limits.max_sg; | 96 | props->max_sge = mdev->limits.max_sg; |
@@ -615,11 +616,11 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd, | |||
615 | return ERR_PTR(err); | 616 | return ERR_PTR(err); |
616 | } | 617 | } |
617 | 618 | ||
618 | init_attr->cap.max_inline_data = 0; | ||
619 | init_attr->cap.max_send_wr = qp->sq.max; | 619 | init_attr->cap.max_send_wr = qp->sq.max; |
620 | init_attr->cap.max_recv_wr = qp->rq.max; | 620 | init_attr->cap.max_recv_wr = qp->rq.max; |
621 | init_attr->cap.max_send_sge = qp->sq.max_gs; | 621 | init_attr->cap.max_send_sge = qp->sq.max_gs; |
622 | init_attr->cap.max_recv_sge = qp->rq.max_gs; | 622 | init_attr->cap.max_recv_sge = qp->rq.max_gs; |
623 | init_attr->cap.max_inline_data = qp->max_inline_data; | ||
623 | 624 | ||
624 | return &qp->ibqp; | 625 | return &qp->ibqp; |
625 | } | 626 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h index bcd4b01a339c..1e73947b4702 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.h +++ b/drivers/infiniband/hw/mthca/mthca_provider.h | |||
@@ -251,6 +251,7 @@ struct mthca_qp { | |||
251 | struct mthca_wq sq; | 251 | struct mthca_wq sq; |
252 | enum ib_sig_type sq_policy; | 252 | enum ib_sig_type sq_policy; |
253 | int send_wqe_offset; | 253 | int send_wqe_offset; |
254 | int max_inline_data; | ||
254 | 255 | ||
255 | u64 *wrid; | 256 | u64 *wrid; |
256 | union mthca_buf queue; | 257 | union mthca_buf queue; |
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 8852ea477c21..760c418d5bc9 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -885,6 +885,48 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
885 | return err; | 885 | return err; |
886 | } | 886 | } |
887 | 887 | ||
888 | static void mthca_adjust_qp_caps(struct mthca_dev *dev, | ||
889 | struct mthca_pd *pd, | ||
890 | struct mthca_qp *qp) | ||
891 | { | ||
892 | int max_data_size; | ||
893 | |||
894 | /* | ||
895 | * Calculate the maximum size of WQE s/g segments, excluding | ||
896 | * the next segment and other non-data segments. | ||
897 | */ | ||
898 | max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) - | ||
899 | sizeof (struct mthca_next_seg); | ||
900 | |||
901 | switch (qp->transport) { | ||
902 | case MLX: | ||
903 | max_data_size -= 2 * sizeof (struct mthca_data_seg); | ||
904 | break; | ||
905 | |||
906 | case UD: | ||
907 | if (mthca_is_memfree(dev)) | ||
908 | max_data_size -= sizeof (struct mthca_arbel_ud_seg); | ||
909 | else | ||
910 | max_data_size -= sizeof (struct mthca_tavor_ud_seg); | ||
911 | break; | ||
912 | |||
913 | default: | ||
914 | max_data_size -= sizeof (struct mthca_raddr_seg); | ||
915 | break; | ||
916 | } | ||
917 | |||
918 | /* We don't support inline data for kernel QPs (yet). */ | ||
919 | if (!pd->ibpd.uobject) | ||
920 | qp->max_inline_data = 0; | ||
921 | else | ||
922 | qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE; | ||
923 | |||
924 | qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg); | ||
925 | qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) - | ||
926 | sizeof (struct mthca_next_seg)) / | ||
927 | sizeof (struct mthca_data_seg); | ||
928 | } | ||
929 | |||
888 | /* | 930 | /* |
889 | * Allocate and register buffer for WQEs. qp->rq.max, sq.max, | 931 | * Allocate and register buffer for WQEs. qp->rq.max, sq.max, |
890 | * rq.max_gs and sq.max_gs must all be assigned. | 932 | * rq.max_gs and sq.max_gs must all be assigned. |
@@ -902,27 +944,53 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev, | |||
902 | size = sizeof (struct mthca_next_seg) + | 944 | size = sizeof (struct mthca_next_seg) + |
903 | qp->rq.max_gs * sizeof (struct mthca_data_seg); | 945 | qp->rq.max_gs * sizeof (struct mthca_data_seg); |
904 | 946 | ||
947 | if (size > dev->limits.max_desc_sz) | ||
948 | return -EINVAL; | ||
949 | |||
905 | for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size; | 950 | for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size; |
906 | qp->rq.wqe_shift++) | 951 | qp->rq.wqe_shift++) |
907 | ; /* nothing */ | 952 | ; /* nothing */ |
908 | 953 | ||
909 | size = sizeof (struct mthca_next_seg) + | 954 | size = qp->sq.max_gs * sizeof (struct mthca_data_seg); |
910 | qp->sq.max_gs * sizeof (struct mthca_data_seg); | ||
911 | switch (qp->transport) { | 955 | switch (qp->transport) { |
912 | case MLX: | 956 | case MLX: |
913 | size += 2 * sizeof (struct mthca_data_seg); | 957 | size += 2 * sizeof (struct mthca_data_seg); |
914 | break; | 958 | break; |
959 | |||
915 | case UD: | 960 | case UD: |
916 | if (mthca_is_memfree(dev)) | 961 | size += mthca_is_memfree(dev) ? |
917 | size += sizeof (struct mthca_arbel_ud_seg); | 962 | sizeof (struct mthca_arbel_ud_seg) : |
918 | else | 963 | sizeof (struct mthca_tavor_ud_seg); |
919 | size += sizeof (struct mthca_tavor_ud_seg); | ||
920 | break; | 964 | break; |
965 | |||
966 | case UC: | ||
967 | size += sizeof (struct mthca_raddr_seg); | ||
968 | break; | ||
969 | |||
970 | case RC: | ||
971 | size += sizeof (struct mthca_raddr_seg); | ||
972 | /* | ||
973 | * An atomic op will require an atomic segment, a | ||
974 | * remote address segment and one scatter entry. | ||
975 | */ | ||
976 | size = max_t(int, size, | ||
977 | sizeof (struct mthca_atomic_seg) + | ||
978 | sizeof (struct mthca_raddr_seg) + | ||
979 | sizeof (struct mthca_data_seg)); | ||
980 | break; | ||
981 | |||
921 | default: | 982 | default: |
922 | /* bind seg is as big as atomic + raddr segs */ | 983 | break; |
923 | size += sizeof (struct mthca_bind_seg); | ||
924 | } | 984 | } |
925 | 985 | ||
986 | /* Make sure that we have enough space for a bind request */ | ||
987 | size = max_t(int, size, sizeof (struct mthca_bind_seg)); | ||
988 | |||
989 | size += sizeof (struct mthca_next_seg); | ||
990 | |||
991 | if (size > dev->limits.max_desc_sz) | ||
992 | return -EINVAL; | ||
993 | |||
926 | for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size; | 994 | for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size; |
927 | qp->sq.wqe_shift++) | 995 | qp->sq.wqe_shift++) |
928 | ; /* nothing */ | 996 | ; /* nothing */ |
@@ -1066,6 +1134,8 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, | |||
1066 | return ret; | 1134 | return ret; |
1067 | } | 1135 | } |
1068 | 1136 | ||
1137 | mthca_adjust_qp_caps(dev, pd, qp); | ||
1138 | |||
1069 | /* | 1139 | /* |
1070 | * If this is a userspace QP, we're done now. The doorbells | 1140 | * If this is a userspace QP, we're done now. The doorbells |
1071 | * will be allocated and buffers will be initialized in | 1141 | * will be allocated and buffers will be initialized in |
@@ -1486,8 +1556,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1486 | } | 1556 | } |
1487 | 1557 | ||
1488 | wqe += sizeof (struct mthca_atomic_seg); | 1558 | wqe += sizeof (struct mthca_atomic_seg); |
1489 | size += sizeof (struct mthca_raddr_seg) / 16 + | 1559 | size += (sizeof (struct mthca_raddr_seg) + |
1490 | sizeof (struct mthca_atomic_seg); | 1560 | sizeof (struct mthca_atomic_seg)) / 16; |
1491 | break; | 1561 | break; |
1492 | 1562 | ||
1493 | case IB_WR_RDMA_WRITE: | 1563 | case IB_WR_RDMA_WRITE: |
@@ -1637,6 +1707,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
1637 | { | 1707 | { |
1638 | struct mthca_dev *dev = to_mdev(ibqp->device); | 1708 | struct mthca_dev *dev = to_mdev(ibqp->device); |
1639 | struct mthca_qp *qp = to_mqp(ibqp); | 1709 | struct mthca_qp *qp = to_mqp(ibqp); |
1710 | __be32 doorbell[2]; | ||
1640 | unsigned long flags; | 1711 | unsigned long flags; |
1641 | int err = 0; | 1712 | int err = 0; |
1642 | int nreq; | 1713 | int nreq; |
@@ -1654,6 +1725,22 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
1654 | ind = qp->rq.next_ind; | 1725 | ind = qp->rq.next_ind; |
1655 | 1726 | ||
1656 | for (nreq = 0; wr; ++nreq, wr = wr->next) { | 1727 | for (nreq = 0; wr; ++nreq, wr = wr->next) { |
1728 | if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) { | ||
1729 | nreq = 0; | ||
1730 | |||
1731 | doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); | ||
1732 | doorbell[1] = cpu_to_be32(qp->qpn << 8); | ||
1733 | |||
1734 | wmb(); | ||
1735 | |||
1736 | mthca_write64(doorbell, | ||
1737 | dev->kar + MTHCA_RECEIVE_DOORBELL, | ||
1738 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); | ||
1739 | |||
1740 | qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB; | ||
1741 | size0 = 0; | ||
1742 | } | ||
1743 | |||
1657 | if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { | 1744 | if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { |
1658 | mthca_err(dev, "RQ %06x full (%u head, %u tail," | 1745 | mthca_err(dev, "RQ %06x full (%u head, %u tail," |
1659 | " %d max, %d nreq)\n", qp->qpn, | 1746 | " %d max, %d nreq)\n", qp->qpn, |
@@ -1711,8 +1798,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
1711 | 1798 | ||
1712 | out: | 1799 | out: |
1713 | if (likely(nreq)) { | 1800 | if (likely(nreq)) { |
1714 | __be32 doorbell[2]; | ||
1715 | |||
1716 | doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); | 1801 | doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); |
1717 | doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq); | 1802 | doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq); |
1718 | 1803 | ||
@@ -1806,8 +1891,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1806 | } | 1891 | } |
1807 | 1892 | ||
1808 | wqe += sizeof (struct mthca_atomic_seg); | 1893 | wqe += sizeof (struct mthca_atomic_seg); |
1809 | size += sizeof (struct mthca_raddr_seg) / 16 + | 1894 | size += (sizeof (struct mthca_raddr_seg) + |
1810 | sizeof (struct mthca_atomic_seg); | 1895 | sizeof (struct mthca_atomic_seg)) / 16; |
1811 | break; | 1896 | break; |
1812 | 1897 | ||
1813 | case IB_WR_RDMA_READ: | 1898 | case IB_WR_RDMA_READ: |
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index 26d5161fde07..f7d234295efe 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c | |||
@@ -417,6 +417,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | |||
417 | { | 417 | { |
418 | struct mthca_dev *dev = to_mdev(ibsrq->device); | 418 | struct mthca_dev *dev = to_mdev(ibsrq->device); |
419 | struct mthca_srq *srq = to_msrq(ibsrq); | 419 | struct mthca_srq *srq = to_msrq(ibsrq); |
420 | __be32 doorbell[2]; | ||
420 | unsigned long flags; | 421 | unsigned long flags; |
421 | int err = 0; | 422 | int err = 0; |
422 | int first_ind; | 423 | int first_ind; |
@@ -432,6 +433,25 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | |||
432 | first_ind = srq->first_free; | 433 | first_ind = srq->first_free; |
433 | 434 | ||
434 | for (nreq = 0; wr; ++nreq, wr = wr->next) { | 435 | for (nreq = 0; wr; ++nreq, wr = wr->next) { |
436 | if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) { | ||
437 | nreq = 0; | ||
438 | |||
439 | doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift); | ||
440 | doorbell[1] = cpu_to_be32(srq->srqn << 8); | ||
441 | |||
442 | /* | ||
443 | * Make sure that descriptors are written | ||
444 | * before doorbell is rung. | ||
445 | */ | ||
446 | wmb(); | ||
447 | |||
448 | mthca_write64(doorbell, | ||
449 | dev->kar + MTHCA_RECEIVE_DOORBELL, | ||
450 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); | ||
451 | |||
452 | first_ind = srq->first_free; | ||
453 | } | ||
454 | |||
435 | ind = srq->first_free; | 455 | ind = srq->first_free; |
436 | 456 | ||
437 | if (ind < 0) { | 457 | if (ind < 0) { |
@@ -494,8 +514,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | |||
494 | } | 514 | } |
495 | 515 | ||
496 | if (likely(nreq)) { | 516 | if (likely(nreq)) { |
497 | __be32 doorbell[2]; | ||
498 | |||
499 | doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift); | 517 | doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift); |
500 | doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq); | 518 | doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq); |
501 | 519 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h index 1f4c0ff28f79..73f1c0b9021e 100644 --- a/drivers/infiniband/hw/mthca/mthca_wqe.h +++ b/drivers/infiniband/hw/mthca/mthca_wqe.h | |||
@@ -49,7 +49,8 @@ enum { | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | enum { | 51 | enum { |
52 | MTHCA_INVAL_LKEY = 0x100 | 52 | MTHCA_INVAL_LKEY = 0x100, |
53 | MTHCA_TAVOR_MAX_WQES_PER_RECV_DB = 256 | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | struct mthca_next_seg { | 56 | struct mthca_next_seg { |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 0095acc0fbbe..9923a15a9996 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -179,6 +179,7 @@ struct ipoib_dev_priv { | |||
179 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | 179 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG |
180 | struct list_head fs_list; | 180 | struct list_head fs_list; |
181 | struct dentry *mcg_dentry; | 181 | struct dentry *mcg_dentry; |
182 | struct dentry *path_dentry; | ||
182 | #endif | 183 | #endif |
183 | }; | 184 | }; |
184 | 185 | ||
@@ -270,7 +271,6 @@ void ipoib_mcast_dev_flush(struct net_device *dev); | |||
270 | 271 | ||
271 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | 272 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG |
272 | struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev); | 273 | struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev); |
273 | void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter); | ||
274 | int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter); | 274 | int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter); |
275 | void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter, | 275 | void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter, |
276 | union ib_gid *gid, | 276 | union ib_gid *gid, |
@@ -278,6 +278,11 @@ void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter, | |||
278 | unsigned int *queuelen, | 278 | unsigned int *queuelen, |
279 | unsigned int *complete, | 279 | unsigned int *complete, |
280 | unsigned int *send_only); | 280 | unsigned int *send_only); |
281 | |||
282 | struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev); | ||
283 | int ipoib_path_iter_next(struct ipoib_path_iter *iter); | ||
284 | void ipoib_path_iter_read(struct ipoib_path_iter *iter, | ||
285 | struct ipoib_path *path); | ||
281 | #endif | 286 | #endif |
282 | 287 | ||
283 | int ipoib_mcast_attach(struct net_device *dev, u16 mlid, | 288 | int ipoib_mcast_attach(struct net_device *dev, u16 mlid, |
@@ -299,13 +304,13 @@ void ipoib_pkey_poll(void *dev); | |||
299 | int ipoib_pkey_dev_delay_open(struct net_device *dev); | 304 | int ipoib_pkey_dev_delay_open(struct net_device *dev); |
300 | 305 | ||
301 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | 306 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG |
302 | int ipoib_create_debug_file(struct net_device *dev); | 307 | void ipoib_create_debug_files(struct net_device *dev); |
303 | void ipoib_delete_debug_file(struct net_device *dev); | 308 | void ipoib_delete_debug_files(struct net_device *dev); |
304 | int ipoib_register_debugfs(void); | 309 | int ipoib_register_debugfs(void); |
305 | void ipoib_unregister_debugfs(void); | 310 | void ipoib_unregister_debugfs(void); |
306 | #else | 311 | #else |
307 | static inline int ipoib_create_debug_file(struct net_device *dev) { return 0; } | 312 | static inline void ipoib_create_debug_files(struct net_device *dev) { } |
308 | static inline void ipoib_delete_debug_file(struct net_device *dev) { } | 313 | static inline void ipoib_delete_debug_files(struct net_device *dev) { } |
309 | static inline int ipoib_register_debugfs(void) { return 0; } | 314 | static inline int ipoib_register_debugfs(void) { return 0; } |
310 | static inline void ipoib_unregister_debugfs(void) { } | 315 | static inline void ipoib_unregister_debugfs(void) { } |
311 | #endif | 316 | #endif |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index 38b150f775e7..685258e34034 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c | |||
@@ -43,6 +43,18 @@ struct file_operations; | |||
43 | 43 | ||
44 | static struct dentry *ipoib_root; | 44 | static struct dentry *ipoib_root; |
45 | 45 | ||
46 | static void format_gid(union ib_gid *gid, char *buf) | ||
47 | { | ||
48 | int i, n; | ||
49 | |||
50 | for (n = 0, i = 0; i < 8; ++i) { | ||
51 | n += sprintf(buf + n, "%x", | ||
52 | be16_to_cpu(((__be16 *) gid->raw)[i])); | ||
53 | if (i < 7) | ||
54 | buf[n++] = ':'; | ||
55 | } | ||
56 | } | ||
57 | |||
46 | static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos) | 58 | static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos) |
47 | { | 59 | { |
48 | struct ipoib_mcast_iter *iter; | 60 | struct ipoib_mcast_iter *iter; |
@@ -54,7 +66,7 @@ static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos) | |||
54 | 66 | ||
55 | while (n--) { | 67 | while (n--) { |
56 | if (ipoib_mcast_iter_next(iter)) { | 68 | if (ipoib_mcast_iter_next(iter)) { |
57 | ipoib_mcast_iter_free(iter); | 69 | kfree(iter); |
58 | return NULL; | 70 | return NULL; |
59 | } | 71 | } |
60 | } | 72 | } |
@@ -70,7 +82,7 @@ static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr, | |||
70 | (*pos)++; | 82 | (*pos)++; |
71 | 83 | ||
72 | if (ipoib_mcast_iter_next(iter)) { | 84 | if (ipoib_mcast_iter_next(iter)) { |
73 | ipoib_mcast_iter_free(iter); | 85 | kfree(iter); |
74 | return NULL; | 86 | return NULL; |
75 | } | 87 | } |
76 | 88 | ||
@@ -87,32 +99,32 @@ static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr) | |||
87 | struct ipoib_mcast_iter *iter = iter_ptr; | 99 | struct ipoib_mcast_iter *iter = iter_ptr; |
88 | char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; | 100 | char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; |
89 | union ib_gid mgid; | 101 | union ib_gid mgid; |
90 | int i, n; | ||
91 | unsigned long created; | 102 | unsigned long created; |
92 | unsigned int queuelen, complete, send_only; | 103 | unsigned int queuelen, complete, send_only; |
93 | 104 | ||
94 | if (iter) { | 105 | if (!iter) |
95 | ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen, | 106 | return 0; |
96 | &complete, &send_only); | ||
97 | 107 | ||
98 | for (n = 0, i = 0; i < sizeof mgid / 2; ++i) { | 108 | ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen, |
99 | n += sprintf(gid_buf + n, "%x", | 109 | &complete, &send_only); |
100 | be16_to_cpu(((__be16 *) mgid.raw)[i])); | ||
101 | if (i < sizeof mgid / 2 - 1) | ||
102 | gid_buf[n++] = ':'; | ||
103 | } | ||
104 | } | ||
105 | 110 | ||
106 | seq_printf(file, "GID: %*s", -(1 + (int) sizeof gid_buf), gid_buf); | 111 | format_gid(&mgid, gid_buf); |
107 | 112 | ||
108 | seq_printf(file, | 113 | seq_printf(file, |
109 | " created: %10ld queuelen: %4d complete: %d send_only: %d\n", | 114 | "GID: %s\n" |
110 | created, queuelen, complete, send_only); | 115 | " created: %10ld\n" |
116 | " queuelen: %9d\n" | ||
117 | " complete: %9s\n" | ||
118 | " send_only: %8s\n" | ||
119 | "\n", | ||
120 | gid_buf, created, queuelen, | ||
121 | complete ? "yes" : "no", | ||
122 | send_only ? "yes" : "no"); | ||
111 | 123 | ||
112 | return 0; | 124 | return 0; |
113 | } | 125 | } |
114 | 126 | ||
115 | static struct seq_operations ipoib_seq_ops = { | 127 | static struct seq_operations ipoib_mcg_seq_ops = { |
116 | .start = ipoib_mcg_seq_start, | 128 | .start = ipoib_mcg_seq_start, |
117 | .next = ipoib_mcg_seq_next, | 129 | .next = ipoib_mcg_seq_next, |
118 | .stop = ipoib_mcg_seq_stop, | 130 | .stop = ipoib_mcg_seq_stop, |
@@ -124,7 +136,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file) | |||
124 | struct seq_file *seq; | 136 | struct seq_file *seq; |
125 | int ret; | 137 | int ret; |
126 | 138 | ||
127 | ret = seq_open(file, &ipoib_seq_ops); | 139 | ret = seq_open(file, &ipoib_mcg_seq_ops); |
128 | if (ret) | 140 | if (ret) |
129 | return ret; | 141 | return ret; |
130 | 142 | ||
@@ -134,7 +146,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file) | |||
134 | return 0; | 146 | return 0; |
135 | } | 147 | } |
136 | 148 | ||
137 | static struct file_operations ipoib_fops = { | 149 | static struct file_operations ipoib_mcg_fops = { |
138 | .owner = THIS_MODULE, | 150 | .owner = THIS_MODULE, |
139 | .open = ipoib_mcg_open, | 151 | .open = ipoib_mcg_open, |
140 | .read = seq_read, | 152 | .read = seq_read, |
@@ -142,25 +154,138 @@ static struct file_operations ipoib_fops = { | |||
142 | .release = seq_release | 154 | .release = seq_release |
143 | }; | 155 | }; |
144 | 156 | ||
145 | int ipoib_create_debug_file(struct net_device *dev) | 157 | static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos) |
158 | { | ||
159 | struct ipoib_path_iter *iter; | ||
160 | loff_t n = *pos; | ||
161 | |||
162 | iter = ipoib_path_iter_init(file->private); | ||
163 | if (!iter) | ||
164 | return NULL; | ||
165 | |||
166 | while (n--) { | ||
167 | if (ipoib_path_iter_next(iter)) { | ||
168 | kfree(iter); | ||
169 | return NULL; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | return iter; | ||
174 | } | ||
175 | |||
176 | static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr, | ||
177 | loff_t *pos) | ||
178 | { | ||
179 | struct ipoib_path_iter *iter = iter_ptr; | ||
180 | |||
181 | (*pos)++; | ||
182 | |||
183 | if (ipoib_path_iter_next(iter)) { | ||
184 | kfree(iter); | ||
185 | return NULL; | ||
186 | } | ||
187 | |||
188 | return iter; | ||
189 | } | ||
190 | |||
191 | static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr) | ||
192 | { | ||
193 | /* nothing for now */ | ||
194 | } | ||
195 | |||
196 | static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr) | ||
197 | { | ||
198 | struct ipoib_path_iter *iter = iter_ptr; | ||
199 | char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; | ||
200 | struct ipoib_path path; | ||
201 | int rate; | ||
202 | |||
203 | if (!iter) | ||
204 | return 0; | ||
205 | |||
206 | ipoib_path_iter_read(iter, &path); | ||
207 | |||
208 | format_gid(&path.pathrec.dgid, gid_buf); | ||
209 | |||
210 | seq_printf(file, | ||
211 | "GID: %s\n" | ||
212 | " complete: %6s\n", | ||
213 | gid_buf, path.pathrec.dlid ? "yes" : "no"); | ||
214 | |||
215 | if (path.pathrec.dlid) { | ||
216 | rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25; | ||
217 | |||
218 | seq_printf(file, | ||
219 | " DLID: 0x%04x\n" | ||
220 | " SL: %12d\n" | ||
221 | " rate: %*d%s Gb/sec\n", | ||
222 | be16_to_cpu(path.pathrec.dlid), | ||
223 | path.pathrec.sl, | ||
224 | 10 - ((rate % 10) ? 2 : 0), | ||
225 | rate / 10, rate % 10 ? ".5" : ""); | ||
226 | } | ||
227 | |||
228 | seq_putc(file, '\n'); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static struct seq_operations ipoib_path_seq_ops = { | ||
234 | .start = ipoib_path_seq_start, | ||
235 | .next = ipoib_path_seq_next, | ||
236 | .stop = ipoib_path_seq_stop, | ||
237 | .show = ipoib_path_seq_show, | ||
238 | }; | ||
239 | |||
240 | static int ipoib_path_open(struct inode *inode, struct file *file) | ||
241 | { | ||
242 | struct seq_file *seq; | ||
243 | int ret; | ||
244 | |||
245 | ret = seq_open(file, &ipoib_path_seq_ops); | ||
246 | if (ret) | ||
247 | return ret; | ||
248 | |||
249 | seq = file->private_data; | ||
250 | seq->private = inode->u.generic_ip; | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static struct file_operations ipoib_path_fops = { | ||
256 | .owner = THIS_MODULE, | ||
257 | .open = ipoib_path_open, | ||
258 | .read = seq_read, | ||
259 | .llseek = seq_lseek, | ||
260 | .release = seq_release | ||
261 | }; | ||
262 | |||
263 | void ipoib_create_debug_files(struct net_device *dev) | ||
146 | { | 264 | { |
147 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 265 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
148 | char name[IFNAMSIZ + sizeof "_mcg"]; | 266 | char name[IFNAMSIZ + sizeof "_path"]; |
149 | 267 | ||
150 | snprintf(name, sizeof name, "%s_mcg", dev->name); | 268 | snprintf(name, sizeof name, "%s_mcg", dev->name); |
151 | |||
152 | priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, | 269 | priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, |
153 | ipoib_root, dev, &ipoib_fops); | 270 | ipoib_root, dev, &ipoib_mcg_fops); |
154 | 271 | if (!priv->mcg_dentry) | |
155 | return priv->mcg_dentry ? 0 : -ENOMEM; | 272 | ipoib_warn(priv, "failed to create mcg debug file\n"); |
273 | |||
274 | snprintf(name, sizeof name, "%s_path", dev->name); | ||
275 | priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, | ||
276 | ipoib_root, dev, &ipoib_path_fops); | ||
277 | if (!priv->path_dentry) | ||
278 | ipoib_warn(priv, "failed to create path debug file\n"); | ||
156 | } | 279 | } |
157 | 280 | ||
158 | void ipoib_delete_debug_file(struct net_device *dev) | 281 | void ipoib_delete_debug_files(struct net_device *dev) |
159 | { | 282 | { |
160 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 283 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
161 | 284 | ||
162 | if (priv->mcg_dentry) | 285 | if (priv->mcg_dentry) |
163 | debugfs_remove(priv->mcg_dentry); | 286 | debugfs_remove(priv->mcg_dentry); |
287 | if (priv->path_dentry) | ||
288 | debugfs_remove(priv->path_dentry); | ||
164 | } | 289 | } |
165 | 290 | ||
166 | int ipoib_register_debugfs(void) | 291 | int ipoib_register_debugfs(void) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index ce0296273e76..2fa30751f362 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -58,6 +58,11 @@ module_param_named(debug_level, ipoib_debug_level, int, 0644); | |||
58 | MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); | 58 | MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | struct ipoib_path_iter { | ||
62 | struct net_device *dev; | ||
63 | struct ipoib_path path; | ||
64 | }; | ||
65 | |||
61 | static const u8 ipv4_bcast_addr[] = { | 66 | static const u8 ipv4_bcast_addr[] = { |
62 | 0x00, 0xff, 0xff, 0xff, | 67 | 0x00, 0xff, 0xff, 0xff, |
63 | 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00, | 68 | 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00, |
@@ -250,6 +255,64 @@ static void path_free(struct net_device *dev, struct ipoib_path *path) | |||
250 | kfree(path); | 255 | kfree(path); |
251 | } | 256 | } |
252 | 257 | ||
258 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | ||
259 | |||
260 | struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev) | ||
261 | { | ||
262 | struct ipoib_path_iter *iter; | ||
263 | |||
264 | iter = kmalloc(sizeof *iter, GFP_KERNEL); | ||
265 | if (!iter) | ||
266 | return NULL; | ||
267 | |||
268 | iter->dev = dev; | ||
269 | memset(iter->path.pathrec.dgid.raw, 0, 16); | ||
270 | |||
271 | if (ipoib_path_iter_next(iter)) { | ||
272 | kfree(iter); | ||
273 | return NULL; | ||
274 | } | ||
275 | |||
276 | return iter; | ||
277 | } | ||
278 | |||
279 | int ipoib_path_iter_next(struct ipoib_path_iter *iter) | ||
280 | { | ||
281 | struct ipoib_dev_priv *priv = netdev_priv(iter->dev); | ||
282 | struct rb_node *n; | ||
283 | struct ipoib_path *path; | ||
284 | int ret = 1; | ||
285 | |||
286 | spin_lock_irq(&priv->lock); | ||
287 | |||
288 | n = rb_first(&priv->path_tree); | ||
289 | |||
290 | while (n) { | ||
291 | path = rb_entry(n, struct ipoib_path, rb_node); | ||
292 | |||
293 | if (memcmp(iter->path.pathrec.dgid.raw, path->pathrec.dgid.raw, | ||
294 | sizeof (union ib_gid)) < 0) { | ||
295 | iter->path = *path; | ||
296 | ret = 0; | ||
297 | break; | ||
298 | } | ||
299 | |||
300 | n = rb_next(n); | ||
301 | } | ||
302 | |||
303 | spin_unlock_irq(&priv->lock); | ||
304 | |||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | void ipoib_path_iter_read(struct ipoib_path_iter *iter, | ||
309 | struct ipoib_path *path) | ||
310 | { | ||
311 | *path = iter->path; | ||
312 | } | ||
313 | |||
314 | #endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */ | ||
315 | |||
253 | void ipoib_flush_paths(struct net_device *dev) | 316 | void ipoib_flush_paths(struct net_device *dev) |
254 | { | 317 | { |
255 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 318 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
@@ -763,7 +826,7 @@ void ipoib_dev_cleanup(struct net_device *dev) | |||
763 | { | 826 | { |
764 | struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv; | 827 | struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv; |
765 | 828 | ||
766 | ipoib_delete_debug_file(dev); | 829 | ipoib_delete_debug_files(dev); |
767 | 830 | ||
768 | /* Delete any child interfaces first */ | 831 | /* Delete any child interfaces first */ |
769 | list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) { | 832 | list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) { |
@@ -972,8 +1035,7 @@ static struct net_device *ipoib_add_port(const char *format, | |||
972 | goto register_failed; | 1035 | goto register_failed; |
973 | } | 1036 | } |
974 | 1037 | ||
975 | if (ipoib_create_debug_file(priv->dev)) | 1038 | ipoib_create_debug_files(priv->dev); |
976 | goto debug_failed; | ||
977 | 1039 | ||
978 | if (ipoib_add_pkey_attr(priv->dev)) | 1040 | if (ipoib_add_pkey_attr(priv->dev)) |
979 | goto sysfs_failed; | 1041 | goto sysfs_failed; |
@@ -987,9 +1049,7 @@ static struct net_device *ipoib_add_port(const char *format, | |||
987 | return priv->dev; | 1049 | return priv->dev; |
988 | 1050 | ||
989 | sysfs_failed: | 1051 | sysfs_failed: |
990 | ipoib_delete_debug_file(priv->dev); | 1052 | ipoib_delete_debug_files(priv->dev); |
991 | |||
992 | debug_failed: | ||
993 | unregister_netdev(priv->dev); | 1053 | unregister_netdev(priv->dev); |
994 | 1054 | ||
995 | register_failed: | 1055 | register_failed: |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 3ecf78a9493a..c33ed87f9dff 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -120,12 +120,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) | |||
120 | if (mcast->ah) | 120 | if (mcast->ah) |
121 | ipoib_put_ah(mcast->ah); | 121 | ipoib_put_ah(mcast->ah); |
122 | 122 | ||
123 | while (!skb_queue_empty(&mcast->pkt_queue)) { | 123 | while (!skb_queue_empty(&mcast->pkt_queue)) |
124 | struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); | 124 | dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue)); |
125 | |||
126 | skb->dev = dev; | ||
127 | dev_kfree_skb_any(skb); | ||
128 | } | ||
129 | 125 | ||
130 | kfree(mcast); | 126 | kfree(mcast); |
131 | } | 127 | } |
@@ -317,13 +313,8 @@ ipoib_mcast_sendonly_join_complete(int status, | |||
317 | IPOIB_GID_ARG(mcast->mcmember.mgid), status); | 313 | IPOIB_GID_ARG(mcast->mcmember.mgid), status); |
318 | 314 | ||
319 | /* Flush out any queued packets */ | 315 | /* Flush out any queued packets */ |
320 | while (!skb_queue_empty(&mcast->pkt_queue)) { | 316 | while (!skb_queue_empty(&mcast->pkt_queue)) |
321 | struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); | 317 | dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue)); |
322 | |||
323 | skb->dev = dev; | ||
324 | |||
325 | dev_kfree_skb_any(skb); | ||
326 | } | ||
327 | 318 | ||
328 | /* Clear the busy flag so we try again */ | 319 | /* Clear the busy flag so we try again */ |
329 | clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); | 320 | clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); |
@@ -928,21 +919,16 @@ struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev) | |||
928 | return NULL; | 919 | return NULL; |
929 | 920 | ||
930 | iter->dev = dev; | 921 | iter->dev = dev; |
931 | memset(iter->mgid.raw, 0, sizeof iter->mgid); | 922 | memset(iter->mgid.raw, 0, 16); |
932 | 923 | ||
933 | if (ipoib_mcast_iter_next(iter)) { | 924 | if (ipoib_mcast_iter_next(iter)) { |
934 | ipoib_mcast_iter_free(iter); | 925 | kfree(iter); |
935 | return NULL; | 926 | return NULL; |
936 | } | 927 | } |
937 | 928 | ||
938 | return iter; | 929 | return iter; |
939 | } | 930 | } |
940 | 931 | ||
941 | void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter) | ||
942 | { | ||
943 | kfree(iter); | ||
944 | } | ||
945 | |||
946 | int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter) | 932 | int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter) |
947 | { | 933 | { |
948 | struct ipoib_dev_priv *priv = netdev_priv(iter->dev); | 934 | struct ipoib_dev_priv *priv = netdev_priv(iter->dev); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 332d730e60c2..d280b341a37f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c | |||
@@ -113,8 +113,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) | |||
113 | 113 | ||
114 | priv->parent = ppriv->dev; | 114 | priv->parent = ppriv->dev; |
115 | 115 | ||
116 | if (ipoib_create_debug_file(priv->dev)) | 116 | ipoib_create_debug_files(priv->dev); |
117 | goto debug_failed; | ||
118 | 117 | ||
119 | if (ipoib_add_pkey_attr(priv->dev)) | 118 | if (ipoib_add_pkey_attr(priv->dev)) |
120 | goto sysfs_failed; | 119 | goto sysfs_failed; |
@@ -130,9 +129,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) | |||
130 | return 0; | 129 | return 0; |
131 | 130 | ||
132 | sysfs_failed: | 131 | sysfs_failed: |
133 | ipoib_delete_debug_file(priv->dev); | 132 | ipoib_delete_debug_files(priv->dev); |
134 | |||
135 | debug_failed: | ||
136 | unregister_netdev(priv->dev); | 133 | unregister_netdev(priv->dev); |
137 | 134 | ||
138 | register_failed: | 135 | register_failed: |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 8f464271664d..49fa1e4413fa 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -2707,7 +2707,7 @@ bnx2_init_nvram(struct bnx2 *bp) | |||
2707 | 2707 | ||
2708 | if (j == entry_count) { | 2708 | if (j == entry_count) { |
2709 | bp->flash_info = NULL; | 2709 | bp->flash_info = NULL; |
2710 | printk(KERN_ALERT "Unknown flash/EEPROM type.\n"); | 2710 | printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n"); |
2711 | rc = -ENODEV; | 2711 | rc = -ENODEV; |
2712 | } | 2712 | } |
2713 | 2713 | ||
@@ -3903,6 +3903,8 @@ bnx2_test_loopback(struct bnx2 *bp) | |||
3903 | 3903 | ||
3904 | pkt_size = 1514; | 3904 | pkt_size = 1514; |
3905 | skb = dev_alloc_skb(pkt_size); | 3905 | skb = dev_alloc_skb(pkt_size); |
3906 | if (!skb) | ||
3907 | return -ENOMEM; | ||
3906 | packet = skb_put(skb, pkt_size); | 3908 | packet = skb_put(skb, pkt_size); |
3907 | memcpy(packet, bp->mac_addr, 6); | 3909 | memcpy(packet, bp->mac_addr, 6); |
3908 | memset(packet + 6, 0x0, 8); | 3910 | memset(packet + 6, 0x0, 8); |
@@ -4798,11 +4800,7 @@ bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | |||
4798 | struct bnx2 *bp = dev->priv; | 4800 | struct bnx2 *bp = dev->priv; |
4799 | int rc; | 4801 | int rc; |
4800 | 4802 | ||
4801 | if (eeprom->offset > bp->flash_info->total_size) | 4803 | /* parameters already validated in ethtool_get_eeprom */ |
4802 | return -EINVAL; | ||
4803 | |||
4804 | if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size) | ||
4805 | eeprom->len = bp->flash_info->total_size - eeprom->offset; | ||
4806 | 4804 | ||
4807 | rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len); | 4805 | rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len); |
4808 | 4806 | ||
@@ -4816,11 +4814,7 @@ bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | |||
4816 | struct bnx2 *bp = dev->priv; | 4814 | struct bnx2 *bp = dev->priv; |
4817 | int rc; | 4815 | int rc; |
4818 | 4816 | ||
4819 | if (eeprom->offset > bp->flash_info->total_size) | 4817 | /* parameters already validated in ethtool_set_eeprom */ |
4820 | return -EINVAL; | ||
4821 | |||
4822 | if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size) | ||
4823 | eeprom->len = bp->flash_info->total_size - eeprom->offset; | ||
4824 | 4818 | ||
4825 | rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); | 4819 | rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); |
4826 | 4820 | ||
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 9342d5bc7bb4..f5d49a110654 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/ethtool.h> | 37 | #include <linux/ethtool.h> |
38 | #include <linux/bitops.h> | 38 | #include <linux/bitops.h> |
39 | #include <linux/fs.h> | 39 | #include <linux/fs.h> |
40 | #include <linux/platform_device.h> | ||
40 | 41 | ||
41 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
42 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index a940b96433c7..e67b1d06611c 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/ethtool.h> | 34 | #include <linux/ethtool.h> |
35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/platform_device.h> | ||
37 | 38 | ||
38 | #include <asm/immap_cpm2.h> | 39 | #include <asm/immap_cpm2.h> |
39 | #include <asm/mpc8260.h> | 40 | #include <asm/mpc8260.h> |
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index 5ef4e845a387..2e8f44469699 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/ethtool.h> | 34 | #include <linux/ethtool.h> |
35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/platform_device.h> | ||
37 | 38 | ||
38 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index d8c6e9cadcf5..a3897fda71fa 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/ethtool.h> | 34 | #include <linux/ethtool.h> |
35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/platform_device.h> | ||
37 | 38 | ||
38 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index fcb66b9a0e28..e8593a60ee89 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -306,7 +306,7 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn) | |||
306 | { | 306 | { |
307 | struct pci_controller *phb; | 307 | struct pci_controller *phb; |
308 | 308 | ||
309 | if (PCI_DN(dn)->phb) { | 309 | if (PCI_DN(dn) && PCI_DN(dn)->phb) { |
310 | /* PHB already exists */ | 310 | /* PHB already exists */ |
311 | return -EINVAL; | 311 | return -EINVAL; |
312 | } | 312 | } |
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index ccf20039e909..309eb557f9a3 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -156,7 +156,7 @@ config TCIC | |||
156 | 156 | ||
157 | config PCMCIA_M8XX | 157 | config PCMCIA_M8XX |
158 | tristate "MPC8xx PCMCIA support" | 158 | tristate "MPC8xx PCMCIA support" |
159 | depends on PCMCIA && PPC | 159 | depends on PCMCIA && PPC && 8xx |
160 | select PCCARD_NONSTATIC | 160 | select PCCARD_NONSTATIC |
161 | help | 161 | help |
162 | Say Y here to include support for PowerPC 8xx series PCMCIA | 162 | Say Y here to include support for PowerPC 8xx series PCMCIA |
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index fe37541abbfe..bcecf5133b7e 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
@@ -25,7 +25,7 @@ obj-$(CONFIG_PD6729) += pd6729.o | |||
25 | obj-$(CONFIG_I82365) += i82365.o | 25 | obj-$(CONFIG_I82365) += i82365.o |
26 | obj-$(CONFIG_I82092) += i82092.o | 26 | obj-$(CONFIG_I82092) += i82092.o |
27 | obj-$(CONFIG_TCIC) += tcic.o | 27 | obj-$(CONFIG_TCIC) += tcic.o |
28 | obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o | 28 | obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o |
29 | obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o | 29 | obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o |
30 | obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o | 30 | obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o |
31 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o | 31 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o |
@@ -47,10 +47,10 @@ au1x00_ss-$(CONFIG_MIPS_PB1200) += au1000_db1x00.o | |||
47 | au1x00_ss-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o | 47 | au1x00_ss-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o |
48 | au1x00_ss-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o | 48 | au1x00_ss-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o |
49 | au1x00_ss-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o | 49 | au1x00_ss-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o |
50 | au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o | 50 | au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o |
51 | au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o | 51 | au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o |
52 | au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o | 52 | au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o |
53 | au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o | 53 | au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o |
54 | 54 | ||
55 | sa1111_cs-y += sa1111_generic.o | 55 | sa1111_cs-y += sa1111_generic.o |
56 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o | 56 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o |
diff --git a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c index 24cfee1a412c..abc13f28ba3f 100644 --- a/drivers/pcmcia/au1000_db1x00.c +++ b/drivers/pcmcia/au1000_db1x00.c | |||
@@ -30,6 +30,7 @@ | |||
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <linux/config.h> | ||
33 | #include <linux/module.h> | 34 | #include <linux/module.h> |
34 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
35 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h index b0e7908392a7..f2c970b5f4ff 100644 --- a/drivers/pcmcia/au1000_generic.h +++ b/drivers/pcmcia/au1000_generic.h | |||
@@ -22,6 +22,8 @@ | |||
22 | #define __ASM_AU1000_PCMCIA_H | 22 | #define __ASM_AU1000_PCMCIA_H |
23 | 23 | ||
24 | /* include the world */ | 24 | /* include the world */ |
25 | #include <linux/config.h> | ||
26 | |||
25 | #include <pcmcia/cs_types.h> | 27 | #include <pcmcia/cs_types.h> |
26 | #include <pcmcia/cs.h> | 28 | #include <pcmcia/cs.h> |
27 | #include <pcmcia/ss.h> | 29 | #include <pcmcia/ss.h> |
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c index 86c0808d6a05..fd5522ede867 100644 --- a/drivers/pcmcia/au1000_pb1x00.c +++ b/drivers/pcmcia/au1000_pb1x00.c | |||
@@ -21,6 +21,7 @@ | |||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | 21 | * with this program; if not, write to the Free Software Foundation, Inc., |
22 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 22 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
23 | */ | 23 | */ |
24 | #include <linux/config.h> | ||
24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
25 | #include <linux/init.h> | 26 | #include <linux/init.h> |
26 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c index 01a895bc9a47..01874b0bb03b 100644 --- a/drivers/pcmcia/au1000_xxs1500.c +++ b/drivers/pcmcia/au1000_xxs1500.c | |||
@@ -27,7 +27,6 @@ | |||
27 | */ | 27 | */ |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/config.h> | ||
31 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
32 | #include <linux/ioport.h> | 31 | #include <linux/ioport.h> |
33 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 7ce455d01cc9..4ddd76239b34 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c | |||
@@ -1366,6 +1366,7 @@ static int __init init_i82365(void) | |||
1366 | if (sockets == 0) { | 1366 | if (sockets == 0) { |
1367 | printk("not found.\n"); | 1367 | printk("not found.\n"); |
1368 | platform_device_unregister(&i82365_device); | 1368 | platform_device_unregister(&i82365_device); |
1369 | release_region(i365_base, 2); | ||
1369 | driver_unregister(&i82365_driver); | 1370 | driver_unregister(&i82365_driver); |
1370 | return -ENODEV; | 1371 | return -ENODEV; |
1371 | } | 1372 | } |
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index f8bed87cf2f1..6d9f71cfcb34 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -39,7 +39,6 @@ | |||
39 | 39 | ||
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | #include <asm/bitops.h> | 41 | #include <asm/bitops.h> |
42 | #include <asm/segment.h> | ||
43 | #include <asm/system.h> | 42 | #include <asm/system.h> |
44 | 43 | ||
45 | #include <linux/kernel.h> | 44 | #include <linux/kernel.h> |
@@ -50,6 +49,7 @@ | |||
50 | #include <linux/ioport.h> | 49 | #include <linux/ioport.h> |
51 | #include <linux/delay.h> | 50 | #include <linux/delay.h> |
52 | #include <linux/interrupt.h> | 51 | #include <linux/interrupt.h> |
52 | #include <linux/platform_device.h> | ||
53 | 53 | ||
54 | #include <asm/mpc8xx.h> | 54 | #include <asm/mpc8xx.h> |
55 | #include <asm/8xx_immap.h> | 55 | #include <asm/8xx_immap.h> |
@@ -546,29 +546,11 @@ static void m8xx_shutdown(void) | |||
546 | free_irq(pcmcia_schlvl, NULL); | 546 | free_irq(pcmcia_schlvl, NULL); |
547 | } | 547 | } |
548 | 548 | ||
549 | /* copied from tcic.c */ | ||
550 | |||
551 | static int m8xx_drv_suspend(struct device *dev, pm_message_t state, u32 level) | ||
552 | { | ||
553 | int ret = 0; | ||
554 | if (level == SUSPEND_SAVE_STATE) | ||
555 | ret = pcmcia_socket_dev_suspend(dev, state); | ||
556 | return ret; | ||
557 | } | ||
558 | |||
559 | static int m8xx_drv_resume(struct device *dev, u32 level) | ||
560 | { | ||
561 | int ret = 0; | ||
562 | if (level == RESUME_RESTORE_STATE) | ||
563 | ret = pcmcia_socket_dev_resume(dev); | ||
564 | return ret; | ||
565 | } | ||
566 | |||
567 | static struct device_driver m8xx_driver = { | 549 | static struct device_driver m8xx_driver = { |
568 | .name = "m8xx-pcmcia", | 550 | .name = "m8xx-pcmcia", |
569 | .bus = &platform_bus_type, | 551 | .bus = &platform_bus_type, |
570 | .suspend = m8xx_drv_suspend, | 552 | .suspend = pcmcia_socket_dev_suspend, |
571 | .resume = m8xx_drv_resume, | 553 | .resume = pcmcia_socket_dev_resume, |
572 | }; | 554 | }; |
573 | 555 | ||
574 | static struct platform_device m8xx_device = { | 556 | static struct platform_device m8xx_device = { |
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index c888af4a4562..3553da0e1cd5 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -395,6 +395,7 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) | |||
395 | int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); | 395 | int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); |
396 | struct Scsi_Host *host; | 396 | struct Scsi_Host *host; |
397 | u8 *scsi_buf; | 397 | u8 *scsi_buf; |
398 | int errors = rq->errors; | ||
398 | unsigned long flags; | 399 | unsigned long flags; |
399 | 400 | ||
400 | if (!(rq->flags & (REQ_SPECIAL|REQ_SENSE))) { | 401 | if (!(rq->flags & (REQ_SPECIAL|REQ_SENSE))) { |
@@ -421,11 +422,11 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) | |||
421 | printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n", | 422 | printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n", |
422 | drive->name, pc->scsi_cmd->serial_number); | 423 | drive->name, pc->scsi_cmd->serial_number); |
423 | pc->scsi_cmd->result = DID_TIME_OUT << 16; | 424 | pc->scsi_cmd->result = DID_TIME_OUT << 16; |
424 | } else if (rq->errors >= ERROR_MAX) { | 425 | } else if (errors >= ERROR_MAX) { |
425 | pc->scsi_cmd->result = DID_ERROR << 16; | 426 | pc->scsi_cmd->result = DID_ERROR << 16; |
426 | if (log) | 427 | if (log) |
427 | printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number); | 428 | printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number); |
428 | } else if (rq->errors) { | 429 | } else if (errors) { |
429 | if (log) | 430 | if (log) |
430 | printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number); | 431 | printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number); |
431 | if (!idescsi_check_condition(drive, rq)) | 432 | if (!idescsi_check_condition(drive, rq)) |
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index 4867498f68e8..bd9a6996aee7 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c | |||
@@ -48,6 +48,12 @@ static void corgibl_send_intensity(int intensity) | |||
48 | corgibl_mach_set_intensity(intensity); | 48 | corgibl_mach_set_intensity(intensity); |
49 | 49 | ||
50 | spin_unlock_irqrestore(&bl_lock, flags); | 50 | spin_unlock_irqrestore(&bl_lock, flags); |
51 | |||
52 | corgi_kick_batt = symbol_get(sharpsl_battery_kick); | ||
53 | if (corgi_kick_batt) { | ||
54 | corgi_kick_batt(); | ||
55 | symbol_put(sharpsl_battery_kick); | ||
56 | } | ||
51 | } | 57 | } |
52 | 58 | ||
53 | static void corgibl_blank(int blank) | 59 | static void corgibl_blank(int blank) |