From: Greg Kroah-Hartman Date: Thu, 1 Nov 2012 17:13:07 +0000 (-0700) Subject: 3.6-stable patches X-Git-Tag: v3.0.51~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0a2c6174f3d325fc1c1f8f7a78b1d3b45dcf9065;p=thirdparty%2Fkernel%2Fstable-queue.git 3.6-stable patches added patches: alsa-avoid-endless-sleep-after-disconnect.patch alsa-pcm-fix-some-races-at-disconnection.patch hid-microsoft-fix-invalid-rdesc-for-3k-kbd.patch qla2xxx-update-target-lookup-session-tables-when-a-target-session-changes.patch target-fix-double-free-of-se_cmd-in-target_complete_tmr_failure.patch target-reintroduce-some-obsolete-scsi-2-commands.patch --- diff --git a/queue-3.6/alsa-avoid-endless-sleep-after-disconnect.patch b/queue-3.6/alsa-avoid-endless-sleep-after-disconnect.patch new file mode 100644 index 00000000000..fb77433ae15 --- /dev/null +++ b/queue-3.6/alsa-avoid-endless-sleep-after-disconnect.patch @@ -0,0 +1,182 @@ +From 0914f7961babbf28aaa2f19b453951fb4841c03f Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 16 Oct 2012 16:43:39 +0200 +Subject: ALSA: Avoid endless sleep after disconnect + +From: Takashi Iwai + +commit 0914f7961babbf28aaa2f19b453951fb4841c03f upstream. + +When disconnect callback is called, each component should wake up +sleepers and check card->shutdown flag for avoiding the endless sleep +blocking the proper resource release. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/control.c | 2 ++ + sound/core/hwdep.c | 7 +++++++ + sound/core/oss/pcm_oss.c | 4 ++++ + sound/core/pcm.c | 6 +++++- + sound/core/pcm_native.c | 8 ++++++++ + sound/core/rawmidi.c | 20 ++++++++++++++++++++ + 6 files changed, 46 insertions(+), 1 deletion(-) + +--- a/sound/core/control.c ++++ b/sound/core/control.c +@@ -1433,6 +1433,8 @@ static ssize_t snd_ctl_read(struct file + spin_unlock_irq(&ctl->read_lock); + schedule(); + remove_wait_queue(&ctl->change_sleep, &wait); ++ if (ctl->card->shutdown) ++ return -ENODEV; + if (signal_pending(current)) + return -ERESTARTSYS; + spin_lock_irq(&ctl->read_lock); +--- a/sound/core/hwdep.c ++++ b/sound/core/hwdep.c +@@ -129,6 +129,10 @@ static int snd_hwdep_open(struct inode * + mutex_unlock(&hw->open_mutex); + schedule(); + mutex_lock(&hw->open_mutex); ++ if (hw->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +@@ -459,12 +463,15 @@ static int snd_hwdep_dev_disconnect(stru + mutex_unlock(®ister_mutex); + return -EINVAL; + } ++ mutex_lock(&hwdep->open_mutex); ++ wake_up(&hwdep->open_wait); + #ifdef CONFIG_SND_OSSEMUL + if (hwdep->ossreg) + snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device); + #endif + snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); + list_del_init(&hwdep->list); ++ mutex_unlock(&hwdep->open_mutex); + mutex_unlock(®ister_mutex); + return 0; + } +--- a/sound/core/oss/pcm_oss.c ++++ b/sound/core/oss/pcm_oss.c +@@ -2441,6 +2441,10 @@ static int snd_pcm_oss_open(struct inode + mutex_unlock(&pcm->open_mutex); + schedule(); + mutex_lock(&pcm->open_mutex); ++ if (pcm->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +--- a/sound/core/pcm.c ++++ b/sound/core/pcm.c +@@ -1087,12 +1087,16 @@ static int snd_pcm_dev_disconnect(struct + goto unlock; + + mutex_lock(&pcm->open_mutex); ++ wake_up(&pcm->open_wait); + list_del_init(&pcm->list); + for (cidx = 0; cidx < 2; cidx++) + for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { + snd_pcm_stream_lock_irq(substream); +- if (substream->runtime) ++ if (substream->runtime) { + substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; ++ wake_up(&substream->runtime->sleep); ++ wake_up(&substream->runtime->tsleep); ++ } + snd_pcm_stream_unlock_irq(substream); + } + list_for_each_entry(notify, &snd_pcm_notify_list, list) { +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -1518,6 +1518,10 @@ static int snd_pcm_drain(struct snd_pcm_ + down_read(&snd_pcm_link_rwsem); + snd_pcm_stream_lock_irq(substream); + remove_wait_queue(&to_check->sleep, &wait); ++ if (card->shutdown) { ++ result = -ENODEV; ++ break; ++ } + if (tout == 0) { + if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) + result = -ESTRPIPE; +@@ -2163,6 +2167,10 @@ static int snd_pcm_open(struct file *fil + mutex_unlock(&pcm->open_mutex); + schedule(); + mutex_lock(&pcm->open_mutex); ++ if (pcm->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +--- a/sound/core/rawmidi.c ++++ b/sound/core/rawmidi.c +@@ -422,6 +422,10 @@ static int snd_rawmidi_open(struct inode + mutex_unlock(&rmidi->open_mutex); + schedule(); + mutex_lock(&rmidi->open_mutex); ++ if (rmidi->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +@@ -991,6 +995,8 @@ static ssize_t snd_rawmidi_read(struct f + spin_unlock_irq(&runtime->lock); + schedule(); + remove_wait_queue(&runtime->sleep, &wait); ++ if (rfile->rmidi->card->shutdown) ++ return -ENODEV; + if (signal_pending(current)) + return result > 0 ? result : -ERESTARTSYS; + if (!runtime->avail) +@@ -1234,6 +1240,8 @@ static ssize_t snd_rawmidi_write(struct + spin_unlock_irq(&runtime->lock); + timeout = schedule_timeout(30 * HZ); + remove_wait_queue(&runtime->sleep, &wait); ++ if (rfile->rmidi->card->shutdown) ++ return -ENODEV; + if (signal_pending(current)) + return result > 0 ? result : -ERESTARTSYS; + if (!runtime->avail && !timeout) +@@ -1609,9 +1617,20 @@ static int snd_rawmidi_dev_register(stru + static int snd_rawmidi_dev_disconnect(struct snd_device *device) + { + struct snd_rawmidi *rmidi = device->device_data; ++ int dir; + + mutex_lock(®ister_mutex); ++ mutex_lock(&rmidi->open_mutex); ++ wake_up(&rmidi->open_wait); + list_del_init(&rmidi->list); ++ for (dir = 0; dir < 2; dir++) { ++ struct snd_rawmidi_substream *s; ++ list_for_each_entry(s, &rmidi->streams[dir].substreams, list) { ++ if (s->runtime) ++ wake_up(&s->runtime->sleep); ++ } ++ } ++ + #ifdef CONFIG_SND_OSSEMUL + if (rmidi->ossreg) { + if ((int)rmidi->device == midi_map[rmidi->card->number]) { +@@ -1626,6 +1645,7 @@ static int snd_rawmidi_dev_disconnect(st + } + #endif /* CONFIG_SND_OSSEMUL */ + snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); ++ mutex_unlock(&rmidi->open_mutex); + mutex_unlock(®ister_mutex); + return 0; + } diff --git a/queue-3.6/alsa-pcm-fix-some-races-at-disconnection.patch b/queue-3.6/alsa-pcm-fix-some-races-at-disconnection.patch new file mode 100644 index 00000000000..a984a9b6cce --- /dev/null +++ b/queue-3.6/alsa-pcm-fix-some-races-at-disconnection.patch @@ -0,0 +1,103 @@ +From 9b0573c07f278e9888c352aa9724035c75784ea0 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 12 Oct 2012 15:07:34 +0200 +Subject: ALSA: PCM: Fix some races at disconnection + +From: Takashi Iwai + +commit 9b0573c07f278e9888c352aa9724035c75784ea0 upstream. + +Fix races at PCM disconnection: +- while a PCM device is being opened or closed +- while the PCM state is being changed without lock in prepare, + hw_params, hw_free ops + +Reported-by: Matthieu CASTET +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/pcm.c | 7 ++++++- + sound/core/pcm_native.c | 16 ++++++++++++---- + 2 files changed, 18 insertions(+), 5 deletions(-) + +--- a/sound/core/pcm.c ++++ b/sound/core/pcm.c +@@ -1086,11 +1086,15 @@ static int snd_pcm_dev_disconnect(struct + if (list_empty(&pcm->list)) + goto unlock; + ++ mutex_lock(&pcm->open_mutex); + list_del_init(&pcm->list); + for (cidx = 0; cidx < 2; cidx++) +- for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) ++ for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { ++ snd_pcm_stream_lock_irq(substream); + if (substream->runtime) + substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; ++ snd_pcm_stream_unlock_irq(substream); ++ } + list_for_each_entry(notify, &snd_pcm_notify_list, list) { + notify->n_disconnect(pcm); + } +@@ -1106,6 +1110,7 @@ static int snd_pcm_dev_disconnect(struct + } + snd_unregister_device(devtype, pcm->card, pcm->device); + } ++ mutex_unlock(&pcm->open_mutex); + unlock: + mutex_unlock(®ister_mutex); + return 0; +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -369,6 +369,14 @@ static int period_to_usecs(struct snd_pc + return usecs; + } + ++static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state) ++{ ++ snd_pcm_stream_lock_irq(substream); ++ if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED) ++ substream->runtime->status->state = state; ++ snd_pcm_stream_unlock_irq(substream); ++} ++ + static int snd_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) + { +@@ -452,7 +460,7 @@ static int snd_pcm_hw_params(struct snd_ + runtime->boundary *= 2; + + snd_pcm_timer_resolution_change(substream); +- runtime->status->state = SNDRV_PCM_STATE_SETUP; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP); + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); +@@ -464,7 +472,7 @@ static int snd_pcm_hw_params(struct snd_ + /* hardware might be unusable from this time, + so we force application to retry to set + the correct hardware parameter settings */ +- runtime->status->state = SNDRV_PCM_STATE_OPEN; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + if (substream->ops->hw_free != NULL) + substream->ops->hw_free(substream); + return err; +@@ -512,7 +520,7 @@ static int snd_pcm_hw_free(struct snd_pc + return -EBADFD; + if (substream->ops->hw_free) + result = substream->ops->hw_free(substream); +- runtime->status->state = SNDRV_PCM_STATE_OPEN; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + pm_qos_remove_request(&substream->latency_pm_qos_req); + return result; + } +@@ -1320,7 +1328,7 @@ static void snd_pcm_post_prepare(struct + { + struct snd_pcm_runtime *runtime = substream->runtime; + runtime->control->appl_ptr = runtime->status->hw_ptr; +- runtime->status->state = SNDRV_PCM_STATE_PREPARED; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED); + } + + static struct action_ops snd_pcm_action_prepare = { diff --git a/queue-3.6/hid-microsoft-fix-invalid-rdesc-for-3k-kbd.patch b/queue-3.6/hid-microsoft-fix-invalid-rdesc-for-3k-kbd.patch new file mode 100644 index 00000000000..163bf2d9ffd --- /dev/null +++ b/queue-3.6/hid-microsoft-fix-invalid-rdesc-for-3k-kbd.patch @@ -0,0 +1,86 @@ +From 3ccc60f9d8c39180c205dba1a020735bda1b2491 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Fri, 19 Oct 2012 13:28:46 +0200 +Subject: HID: microsoft: fix invalid rdesc for 3k kbd + +From: Jiri Slaby + +commit 3ccc60f9d8c39180c205dba1a020735bda1b2491 upstream. + +Microsoft Digital Media Keyboard 3000 has two interfaces, and the +second one has a report descriptor with a bug. The second collection +says: +05 01 -- global; usage page -- 01 -- Generic Desktop Controls +09 80 -- local; usage -- 80 -- System Control +a1 01 -- main; collection -- 01 -- application + +85 03 -- global; report ID -- 03 +19 00 -- local; Usage Minimum -- 00 +29 ff -- local; Usage Maximum -- ff +15 00 -- global; Logical Minimum -- 0 +26 ff 00 -- global; Logical Maximum -- ff +81 00 -- main; input + +c0 -- main; End Collection + +I.e. it makes us think that there are all kinds of usages of system +control. That the keyboard is a not only a keyboard, but also a +joystick, mouse, gamepad, keypad, etc. The same as for the Wireless +Desktop Receiver, this should be Physical Min/Max. So fix that +appropriately. + +References: https://bugzilla.novell.com/show_bug.cgi?id=776834 +Signed-off-by: Jiri Slaby +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-microsoft.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +--- a/drivers/hid/hid-microsoft.c ++++ b/drivers/hid/hid-microsoft.c +@@ -29,22 +29,30 @@ + #define MS_RDESC 0x08 + #define MS_NOGET 0x10 + #define MS_DUPLICATE_USAGES 0x20 ++#define MS_RDESC_3K 0x40 + +-/* +- * Microsoft Wireless Desktop Receiver (Model 1028) has +- * 'Usage Min/Max' where it ought to have 'Physical Min/Max' +- */ + static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) + { + unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); + ++ /* ++ * Microsoft Wireless Desktop Receiver (Model 1028) has ++ * 'Usage Min/Max' where it ought to have 'Physical Min/Max' ++ */ + if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && + rdesc[559] == 0x29) { + hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); + rdesc[557] = 0x35; + rdesc[559] = 0x45; + } ++ /* the same as above (s/usage/physical/) */ ++ if ((quirks & MS_RDESC_3K) && *rsize == 106 && ++ !memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, ++ &rdesc[94], 4)) { ++ rdesc[94] = 0x35; ++ rdesc[96] = 0x45; ++ } + return rdesc; + } + +@@ -193,7 +201,7 @@ static const struct hid_device_id ms_dev + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), + .driver_data = MS_PRESENTER }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), +- .driver_data = MS_ERGONOMY }, ++ .driver_data = MS_ERGONOMY | MS_RDESC_3K }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), + .driver_data = MS_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), diff --git a/queue-3.6/qla2xxx-update-target-lookup-session-tables-when-a-target-session-changes.patch b/queue-3.6/qla2xxx-update-target-lookup-session-tables-when-a-target-session-changes.patch new file mode 100644 index 00000000000..5cb4f7b7eab --- /dev/null +++ b/queue-3.6/qla2xxx-update-target-lookup-session-tables-when-a-target-session-changes.patch @@ -0,0 +1,199 @@ +From c8292d1da53fa60c7516ab03a9d83f7ea266d335 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Thu, 11 Oct 2012 13:41:32 -0700 +Subject: qla2xxx: Update target lookup session tables when a target session changes + +From: Roland Dreier + +commit c8292d1da53fa60c7516ab03a9d83f7ea266d335 upstream. + +It is possible for the target code to change the loop_id or s_id of a +target session in reaction to an FC fabric change. However, the +session structures are stored in tables that are indexed by these two +keys, and if we just change the session structure but leave the +pointers to it in the old places in the table, havoc can ensue. For +example, a new session might come along that should go in the old slot +in the table and overwrite the old session pointer. + +To handle this, add a new tgt_ops->update_sess() method that also +updates the "by loop_id" and "by s_id" lookup tables when a session +changes, so that the keys where a session pointer is stored in these +tables always matches the keys in the session structure itself. + +(nab: Drop unnecessary double inversion with FCF_CONF_COMP_SUPPORTED + usage) + +Signed-off-by: Roland Dreier +Cc: Chad Dupuis +Cc: Arun Easi +Cc: Saurav Kashyap +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_target.c | 25 +++++------- + drivers/scsi/qla2xxx/qla_target.h | 1 + drivers/scsi/qla2xxx/tcm_qla2xxx.c | 73 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 85 insertions(+), 14 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -557,6 +557,7 @@ static bool qlt_check_fcport_exist(struc + int pmap_len; + fc_port_t *fcport; + int global_resets; ++ unsigned long flags; + + retry: + global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); +@@ -625,10 +626,10 @@ retry: + sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, + fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); + +- sess->s_id = fcport->d_id; +- sess->loop_id = fcport->loop_id; +- sess->conf_compl_supported = !!(fcport->flags & +- FCF_CONF_COMP_SUPPORTED); ++ spin_lock_irqsave(&ha->hardware_lock, flags); ++ ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, ++ (fcport->flags & FCF_CONF_COMP_SUPPORTED)); ++ spin_unlock_irqrestore(&ha->hardware_lock, flags); + + res = true; + +@@ -740,10 +741,9 @@ static struct qla_tgt_sess *qlt_create_s + qlt_undelete_sess(sess); + + kref_get(&sess->se_sess->sess_kref); +- sess->s_id = fcport->d_id; +- sess->loop_id = fcport->loop_id; +- sess->conf_compl_supported = !!(fcport->flags & +- FCF_CONF_COMP_SUPPORTED); ++ ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, ++ (fcport->flags & FCF_CONF_COMP_SUPPORTED)); ++ + if (sess->local && !local) + sess->local = 0; + spin_unlock_irqrestore(&ha->hardware_lock, flags); +@@ -796,8 +796,7 @@ static struct qla_tgt_sess *qlt_create_s + */ + kref_get(&sess->se_sess->sess_kref); + +- sess->conf_compl_supported = !!(fcport->flags & +- FCF_CONF_COMP_SUPPORTED); ++ sess->conf_compl_supported = (fcport->flags & FCF_CONF_COMP_SUPPORTED); + BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); + memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); + +@@ -869,10 +868,8 @@ void qlt_fc_port_added(struct scsi_qla_h + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, + "Reappeared sess %p\n", sess); + } +- sess->s_id = fcport->d_id; +- sess->loop_id = fcport->loop_id; +- sess->conf_compl_supported = !!(fcport->flags & +- FCF_CONF_COMP_SUPPORTED); ++ ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, ++ (fcport->flags & FCF_CONF_COMP_SUPPORTED)); + } + + if (sess && sess->local) { +--- a/drivers/scsi/qla2xxx/qla_target.h ++++ b/drivers/scsi/qla2xxx/qla_target.h +@@ -648,6 +648,7 @@ struct qla_tgt_func_tmpl { + + int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, + void *, uint8_t *, uint16_t); ++ void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool); + struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, + const uint16_t); + struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, +--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c ++++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c +@@ -1468,6 +1468,78 @@ static int tcm_qla2xxx_check_initiator_n + return 0; + } + ++static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id, ++ uint16_t loop_id, bool conf_compl_supported) ++{ ++ struct qla_tgt *tgt = sess->tgt; ++ struct qla_hw_data *ha = tgt->ha; ++ struct tcm_qla2xxx_lport *lport = ha->tgt.target_lport_ptr; ++ struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; ++ struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, ++ struct tcm_qla2xxx_nacl, se_node_acl); ++ u32 key; ++ ++ ++ if (sess->loop_id != loop_id || sess->s_id.b24 != s_id.b24) ++ 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", ++ sess, ++ sess->port_name[0], sess->port_name[1], ++ sess->port_name[2], sess->port_name[3], ++ sess->port_name[4], sess->port_name[5], ++ sess->port_name[6], sess->port_name[7], ++ sess->loop_id, loop_id, ++ sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa, ++ s_id.b.domain, s_id.b.area, s_id.b.al_pa); ++ ++ if (sess->loop_id != loop_id) { ++ /* ++ * Because we can shuffle loop IDs around and we ++ * update different sessions non-atomically, we might ++ * have overwritten this session's old loop ID ++ * already, and we might end up overwriting some other ++ * session that will be updated later. So we have to ++ * be extra careful and we can't warn about those things... ++ */ ++ if (lport->lport_loopid_map[sess->loop_id].se_nacl == se_nacl) ++ lport->lport_loopid_map[sess->loop_id].se_nacl = NULL; ++ ++ lport->lport_loopid_map[loop_id].se_nacl = se_nacl; ++ ++ sess->loop_id = loop_id; ++ } ++ ++ if (sess->s_id.b24 != s_id.b24) { ++ key = (((u32) sess->s_id.b.domain << 16) | ++ ((u32) sess->s_id.b.area << 8) | ++ ((u32) sess->s_id.b.al_pa)); ++ ++ if (btree_lookup32(&lport->lport_fcport_map, key)) ++ WARN(btree_remove32(&lport->lport_fcport_map, key) != se_nacl, ++ "Found wrong se_nacl when updating s_id %x:%x:%x\n", ++ sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); ++ else ++ WARN(1, "No lport_fcport_map entry for s_id %x:%x:%x\n", ++ sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); ++ ++ key = (((u32) s_id.b.domain << 16) | ++ ((u32) s_id.b.area << 8) | ++ ((u32) s_id.b.al_pa)); ++ ++ if (btree_lookup32(&lport->lport_fcport_map, key)) { ++ WARN(1, "Already have lport_fcport_map entry for s_id %x:%x:%x\n", ++ s_id.b.domain, s_id.b.area, s_id.b.al_pa); ++ btree_update32(&lport->lport_fcport_map, key, se_nacl); ++ } else { ++ btree_insert32(&lport->lport_fcport_map, key, se_nacl, GFP_ATOMIC); ++ } ++ ++ sess->s_id = s_id; ++ nacl->nport_id = key; ++ } ++ ++ sess->conf_compl_supported = conf_compl_supported; ++} ++ + /* + * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. + */ +@@ -1478,6 +1550,7 @@ static struct qla_tgt_func_tmpl tcm_qla2 + .free_cmd = tcm_qla2xxx_free_cmd, + .free_mcmd = tcm_qla2xxx_free_mcmd, + .free_session = tcm_qla2xxx_free_session, ++ .update_sess = tcm_qla2xxx_update_sess, + .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, + .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, + .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, diff --git a/queue-3.6/series b/queue-3.6/series index 30fcbc555a5..ee9901ffda5 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -15,3 +15,9 @@ ceph-avoid-32-bit-page-index-overflow.patch usb-mos7840-fix-port-data-memory-leak.patch usb-iuu_phoenix-fix-backported-patches.patch usb-io_edgeport-remove-unused-variable.patch +alsa-pcm-fix-some-races-at-disconnection.patch +alsa-avoid-endless-sleep-after-disconnect.patch +qla2xxx-update-target-lookup-session-tables-when-a-target-session-changes.patch +target-reintroduce-some-obsolete-scsi-2-commands.patch +target-fix-double-free-of-se_cmd-in-target_complete_tmr_failure.patch +hid-microsoft-fix-invalid-rdesc-for-3k-kbd.patch diff --git a/queue-3.6/target-fix-double-free-of-se_cmd-in-target_complete_tmr_failure.patch b/queue-3.6/target-fix-double-free-of-se_cmd-in-target_complete_tmr_failure.patch new file mode 100644 index 00000000000..45aa4365882 --- /dev/null +++ b/queue-3.6/target-fix-double-free-of-se_cmd-in-target_complete_tmr_failure.patch @@ -0,0 +1,41 @@ +From e13d5fef88c40b87c8430f8274c3a9ca32ef90bc Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Fri, 26 Oct 2012 15:35:45 -0700 +Subject: target: Fix double-free of se_cmd in target_complete_tmr_failure + +From: Nicholas Bellinger + +commit e13d5fef88c40b87c8430f8274c3a9ca32ef90bc upstream. + +Fabric drivers currently expect to internally release se_cmd in the event +of a TMR failure during target_submit_tmr(), which means the immediate call +to transport_generic_free_cmd() after TFO->queue_tm_rsp() from within +target_complete_tmr_failure() workqueue context is wrong. + +This is done as some fabrics expect TMR operations to be acknowledged +before releasing the descriptor, so the assumption that core is releasing +se_cmd associated TMR memory is incorrect. This fixes a OOPs where +transport_generic_free_cmd() was being called more than once. + +This bug was originally observed with tcm_qla2xxx fabric ports. + +Signed-off-by: Nicholas Bellinger +Cc: Christoph Hellwig +Cc: Roland Dreier +Cc: Andy Grover +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_transport.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -1553,7 +1553,6 @@ static void target_complete_tmr_failure( + + se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; + se_cmd->se_tfo->queue_tm_rsp(se_cmd); +- transport_generic_free_cmd(se_cmd, 0); + } + + /** diff --git a/queue-3.6/target-reintroduce-some-obsolete-scsi-2-commands.patch b/queue-3.6/target-reintroduce-some-obsolete-scsi-2-commands.patch new file mode 100644 index 00000000000..73b8a18bd0c --- /dev/null +++ b/queue-3.6/target-reintroduce-some-obsolete-scsi-2-commands.patch @@ -0,0 +1,67 @@ +From 1a1ff38c4cebf23be8bf0009a76b082a13bd25cb Mon Sep 17 00:00:00 2001 +From: Bernhard Kohl +Date: Wed, 24 Oct 2012 15:53:58 +0200 +Subject: target: reintroduce some obsolete SCSI-2 commands + +From: Bernhard Kohl + +commit 1a1ff38c4cebf23be8bf0009a76b082a13bd25cb upstream. + +With kernel 3.6 some obsolete SCSI-2 commands including SEEK_10 have +have been removed by commit 1fd032ee10d2816c947f5d5b9abda95e728f0a8f +"target: move code for CDB emulation". + +There are still clients out there which use these old SCSI-2 commands. +This mainly happens when running VMs with legacy guest systems, +connected via SCSI command pass-through to iSCSI targets. Make them +happy and return status GOOD. + +Many real SCSI disks or external iSCSI storage devices still support +these old commands. So let's make LIO backward compatible as well. + +This patch adds support for the previously removed SEEK_10 and +additionally the SEEK_6 and REZERO_UNIT commands. + +Signed-off-by: Bernhard Kohl +Reviewed-by: Christoph Hellwig +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_sbc.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/target/target_core_sbc.c ++++ b/drivers/target/target_core_sbc.c +@@ -128,6 +128,12 @@ static int sbc_emulate_verify(struct se_ + return 0; + } + ++static int sbc_emulate_noop(struct se_cmd *cmd) ++{ ++ target_complete_cmd(cmd, GOOD); ++ return 0; ++} ++ + static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) + { + return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; +@@ -524,6 +530,18 @@ int sbc_parse_cdb(struct se_cmd *cmd, st + size = 0; + cmd->execute_cmd = sbc_emulate_verify; + break; ++ case REZERO_UNIT: ++ case SEEK_6: ++ case SEEK_10: ++ /* ++ * There are still clients out there which use these old SCSI-2 ++ * commands. This mainly happens when running VMs with legacy ++ * guest systems, connected via SCSI command pass-through to ++ * iSCSI targets. Make them happy and return status GOOD. ++ */ ++ size = 0; ++ cmd->execute_cmd = sbc_emulate_noop; ++ break; + default: + ret = spc_parse_cdb(cmd, &size); + if (ret)