diff options
Diffstat (limited to 'drivers')
59 files changed, 532 insertions, 272 deletions
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index cc250577d405..eeea477d9601 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c | |||
@@ -173,7 +173,7 @@ skbfree(struct sk_buff *skb) | |||
173 | return; | 173 | return; |
174 | while (atomic_read(&skb_shinfo(skb)->dataref) != 1 && i-- > 0) | 174 | while (atomic_read(&skb_shinfo(skb)->dataref) != 1 && i-- > 0) |
175 | msleep(Sms); | 175 | msleep(Sms); |
176 | if (i <= 0) { | 176 | if (i < 0) { |
177 | printk(KERN_ERR | 177 | printk(KERN_ERR |
178 | "aoe: %s holds ref: %s\n", | 178 | "aoe: %s holds ref: %s\n", |
179 | skb->dev ? skb->dev->name : "netif", | 179 | skb->dev ? skb->dev->name : "netif", |
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 2d637e0fbc03..d9e751be8c5f 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c | |||
@@ -457,10 +457,12 @@ static int init_ixp_crypto(void) | |||
457 | if (!ctx_pool) { | 457 | if (!ctx_pool) { |
458 | goto err; | 458 | goto err; |
459 | } | 459 | } |
460 | ret = qmgr_request_queue(SEND_QID, NPE_QLEN_TOTAL, 0, 0); | 460 | ret = qmgr_request_queue(SEND_QID, NPE_QLEN_TOTAL, 0, 0, |
461 | "ixp_crypto:out", NULL); | ||
461 | if (ret) | 462 | if (ret) |
462 | goto err; | 463 | goto err; |
463 | ret = qmgr_request_queue(RECV_QID, NPE_QLEN, 0, 0); | 464 | ret = qmgr_request_queue(RECV_QID, NPE_QLEN, 0, 0, |
465 | "ixp_crypto:in", NULL); | ||
464 | if (ret) { | 466 | if (ret) { |
465 | qmgr_release_queue(SEND_QID); | 467 | qmgr_release_queue(SEND_QID); |
466 | goto err; | 468 | goto err; |
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 856b3cc25583..3f0fdd18255d 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c | |||
@@ -489,4 +489,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algorithm support"); | |||
489 | MODULE_LICENSE("GPL"); | 489 | MODULE_LICENSE("GPL"); |
490 | MODULE_AUTHOR("Michal Ludvig"); | 490 | MODULE_AUTHOR("Michal Ludvig"); |
491 | 491 | ||
492 | MODULE_ALIAS("aes"); | 492 | MODULE_ALIAS("aes-all"); |
diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index a7fbadebf623..a2c8e8514b63 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c | |||
@@ -304,7 +304,7 @@ MODULE_DESCRIPTION("VIA PadLock SHA1/SHA256 algorithms support."); | |||
304 | MODULE_LICENSE("GPL"); | 304 | MODULE_LICENSE("GPL"); |
305 | MODULE_AUTHOR("Michal Ludvig"); | 305 | MODULE_AUTHOR("Michal Ludvig"); |
306 | 306 | ||
307 | MODULE_ALIAS("sha1"); | 307 | MODULE_ALIAS("sha1-all"); |
308 | MODULE_ALIAS("sha256"); | 308 | MODULE_ALIAS("sha256-all"); |
309 | MODULE_ALIAS("sha1-padlock"); | 309 | MODULE_ALIAS("sha1-padlock"); |
310 | MODULE_ALIAS("sha256-padlock"); | 310 | MODULE_ALIAS("sha256-padlock"); |
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index ea5440dd10dc..647374acba94 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c | |||
@@ -1401,7 +1401,7 @@ MODULE_ALIAS("platform:iop-adma"); | |||
1401 | 1401 | ||
1402 | static struct platform_driver iop_adma_driver = { | 1402 | static struct platform_driver iop_adma_driver = { |
1403 | .probe = iop_adma_probe, | 1403 | .probe = iop_adma_probe, |
1404 | .remove = iop_adma_remove, | 1404 | .remove = __devexit_p(iop_adma_remove), |
1405 | .driver = { | 1405 | .driver = { |
1406 | .owner = THIS_MODULE, | 1406 | .owner = THIS_MODULE, |
1407 | .name = "iop-adma", | 1407 | .name = "iop-adma", |
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index d35cbd1ff0b3..5d5d5b31867f 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c | |||
@@ -1287,7 +1287,7 @@ mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp, | |||
1287 | 1287 | ||
1288 | static struct platform_driver mv_xor_driver = { | 1288 | static struct platform_driver mv_xor_driver = { |
1289 | .probe = mv_xor_probe, | 1289 | .probe = mv_xor_probe, |
1290 | .remove = mv_xor_remove, | 1290 | .remove = __devexit_p(mv_xor_remove), |
1291 | .driver = { | 1291 | .driver = { |
1292 | .owner = THIS_MODULE, | 1292 | .owner = THIS_MODULE, |
1293 | .name = MV_XOR_NAME, | 1293 | .name = MV_XOR_NAME, |
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 72c667f9bee1..12715d3c078d 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
@@ -420,7 +420,7 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map) | |||
420 | dev->sigdata.lock = NULL; | 420 | dev->sigdata.lock = NULL; |
421 | master->lock.hw_lock = NULL; /* SHM removed */ | 421 | master->lock.hw_lock = NULL; /* SHM removed */ |
422 | master->lock.file_priv = NULL; | 422 | master->lock.file_priv = NULL; |
423 | wake_up_interruptible(&master->lock.lock_queue); | 423 | wake_up_interruptible_all(&master->lock.lock_queue); |
424 | } | 424 | } |
425 | break; | 425 | break; |
426 | case _DRM_AGP: | 426 | case _DRM_AGP: |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 6c020fe5431c..f52663ebe016 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -484,6 +484,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
484 | mutex_lock(&dev->struct_mutex); | 484 | mutex_lock(&dev->struct_mutex); |
485 | 485 | ||
486 | if (file_priv->is_master) { | 486 | if (file_priv->is_master) { |
487 | struct drm_master *master = file_priv->master; | ||
487 | struct drm_file *temp; | 488 | struct drm_file *temp; |
488 | list_for_each_entry(temp, &dev->filelist, lhead) { | 489 | list_for_each_entry(temp, &dev->filelist, lhead) { |
489 | if ((temp->master == file_priv->master) && | 490 | if ((temp->master == file_priv->master) && |
@@ -491,6 +492,19 @@ int drm_release(struct inode *inode, struct file *filp) | |||
491 | temp->authenticated = 0; | 492 | temp->authenticated = 0; |
492 | } | 493 | } |
493 | 494 | ||
495 | /** | ||
496 | * Since the master is disappearing, so is the | ||
497 | * possibility to lock. | ||
498 | */ | ||
499 | |||
500 | if (master->lock.hw_lock) { | ||
501 | if (dev->sigdata.lock == master->lock.hw_lock) | ||
502 | dev->sigdata.lock = NULL; | ||
503 | master->lock.hw_lock = NULL; | ||
504 | master->lock.file_priv = NULL; | ||
505 | wake_up_interruptible_all(&master->lock.lock_queue); | ||
506 | } | ||
507 | |||
494 | if (file_priv->minor->master == file_priv->master) { | 508 | if (file_priv->minor->master == file_priv->master) { |
495 | /* drop the reference held my the minor */ | 509 | /* drop the reference held my the minor */ |
496 | drm_master_put(&file_priv->minor->master); | 510 | drm_master_put(&file_priv->minor->master); |
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index 46e7b28f0707..e2f70a516c34 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
@@ -80,6 +80,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
80 | __set_current_state(TASK_INTERRUPTIBLE); | 80 | __set_current_state(TASK_INTERRUPTIBLE); |
81 | if (!master->lock.hw_lock) { | 81 | if (!master->lock.hw_lock) { |
82 | /* Device has been unregistered */ | 82 | /* Device has been unregistered */ |
83 | send_sig(SIGTERM, current, 0); | ||
83 | ret = -EINTR; | 84 | ret = -EINTR; |
84 | break; | 85 | break; |
85 | } | 86 | } |
@@ -93,7 +94,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
93 | /* Contention */ | 94 | /* Contention */ |
94 | schedule(); | 95 | schedule(); |
95 | if (signal_pending(current)) { | 96 | if (signal_pending(current)) { |
96 | ret = -ERESTARTSYS; | 97 | ret = -EINTR; |
97 | break; | 98 | break; |
98 | } | 99 | } |
99 | } | 100 | } |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 46bb923b097c..7c8b15b22bf2 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -146,14 +146,6 @@ static void drm_master_destroy(struct kref *kref) | |||
146 | 146 | ||
147 | drm_ht_remove(&master->magiclist); | 147 | drm_ht_remove(&master->magiclist); |
148 | 148 | ||
149 | if (master->lock.hw_lock) { | ||
150 | if (dev->sigdata.lock == master->lock.hw_lock) | ||
151 | dev->sigdata.lock = NULL; | ||
152 | master->lock.hw_lock = NULL; | ||
153 | master->lock.file_priv = NULL; | ||
154 | wake_up_interruptible(&master->lock.lock_queue); | ||
155 | } | ||
156 | |||
157 | drm_free(master, sizeof(*master), DRM_MEM_DRIVER); | 149 | drm_free(master, sizeof(*master), DRM_MEM_DRIVER); |
158 | } | 150 | } |
159 | 151 | ||
@@ -176,7 +168,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, | |||
176 | file_priv->minor->master != file_priv->master) { | 168 | file_priv->minor->master != file_priv->master) { |
177 | mutex_lock(&dev->struct_mutex); | 169 | mutex_lock(&dev->struct_mutex); |
178 | file_priv->minor->master = drm_master_get(file_priv->master); | 170 | file_priv->minor->master = drm_master_get(file_priv->master); |
179 | mutex_lock(&dev->struct_mutex); | 171 | mutex_unlock(&dev->struct_mutex); |
180 | } | 172 | } |
181 | 173 | ||
182 | return 0; | 174 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 548ff2c66431..87b6b603469e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -383,12 +383,13 @@ int i915_irq_emit(struct drm_device *dev, void *data, | |||
383 | drm_i915_irq_emit_t *emit = data; | 383 | drm_i915_irq_emit_t *emit = data; |
384 | int result; | 384 | int result; |
385 | 385 | ||
386 | RING_LOCK_TEST_WITH_RETURN(dev, file_priv); | ||
387 | |||
388 | if (!dev_priv) { | 386 | if (!dev_priv) { |
389 | DRM_ERROR("called with no initialization\n"); | 387 | DRM_ERROR("called with no initialization\n"); |
390 | return -EINVAL; | 388 | return -EINVAL; |
391 | } | 389 | } |
390 | |||
391 | RING_LOCK_TEST_WITH_RETURN(dev, file_priv); | ||
392 | |||
392 | mutex_lock(&dev->struct_mutex); | 393 | mutex_lock(&dev->struct_mutex); |
393 | result = i915_emit_irq(dev); | 394 | result = i915_emit_irq(dev); |
394 | mutex_unlock(&dev->struct_mutex); | 395 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index eeda276f8f16..7f186bbcb99d 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -482,7 +482,7 @@ mv64xxx_i2c_map_regs(struct platform_device *pd, | |||
482 | return 0; | 482 | return 0; |
483 | } | 483 | } |
484 | 484 | ||
485 | static void __devexit | 485 | static void |
486 | mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data) | 486 | mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data) |
487 | { | 487 | { |
488 | if (drv_data->reg_base) { | 488 | if (drv_data->reg_base) { |
@@ -577,7 +577,7 @@ mv64xxx_i2c_remove(struct platform_device *dev) | |||
577 | 577 | ||
578 | static struct platform_driver mv64xxx_i2c_driver = { | 578 | static struct platform_driver mv64xxx_i2c_driver = { |
579 | .probe = mv64xxx_i2c_probe, | 579 | .probe = mv64xxx_i2c_probe, |
580 | .remove = mv64xxx_i2c_remove, | 580 | .remove = __devexit_p(mv64xxx_i2c_remove), |
581 | .driver = { | 581 | .driver = { |
582 | .owner = THIS_MODULE, | 582 | .owner = THIS_MODULE, |
583 | .name = MV64XXX_I2C_CTLR_NAME, | 583 | .name = MV64XXX_I2C_CTLR_NAME, |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index c3c8b9bc40ae..45470f18d7e9 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -839,7 +839,7 @@ static void atkbd_disconnect(struct serio *serio) | |||
839 | */ | 839 | */ |
840 | static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) | 840 | static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) |
841 | { | 841 | { |
842 | const unsigned int forced_release_keys[] = { | 842 | static const unsigned int forced_release_keys[] = { |
843 | 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, | 843 | 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, |
844 | }; | 844 | }; |
845 | int i; | 845 | int i; |
@@ -856,7 +856,7 @@ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) | |||
856 | */ | 856 | */ |
857 | static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) | 857 | static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) |
858 | { | 858 | { |
859 | const unsigned int forced_release_keys[] = { | 859 | static const unsigned int forced_release_keys[] = { |
860 | 0x94, | 860 | 0x94, |
861 | }; | 861 | }; |
862 | int i; | 862 | int i; |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 19284016e0f4..ee855c5202e8 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -209,8 +209,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
209 | goto out; | 209 | goto out; |
210 | } | 210 | } |
211 | 211 | ||
212 | if (!pdata->debounce_time || !pdata->debounce_time > MAX_MULT || | 212 | if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || |
213 | !pdata->coldrive_time || !pdata->coldrive_time > MAX_MULT) { | 213 | !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { |
214 | printk(KERN_ERR DRV_NAME | 214 | printk(KERN_ERR DRV_NAME |
215 | ": Invalid Debounce/Columdrive Time from pdata\n"); | 215 | ": Invalid Debounce/Columdrive Time from pdata\n"); |
216 | bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ | 216 | bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ |
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index c8ed065ea0cb..abb04c82c622 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c | |||
@@ -288,7 +288,7 @@ static int corgikbd_resume(struct platform_device *dev) | |||
288 | #define corgikbd_resume NULL | 288 | #define corgikbd_resume NULL |
289 | #endif | 289 | #endif |
290 | 290 | ||
291 | static int __init corgikbd_probe(struct platform_device *pdev) | 291 | static int __devinit corgikbd_probe(struct platform_device *pdev) |
292 | { | 292 | { |
293 | struct corgikbd *corgikbd; | 293 | struct corgikbd *corgikbd; |
294 | struct input_dev *input_dev; | 294 | struct input_dev *input_dev; |
@@ -368,7 +368,7 @@ static int __init corgikbd_probe(struct platform_device *pdev) | |||
368 | return err; | 368 | return err; |
369 | } | 369 | } |
370 | 370 | ||
371 | static int corgikbd_remove(struct platform_device *pdev) | 371 | static int __devexit corgikbd_remove(struct platform_device *pdev) |
372 | { | 372 | { |
373 | int i; | 373 | int i; |
374 | struct corgikbd *corgikbd = platform_get_drvdata(pdev); | 374 | struct corgikbd *corgikbd = platform_get_drvdata(pdev); |
@@ -388,7 +388,7 @@ static int corgikbd_remove(struct platform_device *pdev) | |||
388 | 388 | ||
389 | static struct platform_driver corgikbd_driver = { | 389 | static struct platform_driver corgikbd_driver = { |
390 | .probe = corgikbd_probe, | 390 | .probe = corgikbd_probe, |
391 | .remove = corgikbd_remove, | 391 | .remove = __devexit_p(corgikbd_remove), |
392 | .suspend = corgikbd_suspend, | 392 | .suspend = corgikbd_suspend, |
393 | .resume = corgikbd_resume, | 393 | .resume = corgikbd_resume, |
394 | .driver = { | 394 | .driver = { |
@@ -397,7 +397,7 @@ static struct platform_driver corgikbd_driver = { | |||
397 | }, | 397 | }, |
398 | }; | 398 | }; |
399 | 399 | ||
400 | static int __devinit corgikbd_init(void) | 400 | static int __init corgikbd_init(void) |
401 | { | 401 | { |
402 | return platform_driver_register(&corgikbd_driver); | 402 | return platform_driver_register(&corgikbd_driver); |
403 | } | 403 | } |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 3f3d1198cdb1..058fa8b02c21 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -279,7 +279,7 @@ static int omap_kp_resume(struct platform_device *dev) | |||
279 | #define omap_kp_resume NULL | 279 | #define omap_kp_resume NULL |
280 | #endif | 280 | #endif |
281 | 281 | ||
282 | static int __init omap_kp_probe(struct platform_device *pdev) | 282 | static int __devinit omap_kp_probe(struct platform_device *pdev) |
283 | { | 283 | { |
284 | struct omap_kp *omap_kp; | 284 | struct omap_kp *omap_kp; |
285 | struct input_dev *input_dev; | 285 | struct input_dev *input_dev; |
@@ -422,7 +422,7 @@ err1: | |||
422 | return -EINVAL; | 422 | return -EINVAL; |
423 | } | 423 | } |
424 | 424 | ||
425 | static int omap_kp_remove(struct platform_device *pdev) | 425 | static int __devexit omap_kp_remove(struct platform_device *pdev) |
426 | { | 426 | { |
427 | struct omap_kp *omap_kp = platform_get_drvdata(pdev); | 427 | struct omap_kp *omap_kp = platform_get_drvdata(pdev); |
428 | 428 | ||
@@ -454,7 +454,7 @@ static int omap_kp_remove(struct platform_device *pdev) | |||
454 | 454 | ||
455 | static struct platform_driver omap_kp_driver = { | 455 | static struct platform_driver omap_kp_driver = { |
456 | .probe = omap_kp_probe, | 456 | .probe = omap_kp_probe, |
457 | .remove = omap_kp_remove, | 457 | .remove = __devexit_p(omap_kp_remove), |
458 | .suspend = omap_kp_suspend, | 458 | .suspend = omap_kp_suspend, |
459 | .resume = omap_kp_resume, | 459 | .resume = omap_kp_resume, |
460 | .driver = { | 460 | .driver = { |
@@ -463,7 +463,7 @@ static struct platform_driver omap_kp_driver = { | |||
463 | }, | 463 | }, |
464 | }; | 464 | }; |
465 | 465 | ||
466 | static int __devinit omap_kp_init(void) | 466 | static int __init omap_kp_init(void) |
467 | { | 467 | { |
468 | printk(KERN_INFO "OMAP Keypad Driver\n"); | 468 | printk(KERN_INFO "OMAP Keypad Driver\n"); |
469 | return platform_driver_register(&omap_kp_driver); | 469 | return platform_driver_register(&omap_kp_driver); |
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index c48b76a46a58..9d1781a618e9 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c | |||
@@ -343,7 +343,7 @@ static int spitzkbd_resume(struct platform_device *dev) | |||
343 | #define spitzkbd_resume NULL | 343 | #define spitzkbd_resume NULL |
344 | #endif | 344 | #endif |
345 | 345 | ||
346 | static int __init spitzkbd_probe(struct platform_device *dev) | 346 | static int __devinit spitzkbd_probe(struct platform_device *dev) |
347 | { | 347 | { |
348 | struct spitzkbd *spitzkbd; | 348 | struct spitzkbd *spitzkbd; |
349 | struct input_dev *input_dev; | 349 | struct input_dev *input_dev; |
@@ -444,7 +444,7 @@ static int __init spitzkbd_probe(struct platform_device *dev) | |||
444 | return err; | 444 | return err; |
445 | } | 445 | } |
446 | 446 | ||
447 | static int spitzkbd_remove(struct platform_device *dev) | 447 | static int __devexit spitzkbd_remove(struct platform_device *dev) |
448 | { | 448 | { |
449 | int i; | 449 | int i; |
450 | struct spitzkbd *spitzkbd = platform_get_drvdata(dev); | 450 | struct spitzkbd *spitzkbd = platform_get_drvdata(dev); |
@@ -470,7 +470,7 @@ static int spitzkbd_remove(struct platform_device *dev) | |||
470 | 470 | ||
471 | static struct platform_driver spitzkbd_driver = { | 471 | static struct platform_driver spitzkbd_driver = { |
472 | .probe = spitzkbd_probe, | 472 | .probe = spitzkbd_probe, |
473 | .remove = spitzkbd_remove, | 473 | .remove = __devexit_p(spitzkbd_remove), |
474 | .suspend = spitzkbd_suspend, | 474 | .suspend = spitzkbd_suspend, |
475 | .resume = spitzkbd_resume, | 475 | .resume = spitzkbd_resume, |
476 | .driver = { | 476 | .driver = { |
@@ -479,7 +479,7 @@ static struct platform_driver spitzkbd_driver = { | |||
479 | }, | 479 | }, |
480 | }; | 480 | }; |
481 | 481 | ||
482 | static int __devinit spitzkbd_init(void) | 482 | static int __init spitzkbd_init(void) |
483 | { | 483 | { |
484 | return platform_driver_register(&spitzkbd_driver); | 484 | return platform_driver_register(&spitzkbd_driver); |
485 | } | 485 | } |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 093c8c1bca74..9705f3a00a3d 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -70,7 +70,7 @@ config MOUSE_PS2_SYNAPTICS | |||
70 | config MOUSE_PS2_LIFEBOOK | 70 | config MOUSE_PS2_LIFEBOOK |
71 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED | 71 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED |
72 | default y | 72 | default y |
73 | depends on MOUSE_PS2 | 73 | depends on MOUSE_PS2 && X86 |
74 | help | 74 | help |
75 | Say Y here if you have a Fujitsu B-series Lifebook PS/2 | 75 | Say Y here if you have a Fujitsu B-series Lifebook PS/2 |
76 | TouchScreen connected to your system. | 76 | TouchScreen connected to your system. |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index b9a25d57bc5e..6ab0eb1ada1c 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -542,7 +542,7 @@ int elantech_detect(struct psmouse *psmouse, int set_properties) | |||
542 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 542 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
543 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 543 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
544 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 544 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
545 | pr_err("elantech.c: sending Elantech magic knock failed.\n"); | 545 | pr_debug("elantech.c: sending Elantech magic knock failed.\n"); |
546 | return -1; | 546 | return -1; |
547 | } | 547 | } |
548 | 548 | ||
@@ -551,8 +551,27 @@ int elantech_detect(struct psmouse *psmouse, int set_properties) | |||
551 | * set of magic numbers | 551 | * set of magic numbers |
552 | */ | 552 | */ |
553 | if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { | 553 | if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { |
554 | pr_info("elantech.c: unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", | 554 | pr_debug("elantech.c: " |
555 | param[0], param[1], param[2]); | 555 | "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", |
556 | param[0], param[1], param[2]); | ||
557 | return -1; | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * Query touchpad's firmware version and see if it reports known | ||
562 | * value to avoid mis-detection. Logitech mice are known to respond | ||
563 | * to Elantech magic knock and there might be more. | ||
564 | */ | ||
565 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | ||
566 | pr_debug("elantech.c: failed to query firmware version.\n"); | ||
567 | return -1; | ||
568 | } | ||
569 | |||
570 | pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", | ||
571 | param[0], param[1], param[2]); | ||
572 | |||
573 | if (param[0] == 0 || param[1] != 0) { | ||
574 | pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); | ||
556 | return -1; | 575 | return -1; |
557 | } | 576 | } |
558 | 577 | ||
@@ -600,8 +619,7 @@ int elantech_init(struct psmouse *psmouse) | |||
600 | int i, error; | 619 | int i, error; |
601 | unsigned char param[3]; | 620 | unsigned char param[3]; |
602 | 621 | ||
603 | etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); | 622 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); |
604 | psmouse->private = etd; | ||
605 | if (!etd) | 623 | if (!etd) |
606 | return -1; | 624 | return -1; |
607 | 625 | ||
@@ -610,14 +628,12 @@ int elantech_init(struct psmouse *psmouse) | |||
610 | etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; | 628 | etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; |
611 | 629 | ||
612 | /* | 630 | /* |
613 | * Find out what version hardware this is | 631 | * Do the version query again so we can store the result |
614 | */ | 632 | */ |
615 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 633 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
616 | pr_err("elantech.c: failed to query firmware version.\n"); | 634 | pr_err("elantech.c: failed to query firmware version.\n"); |
617 | goto init_fail; | 635 | goto init_fail; |
618 | } | 636 | } |
619 | pr_info("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", | ||
620 | param[0], param[1], param[2]); | ||
621 | etd->fw_version_maj = param[0]; | 637 | etd->fw_version_maj = param[0]; |
622 | etd->fw_version_min = param[2]; | 638 | etd->fw_version_min = param[2]; |
623 | 639 | ||
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index d297accf9a7f..1e827ad0afbe 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c | |||
@@ -83,7 +83,7 @@ static int write_tbcr(struct pxa930_trkball *trkball, int v) | |||
83 | 83 | ||
84 | __raw_writel(v, trkball->mmio_base + TBCR); | 84 | __raw_writel(v, trkball->mmio_base + TBCR); |
85 | 85 | ||
86 | while (i--) { | 86 | while (--i) { |
87 | if (__raw_readl(trkball->mmio_base + TBCR) == v) | 87 | if (__raw_readl(trkball->mmio_base + TBCR) == v) |
88 | break; | 88 | break; |
89 | msleep(1); | 89 | msleep(1); |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 865fc69e9bc3..f3e4f7b0240d 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -182,11 +182,6 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
182 | 182 | ||
183 | static int synaptics_query_hardware(struct psmouse *psmouse) | 183 | static int synaptics_query_hardware(struct psmouse *psmouse) |
184 | { | 184 | { |
185 | int retries = 0; | ||
186 | |||
187 | while ((retries++ < 3) && psmouse_reset(psmouse)) | ||
188 | /* empty */; | ||
189 | |||
190 | if (synaptics_identify(psmouse)) | 185 | if (synaptics_identify(psmouse)) |
191 | return -1; | 186 | return -1; |
192 | if (synaptics_model_id(psmouse)) | 187 | if (synaptics_model_id(psmouse)) |
@@ -582,6 +577,8 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
582 | struct synaptics_data *priv = psmouse->private; | 577 | struct synaptics_data *priv = psmouse->private; |
583 | struct synaptics_data old_priv = *priv; | 578 | struct synaptics_data old_priv = *priv; |
584 | 579 | ||
580 | psmouse_reset(psmouse); | ||
581 | |||
585 | if (synaptics_detect(psmouse, 0)) | 582 | if (synaptics_detect(psmouse, 0)) |
586 | return -1; | 583 | return -1; |
587 | 584 | ||
@@ -640,6 +637,8 @@ int synaptics_init(struct psmouse *psmouse) | |||
640 | if (!priv) | 637 | if (!priv) |
641 | return -1; | 638 | return -1; |
642 | 639 | ||
640 | psmouse_reset(psmouse); | ||
641 | |||
643 | if (synaptics_query_hardware(psmouse)) { | 642 | if (synaptics_query_hardware(psmouse)) { |
644 | printk(KERN_ERR "Unable to query Synaptics hardware.\n"); | 643 | printk(KERN_ERR "Unable to query Synaptics hardware.\n"); |
645 | goto init_fail; | 644 | goto init_fail; |
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index b10ffae7c39b..e29cdc13a199 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c | |||
@@ -57,7 +57,7 @@ static int amba_kmi_write(struct serio *io, unsigned char val) | |||
57 | struct amba_kmi_port *kmi = io->port_data; | 57 | struct amba_kmi_port *kmi = io->port_data; |
58 | unsigned int timeleft = 10000; /* timeout in 100ms */ | 58 | unsigned int timeleft = 10000; /* timeout in 100ms */ |
59 | 59 | ||
60 | while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--) | 60 | while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && --timeleft) |
61 | udelay(10); | 61 | udelay(10); |
62 | 62 | ||
63 | if (timeleft) | 63 | if (timeleft) |
@@ -129,8 +129,8 @@ static int amba_kmi_probe(struct amba_device *dev, void *id) | |||
129 | io->write = amba_kmi_write; | 129 | io->write = amba_kmi_write; |
130 | io->open = amba_kmi_open; | 130 | io->open = amba_kmi_open; |
131 | io->close = amba_kmi_close; | 131 | io->close = amba_kmi_close; |
132 | strlcpy(io->name, dev->dev.bus_id, sizeof(io->name)); | 132 | strlcpy(io->name, dev_name(&dev->dev), sizeof(io->name)); |
133 | strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys)); | 133 | strlcpy(io->phys, dev_name(&dev->dev), sizeof(io->phys)); |
134 | io->port_data = kmi; | 134 | io->port_data = kmi; |
135 | io->dev.parent = &dev->dev; | 135 | io->dev.parent = &dev->dev; |
136 | 136 | ||
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index adc3bd6e7f7b..bd0f92d9f40f 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c | |||
@@ -359,7 +359,7 @@ static int __init gscps2_probe(struct parisc_device *dev) | |||
359 | 359 | ||
360 | snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s", | 360 | snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s", |
361 | (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); | 361 | (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); |
362 | strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); | 362 | strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); |
363 | serio->id.type = SERIO_8042; | 363 | serio->id.type = SERIO_8042; |
364 | serio->write = gscps2_write; | 364 | serio->write = gscps2_write; |
365 | serio->open = gscps2_open; | 365 | serio->open = gscps2_open; |
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 2ad88780a170..57953c0eb82f 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c | |||
@@ -246,8 +246,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev) | |||
246 | serio->write = ps2_write; | 246 | serio->write = ps2_write; |
247 | serio->open = ps2_open; | 247 | serio->open = ps2_open; |
248 | serio->close = ps2_close; | 248 | serio->close = ps2_close; |
249 | strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name)); | 249 | strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name)); |
250 | strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); | 250 | strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); |
251 | serio->port_data = ps2if; | 251 | serio->port_data = ps2if; |
252 | serio->dev.parent = &dev->dev; | 252 | serio->dev.parent = &dev->dev; |
253 | ps2if->io = serio; | 253 | ps2if->io = serio; |
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c index a89a6a8f05e6..055969e8be13 100644 --- a/drivers/input/touchscreen/atmel_tsadcc.c +++ b/drivers/input/touchscreen/atmel_tsadcc.c | |||
@@ -236,7 +236,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) | |||
236 | ts_dev->bufferedmeasure = 0; | 236 | ts_dev->bufferedmeasure = 0; |
237 | 237 | ||
238 | snprintf(ts_dev->phys, sizeof(ts_dev->phys), | 238 | snprintf(ts_dev->phys, sizeof(ts_dev->phys), |
239 | "%s/input0", pdev->dev.bus_id); | 239 | "%s/input0", dev_name(&pdev->dev)); |
240 | 240 | ||
241 | input_dev->name = "atmel touch screen controller"; | 241 | input_dev->name = "atmel touch screen controller"; |
242 | input_dev->phys = ts_dev->phys; | 242 | input_dev->phys = ts_dev->phys; |
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 65202c9f63ff..3fb51b54fe61 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c | |||
@@ -268,7 +268,7 @@ static int corgits_resume(struct platform_device *dev) | |||
268 | #define corgits_resume NULL | 268 | #define corgits_resume NULL |
269 | #endif | 269 | #endif |
270 | 270 | ||
271 | static int __init corgits_probe(struct platform_device *pdev) | 271 | static int __devinit corgits_probe(struct platform_device *pdev) |
272 | { | 272 | { |
273 | struct corgi_ts *corgi_ts; | 273 | struct corgi_ts *corgi_ts; |
274 | struct input_dev *input_dev; | 274 | struct input_dev *input_dev; |
@@ -343,7 +343,7 @@ static int __init corgits_probe(struct platform_device *pdev) | |||
343 | return err; | 343 | return err; |
344 | } | 344 | } |
345 | 345 | ||
346 | static int corgits_remove(struct platform_device *pdev) | 346 | static int __devexit corgits_remove(struct platform_device *pdev) |
347 | { | 347 | { |
348 | struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); | 348 | struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); |
349 | 349 | ||
@@ -352,12 +352,13 @@ static int corgits_remove(struct platform_device *pdev) | |||
352 | corgi_ts->machinfo->put_hsync(); | 352 | corgi_ts->machinfo->put_hsync(); |
353 | input_unregister_device(corgi_ts->input); | 353 | input_unregister_device(corgi_ts->input); |
354 | kfree(corgi_ts); | 354 | kfree(corgi_ts); |
355 | |||
355 | return 0; | 356 | return 0; |
356 | } | 357 | } |
357 | 358 | ||
358 | static struct platform_driver corgits_driver = { | 359 | static struct platform_driver corgits_driver = { |
359 | .probe = corgits_probe, | 360 | .probe = corgits_probe, |
360 | .remove = corgits_remove, | 361 | .remove = __devexit_p(corgits_remove), |
361 | .suspend = corgits_suspend, | 362 | .suspend = corgits_suspend, |
362 | .resume = corgits_resume, | 363 | .resume = corgits_resume, |
363 | .driver = { | 364 | .driver = { |
@@ -366,7 +367,7 @@ static struct platform_driver corgits_driver = { | |||
366 | }, | 367 | }, |
367 | }; | 368 | }; |
368 | 369 | ||
369 | static int __devinit corgits_init(void) | 370 | static int __init corgits_init(void) |
370 | { | 371 | { |
371 | return platform_driver_register(&corgits_driver); | 372 | return platform_driver_register(&corgits_driver); |
372 | } | 373 | } |
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index b75dc2990574..4ab070246892 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c | |||
@@ -289,7 +289,8 @@ static int tsc2007_probe(struct i2c_client *client, | |||
289 | 289 | ||
290 | pdata->init_platform_hw(); | 290 | pdata->init_platform_hw(); |
291 | 291 | ||
292 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", client->dev.bus_id); | 292 | snprintf(ts->phys, sizeof(ts->phys), |
293 | "%s/input0", dev_name(&client->dev)); | ||
293 | 294 | ||
294 | input_dev->name = "TSC2007 Touchscreen"; | 295 | input_dev->name = "TSC2007 Touchscreen"; |
295 | input_dev->phys = ts->phys; | 296 | input_dev->phys = ts->phys; |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 5080b26ba160..fb7cb9bdfbd5 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -60,6 +60,10 @@ static int swap_xy; | |||
60 | module_param(swap_xy, bool, 0644); | 60 | module_param(swap_xy, bool, 0644); |
61 | MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); | 61 | MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); |
62 | 62 | ||
63 | static int hwcalib_xy; | ||
64 | module_param(hwcalib_xy, bool, 0644); | ||
65 | MODULE_PARM_DESC(hwcalib_xy, "If set hw-calibrated X/Y are used if available"); | ||
66 | |||
63 | /* device specifc data/functions */ | 67 | /* device specifc data/functions */ |
64 | struct usbtouch_usb; | 68 | struct usbtouch_usb; |
65 | struct usbtouch_device_info { | 69 | struct usbtouch_device_info { |
@@ -118,6 +122,7 @@ enum { | |||
118 | 122 | ||
119 | #define USB_DEVICE_HID_CLASS(vend, prod) \ | 123 | #define USB_DEVICE_HID_CLASS(vend, prod) \ |
120 | .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \ | 124 | .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \ |
125 | | USB_DEVICE_ID_MATCH_INT_PROTOCOL \ | ||
121 | | USB_DEVICE_ID_MATCH_DEVICE, \ | 126 | | USB_DEVICE_ID_MATCH_DEVICE, \ |
122 | .idVendor = (vend), \ | 127 | .idVendor = (vend), \ |
123 | .idProduct = (prod), \ | 128 | .idProduct = (prod), \ |
@@ -260,8 +265,13 @@ static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
260 | 265 | ||
261 | static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | 266 | static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
262 | { | 267 | { |
263 | dev->x = (pkt[8] << 8) | pkt[7]; | 268 | if (hwcalib_xy) { |
264 | dev->y = (pkt[10] << 8) | pkt[9]; | 269 | dev->x = (pkt[4] << 8) | pkt[3]; |
270 | dev->y = 0xffff - ((pkt[6] << 8) | pkt[5]); | ||
271 | } else { | ||
272 | dev->x = (pkt[8] << 8) | pkt[7]; | ||
273 | dev->y = (pkt[10] << 8) | pkt[9]; | ||
274 | } | ||
265 | dev->touch = (pkt[2] & 0x40) ? 1 : 0; | 275 | dev->touch = (pkt[2] & 0x40) ? 1 : 0; |
266 | 276 | ||
267 | return 1; | 277 | return 1; |
@@ -294,6 +304,12 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) | |||
294 | return ret; | 304 | return ret; |
295 | } | 305 | } |
296 | 306 | ||
307 | /* Default min/max xy are the raw values, override if using hw-calib */ | ||
308 | if (hwcalib_xy) { | ||
309 | input_set_abs_params(usbtouch->input, ABS_X, 0, 0xffff, 0, 0); | ||
310 | input_set_abs_params(usbtouch->input, ABS_Y, 0, 0xffff, 0, 0); | ||
311 | } | ||
312 | |||
297 | return 0; | 313 | return 0; |
298 | } | 314 | } |
299 | #endif | 315 | #endif |
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index c1e4ae27c613..c705f248da88 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c | |||
@@ -46,8 +46,8 @@ static int uvc_input_init(struct uvc_device *dev) | |||
46 | usb_to_input_id(udev, &input->id); | 46 | usb_to_input_id(udev, &input->id); |
47 | input->dev.parent = &dev->intf->dev; | 47 | input->dev.parent = &dev->intf->dev; |
48 | 48 | ||
49 | set_bit(EV_KEY, input->evbit); | 49 | __set_bit(EV_KEY, input->evbit); |
50 | set_bit(BTN_0, input->keybit); | 50 | __set_bit(KEY_CAMERA, input->keybit); |
51 | 51 | ||
52 | if ((ret = input_register_device(input)) < 0) | 52 | if ((ret = input_register_device(input)) < 0) |
53 | goto error; | 53 | goto error; |
@@ -70,8 +70,10 @@ static void uvc_input_cleanup(struct uvc_device *dev) | |||
70 | static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, | 70 | static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, |
71 | int value) | 71 | int value) |
72 | { | 72 | { |
73 | if (dev->input) | 73 | if (dev->input) { |
74 | input_report_key(dev->input, code, value); | 74 | input_report_key(dev->input, code, value); |
75 | input_sync(dev->input); | ||
76 | } | ||
75 | } | 77 | } |
76 | 78 | ||
77 | #else | 79 | #else |
@@ -96,7 +98,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) | |||
96 | return; | 98 | return; |
97 | uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", | 99 | uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", |
98 | data[1], data[3] ? "pressed" : "released", len); | 100 | data[1], data[3] ? "pressed" : "released", len); |
99 | uvc_input_report_key(dev, BTN_0, data[3]); | 101 | uvc_input_report_key(dev, KEY_CAMERA, data[3]); |
100 | } else { | 102 | } else { |
101 | uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " | 103 | uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " |
102 | "len %d.\n", data[1], data[2], data[3], len); | 104 | "len %d.\n", data[1], data[2], data[3], len); |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 96ac88317b8e..ea3aafbbda44 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -91,9 +91,9 @@ MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \ | |||
91 | controllers (default=0)"); | 91 | controllers (default=0)"); |
92 | 92 | ||
93 | static int mpt_msi_enable_sas; | 93 | static int mpt_msi_enable_sas; |
94 | module_param(mpt_msi_enable_sas, int, 1); | 94 | module_param(mpt_msi_enable_sas, int, 0); |
95 | MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \ | 95 | MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \ |
96 | controllers (default=1)"); | 96 | controllers (default=0)"); |
97 | 97 | ||
98 | 98 | ||
99 | static int mpt_channel_mapping; | 99 | static int mpt_channel_mapping; |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 8cff5f5e7f86..406da9a8d453 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -107,6 +107,7 @@ static const struct sdhci_pci_fixes sdhci_ene_714 = { | |||
107 | 107 | ||
108 | static const struct sdhci_pci_fixes sdhci_cafe = { | 108 | static const struct sdhci_pci_fixes sdhci_cafe = { |
109 | .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | | 109 | .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | |
110 | SDHCI_QUIRK_NO_BUSY_IRQ | | ||
110 | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, | 111 | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, |
111 | }; | 112 | }; |
112 | 113 | ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f52f3053ed92..accb592764ed 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1291,8 +1291,11 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) | |||
1291 | if (host->cmd->data) | 1291 | if (host->cmd->data) |
1292 | DBG("Cannot wait for busy signal when also " | 1292 | DBG("Cannot wait for busy signal when also " |
1293 | "doing a data transfer"); | 1293 | "doing a data transfer"); |
1294 | else | 1294 | else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ)) |
1295 | return; | 1295 | return; |
1296 | |||
1297 | /* The controller does not support the end-of-busy IRQ, | ||
1298 | * fall through and take the SDHCI_INT_RESPONSE */ | ||
1296 | } | 1299 | } |
1297 | 1300 | ||
1298 | if (intmask & SDHCI_INT_RESPONSE) | 1301 | if (intmask & SDHCI_INT_RESPONSE) |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index ebb83657e27a..43c37c68d07a 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -208,6 +208,8 @@ struct sdhci_host { | |||
208 | #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) | 208 | #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) |
209 | /* Controller has an issue with buffer bits for small transfers */ | 209 | /* Controller has an issue with buffer bits for small transfers */ |
210 | #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) | 210 | #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) |
211 | /* Controller does not provide transfer-complete interrupt when not busy */ | ||
212 | #define SDHCI_QUIRK_NO_BUSY_IRQ (1<<14) | ||
211 | 213 | ||
212 | int irq; /* Device IRQ */ | 214 | int irq; /* Device IRQ */ |
213 | void __iomem * ioaddr; /* Mapped address */ | 215 | void __iomem * ioaddr; /* Mapped address */ |
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 917cf8d3ae95..c2dfd3ea353d 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
@@ -149,7 +149,7 @@ static int __devexit orion_nand_remove(struct platform_device *pdev) | |||
149 | 149 | ||
150 | static struct platform_driver orion_nand_driver = { | 150 | static struct platform_driver orion_nand_driver = { |
151 | .probe = orion_nand_probe, | 151 | .probe = orion_nand_probe, |
152 | .remove = orion_nand_remove, | 152 | .remove = __devexit_p(orion_nand_remove), |
153 | .driver = { | 153 | .driver = { |
154 | .name = "orion_nand", | 154 | .name = "orion_nand", |
155 | .owner = THIS_MODULE, | 155 | .owner = THIS_MODULE, |
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile index c69c0cdba4a2..811a3ccd14c1 100644 --- a/drivers/net/arm/Makefile +++ b/drivers/net/arm/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o | 6 | obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o |
7 | obj-$(CONFIG_ARM_ETHERH) += etherh.o ../8390.o | 7 | obj-$(CONFIG_ARM_ETHERH) += etherh.o |
8 | obj-$(CONFIG_ARM_ETHER3) += ether3.o | 8 | obj-$(CONFIG_ARM_ETHER3) += ether3.o |
9 | obj-$(CONFIG_ARM_ETHER1) += ether1.o | 9 | obj-$(CONFIG_ARM_ETHER1) += ether1.o |
10 | obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o | 10 | obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o |
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 54b52e5b1821..f52f668c49bf 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c | |||
@@ -641,15 +641,15 @@ static const struct net_device_ops etherh_netdev_ops = { | |||
641 | .ndo_open = etherh_open, | 641 | .ndo_open = etherh_open, |
642 | .ndo_stop = etherh_close, | 642 | .ndo_stop = etherh_close, |
643 | .ndo_set_config = etherh_set_config, | 643 | .ndo_set_config = etherh_set_config, |
644 | .ndo_start_xmit = ei_start_xmit, | 644 | .ndo_start_xmit = __ei_start_xmit, |
645 | .ndo_tx_timeout = ei_tx_timeout, | 645 | .ndo_tx_timeout = __ei_tx_timeout, |
646 | .ndo_get_stats = ei_get_stats, | 646 | .ndo_get_stats = __ei_get_stats, |
647 | .ndo_set_multicast_list = ei_set_multicast_list, | 647 | .ndo_set_multicast_list = __ei_set_multicast_list, |
648 | .ndo_validate_addr = eth_validate_addr, | 648 | .ndo_validate_addr = eth_validate_addr, |
649 | .ndo_set_mac_address = eth_mac_addr, | 649 | .ndo_set_mac_address = eth_mac_addr, |
650 | .ndo_change_mtu = eth_change_mtu, | 650 | .ndo_change_mtu = eth_change_mtu, |
651 | #ifdef CONFIG_NET_POLL_CONTROLLER | 651 | #ifdef CONFIG_NET_POLL_CONTROLLER |
652 | .ndo_poll_controller = ei_poll, | 652 | .ndo_poll_controller = __ei_poll, |
653 | #endif | 653 | #endif |
654 | }; | 654 | }; |
655 | 655 | ||
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index b39210cf4fb3..35cd264abae7 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c | |||
@@ -560,7 +560,7 @@ ks8695_reset(struct ks8695_priv *ksp) | |||
560 | msleep(1); | 560 | msleep(1); |
561 | } | 561 | } |
562 | 562 | ||
563 | if (reset_timeout == 0) { | 563 | if (reset_timeout < 0) { |
564 | dev_crit(ksp->dev, | 564 | dev_crit(ksp->dev, |
565 | "Timeout waiting for DMA engines to reset\n"); | 565 | "Timeout waiting for DMA engines to reset\n"); |
566 | /* And blithely carry on */ | 566 | /* And blithely carry on */ |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2c96b93b12a5..bfe1ed8389ca 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -4121,7 +4121,7 @@ static int bond_neigh_setup(struct net_device *dev, struct neigh_parms *parms) | |||
4121 | const struct net_device_ops *slave_ops | 4121 | const struct net_device_ops *slave_ops |
4122 | = slave->dev->netdev_ops; | 4122 | = slave->dev->netdev_ops; |
4123 | if (slave_ops->ndo_neigh_setup) | 4123 | if (slave_ops->ndo_neigh_setup) |
4124 | return slave_ops->ndo_neigh_setup(dev, parms); | 4124 | return slave_ops->ndo_neigh_setup(slave->dev, parms); |
4125 | } | 4125 | } |
4126 | return 0; | 4126 | return 0; |
4127 | } | 4127 | } |
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index c434a156d7a9..b0ce1445d4a8 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c | |||
@@ -129,7 +129,7 @@ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | |||
129 | static int fsl_pq_mdio_reset(struct mii_bus *bus) | 129 | static int fsl_pq_mdio_reset(struct mii_bus *bus) |
130 | { | 130 | { |
131 | struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv; | 131 | struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv; |
132 | unsigned int timeout = PHY_INIT_TIMEOUT; | 132 | int timeout = PHY_INIT_TIMEOUT; |
133 | 133 | ||
134 | mutex_lock(&bus->mdio_lock); | 134 | mutex_lock(&bus->mdio_lock); |
135 | 135 | ||
@@ -145,7 +145,7 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus) | |||
145 | 145 | ||
146 | mutex_unlock(&bus->mdio_lock); | 146 | mutex_unlock(&bus->mdio_lock); |
147 | 147 | ||
148 | if(timeout == 0) { | 148 | if (timeout < 0) { |
149 | printk(KERN_ERR "%s: The MII Bus is stuck!\n", | 149 | printk(KERN_ERR "%s: The MII Bus is stuck!\n", |
150 | bus->name); | 150 | bus->name); |
151 | return -EBUSY; | 151 | return -EBUSY; |
diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 4da81a3602dc..860dcd98a07c 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c | |||
@@ -956,13 +956,14 @@ jme_process_receive(struct jme_adapter *jme, int limit) | |||
956 | goto out_inc; | 956 | goto out_inc; |
957 | 957 | ||
958 | i = atomic_read(&rxring->next_to_clean); | 958 | i = atomic_read(&rxring->next_to_clean); |
959 | while (limit-- > 0) { | 959 | while (limit > 0) { |
960 | rxdesc = rxring->desc; | 960 | rxdesc = rxring->desc; |
961 | rxdesc += i; | 961 | rxdesc += i; |
962 | 962 | ||
963 | if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) || | 963 | if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) || |
964 | !(rxdesc->descwb.desccnt & RXWBDCNT_WBCPL)) | 964 | !(rxdesc->descwb.desccnt & RXWBDCNT_WBCPL)) |
965 | goto out; | 965 | goto out; |
966 | --limit; | ||
966 | 967 | ||
967 | desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT; | 968 | desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT; |
968 | 969 | ||
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index e5cb6b1f0ebd..2404a838b1fe 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c | |||
@@ -1035,7 +1035,8 @@ static int el3_rx(struct net_device *dev, int worklimit) | |||
1035 | DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", | 1035 | DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", |
1036 | dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus)); | 1036 | dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus)); |
1037 | while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) && | 1037 | while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) && |
1038 | (--worklimit >= 0)) { | 1038 | worklimit > 0) { |
1039 | worklimit--; | ||
1039 | if (rx_status & 0x4000) { /* Error, update stats. */ | 1040 | if (rx_status & 0x4000) { /* Error, update stats. */ |
1040 | short error = rx_status & 0x3800; | 1041 | short error = rx_status & 0x3800; |
1041 | dev->stats.rx_errors++; | 1042 | dev->stats.rx_errors++; |
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 73ecc657999d..1e01b8a6dbf3 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c | |||
@@ -857,7 +857,8 @@ static int el3_rx(struct net_device *dev) | |||
857 | DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", | 857 | DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", |
858 | dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS)); | 858 | dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS)); |
859 | while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) && | 859 | while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) && |
860 | (--worklimit >= 0)) { | 860 | worklimit > 0) { |
861 | worklimit--; | ||
861 | if (rx_status & 0x4000) { /* Error, update stats. */ | 862 | if (rx_status & 0x4000) { /* Error, update stats. */ |
862 | short error = rx_status & 0x3800; | 863 | short error = rx_status & 0x3800; |
863 | dev->stats.rx_errors++; | 864 | dev->stats.rx_errors++; |
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h index 870b4c33f108..a45952e72018 100644 --- a/drivers/net/smc911x.h +++ b/drivers/net/smc911x.h | |||
@@ -42,6 +42,16 @@ | |||
42 | #define SMC_USE_16BIT 0 | 42 | #define SMC_USE_16BIT 0 |
43 | #define SMC_USE_32BIT 1 | 43 | #define SMC_USE_32BIT 1 |
44 | #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW | 44 | #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW |
45 | #elif defined(CONFIG_ARCH_OMAP34XX) | ||
46 | #define SMC_USE_16BIT 0 | ||
47 | #define SMC_USE_32BIT 1 | ||
48 | #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW | ||
49 | #define SMC_MEM_RESERVED 1 | ||
50 | #elif defined(CONFIG_ARCH_OMAP24XX) | ||
51 | #define SMC_USE_16BIT 0 | ||
52 | #define SMC_USE_32BIT 1 | ||
53 | #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW | ||
54 | #define SMC_MEM_RESERVED 1 | ||
45 | #else | 55 | #else |
46 | /* | 56 | /* |
47 | * Default configuration | 57 | * Default configuration |
@@ -675,6 +685,7 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr, | |||
675 | #define CHIP_9116 0x0116 | 685 | #define CHIP_9116 0x0116 |
676 | #define CHIP_9117 0x0117 | 686 | #define CHIP_9117 0x0117 |
677 | #define CHIP_9118 0x0118 | 687 | #define CHIP_9118 0x0118 |
688 | #define CHIP_9211 0x9211 | ||
678 | #define CHIP_9215 0x115A | 689 | #define CHIP_9215 0x115A |
679 | #define CHIP_9217 0x117A | 690 | #define CHIP_9217 0x117A |
680 | #define CHIP_9218 0x118A | 691 | #define CHIP_9218 0x118A |
@@ -689,6 +700,7 @@ static const struct chip_id chip_ids[] = { | |||
689 | { CHIP_9116, "LAN9116" }, | 700 | { CHIP_9116, "LAN9116" }, |
690 | { CHIP_9117, "LAN9117" }, | 701 | { CHIP_9117, "LAN9117" }, |
691 | { CHIP_9118, "LAN9118" }, | 702 | { CHIP_9118, "LAN9118" }, |
703 | { CHIP_9211, "LAN9211" }, | ||
692 | { CHIP_9215, "LAN9215" }, | 704 | { CHIP_9215, "LAN9215" }, |
693 | { CHIP_9217, "LAN9217" }, | 705 | { CHIP_9217, "LAN9217" }, |
694 | { CHIP_9218, "LAN9218" }, | 706 | { CHIP_9218, "LAN9218" }, |
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index c3e6aa137cdf..64dfa7f5f374 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
@@ -1229,7 +1229,7 @@ static void gem_reset(struct gem *gp) | |||
1229 | break; | 1229 | break; |
1230 | } while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST)); | 1230 | } while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST)); |
1231 | 1231 | ||
1232 | if (limit <= 0) | 1232 | if (limit < 0) |
1233 | printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name); | 1233 | printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name); |
1234 | 1234 | ||
1235 | if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes) | 1235 | if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes) |
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c index b397e8785d6d..f92fe86fdcae 100644 --- a/drivers/net/tokenring/tmspci.c +++ b/drivers/net/tokenring/tmspci.c | |||
@@ -121,11 +121,6 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic | |||
121 | goto err_out_trdev; | 121 | goto err_out_trdev; |
122 | } | 122 | } |
123 | 123 | ||
124 | ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, | ||
125 | dev->name, dev); | ||
126 | if (ret) | ||
127 | goto err_out_region; | ||
128 | |||
129 | dev->base_addr = pci_ioaddr; | 124 | dev->base_addr = pci_ioaddr; |
130 | dev->irq = pci_irq_line; | 125 | dev->irq = pci_irq_line; |
131 | dev->dma = 0; | 126 | dev->dma = 0; |
@@ -142,7 +137,7 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic | |||
142 | ret = tmsdev_init(dev, &pdev->dev); | 137 | ret = tmsdev_init(dev, &pdev->dev); |
143 | if (ret) { | 138 | if (ret) { |
144 | printk("%s: unable to get memory for dev->priv.\n", dev->name); | 139 | printk("%s: unable to get memory for dev->priv.\n", dev->name); |
145 | goto err_out_irq; | 140 | goto err_out_region; |
146 | } | 141 | } |
147 | 142 | ||
148 | tp = netdev_priv(dev); | 143 | tp = netdev_priv(dev); |
@@ -159,20 +154,25 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic | |||
159 | 154 | ||
160 | dev->netdev_ops = &tms380tr_netdev_ops; | 155 | dev->netdev_ops = &tms380tr_netdev_ops; |
161 | 156 | ||
157 | ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, | ||
158 | dev->name, dev); | ||
159 | if (ret) | ||
160 | goto err_out_tmsdev; | ||
161 | |||
162 | pci_set_drvdata(pdev, dev); | 162 | pci_set_drvdata(pdev, dev); |
163 | SET_NETDEV_DEV(dev, &pdev->dev); | 163 | SET_NETDEV_DEV(dev, &pdev->dev); |
164 | 164 | ||
165 | ret = register_netdev(dev); | 165 | ret = register_netdev(dev); |
166 | if (ret) | 166 | if (ret) |
167 | goto err_out_tmsdev; | 167 | goto err_out_irq; |
168 | 168 | ||
169 | return 0; | 169 | return 0; |
170 | 170 | ||
171 | err_out_irq: | ||
172 | free_irq(pdev->irq, dev); | ||
171 | err_out_tmsdev: | 173 | err_out_tmsdev: |
172 | pci_set_drvdata(pdev, NULL); | 174 | pci_set_drvdata(pdev, NULL); |
173 | tmsdev_term(dev); | 175 | tmsdev_term(dev); |
174 | err_out_irq: | ||
175 | free_irq(pdev->irq, dev); | ||
176 | err_out_region: | 176 | err_out_region: |
177 | release_region(pci_ioaddr, TMS_PCI_IO_EXTENT); | 177 | release_region(pci_ioaddr, TMS_PCI_IO_EXTENT); |
178 | err_out_trdev: | 178 | err_out_trdev: |
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 5b67bbf1987e..81682c6defa0 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c | |||
@@ -635,6 +635,10 @@ static const struct usb_device_id products[] = { | |||
635 | USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */ | 635 | USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */ |
636 | .driver_info = (unsigned long)&dm9601_info, | 636 | .driver_info = (unsigned long)&dm9601_info, |
637 | }, | 637 | }, |
638 | { | ||
639 | USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */ | ||
640 | .driver_info = (unsigned long)&dm9601_info, | ||
641 | }, | ||
638 | {}, // END | 642 | {}, // END |
639 | }; | 643 | }; |
640 | 644 | ||
diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h index fde6e4c634e7..a7cf550b9cca 100644 --- a/drivers/scsi/cxgb3i/cxgb3i.h +++ b/drivers/scsi/cxgb3i/cxgb3i.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | #include <linux/netdevice.h> | 21 | #include <linux/netdevice.h> |
22 | #include <linux/scatterlist.h> | 22 | #include <linux/scatterlist.h> |
23 | #include <linux/skbuff.h> | ||
23 | #include <scsi/libiscsi_tcp.h> | 24 | #include <scsi/libiscsi_tcp.h> |
24 | 25 | ||
25 | /* from cxgb3 LLD */ | 26 | /* from cxgb3 LLD */ |
@@ -113,6 +114,26 @@ struct cxgb3i_endpoint { | |||
113 | struct cxgb3i_conn *cconn; | 114 | struct cxgb3i_conn *cconn; |
114 | }; | 115 | }; |
115 | 116 | ||
117 | /** | ||
118 | * struct cxgb3i_task_data - private iscsi task data | ||
119 | * | ||
120 | * @nr_frags: # of coalesced page frags (from scsi sgl) | ||
121 | * @frags: coalesced page frags (from scsi sgl) | ||
122 | * @skb: tx pdu skb | ||
123 | * @offset: data offset for the next pdu | ||
124 | * @count: max. possible pdu payload | ||
125 | * @sgoffset: offset to the first sg entry for a given offset | ||
126 | */ | ||
127 | #define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512) | ||
128 | struct cxgb3i_task_data { | ||
129 | unsigned short nr_frags; | ||
130 | skb_frag_t frags[MAX_PDU_FRAGS]; | ||
131 | struct sk_buff *skb; | ||
132 | unsigned int offset; | ||
133 | unsigned int count; | ||
134 | unsigned int sgoffset; | ||
135 | }; | ||
136 | |||
116 | int cxgb3i_iscsi_init(void); | 137 | int cxgb3i_iscsi_init(void); |
117 | void cxgb3i_iscsi_cleanup(void); | 138 | void cxgb3i_iscsi_cleanup(void); |
118 | 139 | ||
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c index 08f3a09d9233..a83d36e4926f 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c +++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.c | |||
@@ -639,10 +639,11 @@ static int ddp_init(struct t3cdev *tdev) | |||
639 | write_unlock(&cxgb3i_ddp_rwlock); | 639 | write_unlock(&cxgb3i_ddp_rwlock); |
640 | 640 | ||
641 | ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x " | 641 | ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x " |
642 | "pkt %u,%u.\n", | 642 | "pkt %u/%u, %u/%u.\n", |
643 | ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits, | 643 | ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits, |
644 | ddp->idx_mask, ddp->rsvd_tag_mask, | 644 | ddp->idx_mask, ddp->rsvd_tag_mask, |
645 | ddp->max_txsz, ddp->max_rxsz); | 645 | ddp->max_txsz, uinfo.max_txsz, |
646 | ddp->max_rxsz, uinfo.max_rxsz); | ||
646 | return 0; | 647 | return 0; |
647 | 648 | ||
648 | free_ddp_map: | 649 | free_ddp_map: |
@@ -654,8 +655,8 @@ free_ddp_map: | |||
654 | * cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource | 655 | * cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource |
655 | * @tdev: t3cdev adapter | 656 | * @tdev: t3cdev adapter |
656 | * @tformat: tag format | 657 | * @tformat: tag format |
657 | * @txsz: max tx pkt size, filled in by this func. | 658 | * @txsz: max tx pdu payload size, filled in by this func. |
658 | * @rxsz: max rx pkt size, filled in by this func. | 659 | * @rxsz: max rx pdu payload size, filled in by this func. |
659 | * initialize the ddp pagepod manager for a given adapter if needed and | 660 | * initialize the ddp pagepod manager for a given adapter if needed and |
660 | * setup the tag format for a given iscsi entity | 661 | * setup the tag format for a given iscsi entity |
661 | */ | 662 | */ |
@@ -685,10 +686,12 @@ int cxgb3i_adapter_ddp_init(struct t3cdev *tdev, | |||
685 | tformat->sw_bits, tformat->rsvd_bits, | 686 | tformat->sw_bits, tformat->rsvd_bits, |
686 | tformat->rsvd_shift, tformat->rsvd_mask); | 687 | tformat->rsvd_shift, tformat->rsvd_mask); |
687 | 688 | ||
688 | *txsz = ddp->max_txsz; | 689 | *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, |
689 | *rxsz = ddp->max_rxsz; | 690 | ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN); |
690 | ddp_log_info("ddp max pkt size: %u, %u.\n", | 691 | *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, |
691 | ddp->max_txsz, ddp->max_rxsz); | 692 | ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN); |
693 | ddp_log_info("max payload size: %u/%u, %u/%u.\n", | ||
694 | *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz); | ||
692 | return 0; | 695 | return 0; |
693 | } | 696 | } |
694 | EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init); | 697 | EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init); |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h index f675807cc48f..3faae7831c83 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h +++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h | |||
@@ -87,8 +87,9 @@ struct cxgb3i_ddp_info { | |||
87 | struct sk_buff **gl_skb; | 87 | struct sk_buff **gl_skb; |
88 | }; | 88 | }; |
89 | 89 | ||
90 | #define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8) */ | ||
90 | #define ULP2_MAX_PKT_SIZE 16224 | 91 | #define ULP2_MAX_PKT_SIZE 16224 |
91 | #define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_MAX) | 92 | #define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN) |
92 | #define PPOD_PAGES_MAX 4 | 93 | #define PPOD_PAGES_MAX 4 |
93 | #define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */ | 94 | #define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */ |
94 | 95 | ||
diff --git a/drivers/scsi/cxgb3i/cxgb3i_init.c b/drivers/scsi/cxgb3i/cxgb3i_init.c index 091ecb4d9f3d..1ce9f244e46c 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_init.c +++ b/drivers/scsi/cxgb3i/cxgb3i_init.c | |||
@@ -12,8 +12,8 @@ | |||
12 | #include "cxgb3i.h" | 12 | #include "cxgb3i.h" |
13 | 13 | ||
14 | #define DRV_MODULE_NAME "cxgb3i" | 14 | #define DRV_MODULE_NAME "cxgb3i" |
15 | #define DRV_MODULE_VERSION "1.0.0" | 15 | #define DRV_MODULE_VERSION "1.0.1" |
16 | #define DRV_MODULE_RELDATE "Jun. 1, 2008" | 16 | #define DRV_MODULE_RELDATE "Jan. 2009" |
17 | 17 | ||
18 | static char version[] = | 18 | static char version[] = |
19 | "Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME | 19 | "Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index d83464b9b3f9..fa2a44f37b36 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c | |||
@@ -364,7 +364,8 @@ cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth, | |||
364 | 364 | ||
365 | cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost, | 365 | cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost, |
366 | cmds_max, | 366 | cmds_max, |
367 | sizeof(struct iscsi_tcp_task), | 367 | sizeof(struct iscsi_tcp_task) + |
368 | sizeof(struct cxgb3i_task_data), | ||
368 | initial_cmdsn, ISCSI_MAX_TARGET); | 369 | initial_cmdsn, ISCSI_MAX_TARGET); |
369 | if (!cls_session) | 370 | if (!cls_session) |
370 | return NULL; | 371 | return NULL; |
@@ -402,17 +403,15 @@ static inline int cxgb3i_conn_max_xmit_dlength(struct iscsi_conn *conn) | |||
402 | { | 403 | { |
403 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 404 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
404 | struct cxgb3i_conn *cconn = tcp_conn->dd_data; | 405 | struct cxgb3i_conn *cconn = tcp_conn->dd_data; |
405 | unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, | 406 | unsigned int max = max(512 * MAX_SKB_FRAGS, SKB_TX_HEADROOM); |
406 | cconn->hba->snic->tx_max_size - | ||
407 | ISCSI_PDU_NONPAYLOAD_MAX); | ||
408 | 407 | ||
408 | max = min(cconn->hba->snic->tx_max_size, max); | ||
409 | if (conn->max_xmit_dlength) | 409 | if (conn->max_xmit_dlength) |
410 | conn->max_xmit_dlength = min_t(unsigned int, | 410 | conn->max_xmit_dlength = min(conn->max_xmit_dlength, max); |
411 | conn->max_xmit_dlength, max); | ||
412 | else | 411 | else |
413 | conn->max_xmit_dlength = max; | 412 | conn->max_xmit_dlength = max; |
414 | align_pdu_size(conn->max_xmit_dlength); | 413 | align_pdu_size(conn->max_xmit_dlength); |
415 | cxgb3i_log_info("conn 0x%p, max xmit %u.\n", | 414 | cxgb3i_api_debug("conn 0x%p, max xmit %u.\n", |
416 | conn, conn->max_xmit_dlength); | 415 | conn, conn->max_xmit_dlength); |
417 | return 0; | 416 | return 0; |
418 | } | 417 | } |
@@ -427,9 +426,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn) | |||
427 | { | 426 | { |
428 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 427 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
429 | struct cxgb3i_conn *cconn = tcp_conn->dd_data; | 428 | struct cxgb3i_conn *cconn = tcp_conn->dd_data; |
430 | unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, | 429 | unsigned int max = cconn->hba->snic->rx_max_size; |
431 | cconn->hba->snic->rx_max_size - | ||
432 | ISCSI_PDU_NONPAYLOAD_MAX); | ||
433 | 430 | ||
434 | align_pdu_size(max); | 431 | align_pdu_size(max); |
435 | if (conn->max_recv_dlength) { | 432 | if (conn->max_recv_dlength) { |
@@ -439,8 +436,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn) | |||
439 | conn->max_recv_dlength, max); | 436 | conn->max_recv_dlength, max); |
440 | return -EINVAL; | 437 | return -EINVAL; |
441 | } | 438 | } |
442 | conn->max_recv_dlength = min_t(unsigned int, | 439 | conn->max_recv_dlength = min(conn->max_recv_dlength, max); |
443 | conn->max_recv_dlength, max); | ||
444 | align_pdu_size(conn->max_recv_dlength); | 440 | align_pdu_size(conn->max_recv_dlength); |
445 | } else | 441 | } else |
446 | conn->max_recv_dlength = max; | 442 | conn->max_recv_dlength = max; |
@@ -844,7 +840,7 @@ static struct scsi_host_template cxgb3i_host_template = { | |||
844 | .proc_name = "cxgb3i", | 840 | .proc_name = "cxgb3i", |
845 | .queuecommand = iscsi_queuecommand, | 841 | .queuecommand = iscsi_queuecommand, |
846 | .change_queue_depth = iscsi_change_queue_depth, | 842 | .change_queue_depth = iscsi_change_queue_depth, |
847 | .can_queue = 128 * (ISCSI_DEF_XMIT_CMDS_MAX - 1), | 843 | .can_queue = CXGB3I_SCSI_QDEPTH_DFLT - 1, |
848 | .sg_tablesize = SG_ALL, | 844 | .sg_tablesize = SG_ALL, |
849 | .max_sectors = 0xFFFF, | 845 | .max_sectors = 0xFFFF, |
850 | .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, | 846 | .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index a865f1fefe8b..de3b3b614cca 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c | |||
@@ -23,19 +23,19 @@ | |||
23 | #include "cxgb3i_ddp.h" | 23 | #include "cxgb3i_ddp.h" |
24 | 24 | ||
25 | #ifdef __DEBUG_C3CN_CONN__ | 25 | #ifdef __DEBUG_C3CN_CONN__ |
26 | #define c3cn_conn_debug cxgb3i_log_info | 26 | #define c3cn_conn_debug cxgb3i_log_debug |
27 | #else | 27 | #else |
28 | #define c3cn_conn_debug(fmt...) | 28 | #define c3cn_conn_debug(fmt...) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #ifdef __DEBUG_C3CN_TX__ | 31 | #ifdef __DEBUG_C3CN_TX__ |
32 | #define c3cn_tx_debug cxgb3i_log_debug | 32 | #define c3cn_tx_debug cxgb3i_log_debug |
33 | #else | 33 | #else |
34 | #define c3cn_tx_debug(fmt...) | 34 | #define c3cn_tx_debug(fmt...) |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | #ifdef __DEBUG_C3CN_RX__ | 37 | #ifdef __DEBUG_C3CN_RX__ |
38 | #define c3cn_rx_debug cxgb3i_log_debug | 38 | #define c3cn_rx_debug cxgb3i_log_debug |
39 | #else | 39 | #else |
40 | #define c3cn_rx_debug(fmt...) | 40 | #define c3cn_rx_debug(fmt...) |
41 | #endif | 41 | #endif |
@@ -47,9 +47,9 @@ static int cxgb3_rcv_win = 256 * 1024; | |||
47 | module_param(cxgb3_rcv_win, int, 0644); | 47 | module_param(cxgb3_rcv_win, int, 0644); |
48 | MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)"); | 48 | MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)"); |
49 | 49 | ||
50 | static int cxgb3_snd_win = 64 * 1024; | 50 | static int cxgb3_snd_win = 128 * 1024; |
51 | module_param(cxgb3_snd_win, int, 0644); | 51 | module_param(cxgb3_snd_win, int, 0644); |
52 | MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=64KB)"); | 52 | MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=128KB)"); |
53 | 53 | ||
54 | static int cxgb3_rx_credit_thres = 10 * 1024; | 54 | static int cxgb3_rx_credit_thres = 10 * 1024; |
55 | module_param(cxgb3_rx_credit_thres, int, 0644); | 55 | module_param(cxgb3_rx_credit_thres, int, 0644); |
@@ -301,8 +301,8 @@ static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb) | |||
301 | static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb, | 301 | static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb, |
302 | int flags) | 302 | int flags) |
303 | { | 303 | { |
304 | CXGB3_SKB_CB(skb)->seq = c3cn->write_seq; | 304 | skb_tcp_seq(skb) = c3cn->write_seq; |
305 | CXGB3_SKB_CB(skb)->flags = flags; | 305 | skb_flags(skb) = flags; |
306 | __skb_queue_tail(&c3cn->write_queue, skb); | 306 | __skb_queue_tail(&c3cn->write_queue, skb); |
307 | } | 307 | } |
308 | 308 | ||
@@ -457,12 +457,9 @@ static unsigned int wrlen __read_mostly; | |||
457 | * The number of WRs needed for an skb depends on the number of fragments | 457 | * The number of WRs needed for an skb depends on the number of fragments |
458 | * in the skb and whether it has any payload in its main body. This maps the | 458 | * in the skb and whether it has any payload in its main body. This maps the |
459 | * length of the gather list represented by an skb into the # of necessary WRs. | 459 | * length of the gather list represented by an skb into the # of necessary WRs. |
460 | * | 460 | * The extra two fragments are for iscsi bhs and payload padding. |
461 | * The max. length of an skb is controlled by the max pdu size which is ~16K. | ||
462 | * Also, assume the min. fragment length is the sector size (512), then add | ||
463 | * extra fragment counts for iscsi bhs and payload padding. | ||
464 | */ | 461 | */ |
465 | #define SKB_WR_LIST_SIZE (16384/512 + 3) | 462 | #define SKB_WR_LIST_SIZE (MAX_SKB_FRAGS + 2) |
466 | static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly; | 463 | static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly; |
467 | 464 | ||
468 | static void s3_init_wr_tab(unsigned int wr_len) | 465 | static void s3_init_wr_tab(unsigned int wr_len) |
@@ -485,7 +482,7 @@ static void s3_init_wr_tab(unsigned int wr_len) | |||
485 | 482 | ||
486 | static inline void reset_wr_list(struct s3_conn *c3cn) | 483 | static inline void reset_wr_list(struct s3_conn *c3cn) |
487 | { | 484 | { |
488 | c3cn->wr_pending_head = NULL; | 485 | c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL; |
489 | } | 486 | } |
490 | 487 | ||
491 | /* | 488 | /* |
@@ -496,7 +493,7 @@ static inline void reset_wr_list(struct s3_conn *c3cn) | |||
496 | static inline void enqueue_wr(struct s3_conn *c3cn, | 493 | static inline void enqueue_wr(struct s3_conn *c3cn, |
497 | struct sk_buff *skb) | 494 | struct sk_buff *skb) |
498 | { | 495 | { |
499 | skb_wr_data(skb) = NULL; | 496 | skb_tx_wr_next(skb) = NULL; |
500 | 497 | ||
501 | /* | 498 | /* |
502 | * We want to take an extra reference since both us and the driver | 499 | * We want to take an extra reference since both us and the driver |
@@ -509,10 +506,22 @@ static inline void enqueue_wr(struct s3_conn *c3cn, | |||
509 | if (!c3cn->wr_pending_head) | 506 | if (!c3cn->wr_pending_head) |
510 | c3cn->wr_pending_head = skb; | 507 | c3cn->wr_pending_head = skb; |
511 | else | 508 | else |
512 | skb_wr_data(skb) = skb; | 509 | skb_tx_wr_next(c3cn->wr_pending_tail) = skb; |
513 | c3cn->wr_pending_tail = skb; | 510 | c3cn->wr_pending_tail = skb; |
514 | } | 511 | } |
515 | 512 | ||
513 | static int count_pending_wrs(struct s3_conn *c3cn) | ||
514 | { | ||
515 | int n = 0; | ||
516 | const struct sk_buff *skb = c3cn->wr_pending_head; | ||
517 | |||
518 | while (skb) { | ||
519 | n += skb->csum; | ||
520 | skb = skb_tx_wr_next(skb); | ||
521 | } | ||
522 | return n; | ||
523 | } | ||
524 | |||
516 | static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn) | 525 | static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn) |
517 | { | 526 | { |
518 | return c3cn->wr_pending_head; | 527 | return c3cn->wr_pending_head; |
@@ -529,8 +538,8 @@ static inline struct sk_buff *dequeue_wr(struct s3_conn *c3cn) | |||
529 | 538 | ||
530 | if (likely(skb)) { | 539 | if (likely(skb)) { |
531 | /* Don't bother clearing the tail */ | 540 | /* Don't bother clearing the tail */ |
532 | c3cn->wr_pending_head = skb_wr_data(skb); | 541 | c3cn->wr_pending_head = skb_tx_wr_next(skb); |
533 | skb_wr_data(skb) = NULL; | 542 | skb_tx_wr_next(skb) = NULL; |
534 | } | 543 | } |
535 | return skb; | 544 | return skb; |
536 | } | 545 | } |
@@ -543,13 +552,14 @@ static void purge_wr_queue(struct s3_conn *c3cn) | |||
543 | } | 552 | } |
544 | 553 | ||
545 | static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb, | 554 | static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb, |
546 | int len) | 555 | int len, int req_completion) |
547 | { | 556 | { |
548 | struct tx_data_wr *req; | 557 | struct tx_data_wr *req; |
549 | 558 | ||
550 | skb_reset_transport_header(skb); | 559 | skb_reset_transport_header(skb); |
551 | req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req)); | 560 | req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req)); |
552 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 561 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) | |
562 | (req_completion ? F_WR_COMPL : 0)); | ||
553 | req->wr_lo = htonl(V_WR_TID(c3cn->tid)); | 563 | req->wr_lo = htonl(V_WR_TID(c3cn->tid)); |
554 | req->sndseq = htonl(c3cn->snd_nxt); | 564 | req->sndseq = htonl(c3cn->snd_nxt); |
555 | /* len includes the length of any HW ULP additions */ | 565 | /* len includes the length of any HW ULP additions */ |
@@ -592,7 +602,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion) | |||
592 | 602 | ||
593 | if (unlikely(c3cn->state == C3CN_STATE_CONNECTING || | 603 | if (unlikely(c3cn->state == C3CN_STATE_CONNECTING || |
594 | c3cn->state == C3CN_STATE_CLOSE_WAIT_1 || | 604 | c3cn->state == C3CN_STATE_CLOSE_WAIT_1 || |
595 | c3cn->state == C3CN_STATE_ABORTING)) { | 605 | c3cn->state >= C3CN_STATE_ABORTING)) { |
596 | c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n", | 606 | c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n", |
597 | c3cn, c3cn->state); | 607 | c3cn, c3cn->state); |
598 | return 0; | 608 | return 0; |
@@ -615,7 +625,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion) | |||
615 | if (c3cn->wr_avail < wrs_needed) { | 625 | if (c3cn->wr_avail < wrs_needed) { |
616 | c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, " | 626 | c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, " |
617 | "wr %d < %u.\n", | 627 | "wr %d < %u.\n", |
618 | c3cn, skb->len, skb->datalen, frags, | 628 | c3cn, skb->len, skb->data_len, frags, |
619 | wrs_needed, c3cn->wr_avail); | 629 | wrs_needed, c3cn->wr_avail); |
620 | break; | 630 | break; |
621 | } | 631 | } |
@@ -627,20 +637,24 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion) | |||
627 | c3cn->wr_unacked += wrs_needed; | 637 | c3cn->wr_unacked += wrs_needed; |
628 | enqueue_wr(c3cn, skb); | 638 | enqueue_wr(c3cn, skb); |
629 | 639 | ||
630 | if (likely(CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_NEED_HDR)) { | 640 | c3cn_tx_debug("c3cn 0x%p, enqueue, skb len %u/%u, frag %u, " |
631 | len += ulp_extra_len(skb); | 641 | "wr %d, left %u, unack %u.\n", |
632 | make_tx_data_wr(c3cn, skb, len); | 642 | c3cn, skb->len, skb->data_len, frags, |
633 | c3cn->snd_nxt += len; | 643 | wrs_needed, c3cn->wr_avail, c3cn->wr_unacked); |
634 | if ((req_completion | 644 | |
635 | && c3cn->wr_unacked == wrs_needed) | ||
636 | || (CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_COMPL) | ||
637 | || c3cn->wr_unacked >= c3cn->wr_max / 2) { | ||
638 | struct work_request_hdr *wr = cplhdr(skb); | ||
639 | 645 | ||
640 | wr->wr_hi |= htonl(F_WR_COMPL); | 646 | if (likely(skb_flags(skb) & C3CB_FLAG_NEED_HDR)) { |
647 | if ((req_completion && | ||
648 | c3cn->wr_unacked == wrs_needed) || | ||
649 | (skb_flags(skb) & C3CB_FLAG_COMPL) || | ||
650 | c3cn->wr_unacked >= c3cn->wr_max / 2) { | ||
651 | req_completion = 1; | ||
641 | c3cn->wr_unacked = 0; | 652 | c3cn->wr_unacked = 0; |
642 | } | 653 | } |
643 | CXGB3_SKB_CB(skb)->flags &= ~C3CB_FLAG_NEED_HDR; | 654 | len += ulp_extra_len(skb); |
655 | make_tx_data_wr(c3cn, skb, len, req_completion); | ||
656 | c3cn->snd_nxt += len; | ||
657 | skb_flags(skb) &= ~C3CB_FLAG_NEED_HDR; | ||
644 | } | 658 | } |
645 | 659 | ||
646 | total_size += skb->truesize; | 660 | total_size += skb->truesize; |
@@ -735,8 +749,11 @@ static void process_act_establish(struct s3_conn *c3cn, struct sk_buff *skb) | |||
735 | if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED))) | 749 | if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED))) |
736 | /* upper layer has requested closing */ | 750 | /* upper layer has requested closing */ |
737 | send_abort_req(c3cn); | 751 | send_abort_req(c3cn); |
738 | else if (c3cn_push_tx_frames(c3cn, 1)) | 752 | else { |
753 | if (skb_queue_len(&c3cn->write_queue)) | ||
754 | c3cn_push_tx_frames(c3cn, 1); | ||
739 | cxgb3i_conn_tx_open(c3cn); | 755 | cxgb3i_conn_tx_open(c3cn); |
756 | } | ||
740 | } | 757 | } |
741 | 758 | ||
742 | static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb, | 759 | static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb, |
@@ -1082,8 +1099,8 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb) | |||
1082 | return; | 1099 | return; |
1083 | } | 1100 | } |
1084 | 1101 | ||
1085 | CXGB3_SKB_CB(skb)->seq = ntohl(hdr_cpl->seq); | 1102 | skb_tcp_seq(skb) = ntohl(hdr_cpl->seq); |
1086 | CXGB3_SKB_CB(skb)->flags = 0; | 1103 | skb_flags(skb) = 0; |
1087 | 1104 | ||
1088 | skb_reset_transport_header(skb); | 1105 | skb_reset_transport_header(skb); |
1089 | __skb_pull(skb, sizeof(struct cpl_iscsi_hdr)); | 1106 | __skb_pull(skb, sizeof(struct cpl_iscsi_hdr)); |
@@ -1103,12 +1120,12 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb) | |||
1103 | goto abort_conn; | 1120 | goto abort_conn; |
1104 | 1121 | ||
1105 | skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY; | 1122 | skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY; |
1106 | skb_ulp_pdulen(skb) = ntohs(ddp_cpl.len); | 1123 | skb_rx_pdulen(skb) = ntohs(ddp_cpl.len); |
1107 | skb_ulp_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); | 1124 | skb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); |
1108 | status = ntohl(ddp_cpl.ddp_status); | 1125 | status = ntohl(ddp_cpl.ddp_status); |
1109 | 1126 | ||
1110 | c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n", | 1127 | c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n", |
1111 | skb, skb->len, skb_ulp_pdulen(skb), status); | 1128 | skb, skb->len, skb_rx_pdulen(skb), status); |
1112 | 1129 | ||
1113 | if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT)) | 1130 | if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT)) |
1114 | skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR; | 1131 | skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR; |
@@ -1126,7 +1143,7 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb) | |||
1126 | } else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT)) | 1143 | } else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT)) |
1127 | skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED; | 1144 | skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED; |
1128 | 1145 | ||
1129 | c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_ulp_pdulen(skb); | 1146 | c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_rx_pdulen(skb); |
1130 | __pskb_trim(skb, len); | 1147 | __pskb_trim(skb, len); |
1131 | __skb_queue_tail(&c3cn->receive_queue, skb); | 1148 | __skb_queue_tail(&c3cn->receive_queue, skb); |
1132 | cxgb3i_conn_pdu_ready(c3cn); | 1149 | cxgb3i_conn_pdu_ready(c3cn); |
@@ -1151,12 +1168,27 @@ static int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx) | |||
1151 | * Process an acknowledgment of WR completion. Advance snd_una and send the | 1168 | * Process an acknowledgment of WR completion. Advance snd_una and send the |
1152 | * next batch of work requests from the write queue. | 1169 | * next batch of work requests from the write queue. |
1153 | */ | 1170 | */ |
1171 | static void check_wr_invariants(struct s3_conn *c3cn) | ||
1172 | { | ||
1173 | int pending = count_pending_wrs(c3cn); | ||
1174 | |||
1175 | if (unlikely(c3cn->wr_avail + pending != c3cn->wr_max)) | ||
1176 | cxgb3i_log_error("TID %u: credit imbalance: avail %u, " | ||
1177 | "pending %u, total should be %u\n", | ||
1178 | c3cn->tid, c3cn->wr_avail, pending, | ||
1179 | c3cn->wr_max); | ||
1180 | } | ||
1181 | |||
1154 | static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) | 1182 | static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) |
1155 | { | 1183 | { |
1156 | struct cpl_wr_ack *hdr = cplhdr(skb); | 1184 | struct cpl_wr_ack *hdr = cplhdr(skb); |
1157 | unsigned int credits = ntohs(hdr->credits); | 1185 | unsigned int credits = ntohs(hdr->credits); |
1158 | u32 snd_una = ntohl(hdr->snd_una); | 1186 | u32 snd_una = ntohl(hdr->snd_una); |
1159 | 1187 | ||
1188 | c3cn_tx_debug("%u WR credits, avail %u, unack %u, TID %u, state %u.\n", | ||
1189 | credits, c3cn->wr_avail, c3cn->wr_unacked, | ||
1190 | c3cn->tid, c3cn->state); | ||
1191 | |||
1160 | c3cn->wr_avail += credits; | 1192 | c3cn->wr_avail += credits; |
1161 | if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail) | 1193 | if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail) |
1162 | c3cn->wr_unacked = c3cn->wr_max - c3cn->wr_avail; | 1194 | c3cn->wr_unacked = c3cn->wr_max - c3cn->wr_avail; |
@@ -1171,6 +1203,17 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) | |||
1171 | break; | 1203 | break; |
1172 | } | 1204 | } |
1173 | if (unlikely(credits < p->csum)) { | 1205 | if (unlikely(credits < p->csum)) { |
1206 | struct tx_data_wr *w = cplhdr(p); | ||
1207 | cxgb3i_log_error("TID %u got %u WR credits need %u, " | ||
1208 | "len %u, main body %u, frags %u, " | ||
1209 | "seq # %u, ACK una %u, ACK nxt %u, " | ||
1210 | "WR_AVAIL %u, WRs pending %u\n", | ||
1211 | c3cn->tid, credits, p->csum, p->len, | ||
1212 | p->len - p->data_len, | ||
1213 | skb_shinfo(p)->nr_frags, | ||
1214 | ntohl(w->sndseq), snd_una, | ||
1215 | ntohl(hdr->snd_nxt), c3cn->wr_avail, | ||
1216 | count_pending_wrs(c3cn) - credits); | ||
1174 | p->csum -= credits; | 1217 | p->csum -= credits; |
1175 | break; | 1218 | break; |
1176 | } else { | 1219 | } else { |
@@ -1180,15 +1223,24 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) | |||
1180 | } | 1223 | } |
1181 | } | 1224 | } |
1182 | 1225 | ||
1183 | if (unlikely(before(snd_una, c3cn->snd_una))) | 1226 | check_wr_invariants(c3cn); |
1227 | |||
1228 | if (unlikely(before(snd_una, c3cn->snd_una))) { | ||
1229 | cxgb3i_log_error("TID %u, unexpected sequence # %u in WR_ACK " | ||
1230 | "snd_una %u\n", | ||
1231 | c3cn->tid, snd_una, c3cn->snd_una); | ||
1184 | goto out_free; | 1232 | goto out_free; |
1233 | } | ||
1185 | 1234 | ||
1186 | if (c3cn->snd_una != snd_una) { | 1235 | if (c3cn->snd_una != snd_una) { |
1187 | c3cn->snd_una = snd_una; | 1236 | c3cn->snd_una = snd_una; |
1188 | dst_confirm(c3cn->dst_cache); | 1237 | dst_confirm(c3cn->dst_cache); |
1189 | } | 1238 | } |
1190 | 1239 | ||
1191 | if (skb_queue_len(&c3cn->write_queue) && c3cn_push_tx_frames(c3cn, 0)) | 1240 | if (skb_queue_len(&c3cn->write_queue)) { |
1241 | if (c3cn_push_tx_frames(c3cn, 0)) | ||
1242 | cxgb3i_conn_tx_open(c3cn); | ||
1243 | } else | ||
1192 | cxgb3i_conn_tx_open(c3cn); | 1244 | cxgb3i_conn_tx_open(c3cn); |
1193 | out_free: | 1245 | out_free: |
1194 | __kfree_skb(skb); | 1246 | __kfree_skb(skb); |
@@ -1452,7 +1504,7 @@ static void init_offload_conn(struct s3_conn *c3cn, | |||
1452 | struct dst_entry *dst) | 1504 | struct dst_entry *dst) |
1453 | { | 1505 | { |
1454 | BUG_ON(c3cn->cdev != cdev); | 1506 | BUG_ON(c3cn->cdev != cdev); |
1455 | c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs; | 1507 | c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs - 1; |
1456 | c3cn->wr_unacked = 0; | 1508 | c3cn->wr_unacked = 0; |
1457 | c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst)); | 1509 | c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst)); |
1458 | 1510 | ||
@@ -1671,9 +1723,17 @@ int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb) | |||
1671 | goto out_err; | 1723 | goto out_err; |
1672 | } | 1724 | } |
1673 | 1725 | ||
1674 | err = -EPIPE; | ||
1675 | if (c3cn->err) { | 1726 | if (c3cn->err) { |
1676 | c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err); | 1727 | c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err); |
1728 | err = -EPIPE; | ||
1729 | goto out_err; | ||
1730 | } | ||
1731 | |||
1732 | if (c3cn->write_seq - c3cn->snd_una >= cxgb3_snd_win) { | ||
1733 | c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n", | ||
1734 | c3cn, c3cn->write_seq, c3cn->snd_una, | ||
1735 | cxgb3_snd_win); | ||
1736 | err = -EAGAIN; | ||
1677 | goto out_err; | 1737 | goto out_err; |
1678 | } | 1738 | } |
1679 | 1739 | ||
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h index d23156907ffd..6344b9eb2589 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.h +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h | |||
@@ -178,25 +178,33 @@ void cxgb3i_c3cn_release(struct s3_conn *); | |||
178 | * @flag: see C3CB_FLAG_* below | 178 | * @flag: see C3CB_FLAG_* below |
179 | * @ulp_mode: ULP mode/submode of sk_buff | 179 | * @ulp_mode: ULP mode/submode of sk_buff |
180 | * @seq: tcp sequence number | 180 | * @seq: tcp sequence number |
181 | * @ddigest: pdu data digest | ||
182 | * @pdulen: recovered pdu length | ||
183 | * @wr_data: scratch area for tx wr | ||
184 | */ | 181 | */ |
182 | struct cxgb3_skb_rx_cb { | ||
183 | __u32 ddigest; /* data digest */ | ||
184 | __u32 pdulen; /* recovered pdu length */ | ||
185 | }; | ||
186 | |||
187 | struct cxgb3_skb_tx_cb { | ||
188 | struct sk_buff *wr_next; /* next wr */ | ||
189 | }; | ||
190 | |||
185 | struct cxgb3_skb_cb { | 191 | struct cxgb3_skb_cb { |
186 | __u8 flags; | 192 | __u8 flags; |
187 | __u8 ulp_mode; | 193 | __u8 ulp_mode; |
188 | __u32 seq; | 194 | __u32 seq; |
189 | __u32 ddigest; | 195 | union { |
190 | __u32 pdulen; | 196 | struct cxgb3_skb_rx_cb rx; |
191 | struct sk_buff *wr_data; | 197 | struct cxgb3_skb_tx_cb tx; |
198 | }; | ||
192 | }; | 199 | }; |
193 | 200 | ||
194 | #define CXGB3_SKB_CB(skb) ((struct cxgb3_skb_cb *)&((skb)->cb[0])) | 201 | #define CXGB3_SKB_CB(skb) ((struct cxgb3_skb_cb *)&((skb)->cb[0])) |
195 | 202 | #define skb_flags(skb) (CXGB3_SKB_CB(skb)->flags) | |
196 | #define skb_ulp_mode(skb) (CXGB3_SKB_CB(skb)->ulp_mode) | 203 | #define skb_ulp_mode(skb) (CXGB3_SKB_CB(skb)->ulp_mode) |
197 | #define skb_ulp_ddigest(skb) (CXGB3_SKB_CB(skb)->ddigest) | 204 | #define skb_tcp_seq(skb) (CXGB3_SKB_CB(skb)->seq) |
198 | #define skb_ulp_pdulen(skb) (CXGB3_SKB_CB(skb)->pdulen) | 205 | #define skb_rx_ddigest(skb) (CXGB3_SKB_CB(skb)->rx.ddigest) |
199 | #define skb_wr_data(skb) (CXGB3_SKB_CB(skb)->wr_data) | 206 | #define skb_rx_pdulen(skb) (CXGB3_SKB_CB(skb)->rx.pdulen) |
207 | #define skb_tx_wr_next(skb) (CXGB3_SKB_CB(skb)->tx.wr_next) | ||
200 | 208 | ||
201 | enum c3cb_flags { | 209 | enum c3cb_flags { |
202 | C3CB_FLAG_NEED_HDR = 1 << 0, /* packet needs a TX_DATA_WR header */ | 210 | C3CB_FLAG_NEED_HDR = 1 << 0, /* packet needs a TX_DATA_WR header */ |
@@ -217,6 +225,7 @@ struct sge_opaque_hdr { | |||
217 | /* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */ | 225 | /* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */ |
218 | #define TX_HEADER_LEN \ | 226 | #define TX_HEADER_LEN \ |
219 | (sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr)) | 227 | (sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr)) |
228 | #define SKB_TX_HEADROOM SKB_MAX_HEAD(TX_HEADER_LEN) | ||
220 | 229 | ||
221 | /* | 230 | /* |
222 | * get and set private ip for iscsi traffic | 231 | * get and set private ip for iscsi traffic |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c index ce7ce8c6094c..17115c230d65 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c +++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c | |||
@@ -32,6 +32,10 @@ | |||
32 | #define cxgb3i_tx_debug(fmt...) | 32 | #define cxgb3i_tx_debug(fmt...) |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | /* always allocate rooms for AHS */ | ||
36 | #define SKB_TX_PDU_HEADER_LEN \ | ||
37 | (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE) | ||
38 | static unsigned int skb_extra_headroom; | ||
35 | static struct page *pad_page; | 39 | static struct page *pad_page; |
36 | 40 | ||
37 | /* | 41 | /* |
@@ -146,12 +150,13 @@ static inline void tx_skb_setmode(struct sk_buff *skb, int hcrc, int dcrc) | |||
146 | 150 | ||
147 | void cxgb3i_conn_cleanup_task(struct iscsi_task *task) | 151 | void cxgb3i_conn_cleanup_task(struct iscsi_task *task) |
148 | { | 152 | { |
149 | struct iscsi_tcp_task *tcp_task = task->dd_data; | 153 | struct cxgb3i_task_data *tdata = task->dd_data + |
154 | sizeof(struct iscsi_tcp_task); | ||
150 | 155 | ||
151 | /* never reached the xmit task callout */ | 156 | /* never reached the xmit task callout */ |
152 | if (tcp_task->dd_data) | 157 | if (tdata->skb) |
153 | kfree_skb(tcp_task->dd_data); | 158 | __kfree_skb(tdata->skb); |
154 | tcp_task->dd_data = NULL; | 159 | memset(tdata, 0, sizeof(struct cxgb3i_task_data)); |
155 | 160 | ||
156 | /* MNC - Do we need a check in case this is called but | 161 | /* MNC - Do we need a check in case this is called but |
157 | * cxgb3i_conn_alloc_pdu has never been called on the task */ | 162 | * cxgb3i_conn_alloc_pdu has never been called on the task */ |
@@ -159,28 +164,102 @@ void cxgb3i_conn_cleanup_task(struct iscsi_task *task) | |||
159 | iscsi_tcp_cleanup_task(task); | 164 | iscsi_tcp_cleanup_task(task); |
160 | } | 165 | } |
161 | 166 | ||
162 | /* | 167 | static int sgl_seek_offset(struct scatterlist *sgl, unsigned int sgcnt, |
163 | * We do not support ahs yet | 168 | unsigned int offset, unsigned int *off, |
164 | */ | 169 | struct scatterlist **sgp) |
170 | { | ||
171 | int i; | ||
172 | struct scatterlist *sg; | ||
173 | |||
174 | for_each_sg(sgl, sg, sgcnt, i) { | ||
175 | if (offset < sg->length) { | ||
176 | *off = offset; | ||
177 | *sgp = sg; | ||
178 | return 0; | ||
179 | } | ||
180 | offset -= sg->length; | ||
181 | } | ||
182 | return -EFAULT; | ||
183 | } | ||
184 | |||
185 | static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset, | ||
186 | unsigned int dlen, skb_frag_t *frags, | ||
187 | int frag_max) | ||
188 | { | ||
189 | unsigned int datalen = dlen; | ||
190 | unsigned int sglen = sg->length - sgoffset; | ||
191 | struct page *page = sg_page(sg); | ||
192 | int i; | ||
193 | |||
194 | i = 0; | ||
195 | do { | ||
196 | unsigned int copy; | ||
197 | |||
198 | if (!sglen) { | ||
199 | sg = sg_next(sg); | ||
200 | if (!sg) { | ||
201 | cxgb3i_log_error("%s, sg NULL, len %u/%u.\n", | ||
202 | __func__, datalen, dlen); | ||
203 | return -EINVAL; | ||
204 | } | ||
205 | sgoffset = 0; | ||
206 | sglen = sg->length; | ||
207 | page = sg_page(sg); | ||
208 | |||
209 | } | ||
210 | copy = min(datalen, sglen); | ||
211 | if (i && page == frags[i - 1].page && | ||
212 | sgoffset + sg->offset == | ||
213 | frags[i - 1].page_offset + frags[i - 1].size) { | ||
214 | frags[i - 1].size += copy; | ||
215 | } else { | ||
216 | if (i >= frag_max) { | ||
217 | cxgb3i_log_error("%s, too many pages %u, " | ||
218 | "dlen %u.\n", __func__, | ||
219 | frag_max, dlen); | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | |||
223 | frags[i].page = page; | ||
224 | frags[i].page_offset = sg->offset + sgoffset; | ||
225 | frags[i].size = copy; | ||
226 | i++; | ||
227 | } | ||
228 | datalen -= copy; | ||
229 | sgoffset += copy; | ||
230 | sglen -= copy; | ||
231 | } while (datalen); | ||
232 | |||
233 | return i; | ||
234 | } | ||
235 | |||
165 | int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode) | 236 | int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode) |
166 | { | 237 | { |
238 | struct iscsi_conn *conn = task->conn; | ||
167 | struct iscsi_tcp_task *tcp_task = task->dd_data; | 239 | struct iscsi_tcp_task *tcp_task = task->dd_data; |
168 | struct sk_buff *skb; | 240 | struct cxgb3i_task_data *tdata = task->dd_data + sizeof(*tcp_task); |
241 | struct scsi_cmnd *sc = task->sc; | ||
242 | int headroom = SKB_TX_PDU_HEADER_LEN; | ||
169 | 243 | ||
244 | tcp_task->dd_data = tdata; | ||
170 | task->hdr = NULL; | 245 | task->hdr = NULL; |
171 | /* always allocate rooms for AHS */ | 246 | |
172 | skb = alloc_skb(sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE + | 247 | /* write command, need to send data pdus */ |
173 | TX_HEADER_LEN, GFP_ATOMIC); | 248 | if (skb_extra_headroom && (opcode == ISCSI_OP_SCSI_DATA_OUT || |
174 | if (!skb) | 249 | (opcode == ISCSI_OP_SCSI_CMD && |
250 | (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE)))) | ||
251 | headroom += min(skb_extra_headroom, conn->max_xmit_dlength); | ||
252 | |||
253 | tdata->skb = alloc_skb(TX_HEADER_LEN + headroom, GFP_ATOMIC); | ||
254 | if (!tdata->skb) | ||
175 | return -ENOMEM; | 255 | return -ENOMEM; |
256 | skb_reserve(tdata->skb, TX_HEADER_LEN); | ||
176 | 257 | ||
177 | cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n", | 258 | cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n", |
178 | task, opcode, skb); | 259 | task, opcode, tdata->skb); |
179 | 260 | ||
180 | tcp_task->dd_data = skb; | 261 | task->hdr = (struct iscsi_hdr *)tdata->skb->data; |
181 | skb_reserve(skb, TX_HEADER_LEN); | 262 | task->hdr_max = SKB_TX_PDU_HEADER_LEN; |
182 | task->hdr = (struct iscsi_hdr *)skb->data; | ||
183 | task->hdr_max = sizeof(struct iscsi_hdr); | ||
184 | 263 | ||
185 | /* data_out uses scsi_cmd's itt */ | 264 | /* data_out uses scsi_cmd's itt */ |
186 | if (opcode != ISCSI_OP_SCSI_DATA_OUT) | 265 | if (opcode != ISCSI_OP_SCSI_DATA_OUT) |
@@ -192,13 +271,13 @@ int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode) | |||
192 | int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset, | 271 | int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset, |
193 | unsigned int count) | 272 | unsigned int count) |
194 | { | 273 | { |
195 | struct iscsi_tcp_task *tcp_task = task->dd_data; | ||
196 | struct sk_buff *skb = tcp_task->dd_data; | ||
197 | struct iscsi_conn *conn = task->conn; | 274 | struct iscsi_conn *conn = task->conn; |
198 | struct page *pg; | 275 | struct iscsi_tcp_task *tcp_task = task->dd_data; |
276 | struct cxgb3i_task_data *tdata = tcp_task->dd_data; | ||
277 | struct sk_buff *skb = tdata->skb; | ||
199 | unsigned int datalen = count; | 278 | unsigned int datalen = count; |
200 | int i, padlen = iscsi_padding(count); | 279 | int i, padlen = iscsi_padding(count); |
201 | skb_frag_t *frag; | 280 | struct page *pg; |
202 | 281 | ||
203 | cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n", | 282 | cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n", |
204 | task, task->sc, offset, count, skb); | 283 | task, task->sc, offset, count, skb); |
@@ -209,90 +288,94 @@ int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset, | |||
209 | return 0; | 288 | return 0; |
210 | 289 | ||
211 | if (task->sc) { | 290 | if (task->sc) { |
212 | struct scatterlist *sg; | 291 | struct scsi_data_buffer *sdb = scsi_out(task->sc); |
213 | struct scsi_data_buffer *sdb; | 292 | struct scatterlist *sg = NULL; |
214 | unsigned int sgoffset = offset; | 293 | int err; |
215 | struct page *sgpg; | 294 | |
216 | unsigned int sglen; | 295 | tdata->offset = offset; |
217 | 296 | tdata->count = count; | |
218 | sdb = scsi_out(task->sc); | 297 | err = sgl_seek_offset(sdb->table.sgl, sdb->table.nents, |
219 | sg = sdb->table.sgl; | 298 | tdata->offset, &tdata->sgoffset, &sg); |
220 | 299 | if (err < 0) { | |
221 | for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { | 300 | cxgb3i_log_warn("tpdu, sgl %u, bad offset %u/%u.\n", |
222 | cxgb3i_tx_debug("sg %d, page 0x%p, len %u offset %u\n", | 301 | sdb->table.nents, tdata->offset, |
223 | i, sg_page(sg), sg->length, sg->offset); | 302 | sdb->length); |
224 | 303 | return err; | |
225 | if (sgoffset < sg->length) | ||
226 | break; | ||
227 | sgoffset -= sg->length; | ||
228 | } | 304 | } |
229 | sgpg = sg_page(sg); | 305 | err = sgl_read_to_frags(sg, tdata->sgoffset, tdata->count, |
230 | sglen = sg->length - sgoffset; | 306 | tdata->frags, MAX_PDU_FRAGS); |
231 | 307 | if (err < 0) { | |
232 | do { | 308 | cxgb3i_log_warn("tpdu, sgl %u, bad offset %u + %u.\n", |
233 | int j = skb_shinfo(skb)->nr_frags; | 309 | sdb->table.nents, tdata->offset, |
234 | unsigned int copy; | 310 | tdata->count); |
235 | 311 | return err; | |
236 | if (!sglen) { | 312 | } |
237 | sg = sg_next(sg); | 313 | tdata->nr_frags = err; |
238 | sgpg = sg_page(sg); | 314 | |
239 | sgoffset = 0; | 315 | if (tdata->nr_frags > MAX_SKB_FRAGS || |
240 | sglen = sg->length; | 316 | (padlen && tdata->nr_frags == MAX_SKB_FRAGS)) { |
241 | ++i; | 317 | char *dst = skb->data + task->hdr_len; |
318 | skb_frag_t *frag = tdata->frags; | ||
319 | |||
320 | /* data fits in the skb's headroom */ | ||
321 | for (i = 0; i < tdata->nr_frags; i++, frag++) { | ||
322 | char *src = kmap_atomic(frag->page, | ||
323 | KM_SOFTIRQ0); | ||
324 | |||
325 | memcpy(dst, src+frag->page_offset, frag->size); | ||
326 | dst += frag->size; | ||
327 | kunmap_atomic(src, KM_SOFTIRQ0); | ||
242 | } | 328 | } |
243 | copy = min(sglen, datalen); | 329 | if (padlen) { |
244 | if (j && skb_can_coalesce(skb, j, sgpg, | 330 | memset(dst, 0, padlen); |
245 | sg->offset + sgoffset)) { | 331 | padlen = 0; |
246 | skb_shinfo(skb)->frags[j - 1].size += copy; | ||
247 | } else { | ||
248 | get_page(sgpg); | ||
249 | skb_fill_page_desc(skb, j, sgpg, | ||
250 | sg->offset + sgoffset, copy); | ||
251 | } | 332 | } |
252 | sgoffset += copy; | 333 | skb_put(skb, count + padlen); |
253 | sglen -= copy; | 334 | } else { |
254 | datalen -= copy; | 335 | /* data fit into frag_list */ |
255 | } while (datalen); | 336 | for (i = 0; i < tdata->nr_frags; i++) |
337 | get_page(tdata->frags[i].page); | ||
338 | |||
339 | memcpy(skb_shinfo(skb)->frags, tdata->frags, | ||
340 | sizeof(skb_frag_t) * tdata->nr_frags); | ||
341 | skb_shinfo(skb)->nr_frags = tdata->nr_frags; | ||
342 | skb->len += count; | ||
343 | skb->data_len += count; | ||
344 | skb->truesize += count; | ||
345 | } | ||
346 | |||
256 | } else { | 347 | } else { |
257 | pg = virt_to_page(task->data); | 348 | pg = virt_to_page(task->data); |
258 | 349 | ||
259 | while (datalen) { | 350 | get_page(pg); |
260 | i = skb_shinfo(skb)->nr_frags; | 351 | skb_fill_page_desc(skb, 0, pg, offset_in_page(task->data), |
261 | frag = &skb_shinfo(skb)->frags[i]; | 352 | count); |
262 | 353 | skb->len += count; | |
263 | get_page(pg); | 354 | skb->data_len += count; |
264 | frag->page = pg; | 355 | skb->truesize += count; |
265 | frag->page_offset = 0; | ||
266 | frag->size = min((unsigned int)PAGE_SIZE, datalen); | ||
267 | |||
268 | skb_shinfo(skb)->nr_frags++; | ||
269 | datalen -= frag->size; | ||
270 | pg++; | ||
271 | } | ||
272 | } | 356 | } |
273 | 357 | ||
274 | if (padlen) { | 358 | if (padlen) { |
275 | i = skb_shinfo(skb)->nr_frags; | 359 | i = skb_shinfo(skb)->nr_frags; |
276 | frag = &skb_shinfo(skb)->frags[i]; | 360 | get_page(pad_page); |
277 | frag->page = pad_page; | 361 | skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, pad_page, 0, |
278 | frag->page_offset = 0; | 362 | padlen); |
279 | frag->size = padlen; | 363 | |
280 | skb_shinfo(skb)->nr_frags++; | 364 | skb->data_len += padlen; |
365 | skb->truesize += padlen; | ||
366 | skb->len += padlen; | ||
281 | } | 367 | } |
282 | 368 | ||
283 | datalen = count + padlen; | ||
284 | skb->data_len += datalen; | ||
285 | skb->truesize += datalen; | ||
286 | skb->len += datalen; | ||
287 | return 0; | 369 | return 0; |
288 | } | 370 | } |
289 | 371 | ||
290 | int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) | 372 | int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) |
291 | { | 373 | { |
292 | struct iscsi_tcp_task *tcp_task = task->dd_data; | ||
293 | struct sk_buff *skb = tcp_task->dd_data; | ||
294 | struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data; | 374 | struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data; |
295 | struct cxgb3i_conn *cconn = tcp_conn->dd_data; | 375 | struct cxgb3i_conn *cconn = tcp_conn->dd_data; |
376 | struct iscsi_tcp_task *tcp_task = task->dd_data; | ||
377 | struct cxgb3i_task_data *tdata = tcp_task->dd_data; | ||
378 | struct sk_buff *skb = tdata->skb; | ||
296 | unsigned int datalen; | 379 | unsigned int datalen; |
297 | int err; | 380 | int err; |
298 | 381 | ||
@@ -300,13 +383,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) | |||
300 | return 0; | 383 | return 0; |
301 | 384 | ||
302 | datalen = skb->data_len; | 385 | datalen = skb->data_len; |
303 | tcp_task->dd_data = NULL; | 386 | tdata->skb = NULL; |
304 | err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb); | 387 | err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb); |
305 | cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", | ||
306 | task, skb, skb->len, skb->data_len, err); | ||
307 | if (err > 0) { | 388 | if (err > 0) { |
308 | int pdulen = err; | 389 | int pdulen = err; |
309 | 390 | ||
391 | cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", | ||
392 | task, skb, skb->len, skb->data_len, err); | ||
393 | |||
310 | if (task->conn->hdrdgst_en) | 394 | if (task->conn->hdrdgst_en) |
311 | pdulen += ISCSI_DIGEST_SIZE; | 395 | pdulen += ISCSI_DIGEST_SIZE; |
312 | if (datalen && task->conn->datadgst_en) | 396 | if (datalen && task->conn->datadgst_en) |
@@ -325,12 +409,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) | |||
325 | return err; | 409 | return err; |
326 | } | 410 | } |
327 | /* reset skb to send when we are called again */ | 411 | /* reset skb to send when we are called again */ |
328 | tcp_task->dd_data = skb; | 412 | tdata->skb = skb; |
329 | return -EAGAIN; | 413 | return -EAGAIN; |
330 | } | 414 | } |
331 | 415 | ||
332 | int cxgb3i_pdu_init(void) | 416 | int cxgb3i_pdu_init(void) |
333 | { | 417 | { |
418 | if (SKB_TX_HEADROOM > (512 * MAX_SKB_FRAGS)) | ||
419 | skb_extra_headroom = SKB_TX_HEADROOM; | ||
334 | pad_page = alloc_page(GFP_KERNEL); | 420 | pad_page = alloc_page(GFP_KERNEL); |
335 | if (!pad_page) | 421 | if (!pad_page) |
336 | return -ENOMEM; | 422 | return -ENOMEM; |
@@ -366,7 +452,9 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn) | |||
366 | skb = skb_peek(&c3cn->receive_queue); | 452 | skb = skb_peek(&c3cn->receive_queue); |
367 | while (!err && skb) { | 453 | while (!err && skb) { |
368 | __skb_unlink(skb, &c3cn->receive_queue); | 454 | __skb_unlink(skb, &c3cn->receive_queue); |
369 | read += skb_ulp_pdulen(skb); | 455 | read += skb_rx_pdulen(skb); |
456 | cxgb3i_rx_debug("conn 0x%p, cn 0x%p, rx skb 0x%p, pdulen %u.\n", | ||
457 | conn, c3cn, skb, skb_rx_pdulen(skb)); | ||
370 | err = cxgb3i_conn_read_pdu_skb(conn, skb); | 458 | err = cxgb3i_conn_read_pdu_skb(conn, skb); |
371 | __kfree_skb(skb); | 459 | __kfree_skb(skb); |
372 | skb = skb_peek(&c3cn->receive_queue); | 460 | skb = skb_peek(&c3cn->receive_queue); |
@@ -377,6 +465,11 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn) | |||
377 | cxgb3i_c3cn_rx_credits(c3cn, read); | 465 | cxgb3i_c3cn_rx_credits(c3cn, read); |
378 | } | 466 | } |
379 | conn->rxdata_octets += read; | 467 | conn->rxdata_octets += read; |
468 | |||
469 | if (err) { | ||
470 | cxgb3i_log_info("conn 0x%p rx failed err %d.\n", conn, err); | ||
471 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | ||
472 | } | ||
380 | } | 473 | } |
381 | 474 | ||
382 | void cxgb3i_conn_tx_open(struct s3_conn *c3cn) | 475 | void cxgb3i_conn_tx_open(struct s3_conn *c3cn) |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.h b/drivers/scsi/cxgb3i/cxgb3i_pdu.h index a3f685cc2362..0770b23d90da 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_pdu.h +++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.h | |||
@@ -53,7 +53,7 @@ struct cpl_rx_data_ddp_norss { | |||
53 | #define ULP2_FLAG_DCRC_ERROR 0x20 | 53 | #define ULP2_FLAG_DCRC_ERROR 0x20 |
54 | #define ULP2_FLAG_PAD_ERROR 0x40 | 54 | #define ULP2_FLAG_PAD_ERROR 0x40 |
55 | 55 | ||
56 | void cxgb3i_conn_closing(struct s3_conn *); | 56 | void cxgb3i_conn_closing(struct s3_conn *c3cn); |
57 | void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn); | 57 | void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn); |
58 | void cxgb3i_conn_tx_open(struct s3_conn *c3cn); | 58 | void cxgb3i_conn_tx_open(struct s3_conn *c3cn); |
59 | #endif | 59 | #endif |
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index a48e4990fe12..34be88d7afa5 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c | |||
@@ -1251,6 +1251,7 @@ static struct pci_device_id hptiop_id_table[] = { | |||
1251 | { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops }, | 1251 | { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops }, |
1252 | { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops }, | 1252 | { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops }, |
1253 | { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops }, | 1253 | { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops }, |
1254 | { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops }, | ||
1254 | { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops }, | 1255 | { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops }, |
1255 | { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops }, | 1256 | { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops }, |
1256 | { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops }, | 1257 | { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops }, |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 940dc32ff0dc..b82ffd90632e 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1040,12 +1040,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
1040 | action = ACTION_FAIL; | 1040 | action = ACTION_FAIL; |
1041 | break; | 1041 | break; |
1042 | case ABORTED_COMMAND: | 1042 | case ABORTED_COMMAND: |
1043 | action = ACTION_FAIL; | ||
1043 | if (sshdr.asc == 0x10) { /* DIF */ | 1044 | if (sshdr.asc == 0x10) { /* DIF */ |
1044 | description = "Target Data Integrity Failure"; | 1045 | description = "Target Data Integrity Failure"; |
1045 | action = ACTION_FAIL; | ||
1046 | error = -EILSEQ; | 1046 | error = -EILSEQ; |
1047 | } else | 1047 | } |
1048 | action = ACTION_RETRY; | ||
1049 | break; | 1048 | break; |
1050 | case NOT_READY: | 1049 | case NOT_READY: |
1051 | /* If the device is in the process of becoming | 1050 | /* If the device is in the process of becoming |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d57566b8be0a..55310dbc10a6 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -107,6 +107,7 @@ static void scsi_disk_release(struct device *cdev); | |||
107 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); | 107 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); |
108 | static void sd_print_result(struct scsi_disk *, int); | 108 | static void sd_print_result(struct scsi_disk *, int); |
109 | 109 | ||
110 | static DEFINE_SPINLOCK(sd_index_lock); | ||
110 | static DEFINE_IDA(sd_index_ida); | 111 | static DEFINE_IDA(sd_index_ida); |
111 | 112 | ||
112 | /* This semaphore is used to mediate the 0->1 reference get in the | 113 | /* This semaphore is used to mediate the 0->1 reference get in the |
@@ -1914,7 +1915,9 @@ static int sd_probe(struct device *dev) | |||
1914 | if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) | 1915 | if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) |
1915 | goto out_put; | 1916 | goto out_put; |
1916 | 1917 | ||
1918 | spin_lock(&sd_index_lock); | ||
1917 | error = ida_get_new(&sd_index_ida, &index); | 1919 | error = ida_get_new(&sd_index_ida, &index); |
1920 | spin_unlock(&sd_index_lock); | ||
1918 | } while (error == -EAGAIN); | 1921 | } while (error == -EAGAIN); |
1919 | 1922 | ||
1920 | if (error) | 1923 | if (error) |
@@ -1936,7 +1939,9 @@ static int sd_probe(struct device *dev) | |||
1936 | return 0; | 1939 | return 0; |
1937 | 1940 | ||
1938 | out_free_index: | 1941 | out_free_index: |
1942 | spin_lock(&sd_index_lock); | ||
1939 | ida_remove(&sd_index_ida, index); | 1943 | ida_remove(&sd_index_ida, index); |
1944 | spin_unlock(&sd_index_lock); | ||
1940 | out_put: | 1945 | out_put: |
1941 | put_disk(gd); | 1946 | put_disk(gd); |
1942 | out_free: | 1947 | out_free: |
@@ -1986,7 +1991,9 @@ static void scsi_disk_release(struct device *dev) | |||
1986 | struct scsi_disk *sdkp = to_scsi_disk(dev); | 1991 | struct scsi_disk *sdkp = to_scsi_disk(dev); |
1987 | struct gendisk *disk = sdkp->disk; | 1992 | struct gendisk *disk = sdkp->disk; |
1988 | 1993 | ||
1994 | spin_lock(&sd_index_lock); | ||
1989 | ida_remove(&sd_index_ida, sdkp->index); | 1995 | ida_remove(&sd_index_ida, sdkp->index); |
1996 | spin_unlock(&sd_index_lock); | ||
1990 | 1997 | ||
1991 | disk->private_data = NULL; | 1998 | disk->private_data = NULL; |
1992 | put_disk(disk); | 1999 | put_disk(disk); |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 48ff701d3a72..2552b9f325ee 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -2230,7 +2230,7 @@ static int __devexit pxafb_remove(struct platform_device *dev) | |||
2230 | 2230 | ||
2231 | static struct platform_driver pxafb_driver = { | 2231 | static struct platform_driver pxafb_driver = { |
2232 | .probe = pxafb_probe, | 2232 | .probe = pxafb_probe, |
2233 | .remove = pxafb_remove, | 2233 | .remove = __devexit_p(pxafb_remove), |
2234 | .suspend = pxafb_suspend, | 2234 | .suspend = pxafb_suspend, |
2235 | .resume = pxafb_resume, | 2235 | .resume = pxafb_resume, |
2236 | .driver = { | 2236 | .driver = { |