Contents of /trunk/kernel-magellan/patches-3.6/0105-3.6.6-all-fixes.patch
Parent Directory | Revision Log
Revision 1938 -
(show annotations)
(download)
Mon Nov 5 13:38:02 2012 UTC (11 years, 10 months ago) by niro
File size: 43674 byte(s)
Mon Nov 5 13:38:02 2012 UTC (11 years, 10 months ago) by niro
File size: 43674 byte(s)
-3.6.6-magellan-r1
1 | diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c |
2 | index f3b44a6..54f35d1c0 100644 |
3 | --- a/block/blk-cgroup.c |
4 | +++ b/block/blk-cgroup.c |
5 | @@ -285,6 +285,13 @@ static void blkg_destroy_all(struct request_queue *q) |
6 | blkg_destroy(blkg); |
7 | spin_unlock(&blkcg->lock); |
8 | } |
9 | + |
10 | + /* |
11 | + * root blkg is destroyed. Just clear the pointer since |
12 | + * root_rl does not take reference on root blkg. |
13 | + */ |
14 | + q->root_blkg = NULL; |
15 | + q->root_rl.blkg = NULL; |
16 | } |
17 | |
18 | static void blkg_rcu_free(struct rcu_head *rcu_head) |
19 | diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c |
20 | index a7d6347..fe0de7e 100644 |
21 | --- a/drivers/block/floppy.c |
22 | +++ b/drivers/block/floppy.c |
23 | @@ -4138,6 +4138,10 @@ static int __init do_floppy_init(void) |
24 | |
25 | raw_cmd = NULL; |
26 | |
27 | + floppy_wq = alloc_ordered_workqueue("floppy", 0); |
28 | + if (!floppy_wq) |
29 | + return -ENOMEM; |
30 | + |
31 | for (dr = 0; dr < N_DRIVE; dr++) { |
32 | disks[dr] = alloc_disk(1); |
33 | if (!disks[dr]) { |
34 | @@ -4145,16 +4149,11 @@ static int __init do_floppy_init(void) |
35 | goto out_put_disk; |
36 | } |
37 | |
38 | - floppy_wq = alloc_ordered_workqueue("floppy", 0); |
39 | - if (!floppy_wq) { |
40 | - err = -ENOMEM; |
41 | - goto out_put_disk; |
42 | - } |
43 | - |
44 | disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); |
45 | if (!disks[dr]->queue) { |
46 | + put_disk(disks[dr]); |
47 | err = -ENOMEM; |
48 | - goto out_destroy_workq; |
49 | + goto out_put_disk; |
50 | } |
51 | |
52 | blk_queue_max_hw_sectors(disks[dr]->queue, 64); |
53 | @@ -4294,7 +4293,7 @@ static int __init do_floppy_init(void) |
54 | |
55 | err = platform_device_register(&floppy_device[drive]); |
56 | if (err) |
57 | - goto out_release_dma; |
58 | + goto out_remove_drives; |
59 | |
60 | err = device_create_file(&floppy_device[drive].dev, |
61 | &dev_attr_cmos); |
62 | @@ -4312,14 +4311,21 @@ static int __init do_floppy_init(void) |
63 | |
64 | out_unreg_platform_dev: |
65 | platform_device_unregister(&floppy_device[drive]); |
66 | +out_remove_drives: |
67 | + while (drive--) { |
68 | + if ((allowed_drive_mask & (1 << drive)) && |
69 | + fdc_state[FDC(drive)].version != FDC_NONE) { |
70 | + del_gendisk(disks[drive]); |
71 | + device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); |
72 | + platform_device_unregister(&floppy_device[drive]); |
73 | + } |
74 | + } |
75 | out_release_dma: |
76 | if (atomic_read(&usage_count)) |
77 | floppy_release_irq_and_dma(); |
78 | out_unreg_region: |
79 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); |
80 | platform_driver_unregister(&floppy_driver); |
81 | -out_destroy_workq: |
82 | - destroy_workqueue(floppy_wq); |
83 | out_unreg_blkdev: |
84 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
85 | out_put_disk: |
86 | @@ -4335,6 +4341,7 @@ out_put_disk: |
87 | } |
88 | put_disk(disks[dr]); |
89 | } |
90 | + destroy_workqueue(floppy_wq); |
91 | return err; |
92 | } |
93 | |
94 | diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c |
95 | index 031c6ad..1a3e2b9 100644 |
96 | --- a/drivers/gpio/gpio-timberdale.c |
97 | +++ b/drivers/gpio/gpio-timberdale.c |
98 | @@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d) |
99 | unsigned long flags; |
100 | |
101 | spin_lock_irqsave(&tgpio->lock, flags); |
102 | - tgpio->last_ier &= ~(1 << offset); |
103 | + tgpio->last_ier &= ~(1UL << offset); |
104 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); |
105 | spin_unlock_irqrestore(&tgpio->lock, flags); |
106 | } |
107 | @@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d) |
108 | unsigned long flags; |
109 | |
110 | spin_lock_irqsave(&tgpio->lock, flags); |
111 | - tgpio->last_ier |= 1 << offset; |
112 | + tgpio->last_ier |= 1UL << offset; |
113 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); |
114 | spin_unlock_irqrestore(&tgpio->lock, flags); |
115 | } |
116 | diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c |
117 | index de0213c..f03ae68 100644 |
118 | --- a/drivers/gpio/gpiolib.c |
119 | +++ b/drivers/gpio/gpiolib.c |
120 | @@ -623,9 +623,11 @@ static ssize_t export_store(struct class *class, |
121 | */ |
122 | |
123 | status = gpio_request(gpio, "sysfs"); |
124 | - if (status < 0) |
125 | + if (status < 0) { |
126 | + if (status == -EPROBE_DEFER) |
127 | + status = -ENODEV; |
128 | goto done; |
129 | - |
130 | + } |
131 | status = gpio_export(gpio, true); |
132 | if (status < 0) |
133 | gpio_free(gpio); |
134 | @@ -1191,8 +1193,10 @@ int gpio_request(unsigned gpio, const char *label) |
135 | |
136 | spin_lock_irqsave(&gpio_lock, flags); |
137 | |
138 | - if (!gpio_is_valid(gpio)) |
139 | + if (!gpio_is_valid(gpio)) { |
140 | + status = -EINVAL; |
141 | goto done; |
142 | + } |
143 | desc = &gpio_desc[gpio]; |
144 | chip = desc->chip; |
145 | if (chip == NULL) |
146 | diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c |
147 | index 9a36f5f..a06eb3d 100644 |
148 | --- a/drivers/gpu/drm/nouveau/nouveau_drv.c |
149 | +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c |
150 | @@ -188,11 +188,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) |
151 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
152 | return 0; |
153 | |
154 | - NV_INFO(dev, "Disabling display...\n"); |
155 | - nouveau_display_fini(dev); |
156 | + if (dev->mode_config.num_crtc) { |
157 | + NV_INFO(dev, "Disabling display...\n"); |
158 | + nouveau_display_fini(dev); |
159 | |
160 | - NV_INFO(dev, "Disabling fbcon...\n"); |
161 | - nouveau_fbcon_set_suspend(dev, 1); |
162 | + NV_INFO(dev, "Disabling fbcon...\n"); |
163 | + nouveau_fbcon_set_suspend(dev, 1); |
164 | + } |
165 | |
166 | NV_INFO(dev, "Unpinning framebuffer(s)...\n"); |
167 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
168 | @@ -359,10 +361,12 @@ nouveau_pci_resume(struct pci_dev *pdev) |
169 | NV_ERROR(dev, "Could not pin/map cursor.\n"); |
170 | } |
171 | |
172 | - nouveau_fbcon_set_suspend(dev, 0); |
173 | - nouveau_fbcon_zfill_all(dev); |
174 | + if (dev->mode_config.num_crtc) { |
175 | + nouveau_fbcon_set_suspend(dev, 0); |
176 | + nouveau_fbcon_zfill_all(dev); |
177 | |
178 | - nouveau_display_init(dev); |
179 | + nouveau_display_init(dev); |
180 | + } |
181 | |
182 | /* Force CLUT to get re-loaded during modeset */ |
183 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
184 | @@ -484,9 +488,7 @@ static int __init nouveau_init(void) |
185 | #ifdef CONFIG_VGA_CONSOLE |
186 | if (vgacon_text_force()) |
187 | nouveau_modeset = 0; |
188 | - else |
189 | #endif |
190 | - nouveau_modeset = 1; |
191 | } |
192 | |
193 | if (!nouveau_modeset) |
194 | diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c |
195 | index c610144..f5e9584 100644 |
196 | --- a/drivers/gpu/drm/nouveau/nouveau_state.c |
197 | +++ b/drivers/gpu/drm/nouveau/nouveau_state.c |
198 | @@ -50,6 +50,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) |
199 | { |
200 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
201 | struct nouveau_engine *engine = &dev_priv->engine; |
202 | + u32 pclass = dev->pdev->class >> 8; |
203 | |
204 | switch (dev_priv->chipset & 0xf0) { |
205 | case 0x00: |
206 | @@ -428,7 +429,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) |
207 | } |
208 | |
209 | /* headless mode */ |
210 | - if (nouveau_modeset == 2) { |
211 | + if (nouveau_modeset == 2 || |
212 | + (nouveau_modeset < 0 && pclass != PCI_CLASS_DISPLAY_VGA)) { |
213 | engine->display.early_init = nouveau_stub_init; |
214 | engine->display.late_takedown = nouveau_stub_takedown; |
215 | engine->display.create = nouveau_stub_init; |
216 | diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c |
217 | index 38f1947..09ac275 100644 |
218 | --- a/drivers/gpu/drm/nouveau/nv04_dac.c |
219 | +++ b/drivers/gpu/drm/nouveau/nv04_dac.c |
220 | @@ -210,7 +210,7 @@ out: |
221 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); |
222 | |
223 | if (blue == 0x18) { |
224 | - NV_INFO(dev, "Load detected on head A\n"); |
225 | + NV_DEBUG(dev, "Load detected on head A\n"); |
226 | return connector_status_connected; |
227 | } |
228 | |
229 | @@ -323,7 +323,7 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) |
230 | |
231 | if (nv17_dac_sample_load(encoder) & |
232 | NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { |
233 | - NV_INFO(dev, "Load detected on output %c\n", |
234 | + NV_DEBUG(dev, "Load detected on output %c\n", |
235 | '@' + ffs(dcb->or)); |
236 | return connector_status_connected; |
237 | } else { |
238 | @@ -398,7 +398,7 @@ static void nv04_dac_commit(struct drm_encoder *encoder) |
239 | |
240 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
241 | |
242 | - NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", |
243 | + NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n", |
244 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), |
245 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
246 | } |
247 | @@ -447,7 +447,7 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) |
248 | return; |
249 | nv_encoder->last_dpms = mode; |
250 | |
251 | - NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n", |
252 | + NV_DEBUG(dev, "Setting dpms mode %d on vga encoder (output %d)\n", |
253 | mode, nv_encoder->dcb->index); |
254 | |
255 | nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); |
256 | diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c |
257 | index c267562..89640f2 100644 |
258 | --- a/drivers/gpu/drm/nouveau/nv04_dfp.c |
259 | +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c |
260 | @@ -476,7 +476,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) |
261 | |
262 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
263 | |
264 | - NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", |
265 | + NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n", |
266 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), |
267 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
268 | } |
269 | @@ -519,7 +519,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) |
270 | return; |
271 | nv_encoder->last_dpms = mode; |
272 | |
273 | - NV_INFO(dev, "Setting dpms mode %d on lvds encoder (output %d)\n", |
274 | + NV_DEBUG(dev, "Setting dpms mode %d on lvds encoder (output %d)\n", |
275 | mode, nv_encoder->dcb->index); |
276 | |
277 | if (was_powersaving && is_powersaving_dpms(mode)) |
278 | @@ -564,7 +564,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) |
279 | return; |
280 | nv_encoder->last_dpms = mode; |
281 | |
282 | - NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", |
283 | + NV_DEBUG(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", |
284 | mode, nv_encoder->dcb->index); |
285 | |
286 | nv04_dfp_update_backlight(encoder, mode); |
287 | diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c |
288 | index 3eb605d..4de1fbe 100644 |
289 | --- a/drivers/gpu/drm/nouveau/nv04_tv.c |
290 | +++ b/drivers/gpu/drm/nouveau/nv04_tv.c |
291 | @@ -69,7 +69,7 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) |
292 | struct nv04_mode_state *state = &dev_priv->mode_reg; |
293 | uint8_t crtc1A; |
294 | |
295 | - NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n", |
296 | + NV_DEBUG(dev, "Setting dpms mode %d on TV encoder (output %d)\n", |
297 | mode, nv_encoder->dcb->index); |
298 | |
299 | state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); |
300 | @@ -162,7 +162,7 @@ static void nv04_tv_commit(struct drm_encoder *encoder) |
301 | |
302 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
303 | |
304 | - NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", |
305 | + NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n", |
306 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, |
307 | '@' + ffs(nv_encoder->dcb->or)); |
308 | } |
309 | diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c |
310 | index e5c699b..3899989 100644 |
311 | --- a/drivers/hid/hid-microsoft.c |
312 | +++ b/drivers/hid/hid-microsoft.c |
313 | @@ -29,22 +29,30 @@ |
314 | #define MS_RDESC 0x08 |
315 | #define MS_NOGET 0x10 |
316 | #define MS_DUPLICATE_USAGES 0x20 |
317 | +#define MS_RDESC_3K 0x40 |
318 | |
319 | -/* |
320 | - * Microsoft Wireless Desktop Receiver (Model 1028) has |
321 | - * 'Usage Min/Max' where it ought to have 'Physical Min/Max' |
322 | - */ |
323 | static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
324 | unsigned int *rsize) |
325 | { |
326 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
327 | |
328 | + /* |
329 | + * Microsoft Wireless Desktop Receiver (Model 1028) has |
330 | + * 'Usage Min/Max' where it ought to have 'Physical Min/Max' |
331 | + */ |
332 | if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && |
333 | rdesc[559] == 0x29) { |
334 | hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); |
335 | rdesc[557] = 0x35; |
336 | rdesc[559] = 0x45; |
337 | } |
338 | + /* the same as above (s/usage/physical/) */ |
339 | + if ((quirks & MS_RDESC_3K) && *rsize == 106 && |
340 | + !memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, |
341 | + &rdesc[94], 4)) { |
342 | + rdesc[94] = 0x35; |
343 | + rdesc[96] = 0x45; |
344 | + } |
345 | return rdesc; |
346 | } |
347 | |
348 | @@ -193,7 +201,7 @@ static const struct hid_device_id ms_devices[] = { |
349 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), |
350 | .driver_data = MS_PRESENTER }, |
351 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), |
352 | - .driver_data = MS_ERGONOMY }, |
353 | + .driver_data = MS_ERGONOMY | MS_RDESC_3K }, |
354 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), |
355 | .driver_data = MS_NOGET }, |
356 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), |
357 | diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c |
358 | index 611b5f7..05bb49e 100644 |
359 | --- a/drivers/md/raid1.c |
360 | +++ b/drivers/md/raid1.c |
361 | @@ -2699,7 +2699,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) |
362 | || disk_idx < 0) |
363 | continue; |
364 | if (test_bit(Replacement, &rdev->flags)) |
365 | - disk = conf->mirrors + conf->raid_disks + disk_idx; |
366 | + disk = conf->mirrors + mddev->raid_disks + disk_idx; |
367 | else |
368 | disk = conf->mirrors + disk_idx; |
369 | |
370 | diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c |
371 | index 41b74ba..515c250 100644 |
372 | --- a/drivers/scsi/qla2xxx/qla_target.c |
373 | +++ b/drivers/scsi/qla2xxx/qla_target.c |
374 | @@ -557,6 +557,7 @@ static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, |
375 | int pmap_len; |
376 | fc_port_t *fcport; |
377 | int global_resets; |
378 | + unsigned long flags; |
379 | |
380 | retry: |
381 | global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); |
382 | @@ -625,10 +626,10 @@ retry: |
383 | sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, |
384 | fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); |
385 | |
386 | - sess->s_id = fcport->d_id; |
387 | - sess->loop_id = fcport->loop_id; |
388 | - sess->conf_compl_supported = !!(fcport->flags & |
389 | - FCF_CONF_COMP_SUPPORTED); |
390 | + spin_lock_irqsave(&ha->hardware_lock, flags); |
391 | + ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, |
392 | + (fcport->flags & FCF_CONF_COMP_SUPPORTED)); |
393 | + spin_unlock_irqrestore(&ha->hardware_lock, flags); |
394 | |
395 | res = true; |
396 | |
397 | @@ -740,10 +741,9 @@ static struct qla_tgt_sess *qlt_create_sess( |
398 | qlt_undelete_sess(sess); |
399 | |
400 | kref_get(&sess->se_sess->sess_kref); |
401 | - sess->s_id = fcport->d_id; |
402 | - sess->loop_id = fcport->loop_id; |
403 | - sess->conf_compl_supported = !!(fcport->flags & |
404 | - FCF_CONF_COMP_SUPPORTED); |
405 | + ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, |
406 | + (fcport->flags & FCF_CONF_COMP_SUPPORTED)); |
407 | + |
408 | if (sess->local && !local) |
409 | sess->local = 0; |
410 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
411 | @@ -796,8 +796,7 @@ static struct qla_tgt_sess *qlt_create_sess( |
412 | */ |
413 | kref_get(&sess->se_sess->sess_kref); |
414 | |
415 | - sess->conf_compl_supported = !!(fcport->flags & |
416 | - FCF_CONF_COMP_SUPPORTED); |
417 | + sess->conf_compl_supported = (fcport->flags & FCF_CONF_COMP_SUPPORTED); |
418 | BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); |
419 | memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); |
420 | |
421 | @@ -869,10 +868,8 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) |
422 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, |
423 | "Reappeared sess %p\n", sess); |
424 | } |
425 | - sess->s_id = fcport->d_id; |
426 | - sess->loop_id = fcport->loop_id; |
427 | - sess->conf_compl_supported = !!(fcport->flags & |
428 | - FCF_CONF_COMP_SUPPORTED); |
429 | + ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, |
430 | + (fcport->flags & FCF_CONF_COMP_SUPPORTED)); |
431 | } |
432 | |
433 | if (sess && sess->local) { |
434 | diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h |
435 | index 170af15..bad7495 100644 |
436 | --- a/drivers/scsi/qla2xxx/qla_target.h |
437 | +++ b/drivers/scsi/qla2xxx/qla_target.h |
438 | @@ -648,6 +648,7 @@ struct qla_tgt_func_tmpl { |
439 | |
440 | int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, |
441 | void *, uint8_t *, uint16_t); |
442 | + void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool); |
443 | struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, |
444 | const uint16_t); |
445 | struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, |
446 | diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c |
447 | index 4752f65..7fa0672 100644 |
448 | --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c |
449 | +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c |
450 | @@ -1468,6 +1468,78 @@ static int tcm_qla2xxx_check_initiator_node_acl( |
451 | return 0; |
452 | } |
453 | |
454 | +static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id, |
455 | + uint16_t loop_id, bool conf_compl_supported) |
456 | +{ |
457 | + struct qla_tgt *tgt = sess->tgt; |
458 | + struct qla_hw_data *ha = tgt->ha; |
459 | + struct tcm_qla2xxx_lport *lport = ha->tgt.target_lport_ptr; |
460 | + struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; |
461 | + struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, |
462 | + struct tcm_qla2xxx_nacl, se_node_acl); |
463 | + u32 key; |
464 | + |
465 | + |
466 | + if (sess->loop_id != loop_id || sess->s_id.b24 != s_id.b24) |
467 | + pr_info("Updating session %p from port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x loop_id %d -> %d s_id %x:%x:%x -> %x:%x:%x\n", |
468 | + sess, |
469 | + sess->port_name[0], sess->port_name[1], |
470 | + sess->port_name[2], sess->port_name[3], |
471 | + sess->port_name[4], sess->port_name[5], |
472 | + sess->port_name[6], sess->port_name[7], |
473 | + sess->loop_id, loop_id, |
474 | + sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa, |
475 | + s_id.b.domain, s_id.b.area, s_id.b.al_pa); |
476 | + |
477 | + if (sess->loop_id != loop_id) { |
478 | + /* |
479 | + * Because we can shuffle loop IDs around and we |
480 | + * update different sessions non-atomically, we might |
481 | + * have overwritten this session's old loop ID |
482 | + * already, and we might end up overwriting some other |
483 | + * session that will be updated later. So we have to |
484 | + * be extra careful and we can't warn about those things... |
485 | + */ |
486 | + if (lport->lport_loopid_map[sess->loop_id].se_nacl == se_nacl) |
487 | + lport->lport_loopid_map[sess->loop_id].se_nacl = NULL; |
488 | + |
489 | + lport->lport_loopid_map[loop_id].se_nacl = se_nacl; |
490 | + |
491 | + sess->loop_id = loop_id; |
492 | + } |
493 | + |
494 | + if (sess->s_id.b24 != s_id.b24) { |
495 | + key = (((u32) sess->s_id.b.domain << 16) | |
496 | + ((u32) sess->s_id.b.area << 8) | |
497 | + ((u32) sess->s_id.b.al_pa)); |
498 | + |
499 | + if (btree_lookup32(&lport->lport_fcport_map, key)) |
500 | + WARN(btree_remove32(&lport->lport_fcport_map, key) != se_nacl, |
501 | + "Found wrong se_nacl when updating s_id %x:%x:%x\n", |
502 | + sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); |
503 | + else |
504 | + WARN(1, "No lport_fcport_map entry for s_id %x:%x:%x\n", |
505 | + sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); |
506 | + |
507 | + key = (((u32) s_id.b.domain << 16) | |
508 | + ((u32) s_id.b.area << 8) | |
509 | + ((u32) s_id.b.al_pa)); |
510 | + |
511 | + if (btree_lookup32(&lport->lport_fcport_map, key)) { |
512 | + WARN(1, "Already have lport_fcport_map entry for s_id %x:%x:%x\n", |
513 | + s_id.b.domain, s_id.b.area, s_id.b.al_pa); |
514 | + btree_update32(&lport->lport_fcport_map, key, se_nacl); |
515 | + } else { |
516 | + btree_insert32(&lport->lport_fcport_map, key, se_nacl, GFP_ATOMIC); |
517 | + } |
518 | + |
519 | + sess->s_id = s_id; |
520 | + nacl->nport_id = key; |
521 | + } |
522 | + |
523 | + sess->conf_compl_supported = conf_compl_supported; |
524 | +} |
525 | + |
526 | /* |
527 | * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. |
528 | */ |
529 | @@ -1478,6 +1550,7 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { |
530 | .free_cmd = tcm_qla2xxx_free_cmd, |
531 | .free_mcmd = tcm_qla2xxx_free_mcmd, |
532 | .free_session = tcm_qla2xxx_free_session, |
533 | + .update_sess = tcm_qla2xxx_update_sess, |
534 | .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, |
535 | .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, |
536 | .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, |
537 | diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c |
538 | index a9dd946..323e192 100644 |
539 | --- a/drivers/target/target_core_sbc.c |
540 | +++ b/drivers/target/target_core_sbc.c |
541 | @@ -128,6 +128,12 @@ static int sbc_emulate_verify(struct se_cmd *cmd) |
542 | return 0; |
543 | } |
544 | |
545 | +static int sbc_emulate_noop(struct se_cmd *cmd) |
546 | +{ |
547 | + target_complete_cmd(cmd, GOOD); |
548 | + return 0; |
549 | +} |
550 | + |
551 | static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) |
552 | { |
553 | return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; |
554 | @@ -524,6 +530,18 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) |
555 | size = 0; |
556 | cmd->execute_cmd = sbc_emulate_verify; |
557 | break; |
558 | + case REZERO_UNIT: |
559 | + case SEEK_6: |
560 | + case SEEK_10: |
561 | + /* |
562 | + * There are still clients out there which use these old SCSI-2 |
563 | + * commands. This mainly happens when running VMs with legacy |
564 | + * guest systems, connected via SCSI command pass-through to |
565 | + * iSCSI targets. Make them happy and return status GOOD. |
566 | + */ |
567 | + size = 0; |
568 | + cmd->execute_cmd = sbc_emulate_noop; |
569 | + break; |
570 | default: |
571 | ret = spc_parse_cdb(cmd, &size); |
572 | if (ret) |
573 | diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c |
574 | index 269f544..7502660 100644 |
575 | --- a/drivers/target/target_core_transport.c |
576 | +++ b/drivers/target/target_core_transport.c |
577 | @@ -1553,7 +1553,6 @@ static void target_complete_tmr_failure(struct work_struct *work) |
578 | |
579 | se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; |
580 | se_cmd->se_tfo->queue_tm_rsp(se_cmd); |
581 | - transport_generic_free_cmd(se_cmd, 0); |
582 | } |
583 | |
584 | /** |
585 | diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c |
586 | index dca27a5..6c22679 100644 |
587 | --- a/drivers/usb/serial/io_edgeport.c |
588 | +++ b/drivers/usb/serial/io_edgeport.c |
589 | @@ -3152,7 +3152,6 @@ static void edge_disconnect(struct usb_serial *serial) |
590 | static void edge_release(struct usb_serial *serial) |
591 | { |
592 | struct edgeport_serial *edge_serial = usb_get_serial_data(serial); |
593 | - int i; |
594 | |
595 | dbg("%s", __func__); |
596 | |
597 | diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c |
598 | index cdf0f99..8d3692b 100644 |
599 | --- a/drivers/usb/serial/iuu_phoenix.c |
600 | +++ b/drivers/usb/serial/iuu_phoenix.c |
601 | @@ -105,7 +105,7 @@ static int iuu_port_probe(struct usb_serial_port *port) |
602 | } |
603 | |
604 | priv->dbgbuf = kzalloc(256, GFP_KERNEL); |
605 | - if (!priv->writebuf) { |
606 | + if (!priv->dbgbuf) { |
607 | kfree(priv->writebuf); |
608 | kfree(priv->buf); |
609 | kfree(priv); |
610 | @@ -120,6 +120,7 @@ static int iuu_port_probe(struct usb_serial_port *port) |
611 | |
612 | ret = iuu_create_sysfs_attrs(port); |
613 | if (ret) { |
614 | + kfree(priv->dbgbuf); |
615 | kfree(priv->writebuf); |
616 | kfree(priv->buf); |
617 | kfree(priv); |
618 | diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c |
619 | index 52e5ca7..5311819 100644 |
620 | --- a/drivers/usb/serial/mos7840.c |
621 | +++ b/drivers/usb/serial/mos7840.c |
622 | @@ -2405,52 +2405,43 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) |
623 | return mos7840_num_ports; |
624 | } |
625 | |
626 | -/**************************************************************************** |
627 | - * mos7840_startup |
628 | - ****************************************************************************/ |
629 | - |
630 | -static int mos7840_startup(struct usb_serial *serial) |
631 | +static int mos7840_port_probe(struct usb_serial_port *port) |
632 | { |
633 | + struct usb_serial *serial = port->serial; |
634 | struct moschip_port *mos7840_port; |
635 | - struct usb_device *dev; |
636 | - int i, status; |
637 | + int status; |
638 | + int pnum; |
639 | __u16 Data; |
640 | |
641 | - if (!serial) { |
642 | - dbg("%s", "Invalid Handler"); |
643 | - return -1; |
644 | - } |
645 | - |
646 | - dev = serial->dev; |
647 | - |
648 | /* we set up the pointers to the endpoints in the mos7840_open * |
649 | * function, as the structures aren't created yet. */ |
650 | |
651 | - /* set up port private structures */ |
652 | - for (i = 0; i < serial->num_ports; ++i) { |
653 | - dbg ("mos7840_startup: configuring port %d............", i); |
654 | + pnum = port->number - serial->minor; |
655 | + |
656 | + /* FIXME: remove do-while(0) loop used to keep stable patch minimal. |
657 | + */ |
658 | + do { |
659 | + dbg("mos7840_startup: configuring port %d............", pnum); |
660 | mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); |
661 | if (mos7840_port == NULL) { |
662 | - dev_err(&dev->dev, "%s - Out of memory\n", __func__); |
663 | - status = -ENOMEM; |
664 | - i--; /* don't follow NULL pointer cleaning up */ |
665 | - goto error; |
666 | + dev_err(&port->dev, "%s - Out of memory\n", __func__); |
667 | + return -ENOMEM; |
668 | } |
669 | |
670 | /* Initialize all port interrupt end point to port 0 int |
671 | * endpoint. Our device has only one interrupt end point |
672 | * common to all port */ |
673 | |
674 | - mos7840_port->port = serial->port[i]; |
675 | - mos7840_set_port_private(serial->port[i], mos7840_port); |
676 | + mos7840_port->port = port; |
677 | + mos7840_set_port_private(port, mos7840_port); |
678 | spin_lock_init(&mos7840_port->pool_lock); |
679 | |
680 | /* minor is not initialised until later by |
681 | * usb-serial.c:get_free_serial() and cannot therefore be used |
682 | * to index device instances */ |
683 | - mos7840_port->port_num = i + 1; |
684 | - dbg ("serial->port[i]->number = %d", serial->port[i]->number); |
685 | - dbg ("serial->port[i]->serial->minor = %d", serial->port[i]->serial->minor); |
686 | + mos7840_port->port_num = pnum + 1; |
687 | + dbg("port->number = %d", port->number); |
688 | + dbg("port->serial->minor = %d", port->serial->minor); |
689 | dbg ("mos7840_port->port_num = %d", mos7840_port->port_num); |
690 | dbg ("serial->minor = %d", serial->minor); |
691 | |
692 | @@ -2480,10 +2471,10 @@ static int mos7840_startup(struct usb_serial *serial) |
693 | mos7840_port->DcrRegOffset = 0x1c; |
694 | } |
695 | mos7840_dump_serial_port(mos7840_port); |
696 | - mos7840_set_port_private(serial->port[i], mos7840_port); |
697 | + mos7840_set_port_private(port, mos7840_port); |
698 | |
699 | /* enable rx_disable bit in control register */ |
700 | - status = mos7840_get_reg_sync(serial->port[i], |
701 | + status = mos7840_get_reg_sync(port, |
702 | mos7840_port->ControlRegOffset, &Data); |
703 | if (status < 0) { |
704 | dbg("Reading ControlReg failed status-0x%x", status); |
705 | @@ -2491,12 +2482,13 @@ static int mos7840_startup(struct usb_serial *serial) |
706 | } else |
707 | dbg("ControlReg Reading success val is %x, status%d", |
708 | Data, status); |
709 | + |
710 | Data |= 0x08; /* setting driver done bit */ |
711 | Data |= 0x04; /* sp1_bit to have cts change reflect in |
712 | modem status reg */ |
713 | |
714 | /* Data |= 0x20; //rx_disable bit */ |
715 | - status = mos7840_set_reg_sync(serial->port[i], |
716 | + status = mos7840_set_reg_sync(port, |
717 | mos7840_port->ControlRegOffset, Data); |
718 | if (status < 0) { |
719 | dbg("Writing ControlReg failed(rx_disable) status-0x%x", status); |
720 | @@ -2508,7 +2500,7 @@ static int mos7840_startup(struct usb_serial *serial) |
721 | /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 |
722 | and 0x24 in DCR3 */ |
723 | Data = 0x01; |
724 | - status = mos7840_set_reg_sync(serial->port[i], |
725 | + status = mos7840_set_reg_sync(port, |
726 | (__u16) (mos7840_port->DcrRegOffset + 0), Data); |
727 | if (status < 0) { |
728 | dbg("Writing DCR0 failed status-0x%x", status); |
729 | @@ -2517,7 +2509,7 @@ static int mos7840_startup(struct usb_serial *serial) |
730 | dbg("DCR0 Writing success status%d", status); |
731 | |
732 | Data = 0x05; |
733 | - status = mos7840_set_reg_sync(serial->port[i], |
734 | + status = mos7840_set_reg_sync(port, |
735 | (__u16) (mos7840_port->DcrRegOffset + 1), Data); |
736 | if (status < 0) { |
737 | dbg("Writing DCR1 failed status-0x%x", status); |
738 | @@ -2526,7 +2518,7 @@ static int mos7840_startup(struct usb_serial *serial) |
739 | dbg("DCR1 Writing success status%d", status); |
740 | |
741 | Data = 0x24; |
742 | - status = mos7840_set_reg_sync(serial->port[i], |
743 | + status = mos7840_set_reg_sync(port, |
744 | (__u16) (mos7840_port->DcrRegOffset + 2), Data); |
745 | if (status < 0) { |
746 | dbg("Writing DCR2 failed status-0x%x", status); |
747 | @@ -2536,7 +2528,7 @@ static int mos7840_startup(struct usb_serial *serial) |
748 | |
749 | /* write values in clkstart0x0 and clkmulti 0x20 */ |
750 | Data = 0x0; |
751 | - status = mos7840_set_reg_sync(serial->port[i], |
752 | + status = mos7840_set_reg_sync(port, |
753 | CLK_START_VALUE_REGISTER, Data); |
754 | if (status < 0) { |
755 | dbg("Writing CLK_START_VALUE_REGISTER failed status-0x%x", status); |
756 | @@ -2545,7 +2537,7 @@ static int mos7840_startup(struct usb_serial *serial) |
757 | dbg("CLK_START_VALUE_REGISTER Writing success status%d", status); |
758 | |
759 | Data = 0x20; |
760 | - status = mos7840_set_reg_sync(serial->port[i], |
761 | + status = mos7840_set_reg_sync(port, |
762 | CLK_MULTI_REGISTER, Data); |
763 | if (status < 0) { |
764 | dbg("Writing CLK_MULTI_REGISTER failed status-0x%x", |
765 | @@ -2557,7 +2549,7 @@ static int mos7840_startup(struct usb_serial *serial) |
766 | |
767 | /* write value 0x0 to scratchpad register */ |
768 | Data = 0x00; |
769 | - status = mos7840_set_uart_reg(serial->port[i], |
770 | + status = mos7840_set_uart_reg(port, |
771 | SCRATCH_PAD_REGISTER, Data); |
772 | if (status < 0) { |
773 | dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x", |
774 | @@ -2572,7 +2564,7 @@ static int mos7840_startup(struct usb_serial *serial) |
775 | && (serial->num_ports == 2)) { |
776 | |
777 | Data = 0xff; |
778 | - status = mos7840_set_reg_sync(serial->port[i], |
779 | + status = mos7840_set_reg_sync(port, |
780 | (__u16) (ZLP_REG1 + |
781 | ((__u16)mos7840_port->port_num)), Data); |
782 | dbg("ZLIP offset %x", |
783 | @@ -2580,14 +2572,14 @@ static int mos7840_startup(struct usb_serial *serial) |
784 | ((__u16) mos7840_port->port_num))); |
785 | if (status < 0) { |
786 | dbg("Writing ZLP_REG%d failed status-0x%x", |
787 | - i + 2, status); |
788 | + pnum + 2, status); |
789 | break; |
790 | } else |
791 | dbg("ZLP_REG%d Writing success status%d", |
792 | - i + 2, status); |
793 | + pnum + 2, status); |
794 | } else { |
795 | Data = 0xff; |
796 | - status = mos7840_set_reg_sync(serial->port[i], |
797 | + status = mos7840_set_reg_sync(port, |
798 | (__u16) (ZLP_REG1 + |
799 | ((__u16)mos7840_port->port_num) - 0x1), Data); |
800 | dbg("ZLIP offset %x", |
801 | @@ -2595,11 +2587,11 @@ static int mos7840_startup(struct usb_serial *serial) |
802 | ((__u16) mos7840_port->port_num) - 0x1)); |
803 | if (status < 0) { |
804 | dbg("Writing ZLP_REG%d failed status-0x%x", |
805 | - i + 1, status); |
806 | + pnum + 1, status); |
807 | break; |
808 | } else |
809 | dbg("ZLP_REG%d Writing success status%d", |
810 | - i + 1, status); |
811 | + pnum + 1, status); |
812 | |
813 | } |
814 | mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); |
815 | @@ -2636,105 +2628,58 @@ static int mos7840_startup(struct usb_serial *serial) |
816 | mos7840_port->led_flag = false; |
817 | |
818 | /* Turn off LED */ |
819 | - mos7840_set_led_sync(serial->port[i], |
820 | + mos7840_set_led_sync(port, |
821 | MODEM_CONTROL_REGISTER, 0x0300); |
822 | } |
823 | - } |
824 | - dbg ("mos7840_startup: all ports configured..........."); |
825 | + } while (0); |
826 | |
827 | - /* Zero Length flag enable */ |
828 | - Data = 0x0f; |
829 | - status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); |
830 | - if (status < 0) { |
831 | - dbg("Writing ZLP_REG5 failed status-0x%x", status); |
832 | - goto error; |
833 | - } else |
834 | - dbg("ZLP_REG5 Writing success status%d", status); |
835 | - |
836 | - /* setting configuration feature to one */ |
837 | - usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
838 | - (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT); |
839 | + if (pnum == serial->num_ports - 1) { |
840 | + dbg("mos7840_startup: all ports configured..........."); |
841 | + |
842 | + /* Zero Length flag enable */ |
843 | + Data = 0x0f; |
844 | + status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); |
845 | + if (status < 0) { |
846 | + dbg("Writing ZLP_REG5 failed status-0x%x", status); |
847 | + goto error; |
848 | + } else |
849 | + dbg("ZLP_REG5 Writing success status%d", status); |
850 | + |
851 | + /* setting configuration feature to one */ |
852 | + usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
853 | + 0x03, 0x00, 0x01, 0x00, NULL, 0x00, |
854 | + MOS_WDR_TIMEOUT); |
855 | + } |
856 | return 0; |
857 | error: |
858 | - for (/* nothing */; i >= 0; i--) { |
859 | - mos7840_port = mos7840_get_port_private(serial->port[i]); |
860 | + kfree(mos7840_port->dr); |
861 | + kfree(mos7840_port->ctrl_buf); |
862 | + usb_free_urb(mos7840_port->control_urb); |
863 | + kfree(mos7840_port); |
864 | |
865 | - kfree(mos7840_port->dr); |
866 | - kfree(mos7840_port->ctrl_buf); |
867 | - usb_free_urb(mos7840_port->control_urb); |
868 | - kfree(mos7840_port); |
869 | - } |
870 | return status; |
871 | } |
872 | |
873 | -/**************************************************************************** |
874 | - * mos7840_disconnect |
875 | - * This function is called whenever the device is removed from the usb bus. |
876 | - ****************************************************************************/ |
877 | - |
878 | -static void mos7840_disconnect(struct usb_serial *serial) |
879 | +static int mos7840_port_remove(struct usb_serial_port *port) |
880 | { |
881 | - int i; |
882 | - unsigned long flags; |
883 | struct moschip_port *mos7840_port; |
884 | |
885 | - if (!serial) { |
886 | - dbg("%s", "Invalid Handler"); |
887 | - return; |
888 | - } |
889 | - |
890 | - /* check for the ports to be closed,close the ports and disconnect */ |
891 | + mos7840_port = mos7840_get_port_private(port); |
892 | |
893 | - /* free private structure allocated for serial port * |
894 | - * stop reads and writes on all ports */ |
895 | + if (mos7840_port->has_led) { |
896 | + /* Turn off LED */ |
897 | + mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); |
898 | |
899 | - for (i = 0; i < serial->num_ports; ++i) { |
900 | - mos7840_port = mos7840_get_port_private(serial->port[i]); |
901 | - dbg ("mos7840_port %d = %p", i, mos7840_port); |
902 | - if (mos7840_port) { |
903 | - usb_kill_urb(mos7840_port->control_urb); |
904 | - } |
905 | + del_timer_sync(&mos7840_port->led_timer1); |
906 | + del_timer_sync(&mos7840_port->led_timer2); |
907 | } |
908 | -} |
909 | + usb_kill_urb(mos7840_port->control_urb); |
910 | + usb_free_urb(mos7840_port->control_urb); |
911 | + kfree(mos7840_port->ctrl_buf); |
912 | + kfree(mos7840_port->dr); |
913 | + kfree(mos7840_port); |
914 | |
915 | -/**************************************************************************** |
916 | - * mos7840_release |
917 | - * This function is called when the usb_serial structure is freed. |
918 | - ****************************************************************************/ |
919 | - |
920 | -static void mos7840_release(struct usb_serial *serial) |
921 | -{ |
922 | - int i; |
923 | - struct moschip_port *mos7840_port; |
924 | - |
925 | - if (!serial) { |
926 | - dbg("%s", "Invalid Handler"); |
927 | - return; |
928 | - } |
929 | - |
930 | - /* check for the ports to be closed,close the ports and disconnect */ |
931 | - |
932 | - /* free private structure allocated for serial port * |
933 | - * stop reads and writes on all ports */ |
934 | - |
935 | - for (i = 0; i < serial->num_ports; ++i) { |
936 | - mos7840_port = mos7840_get_port_private(serial->port[i]); |
937 | - dbg("mos7840_port %d = %p", i, mos7840_port); |
938 | - if (mos7840_port) { |
939 | - if (mos7840_port->has_led) { |
940 | - /* Turn off LED */ |
941 | - mos7840_set_led_sync(mos7840_port->port, |
942 | - MODEM_CONTROL_REGISTER, 0x0300); |
943 | - |
944 | - del_timer_sync(&mos7840_port->led_timer1); |
945 | - del_timer_sync(&mos7840_port->led_timer2); |
946 | - } |
947 | - usb_free_urb(mos7840_port->control_urb); |
948 | - kfree(mos7840_port->ctrl_buf); |
949 | - kfree(mos7840_port->dr); |
950 | - kfree(mos7840_port); |
951 | - } |
952 | - } |
953 | + return 0; |
954 | } |
955 | |
956 | static struct usb_serial_driver moschip7840_4port_device = { |
957 | @@ -2762,9 +2707,8 @@ static struct usb_serial_driver moschip7840_4port_device = { |
958 | .tiocmget = mos7840_tiocmget, |
959 | .tiocmset = mos7840_tiocmset, |
960 | .get_icount = mos7840_get_icount, |
961 | - .attach = mos7840_startup, |
962 | - .disconnect = mos7840_disconnect, |
963 | - .release = mos7840_release, |
964 | + .port_probe = mos7840_port_probe, |
965 | + .port_remove = mos7840_port_remove, |
966 | .read_bulk_callback = mos7840_bulk_in_callback, |
967 | .read_int_callback = mos7840_interrupt_callback, |
968 | }; |
969 | diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c |
970 | index 452e71a..1ced2d8 100644 |
971 | --- a/fs/ceph/addr.c |
972 | +++ b/fs/ceph/addr.c |
973 | @@ -205,7 +205,7 @@ static int readpage_nounlock(struct file *filp, struct page *page) |
974 | dout("readpage inode %p file %p page %p index %lu\n", |
975 | inode, filp, page, page->index); |
976 | err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout, |
977 | - page->index << PAGE_CACHE_SHIFT, &len, |
978 | + (u64) page_offset(page), &len, |
979 | ci->i_truncate_seq, ci->i_truncate_size, |
980 | &page, 1, 0); |
981 | if (err == -ENOENT) |
982 | @@ -286,7 +286,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max) |
983 | int nr_pages = 0; |
984 | int ret; |
985 | |
986 | - off = page->index << PAGE_CACHE_SHIFT; |
987 | + off = (u64) page_offset(page); |
988 | |
989 | /* count pages */ |
990 | next_index = page->index; |
991 | @@ -426,7 +426,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) |
992 | struct ceph_inode_info *ci; |
993 | struct ceph_fs_client *fsc; |
994 | struct ceph_osd_client *osdc; |
995 | - loff_t page_off = page->index << PAGE_CACHE_SHIFT; |
996 | + loff_t page_off = page_offset(page); |
997 | int len = PAGE_CACHE_SIZE; |
998 | loff_t i_size; |
999 | int err = 0; |
1000 | @@ -817,8 +817,7 @@ get_more_pages: |
1001 | /* ok */ |
1002 | if (locked_pages == 0) { |
1003 | /* prepare async write request */ |
1004 | - offset = (unsigned long long)page->index |
1005 | - << PAGE_CACHE_SHIFT; |
1006 | + offset = (u64) page_offset(page); |
1007 | len = wsize; |
1008 | req = ceph_osdc_new_request(&fsc->client->osdc, |
1009 | &ci->i_layout, |
1010 | @@ -1180,7 +1179,7 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) |
1011 | struct inode *inode = vma->vm_file->f_dentry->d_inode; |
1012 | struct page *page = vmf->page; |
1013 | struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc; |
1014 | - loff_t off = page->index << PAGE_CACHE_SHIFT; |
1015 | + loff_t off = page_offset(page); |
1016 | loff_t size, len; |
1017 | int ret; |
1018 | |
1019 | diff --git a/fs/ceph/export.c b/fs/ceph/export.c |
1020 | index 02ce909..9349bb3 100644 |
1021 | --- a/fs/ceph/export.c |
1022 | +++ b/fs/ceph/export.c |
1023 | @@ -90,6 +90,8 @@ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len, |
1024 | *max_len = handle_length; |
1025 | type = 255; |
1026 | } |
1027 | + if (dentry) |
1028 | + dput(dentry); |
1029 | return type; |
1030 | } |
1031 | |
1032 | diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c |
1033 | index a5a7354..1bcf712 100644 |
1034 | --- a/fs/ceph/mds_client.c |
1035 | +++ b/fs/ceph/mds_client.c |
1036 | @@ -2625,7 +2625,8 @@ static void check_new_map(struct ceph_mds_client *mdsc, |
1037 | ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "", |
1038 | session_state_name(s->s_state)); |
1039 | |
1040 | - if (memcmp(ceph_mdsmap_get_addr(oldmap, i), |
1041 | + if (i >= newmap->m_max_mds || |
1042 | + memcmp(ceph_mdsmap_get_addr(oldmap, i), |
1043 | ceph_mdsmap_get_addr(newmap, i), |
1044 | sizeof(struct ceph_entity_addr))) { |
1045 | if (s->s_state == CEPH_MDS_SESSION_OPENING) { |
1046 | diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c |
1047 | index 8ce0076..cc2d77c 100644 |
1048 | --- a/fs/ext4/ialloc.c |
1049 | +++ b/fs/ext4/ialloc.c |
1050 | @@ -716,6 +716,10 @@ repeat_in_this_group: |
1051 | "inode=%lu", ino + 1); |
1052 | continue; |
1053 | } |
1054 | + BUFFER_TRACE(inode_bitmap_bh, "get_write_access"); |
1055 | + err = ext4_journal_get_write_access(handle, inode_bitmap_bh); |
1056 | + if (err) |
1057 | + goto fail; |
1058 | ext4_lock_group(sb, group); |
1059 | ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data); |
1060 | ext4_unlock_group(sb, group); |
1061 | @@ -729,6 +733,11 @@ repeat_in_this_group: |
1062 | goto out; |
1063 | |
1064 | got: |
1065 | + BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata"); |
1066 | + err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh); |
1067 | + if (err) |
1068 | + goto fail; |
1069 | + |
1070 | /* We may have to initialize the block bitmap if it isn't already */ |
1071 | if (ext4_has_group_desc_csum(sb) && |
1072 | gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { |
1073 | @@ -762,11 +771,6 @@ got: |
1074 | goto fail; |
1075 | } |
1076 | |
1077 | - BUFFER_TRACE(inode_bitmap_bh, "get_write_access"); |
1078 | - err = ext4_journal_get_write_access(handle, inode_bitmap_bh); |
1079 | - if (err) |
1080 | - goto fail; |
1081 | - |
1082 | BUFFER_TRACE(group_desc_bh, "get_write_access"); |
1083 | err = ext4_journal_get_write_access(handle, group_desc_bh); |
1084 | if (err) |
1085 | @@ -814,11 +818,6 @@ got: |
1086 | } |
1087 | ext4_unlock_group(sb, group); |
1088 | |
1089 | - BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata"); |
1090 | - err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh); |
1091 | - if (err) |
1092 | - goto fail; |
1093 | - |
1094 | BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata"); |
1095 | err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh); |
1096 | if (err) |
1097 | diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h |
1098 | index cedfb1a..d9b880e 100644 |
1099 | --- a/include/linux/ceph/osd_client.h |
1100 | +++ b/include/linux/ceph/osd_client.h |
1101 | @@ -207,7 +207,7 @@ extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc, |
1102 | extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc, |
1103 | struct ceph_msg *msg); |
1104 | |
1105 | -extern void ceph_calc_raw_layout(struct ceph_osd_client *osdc, |
1106 | +extern int ceph_calc_raw_layout(struct ceph_osd_client *osdc, |
1107 | struct ceph_file_layout *layout, |
1108 | u64 snapid, |
1109 | u64 off, u64 *plen, u64 *bno, |
1110 | diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h |
1111 | index 311ef8d..e88a620 100644 |
1112 | --- a/include/linux/ceph/osdmap.h |
1113 | +++ b/include/linux/ceph/osdmap.h |
1114 | @@ -109,9 +109,9 @@ extern struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, |
1115 | extern void ceph_osdmap_destroy(struct ceph_osdmap *map); |
1116 | |
1117 | /* calculate mapping of a file extent to an object */ |
1118 | -extern void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, |
1119 | - u64 off, u64 *plen, |
1120 | - u64 *bno, u64 *oxoff, u64 *oxlen); |
1121 | +extern int ceph_calc_file_object_mapping(struct ceph_file_layout *layout, |
1122 | + u64 off, u64 *plen, |
1123 | + u64 *bno, u64 *oxoff, u64 *oxlen); |
1124 | |
1125 | /* calculate mapping of object to a placement group */ |
1126 | extern int ceph_calc_object_layout(struct ceph_object_layout *ol, |
1127 | diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c |
1128 | index 159aa8b..3ef1759 100644 |
1129 | --- a/net/ceph/messenger.c |
1130 | +++ b/net/ceph/messenger.c |
1131 | @@ -2300,10 +2300,11 @@ restart: |
1132 | mutex_unlock(&con->mutex); |
1133 | return; |
1134 | } else { |
1135 | - con->ops->put(con); |
1136 | dout("con_work %p FAILED to back off %lu\n", con, |
1137 | con->delay); |
1138 | + set_bit(CON_FLAG_BACKOFF, &con->flags); |
1139 | } |
1140 | + goto done; |
1141 | } |
1142 | |
1143 | if (con->state == CON_STATE_STANDBY) { |
1144 | @@ -2749,7 +2750,8 @@ static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip) |
1145 | msg = con->ops->alloc_msg(con, hdr, skip); |
1146 | mutex_lock(&con->mutex); |
1147 | if (con->state != CON_STATE_OPEN) { |
1148 | - ceph_msg_put(msg); |
1149 | + if (msg) |
1150 | + ceph_msg_put(msg); |
1151 | return -EAGAIN; |
1152 | } |
1153 | con->in_msg = msg; |
1154 | diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c |
1155 | index 42119c0..f7b56e2 100644 |
1156 | --- a/net/ceph/osd_client.c |
1157 | +++ b/net/ceph/osd_client.c |
1158 | @@ -52,7 +52,7 @@ static int op_has_extent(int op) |
1159 | op == CEPH_OSD_OP_WRITE); |
1160 | } |
1161 | |
1162 | -void ceph_calc_raw_layout(struct ceph_osd_client *osdc, |
1163 | +int ceph_calc_raw_layout(struct ceph_osd_client *osdc, |
1164 | struct ceph_file_layout *layout, |
1165 | u64 snapid, |
1166 | u64 off, u64 *plen, u64 *bno, |
1167 | @@ -62,12 +62,15 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc, |
1168 | struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; |
1169 | u64 orig_len = *plen; |
1170 | u64 objoff, objlen; /* extent in object */ |
1171 | + int r; |
1172 | |
1173 | reqhead->snapid = cpu_to_le64(snapid); |
1174 | |
1175 | /* object extent? */ |
1176 | - ceph_calc_file_object_mapping(layout, off, plen, bno, |
1177 | - &objoff, &objlen); |
1178 | + r = ceph_calc_file_object_mapping(layout, off, plen, bno, |
1179 | + &objoff, &objlen); |
1180 | + if (r < 0) |
1181 | + return r; |
1182 | if (*plen < orig_len) |
1183 | dout(" skipping last %llu, final file extent %llu~%llu\n", |
1184 | orig_len - *plen, off, *plen); |
1185 | @@ -83,7 +86,7 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc, |
1186 | |
1187 | dout("calc_layout bno=%llx %llu~%llu (%d pages)\n", |
1188 | *bno, objoff, objlen, req->r_num_pages); |
1189 | - |
1190 | + return 0; |
1191 | } |
1192 | EXPORT_SYMBOL(ceph_calc_raw_layout); |
1193 | |
1194 | @@ -112,20 +115,25 @@ EXPORT_SYMBOL(ceph_calc_raw_layout); |
1195 | * |
1196 | * fill osd op in request message. |
1197 | */ |
1198 | -static void calc_layout(struct ceph_osd_client *osdc, |
1199 | - struct ceph_vino vino, |
1200 | - struct ceph_file_layout *layout, |
1201 | - u64 off, u64 *plen, |
1202 | - struct ceph_osd_request *req, |
1203 | - struct ceph_osd_req_op *op) |
1204 | +static int calc_layout(struct ceph_osd_client *osdc, |
1205 | + struct ceph_vino vino, |
1206 | + struct ceph_file_layout *layout, |
1207 | + u64 off, u64 *plen, |
1208 | + struct ceph_osd_request *req, |
1209 | + struct ceph_osd_req_op *op) |
1210 | { |
1211 | u64 bno; |
1212 | + int r; |
1213 | |
1214 | - ceph_calc_raw_layout(osdc, layout, vino.snap, off, |
1215 | - plen, &bno, req, op); |
1216 | + r = ceph_calc_raw_layout(osdc, layout, vino.snap, off, |
1217 | + plen, &bno, req, op); |
1218 | + if (r < 0) |
1219 | + return r; |
1220 | |
1221 | snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno); |
1222 | req->r_oid_len = strlen(req->r_oid); |
1223 | + |
1224 | + return r; |
1225 | } |
1226 | |
1227 | /* |
1228 | diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c |
1229 | index 3124b71..5433fb0 100644 |
1230 | --- a/net/ceph/osdmap.c |
1231 | +++ b/net/ceph/osdmap.c |
1232 | @@ -984,7 +984,7 @@ bad: |
1233 | * for now, we write only a single su, until we can |
1234 | * pass a stride back to the caller. |
1235 | */ |
1236 | -void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, |
1237 | +int ceph_calc_file_object_mapping(struct ceph_file_layout *layout, |
1238 | u64 off, u64 *plen, |
1239 | u64 *ono, |
1240 | u64 *oxoff, u64 *oxlen) |
1241 | @@ -998,11 +998,17 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, |
1242 | |
1243 | dout("mapping %llu~%llu osize %u fl_su %u\n", off, *plen, |
1244 | osize, su); |
1245 | + if (su == 0 || sc == 0) |
1246 | + goto invalid; |
1247 | su_per_object = osize / su; |
1248 | + if (su_per_object == 0) |
1249 | + goto invalid; |
1250 | dout("osize %u / su %u = su_per_object %u\n", osize, su, |
1251 | su_per_object); |
1252 | |
1253 | - BUG_ON((su & ~PAGE_MASK) != 0); |
1254 | + if ((su & ~PAGE_MASK) != 0) |
1255 | + goto invalid; |
1256 | + |
1257 | /* bl = *off / su; */ |
1258 | t = off; |
1259 | do_div(t, su); |
1260 | @@ -1030,6 +1036,14 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, |
1261 | *plen = *oxlen; |
1262 | |
1263 | dout(" obj extent %llu~%llu\n", *oxoff, *oxlen); |
1264 | + return 0; |
1265 | + |
1266 | +invalid: |
1267 | + dout(" invalid layout\n"); |
1268 | + *ono = 0; |
1269 | + *oxoff = 0; |
1270 | + *oxlen = 0; |
1271 | + return -EINVAL; |
1272 | } |
1273 | EXPORT_SYMBOL(ceph_calc_file_object_mapping); |
1274 |