6.10.14-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 137/482 nfp: Use IRQF_NO_AUTOEN flag in request_irq()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit daaba19d357f0900b303a530ced96c78086267ea ]
disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ.
--- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/ethernet/netronome/nfp/nfp_net_common.c +2 -3
@@ -821,14 +821,13 @@ nfp_net_prepare_vector(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,snprintf (r_vec->name,sizeof (r_vec->name),"%s-rxtx-%d" ,nfp_net_name (nn), idx); - err =request_irq (r_vec->irq_vector, r_vec->handler,0 , r_vec->name, - r_vec); + err =request_irq (r_vec->irq_vector, r_vec->handler,IRQF_NO_AUTOEN , + r_vec->name, r_vec);if (err) {nfp_net_napi_del (&nn->dp, r_vec);nn_err (nn,"Error requesting IRQ %d\n" , r_vec->irq_vector);return err; } -disable_irq (r_vec->irq_vector);irq_set_affinity_hint (r_vec->irq_vector, &r_vec->affinity_mask);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 138/482 ALSA: usb-audio: Add input value sanity checks for standard types
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 901e85677ec0bb9a69fb9eab1feafe0c4eb7d07e ]
For an invalid input value that is out of the given range, currently USB-audio driver corrects the value silently and accepts without errors. This is no wrong behavior, per se, but the recent kselftest rather wants to have an error in such a case, hence a different behavior is expected now.
This patch adds a sanity check at each control put for the standard mixer types and returns an error if an invalid value is given.
Note that this covers only the standard mixer types. The mixer quirks that have own control callbacks would need different coverage.
--- sound/usb/mixer.c | 35 +++++++++++++++++++++++++++-------- sound/usb/mixer.h | 1 + 2 files changed, 28 insertions(+), 8 deletions(-)
sound/usb/mixer.c +27 -8
@@ -1377,6 +1377,19 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,#define get_min_max (cval, def) get_min_max_with_quirks(cval, def, NULL) +/* get the max value advertised via control API */ +static int get_max_exposed (struct usb_mixer_elem_info *cval) +{ +if (!cval->max_exposed) { +if (cval->res) + cval->max_exposed = +DIV_ROUND_UP (cval->max - cval->min, cval->res); +else + cval->max_exposed = cval->max - cval->min; + } +return cval->max_exposed; +} +/* get a feature/mixer unit info */ static int mixer_ctl_feature_info (struct snd_kcontrol *kcontrol,struct snd_ctl_elem_info *uinfo)
@@ -1389,11 +1402,8 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol,else uinfo->type =SNDRV_CTL_ELEM_TYPE_INTEGER ; uinfo->count = cval->channels; -if (cval->val_type ==USB_MIXER_BOOLEAN || - cval->val_type ==USB_MIXER_INV_BOOLEAN ) { - uinfo->value.integer.min =0 ; - uinfo->value.integer.max =1 ; - }else { +if (cval->val_type !=USB_MIXER_BOOLEAN && + cval->val_type !=USB_MIXER_INV_BOOLEAN ) {if (!cval->initialized) {get_min_max_with_quirks (cval,0 , kcontrol);if (cval->initialized && cval->dBmin >= cval->dBmax) {
@@ -1405,10 +1415,10 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, &kcontrol->id); } } - uinfo->value.integer.min =0 ; - uinfo->value.integer.max = -DIV_ROUND_UP (cval->max - cval->min, cval->res); } + + uinfo->value.integer.min =0 ; + uinfo->value.integer.max =get_max_exposed (cval);return 0 ; }
@@ -1449,6 +1459,7 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {struct usb_mixer_elem_info *cval = kcontrol->private_data; +int max_val =get_max_exposed (cval);int c, cnt, val, oval, err;int changed =0 ;
@@ -1461,6 +1472,8 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,if (err <0 )return filter_error (cval, err); val = ucontrol->value.integer.value[cnt]; +if (val <0 || val > max_val) +return -EINVAL ; val =get_abs_value (cval, val);if (oval != val) {snd_usb_set_cur_mix_value (cval, c +1 , cnt, val);
@@ -1474,6 +1487,8 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,if (err <0 )return filter_error (cval, err); val = ucontrol->value.integer.value[0 ]; +if (val <0 || val > max_val) +return -EINVAL ; val =get_abs_value (cval, val);if (val != oval) {snd_usb_set_cur_mix_value (cval,0 ,0 , val);
@@ -2337,6 +2352,8 @@ static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol,if (err <0 )return filter_error (cval, err); val = ucontrol->value.integer.value[0 ]; +if (val <0 || val >get_max_exposed (cval)) +return -EINVAL ; val =get_abs_value (cval, val);if (val != oval) {set_cur_ctl_value (cval, cval->control <<8 , val);
@@ -2699,6 +2716,8 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol,if (err <0 )return filter_error (cval, err); val = ucontrol->value.enumerated.item[0 ]; +if (val <0 || val >= cval->max)/* here cval->max = # elements */ +return -EINVAL ; val =get_abs_value (cval, val);if (val != oval) {set_cur_ctl_value (cval, cval->control <<8 , val);
sound/usb/mixer.h +1 -0
@@ -88,6 +88,7 @@ struct usb_mixer_elem_info {int channels;int val_type;int min, max, res; +int max_exposed;/* control API exposes the value in 0..max_exposed */ int dBmin, dBmax;int cached;int cache_val[MAX_CHANNELS ];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 139/482 x86/ioapic: Handle allocation failures gracefully
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 830802a0fea8fb39d3dc9fb7d6b5581e1343eb1f ]
Breno observed panics when using failslab under certain conditions during runtime:
can not alloc irq_pin_list (-1,0,20)
Kernel panic - not syncing: IO-APIC: failed to add irq-pin. Can not proceed panic+0x4e9/0x590 mp_irqdomain_alloc+0x9ab/0xa80 irq_domain_alloc_irqs_locked+0x25d/0x8d0 __irq_domain_alloc_irqs+0x80/0x110 mp_map_pin_to_irq+0x645/0x890 acpi_register_gsi_ioapic+0xe6/0x150 hpet_open+0x313/0x480
That's a pointless panic which is a leftover of the historic IO/APIC code which panic'ed during early boot when the interrupt allocation failed.
The only place which might justify panic is the PIT/HPET timer_check() code which tries to figure out whether the timer interrupt is delivered through the IO/APIC. But that code does not require to handle interrupt allocation failures. If the interrupt cannot be allocated then timer delivery fails and it either panics due to that or falls back to legacy mode.
Cure this by removing the panic wrapper around __add_pin_to_irq_node() and making mp_irqdomain_alloc() aware of the failure condition and handle it as any other failure in this function gracefully.
--- arch/x86/kernel/apic/io_apic.c | 46 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 24 deletions(-)
arch/x86/kernel/apic/io_apic.c +22 -24
@@ -352,27 +352,26 @@ static void ioapic_mask_entry(int apic, int pin)* shared ISA-space IRQs, so we have to support them. We are super * fast in the common case, and fast for shared ISA-space IRQs. */ -static int __add_pin_to_irq_node (struct mp_chip_data *data, -int node,int apic,int pin) +static bool add_pin_to_irq_node (struct mp_chip_data *data,int node,int apic,int pin) {struct irq_pin_list *entry; -/* don't allow duplicates */ -for_each_irq_pin (entry, data->irq_2_pin) +/* Don't allow duplicates */ +for_each_irq_pin (entry, data->irq_2_pin) {if (entry->apic == apic && entry->pin == pin) -return 0 ; +return true; + } entry =kzalloc_node (sizeof (struct irq_pin_list ),GFP_ATOMIC , node);if (!entry) { -pr_err ("can not alloc irq_pin_list (%d,%d,%d)\n" , - node, apic, pin); -return -ENOMEM ; +pr_err ("Cannot allocate irq_pin_list (%d,%d,%d)\n" , node, apic, pin); +return false; } + entry->apic = apic; entry->pin = pin;list_add_tail (&entry->list, &data->irq_2_pin); - -return 0 ; +return true; }static void __remove_pin_from_irq (struct mp_chip_data *data,int apic,int pin)
@@ -387,13 +386,6 @@ static void __remove_pin_from_irq(struct mp_chip_data *data, int apic, int pin) } } -static void add_pin_to_irq_node (struct mp_chip_data *data, -int node,int apic,int pin) -{ -if (__add_pin_to_irq_node (data, node, apic, pin)) -panic ("IO-APIC: failed to add irq-pin. Can not proceed\n" ); -} -/* * Reroute an IRQ to a different pin. */
@@ -1002,8 +994,7 @@ static int alloc_isa_irq_from_domain(struct irq_domain *domain,if (irq_data && irq_data->parent_data) {if (!mp_check_pin_attr (irq, info))return -EBUSY ; -if (__add_pin_to_irq_node (irq_data->chip_data, node, ioapic, - info->ioapic.pin)) +if (!add_pin_to_irq_node (irq_data->chip_data, node, ioapic, info->ioapic.pin))return -ENOMEM ; }else { info->flags |=X86_IRQ_ALLOC_LEGACY ;
@@ -3017,10 +3008,8 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,return -ENOMEM ; ret =irq_domain_alloc_irqs_parent (domain, virq, nr_irqs, info); -if (ret <0 ) { -kfree (data); -return ret; - } +if (ret <0 ) + goto free_data;INIT_LIST_HEAD (&data->irq_2_pin); irq_data->hwirq = info->ioapic.pin;
@@ -3029,7 +3018,10 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, irq_data->chip_data = data;mp_irqdomain_get_attr (mp_pin_to_gsi (ioapic, pin), data, info); -add_pin_to_irq_node (data,ioapic_alloc_attr_node (info), ioapic, pin); +if (!add_pin_to_irq_node (data,ioapic_alloc_attr_node (info), ioapic, pin)) { + ret = -ENOMEM ; + goto free_irqs; + }mp_preconfigure_entry (data);mp_register_handler (virq, data->is_level);
@@ -3044,6 +3036,12 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, ioapic,mpc_ioapic_id (ioapic), pin, virq, data->is_level, data->active_low);return 0 ; + +free_irqs: +irq_domain_free_irqs_parent (domain, virq, nr_irqs); +free_data: +kfree (data); +return ret; } void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 140/482 x86/apic: Remove logical destination mode for 64-bit
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 838ba7733e4e3a94a928e8d0a058de1811a58621 ]
Logical destination mode of the local APIC is used for systems with up to 8 CPUs. It has an advantage over physical destination mode as it allows to target multiple CPUs at once with IPIs.
That advantage was definitely worth it when systems with up to 8 CPUs were state of the art for servers and workstations, but that's history.
Aside of that there are systems which fail to work with logical destination mode as the ACPI/DMI quirks show and there are AMD Zen1 systems out there which fail when interrupt remapping is enabled as reported by Rob and Christian. The latter problem can be cured by firmware updates, but not all OEMs distribute the required changes.
Physical destination mode is guaranteed to work because it is the only way to get a CPU up and running via the INIT/INIT/STARTUP sequence.
As the number of CPUs keeps increasing, logical destination mode becomes a less used code path so there is no real good reason to keep it around.
Therefore remove logical destination mode support for 64-bit and default to physical destination mode.
--- arch/x86/include/asm/apic.h | 8 -- arch/x86/kernel/apic/apic_flat_64.c | 119 ++-------------------------- 2 files changed, 7 insertions(+), 120 deletions(-)
arch/x86/include/asm/apic.h +0 -8
@@ -345,20 +345,12 @@ extern struct apic *apic;* APIC drivers are probed based on how they are listed in the .apicdrivers * section. So the order is important and enforced by the ordering * of different apic driver files in the Makefile. -* -* For the files having two apic drivers, we use apic_drivers() -* to enforce the order with in them. */ #define apic_driver (sym) \ static const struct apic *__apicdrivers_##sym __used \ __aligned(sizeof(struct apic *)) \ __section(".apicdrivers") = { &sym } -#define apic_drivers (sym1, sym2) \ - static struct apic *__apicdrivers_##sym1##sym2[2] __used \ - __aligned(sizeof(struct apic *)) \ - __section(".apicdrivers") = { &sym1, &sym2 } -extern struct apic *__apicdrivers[], *__apicdrivers_end[];/*
arch/x86/kernel/apic/apic_flat_64.c +7 -112
151 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 141/482 ALSA: usb-audio: Support multiple control interfaces
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karol Kosik <[email protected]>
[ Upstream commit 6aa8700150f7dc62f60b4cf5b1624e2e3d9ed78e ]
Registering Numark Party Mix II fails with error 'bogus bTerminalLink 1'. The problem stems from the driver not being able to find input/output terminals required to configure audio streaming. The information about those terminals is stored in AudioControl Interface. Numark device contains 2 AudioControl Interfaces and the driver checks only one of them.
According to the USB standard, a device can have multiple audio functions, each represented by Audio Interface Collection. Every audio function is considered to be closed box and will contain unique AudioControl Interface and zero or more AudioStreaming and MIDIStreaming Interfaces.
The Numark device adheres to the standard and defines two audio functions:
- MIDIStreaming function
- AudioStreaming function
It starts with MIDI function, followed by the audio function. The driver saves the first AudioControl Interface in snd_usb_audio structure associated with the entire device. It then attempts to use this interface to query for terminals and clocks. However, this fails because the correct information is stored in the second AudioControl Interface, defined in the second Audio Interface Collection.
This patch introduces a structure holding association between each MIDI/Audio Interface and its corresponding AudioControl Interface, instead of relying on AudioControl Interface defined for the entire device. This structure is populated during usb probing phase and leveraged later when querying for terminals and when sending USB requests.
Alternative solutions considered include:
- defining a quirk for Numark where the order of interface is manually changed, or terminals are hardcoded in the driver. This solution would have fixed only this model, though it seems that device is USB compliant, and it also seems that other devices from this company may be affected. What's more, it looks like products from other manufacturers have similar problems, i.e. Rane One DJ console
- keeping a list of all AudioControl Interfaces and querying all of them to find required information. That would have solved my problem and have low probability of breaking other devices, as we would always start with the same logic of querying first AudioControl Interface. This solution would not have followed the standard though.
This patch preserves the snd_usb_audio.ctrl_intf variable, which holds the first AudioControl Interface, and uses it as a fallback when some interfaces are not parsed correctly and lack an associated AudioControl Interface, i.e., when configured via quirks.
--- sound/usb/card.c | 2 ++ sound/usb/clock.c | 62 ++++++++++++++++++++++++-------------- sound/usb/format.c | 6 ++-- sound/usb/helper.c | 34 +++++++++++++++++++++ sound/usb/helper.h | 10 ++++-- sound/usb/mixer.c | 2 +- sound/usb/mixer_quirks.c | 17 ++++++----- sound/usb/mixer_scarlett.c | 4 +-- sound/usb/power.c | 3 +- sound/usb/power.h | 1 + sound/usb/stream.c | 21 ++++++++----- sound/usb/usbaudio.h | 12 ++++++++ 12 files changed, 127 insertions(+), 47 deletions(-)
sound/usb/card.c +2 -0
@@ -206,6 +206,8 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int intreturn -EINVAL ; } +snd_usb_add_ctrl_interface_link (chip, interface, ctrlif); +if (!snd_usb_parse_audio_interface (chip, interface)) {usb_set_interface (dev, interface,0 );/* reset the current interface */ return usb_driver_claim_interface(&usb_audio_driver, iface,
sound/usb/clock.c +39 -23
187 lines not on this page · raw message
sound/usb/format.c +4 -2
@@ -548,7 +548,9 @@ static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip,unsigned char tmp[2 ], *data;int nr_triplets, data_size, ret =0 , ret_l6;int clock =snd_usb_clock_find_source (chip, fp, false); +struct usb_host_interface *ctrl_intf; + ctrl_intf =snd_usb_find_ctrl_interface (chip, fp->iface);if (clock <0 ) { dev_err(&dev->dev, "%s(): unable to find clock source (clock %d)\n",
@@ -560,7 +562,7 @@ static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip, ret =snd_usb_ctl_msg (dev,usb_rcvctrlpipe (dev,0 ),UAC2_CS_RANGE ,USB_TYPE_CLASS |USB_RECIP_INTERFACE |USB_DIR_IN ,UAC2_CS_CONTROL_SAM_FREQ <<8 , -snd_usb_ctrl_intf (chip) | (clock <<8 ), +snd_usb_ctrl_intf (ctrl_intf) | (clock <<8 ), tmp,sizeof (tmp));if (ret <0 ) {
@@ -595,7 +597,7 @@ static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip, ret =snd_usb_ctl_msg (dev,usb_rcvctrlpipe (dev,0 ),UAC2_CS_RANGE ,USB_TYPE_CLASS |USB_RECIP_INTERFACE |USB_DIR_IN ,UAC2_CS_CONTROL_SAM_FREQ <<8 , -snd_usb_ctrl_intf (chip) | (clock <<8 ), +snd_usb_ctrl_intf (ctrl_intf) | (clock <<8 ), data, data_size);if (ret <0 ) {
sound/usb/helper.c +34 -0
@@ -130,3 +130,37 @@ snd_usb_get_host_interface(struct snd_usb_audio *chip, int ifnum, int altsettingreturn NULL ;return usb_altnum_to_altsetting (iface, altsetting); } + +int snd_usb_add_ctrl_interface_link (struct snd_usb_audio *chip,int ifnum, +int ctrlif) +{ +struct usb_device *dev = chip->dev; +struct usb_host_interface *host_iface; + +if (chip->num_intf_to_ctrl >=MAX_CARD_INTERFACES ) { +dev_info (&dev->dev,"Too many interfaces assigned to the single USB-audio card\n" ); +return -EINVAL ; + } + +/* find audiocontrol interface */ + host_iface = &usb_ifnum_to_if (dev, ctrlif)->altsetting[0 ]; + + chip->intf_to_ctrl[chip->num_intf_to_ctrl].interface = ifnum; + chip->intf_to_ctrl[chip->num_intf_to_ctrl].ctrl_intf = host_iface; + chip->num_intf_to_ctrl++; + +return 0 ; +} + +struct usb_host_interface *snd_usb_find_ctrl_interface (struct snd_usb_audio *chip, +int ifnum) +{ +int i; + +for (i =0 ; i < chip->num_intf_to_ctrl; ++i) +if (chip->intf_to_ctrl[i].interface == ifnum) +return chip->intf_to_ctrl[i].ctrl_intf; + +/* Fallback to first audiocontrol interface */ +return chip->ctrl_intf; +}
sound/usb/helper.h +8 -2
@@ -17,6 +17,12 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,struct usb_host_interface *snd_usb_get_host_interface (struct snd_usb_audio *chip,int ifnum,int altsetting); +int snd_usb_add_ctrl_interface_link (struct snd_usb_audio *chip,int ifnum, +int ctrlif); + +struct usb_host_interface *snd_usb_find_ctrl_interface (struct snd_usb_audio *chip, +int ifnum); +/* * retrieve usb_interface descriptor from the host interface * (conditional for compatibility with the older API)
@@ -28,9 +34,9 @@ snd_usb_get_host_interface(struct snd_usb_audio *chip, int ifnum, int altsetting#define snd_usb_get_speed (dev) ((dev)->speed) -static inline int snd_usb_ctrl_intf (struct snd_usb_audio *chip) +static inline int snd_usb_ctrl_intf (struct usb_host_interface *ctrl_intf) { -return get_iface_desc (chip->ctrl_intf)->bInterfaceNumber; +return get_iface_desc (ctrl_intf)->bInterfaceNumber; }/* in validate.c */
sound/usb/mixer.c +1 -1
@@ -728,7 +728,7 @@ static int get_cluster_channels_v3(struct mixer_build *state, unsigned int clustUAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR ,USB_RECIP_INTERFACE |USB_TYPE_CLASS |USB_DIR_IN , cluster_id, -snd_usb_ctrl_intf (state->chip), +snd_usb_ctrl_intf (state->mixer->hostif), &c_header, sizeof(c_header));if (err <0 ) goto error;
sound/usb/mixer_quirks.c +9 -8
@@ -1043,7 +1043,7 @@ static int snd_ftu_eff_switch_init(struct usb_mixer_interface *mixer, err =snd_usb_ctl_msg (dev,usb_rcvctrlpipe (dev,0 ),UAC_GET_CUR ,USB_RECIP_INTERFACE |USB_TYPE_CLASS |USB_DIR_IN , pval &0xff00 , -snd_usb_ctrl_intf (mixer->chip) | ((pval &0xff ) <<8 ), +snd_usb_ctrl_intf (mixer->hostif) | ((pval &0xff ) <<8 ), value,2 );if (err <0 )return err;
@@ -1077,7 +1077,7 @@ static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list)UAC_SET_CUR ,USB_RECIP_INTERFACE |USB_TYPE_CLASS |USB_DIR_OUT , pval &0xff00 , -snd_usb_ctrl_intf (chip) | ((pval &0xff ) <<8 ), +snd_usb_ctrl_intf (list->mixer->hostif) | ((pval &0xff ) <<8 ), value, 2);snd_usb_unlock_shutdown (chip);return err;
@@ -2115,24 +2115,25 @@ static int dell_dock_mixer_create(struct usb_mixer_interface *mixer)return 0 ; } -static void dell_dock_init_vol (struct snd_usb_audio *chip,int ch,int id) +static void dell_dock_init_vol (struct usb_mixer_interface *mixer,int ch,int id) { +struct snd_usb_audio *chip = mixer->chip;u16 buf =0 ;snd_usb_ctl_msg (chip->dev,usb_sndctrlpipe (chip->dev,0 ),UAC_SET_CUR ,USB_RECIP_INTERFACE |USB_TYPE_CLASS |USB_DIR_OUT , (UAC_FU_VOLUME <<8 ) | ch, -snd_usb_ctrl_intf (chip) | (id <<8 ), +snd_usb_ctrl_intf (mixer->hostif) | (id <<8 ), &buf,2 ); }static int dell_dock_mixer_init (struct usb_mixer_interface *mixer) {/* fix to 0dB playback volumes */ -dell_dock_init_vol (mixer->chip,1 ,16 ); -dell_dock_init_vol (mixer->chip,2 ,16 ); -dell_dock_init_vol (mixer->chip,1 ,19 ); -dell_dock_init_vol (mixer->chip,2 ,19 ); +dell_dock_init_vol (mixer,1 ,16 ); +dell_dock_init_vol (mixer,2 ,16 ); +dell_dock_init_vol (mixer,1 ,19 ); +dell_dock_init_vol (mixer,2 ,19 );return 0 ; }
sound/usb/mixer_scarlett.c +2 -2
@@ -460,7 +460,7 @@ static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,struct snd_usb_audio *chip = elem->head.mixer->chip;unsigned char buf[2 *MAX_CHANNELS ] = {0 , };int wValue = (elem->control <<8 ) | elem->idx_off; -int idx =snd_usb_ctrl_intf (chip) | (elem->head.id <<8 ); +int idx =snd_usb_ctrl_intf (elem->head.mixer->hostif) | (elem->head.id <<8 );int err; err = snd_usb_ctl_msg(chip->dev,
@@ -1002,7 +1002,7 @@ int snd_scarlett_controls_create(struct usb_mixer_interface *mixer) err =snd_usb_ctl_msg (mixer->chip->dev,usb_sndctrlpipe (mixer->chip->dev,0 ),UAC2_CS_CUR ,USB_RECIP_INTERFACE |USB_TYPE_CLASS | -USB_DIR_OUT ,0x0100 ,snd_usb_ctrl_intf (mixer->chip) | +USB_DIR_OUT ,0x0100 ,snd_usb_ctrl_intf (mixer->hostif) | (0x29 <<8 ), sample_rate_buffer,4 );if (err <0 )return err;
sound/usb/power.c +2 -1
@@ -40,6 +40,7 @@ snd_usb_find_power_domain(struct usb_host_interface *ctrl_iface,le16_to_cpu (pd_desc->waRecoveryTime1); pd->pd_d2d0_rec =le16_to_cpu (pd_desc->waRecoveryTime2); + pd->ctrl_iface = ctrl_iface;return pd; } }
@@ -57,7 +58,7 @@ int snd_usb_power_domain_set(struct snd_usb_audio *chip,unsigned char current_state;int err, idx; - idx =snd_usb_ctrl_intf (chip) | (pd->pd_id <<8 ); + idx =snd_usb_ctrl_intf (pd->ctrl_iface) | (pd->pd_id <<8 ); err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR,
sound/usb/power.h +1 -0
@@ -6,6 +6,7 @@ struct snd_usb_power_domain {int pd_id;/* UAC3 Power Domain ID */ int pd_d1d0_rec;/* D1 to D0 recovery time */ int pd_d2d0_rec;/* D2 to D0 recovery time */ +struct usb_host_interface *ctrl_iface;/* Control interface */ };enum {
sound/usb/stream.c +13 -8
@@ -713,10 +713,13 @@ snd_usb_get_audioformat_uac12(struct snd_usb_audio *chip,struct usb_device *dev = chip->dev;struct uac_format_type_i_continuous_descriptor *fmt;unsigned int num_channels =0 , chconfig =0 ; +struct usb_host_interface *ctrl_intf;struct audioformat *fp;int clock =0 ;u64 format; + ctrl_intf =snd_usb_find_ctrl_interface (chip, iface_no); +/* get audio formats */ if (protocol ==UAC_VERSION_1 ) { struct uac1_as_header_descriptor *as =
@@ -740,7 +743,7 @@ snd_usb_get_audioformat_uac12(struct snd_usb_audio *chip, format =le16_to_cpu (as->wFormatTag);/* remember the format value */ - iterm =snd_usb_find_input_terminal_descriptor (chip->ctrl_intf, + iterm =snd_usb_find_input_terminal_descriptor (ctrl_intf, as->bTerminalLink, protocol);if (iterm) {
@@ -776,7 +779,7 @@ snd_usb_get_audioformat_uac12(struct snd_usb_audio *chip,* lookup the terminal associated to this interface * to extract the clock */ - input_term =snd_usb_find_input_terminal_descriptor (chip->ctrl_intf, + input_term =snd_usb_find_input_terminal_descriptor (ctrl_intf, as->bTerminalLink, protocol);if (input_term) {
@@ -786,7 +789,7 @@ snd_usb_get_audioformat_uac12(struct snd_usb_audio *chip, goto found_clock; } - output_term =snd_usb_find_output_terminal_descriptor (chip->ctrl_intf, + output_term =snd_usb_find_output_terminal_descriptor (ctrl_intf, as->bTerminalLink, protocol);if (output_term) {
@@ -870,6 +873,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,struct uac3_cluster_header_descriptor *cluster;struct uac3_as_header_descriptor *as =NULL ;struct uac3_hc_descriptor_header hc_header; +struct usb_host_interface *ctrl_intf;struct snd_pcm_chmap_elem *chmap;struct snd_usb_power_domain *pd;unsigned char badd_profile;
@@ -881,6 +885,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,int err; badd_profile = chip->badd_profile; + ctrl_intf =snd_usb_find_ctrl_interface (chip, iface_no);if (badd_profile >=UAC3_FUNCTION_SUBCLASS_GENERIC_IO ) { unsigned int maxpacksize =
@@ -966,7 +971,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR ,USB_RECIP_INTERFACE |USB_TYPE_CLASS |USB_DIR_IN , cluster_id, -snd_usb_ctrl_intf (chip), +snd_usb_ctrl_intf (ctrl_intf), &hc_header, sizeof(hc_header));if (err <0 )return ERR_PTR (err);
@@ -990,7 +995,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR ,USB_RECIP_INTERFACE |USB_TYPE_CLASS |USB_DIR_IN , cluster_id, -snd_usb_ctrl_intf (chip), +snd_usb_ctrl_intf (ctrl_intf), cluster, wLength);if (err <0 ) {kfree (cluster);
@@ -1011,7 +1016,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,* lookup the terminal associated to this interface * to extract the clock */ - input_term =snd_usb_find_input_terminal_descriptor (chip->ctrl_intf, + input_term =snd_usb_find_input_terminal_descriptor (ctrl_intf, as->bTerminalLink,UAC_VERSION_3 );if (input_term) {
@@ -1019,7 +1024,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip, goto found_clock; } - output_term =snd_usb_find_output_terminal_descriptor (chip->ctrl_intf, + output_term =snd_usb_find_output_terminal_descriptor (ctrl_intf, as->bTerminalLink,UAC_VERSION_3 );if (output_term) {
@@ -1068,7 +1073,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,UAC_VERSION_3 , iface_no); - pd =snd_usb_find_power_domain (chip->ctrl_intf, + pd =snd_usb_find_power_domain (ctrl_intf, as->bTerminalLink);/* ok, let's parse further... */
sound/usb/usbaudio.h +12 -0
@@ -21,6 +21,15 @@ struct media_intf_devnode;#define MAX_CARD_INTERFACES 16 +/* +* Structure holding assosiation between Audio Control Interface +* and given Streaming or Midi Interface. +*/ +struct snd_intf_to_ctrl { +u8 interface; +struct usb_host_interface *ctrl_intf; +}; +struct snd_usb_audio {int index;struct usb_device *dev;
@@ -63,6 +72,9 @@ struct snd_usb_audio {struct usb_host_interface *ctrl_intf;/* the audio control interface */ struct media_device *media_dev;struct media_intf_devnode *ctl_intf_media_devnode; + +unsigned int num_intf_to_ctrl; +struct snd_intf_to_ctrl intf_to_ctrl[MAX_CARD_INTERFACES ]; };#define USB_AUDIO_IFACE_UNUSED ((void *)-1L)
Signature · 1 line
2.43.0
Re: [PATCH 6.10 141/482] ALSA: usb-audio: Support multiple control interfaces
Quoted 6 lines · Greg Kroah-Hartman
6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karol Kosik <[email protected]>
Quoted 7 lines
[ Upstream commit
6aa8700150f7dc62f60b4cf5b1624e2e3d9ed78e]Registering Numark Party Mix II fails with error 'bogus bTerminalLink 1'. The problem stems from the driver not being able to find input/output terminals required to configure audio streaming. The information about those terminals is stored in AudioControl Interface. Numark device contains 2 AudioControl Interfaces and the driver checks only one of them.
Please postpone (or skip) merging my patch to 6.10 due to regression.
I'm sorry for the disruption caused by this commit. Fix for this problem will be sent for review shortly, after I re-run all tests, and I aim to get it into 6.12-rc3.
Regards,
Karol Kosik
Greg Kroah-Hartman
maintainerPATCH 142/482 ALSA: usb-audio: Define macros for quirk table entries
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 0c3ad39b791c2ecf718afcaca30e5ceafa939d5c ]
Many entries in the USB-audio quirk tables have relatively complex expressions. For improving the readability, introduce a few macros. Those are applied in the following patch.
--- sound/usb/quirks-table.h | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
sound/usb/quirks-table.h +77 -0
@@ -35,6 +35,83 @@ .bInterfaceClass = USB_CLASS_AUDIO, \ .bInterfaceSubClass =USB_SUBCLASS_AUDIOCONTROL +/* Quirk .driver_info, followed by the definition of the quirk entry; +* put like QUIRK_DRIVER_INFO { ... } in each entry of the quirk table + */ +#define QUIRK_DRIVER_INFO \ + .driver_info = (unsigned long)&(const struct snd_usb_audio_quirk) + +/* +* Macros for quirk data entries +*/ + +/* Quirk data entry for ignoring the interface */ +#define QUIRK_DATA_IGNORE (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_IGNORE_INTERFACE +/* Quirk data entry for a standard audio interface */ +#define QUIRK_DATA_STANDARD_AUDIO (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_AUDIO_STANDARD_INTERFACE +/* Quirk data entry for a standard MIDI interface */ +#define QUIRK_DATA_STANDARD_MIDI (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_MIDI_STANDARD_INTERFACE +/* Quirk data entry for a standard mixer interface */ +#define QUIRK_DATA_STANDARD_MIXER (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_AUDIO_STANDARD_MIXER + +/* Quirk data entry for Yamaha MIDI */ +#define QUIRK_DATA_MIDI_YAMAHA (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_MIDI_YAMAHA +/* Quirk data entry for Edirol UAxx */ +#define QUIRK_DATA_EDIROL_UAXX (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_AUDIO_EDIROL_UAXX +/* Quirk data entry for raw bytes interface */ +#define QUIRK_DATA_RAW_BYTES (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_MIDI_RAW_BYTES + +/* Quirk composite array terminator */ +#define QUIRK_COMPOSITE_END { .ifnum = -1 } + +/* Quirk data entry for composite quirks; +* followed by the quirk array that is terminated with QUIRK_COMPOSITE_END +* e.g. QUIRK_DATA_COMPOSITE { { quirk1 }, { quirk2 },..., QUIRK_COMPOSITE_END } +*/ +#define QUIRK_DATA_COMPOSITE \ + .ifnum = QUIRK_ANY_INTERFACE, \ + .type = QUIRK_COMPOSITE, \ + .data = &(const struct snd_usb_audio_quirk[]) + +/* Quirk data entry for a fixed audio endpoint; +* followed by audioformat definition +* e.g. QUIRK_DATA_AUDIOFORMAT(n) { .formats = xxx, ... } +*/ +#define QUIRK_DATA_AUDIOFORMAT (_ifno) \ + .ifnum = (_ifno), \ + .type = QUIRK_AUDIO_FIXED_ENDPOINT, \ + .data = &(const struct audioformat) + +/* Quirk data entry for a fixed MIDI endpoint; +* followed by snd_usb_midi_endpoint_info definition +* e.g. QUIRK_DATA_MIDI_FIXED_ENDPOINT(n) { .out_cables = x, .in_cables = y } +*/ +#define QUIRK_DATA_MIDI_FIXED_ENDPOINT (_ifno) \ + .ifnum = (_ifno), \ + .type = QUIRK_MIDI_FIXED_ENDPOINT, \ + .data = &(const struct snd_usb_midi_endpoint_info) +/* Quirk data entry for a MIDIMAN MIDI endpoint */ +#define QUIRK_DATA_MIDI_MIDIMAN (_ifno) \ + .ifnum = (_ifno), \ + .type = QUIRK_MIDI_MIDIMAN, \ + .data = &(const struct snd_usb_midi_endpoint_info) +/* Quirk data entry for a EMAGIC MIDI endpoint */ +#define QUIRK_DATA_MIDI_EMAGIC (_ifno) \ + .ifnum = (_ifno), \ + .type = QUIRK_MIDI_EMAGIC, \ + .data = &(const struct snd_usb_midi_endpoint_info) + +/* +* Here we go... the quirk table definition begins: +*/ +/* FTDI devices */ { USB_DEVICE(0x0403, 0xb8d8),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 143/482 ALSA: usb-audio: Replace complex quirk lines with macros
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit d79e13f8e8abb5cd3a2a0f9fc9bc3fc750c5b06f ]
Apply the newly introduced macros for reduce the complex expressions and cast in the quirk table definitions. It results in a significant code reduction, too.
There should be no functional changes.
--- sound/usb/quirks-table.h | 2210 ++++++++++---------------------------- 1 file changed, 593 insertions(+), 1617 deletions(-)
sound/usb/quirks-table.h +593 -1617
@@ -115,7 +115,7 @@/* FTDI devices */ {USB_DEVICE (0x0403 ,0xb8d8 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "STARR LABS", */ /* .product_name = "Starr Labs MIDI USB device", */ .ifnum = 0,
@@ -126,10 +126,8 @@ {/* Creative BT-D1 */ USB_DEVICE (0x041e ,0x0005 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { - .ifnum =1 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DRIVER_INFO { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels = 2, .iface = 1,
@@ -164,18 +162,11 @@*/ {USB_AUDIO_DEVICE (0x041e ,0x4095 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = &(const struct snd_usb_audio_quirk []) { - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_MIXER , - }, + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_MIXER(2) }, { - .ifnum =3 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(3) { .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels = 2, .fmt_bits = 16,
@@ -191,9 +182,7 @@ .rate_table = (unsigned int[]) { 48000 }, }, }, - { - .ifnum = -1 - }, +QUIRK_COMPOSITE_END }, }, },
@@ -205,31 +194,18 @@*/ {USB_DEVICE (0x0424 ,0xb832 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Standard Microsystems Corp." , .product_name = "HP Wireless Audio", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE {/* Mixer */ - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE , - }, + { QUIRK_DATA_IGNORE(0) },/* Playback */ - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE , - }, + { QUIRK_DATA_IGNORE(1) },/* Capture */ - { - .ifnum =2 , - .type =QUIRK_IGNORE_INTERFACE , - }, + { QUIRK_DATA_IGNORE(2) },/* HID Device, .ifnum = 3 */ - { - .ifnum =-1 , - } + QUIRK_COMPOSITE_END } } },
@@ -252,20 +228,18 @@#define YAMAHA_DEVICE (id, name) { \ USB_DEVICE(0x0499, id), \ - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { \ + QUIRK_DRIVER_INFO { \ .vendor_name = "Yamaha", \ .product_name = name, \ - .ifnum = QUIRK_ANY_INTERFACE, \ - .type = QUIRK_MIDI_YAMAHA \ + QUIRK_DATA_MIDI_YAMAHA(QUIRK_ANY_INTERFACE) \ } \ }#define YAMAHA_INTERFACE (id, intf, name) { \ USB_DEVICE_VENDOR_SPEC(0x0499, id), \ - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { \ + QUIRK_DRIVER_INFO { \ .vendor_name = "Yamaha", \ .product_name = name, \ - .ifnum = intf, \ - .type = QUIRK_MIDI_YAMAHA \ + QUIRK_DATA_MIDI_YAMAHA(intf) \ } \ } YAMAHA_DEVICE(0x1000, "UX256"),
@@ -353,135 +327,67 @@ YAMAHA_DEVICE(0x105d, NULL), YAMAHA_DEVICE(0x1718, "P-125"), { USB_DEVICE(0x0499, 0x1503), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { /* .vendor_name = "Yamaha", */ /* .product_name = "MOX6/MOX8", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =3 , - .type =QUIRK_MIDI_YAMAHA - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + { QUIRK_DATA_MIDI_YAMAHA(3) }, + QUIRK_COMPOSITE_END } } }, { USB_DEVICE(0x0499, 0x1507), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { /* .vendor_name = "Yamaha", */ /* .product_name = "THR10", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =3 , - .type =QUIRK_MIDI_YAMAHA - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + { QUIRK_DATA_MIDI_YAMAHA(3) }, + QUIRK_COMPOSITE_END } } }, { USB_DEVICE(0x0499, 0x1509), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { /* .vendor_name = "Yamaha", */ /* .product_name = "Steinberg UR22", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =3 , - .type =QUIRK_MIDI_YAMAHA - }, - { - .ifnum =4 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + { QUIRK_DATA_MIDI_YAMAHA(3) }, + { QUIRK_DATA_IGNORE(4) }, + QUIRK_COMPOSITE_END } } }, { USB_DEVICE(0x0499, 0x150a), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { /* .vendor_name = "Yamaha", */ /* .product_name = "THR5A", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =3 , - .type =QUIRK_MIDI_YAMAHA - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + { QUIRK_DATA_MIDI_YAMAHA(3) }, + QUIRK_COMPOSITE_END } } }, { USB_DEVICE(0x0499, 0x150c), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { /* .vendor_name = "Yamaha", */ /* .product_name = "THR10C", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =3 , - .type =QUIRK_MIDI_YAMAHA - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + { QUIRK_DATA_MIDI_YAMAHA(3) }, + QUIRK_COMPOSITE_END } } },
@@ -515,7 +421,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), USB_DEVICE_ID_MATCH_INT_CLASS, .idVendor = 0x0499, .bInterfaceClass =USB_CLASS_VENDOR_SPEC , - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { .ifnum =QUIRK_ANY_INTERFACE , .type = QUIRK_AUTODETECT }
@@ -526,16 +432,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),*/ {USB_DEVICE (0x0582 ,0x0000 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "UA-100", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE { { - .ifnum =0 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(0) { .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels = 4, .iface = 0,
@@ -550,9 +452,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 1, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels = 2, .iface = 1,
@@ -567,106 +467,66 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables = 0x0007, .in_cables = 0x0007 } }, - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } }, {USB_DEVICE (0x0582 ,0x0002 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UM-4", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x000f , .in_cables = 0x000f } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {USB_DEVICE (0x0582 ,0x0003 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "SC-8850", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x003f , .in_cables = 0x003f } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {USB_DEVICE (0x0582 ,0x0004 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "U-8", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0005 , .in_cables = 0x0005 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } },
@@ -674,152 +534,92 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* Has ID 0x0099 when not in "Advanced Driver" mode. * The UM-2EX has only one input, but we cannot detect this. */ USB_DEVICE (0x0582 ,0x0005 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UM-2", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0003 , .in_cables = 0x0003 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {USB_DEVICE (0x0582 ,0x0007 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "SC-8820", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0013 , .in_cables = 0x0013 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {USB_DEVICE (0x0582 ,0x0008 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "PC-300", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0001 , .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {/* has ID 0x009d when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0009 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UM-1", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0001 , .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {USB_DEVICE (0x0582 ,0x000b ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "SK-500", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0013 , .in_cables = 0x0013 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } },
@@ -827,31 +627,19 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* thanks to Emiliano Grilli <[email protected]> * for helping researching this data */ USB_DEVICE (0x0582 ,0x000c ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "SC-D70", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(0) }, + { QUIRK_DATA_STANDARD_AUDIO(1) }, { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0007 , .in_cables = 0x0007 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } },
@@ -865,35 +653,23 @@ YAMAHA_DEVICE(0x7010, "UB99"),* the 96kHz sample rate. */ USB_DEVICE (0x0582 ,0x0010 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UA-5", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + QUIRK_COMPOSITE_END } } }, {/* has ID 0x0013 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0012 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "XV-5050", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -902,12 +678,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x0015 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0014 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UM-880", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x01ff , .in_cables = 0x01ff }
@@ -916,74 +690,48 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x0017 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0016 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "SD-90", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(0) }, + { QUIRK_DATA_STANDARD_AUDIO(1) }, { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x000f , .in_cables = 0x000f } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {/* has ID 0x001c when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x001b ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "MMP-2", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0001 , .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {/* has ID 0x001e when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x001d ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "V-SYNTH", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -992,12 +740,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x0024 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0023 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UM-550", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x003f , .in_cables = 0x003f }
@@ -1010,20 +756,13 @@ YAMAHA_DEVICE(0x7010, "UB99"),* and no MIDI. */ USB_DEVICE (0x0582 ,0x0025 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UA-20", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, { - .ifnum =1 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 2, .iface = 1,
@@ -1038,9 +777,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 2, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(2) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 2, .iface = 2,
@@ -1055,28 +792,22 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 3, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(3) { .out_cables = 0x0001, .in_cables = 0x0001 } }, - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } }, {/* has ID 0x0028 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0027 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "SD-20", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0003 , .in_cables = 0x0007 }
@@ -1085,12 +816,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x002a when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0029 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "SD-80", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x000f , .in_cables = 0x000f }
@@ -1103,39 +832,24 @@ YAMAHA_DEVICE(0x7010, "UB99"),* but offers only 16-bit PCM and no MIDI. */ USB_DEVICE_VENDOR_SPEC (0x0582 ,0x002b ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UA-700", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =3 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_EDIROL_UAXX(1) }, + { QUIRK_DATA_EDIROL_UAXX(2) }, + { QUIRK_DATA_EDIROL_UAXX(3) }, + QUIRK_COMPOSITE_END } } }, {/* has ID 0x002e when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x002d ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "XV-2020", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1144,12 +858,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x0030 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x002f ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "VariOS", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0007 , .in_cables = 0x0007 }
@@ -1158,12 +870,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x0034 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0033 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "PCR", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0003 , .in_cables = 0x0007 }
@@ -1175,12 +885,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),* later revisions use IDs 0x0054 and 0x00a2. */ USB_DEVICE (0x0582 ,0x0037 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "Digital Piano", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1193,39 +901,24 @@ YAMAHA_DEVICE(0x7010, "UB99"),* and no MIDI. */ USB_DEVICE_VENDOR_SPEC (0x0582 ,0x003b ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="BOSS" , .product_name = "GS-10", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =3 , - .type =QUIRK_MIDI_STANDARD_INTERFACE - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + { QUIRK_DATA_STANDARD_MIDI(3) }, + QUIRK_COMPOSITE_END } } }, {/* has ID 0x0041 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0040 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "GI-20", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1234,12 +927,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x0043 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0042 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "RS-70", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1248,36 +939,24 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x0049 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0047 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "EDIROL", */ /* .product_name = "UR-80", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE {/* in the 96 kHz modes, only interface 1 is there */ - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =-1 - } + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + QUIRK_COMPOSITE_END } } }, {/* has ID 0x004a when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0048 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "EDIROL", */ /* .product_name = "UR-80", */ - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables = 0x0003, .in_cables = 0x0007 }
@@ -1286,35 +965,23 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x004e when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x004c ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "PCR-A", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + QUIRK_COMPOSITE_END } } }, {/* has ID 0x004f when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x004d ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "PCR-A", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0003 , .in_cables = 0x0007 }
@@ -1326,76 +993,52 @@ YAMAHA_DEVICE(0x7010, "UB99"),* is standard compliant, but has only 16-bit PCM. */ USB_DEVICE (0x0582 ,0x0050 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UA-3FX", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + QUIRK_COMPOSITE_END } } }, {USB_DEVICE (0x0582 ,0x0052 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UM-1SX", - .ifnum =0 , - .type =QUIRK_MIDI_STANDARD_INTERFACE + QUIRK_DATA_STANDARD_MIDI(0) } }, {USB_DEVICE (0x0582 ,0x0060 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "EXR Series", - .ifnum =0 , - .type =QUIRK_MIDI_STANDARD_INTERFACE +QUIRK_DATA_STANDARD_MIDI (0 ) } }, {/* has ID 0x0066 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0064 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "EDIROL", */ /* .product_name = "PCR-1", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, + QUIRK_COMPOSITE_END } } }, {/* has ID 0x0067 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0065 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "EDIROL", */ /* .product_name = "PCR-1", */ - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables = 0x0001, .in_cables =0x0003 }
@@ -1404,12 +1047,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x006e when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x006d ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "FANTOM-X", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1422,39 +1063,24 @@ YAMAHA_DEVICE(0x7010, "UB99"),* offers only 16-bit PCM at 44.1 kHz and no MIDI. */ USB_DEVICE_VENDOR_SPEC (0x0582 ,0x0074 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UA-25", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_EDIROL_UAXX(0) }, + { QUIRK_DATA_EDIROL_UAXX(1) }, + { QUIRK_DATA_EDIROL_UAXX(2) }, + QUIRK_COMPOSITE_END } } }, {/* has ID 0x0076 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0075 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="BOSS" , .product_name = "DR-880", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1463,12 +1089,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x007b when not in "Advanced Driver" mode */ USB_DEVICE_VENDOR_SPEC (0x0582 ,0x007a ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" ,/* "RD" or "RD-700SX"? */ - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0003 , .in_cables = 0x0003 }
@@ -1477,12 +1101,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x0081 when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x0080 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Roland" , .product_name = "G-70", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1491,12 +1113,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* has ID 0x008c when not in "Advanced Driver" mode */ USB_DEVICE (0x0582 ,0x008b ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "PC-50", - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1508,56 +1128,31 @@ YAMAHA_DEVICE(0x7010, "UB99"),* is standard compliant, but has only 16-bit PCM and no MIDI. */ USB_DEVICE (0x0582 ,0x00a3 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UA-4FX", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_EDIROL_UAXX(0) }, + { QUIRK_DATA_EDIROL_UAXX(1) }, + { QUIRK_DATA_EDIROL_UAXX(2) }, + QUIRK_COMPOSITE_END } } }, {/* Edirol M-16DX */ USB_DEVICE (0x0582 ,0x00c4 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(0) }, + { QUIRK_DATA_STANDARD_AUDIO(1) }, { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0001 , .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } },
@@ -1567,37 +1162,22 @@ YAMAHA_DEVICE(0x7010, "UB99"),* offers only 16-bit PCM at 44.1 kHz and no MIDI. */ USB_DEVICE_VENDOR_SPEC (0x0582 ,0x00e6 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="EDIROL" , .product_name = "UA-25EX", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_EDIROL_UAXX - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_EDIROL_UAXX(0) }, + { QUIRK_DATA_EDIROL_UAXX(1) }, + { QUIRK_DATA_EDIROL_UAXX(2) }, + QUIRK_COMPOSITE_END } } }, {/* Edirol UM-3G */ USB_DEVICE_VENDOR_SPEC (0x0582 ,0x0108 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { - .ifnum =0 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DRIVER_INFO { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(0) { .out_cables = 0x0007, .in_cables =0x0007 }
@@ -1606,45 +1186,29 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* BOSS ME-25 */ USB_DEVICE (0x0582 ,0x0113 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(0) }, + { QUIRK_DATA_STANDARD_AUDIO(1) }, { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0001 , .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {/* only 44.1 kHz works at the moment */ USB_DEVICE (0x0582 ,0x0120 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "Roland", */ /* .product_name = "OCTO-CAPTURE", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE { { - .ifnum =0 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(0) { .formats = SNDRV_PCM_FMTBIT_S32_LE, .channels = 10, .iface = 0,
@@ -1660,9 +1224,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 1, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S32_LE, .channels = 12, .iface = 1,
@@ -1678,40 +1240,26 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables = 0x0001, .in_cables = 0x0001 } }, - { - .ifnum = 3, - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 4, - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = -1 - } + { QUIRK_DATA_IGNORE(3) }, + { QUIRK_DATA_IGNORE(4) }, + QUIRK_COMPOSITE_END } } }, {/* only 44.1 kHz works at the moment */ USB_DEVICE (0x0582 ,0x012f ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "Roland", */ /* .product_name = "QUAD-CAPTURE", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE { { - .ifnum =0 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(0) { .formats = SNDRV_PCM_FMTBIT_S32_LE, .channels = 4, .iface = 0,
@@ -1727,9 +1275,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 1, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S32_LE, .channels = 6, .iface = 1,
@@ -1745,54 +1291,32 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables = 0x0001, .in_cables = 0x0001 } }, - { - .ifnum = 3, - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 4, - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = -1 - } + { QUIRK_DATA_IGNORE(3) }, + { QUIRK_DATA_IGNORE(4) }, + QUIRK_COMPOSITE_END } } }, {USB_DEVICE (0x0582 ,0x0159 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "Roland", */ /* .product_name = "UA-22", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(0) }, + { QUIRK_DATA_STANDARD_AUDIO(1) }, { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(2) { .out_cables =0x0001 , .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } },
@@ -1800,19 +1324,19 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* UA101 and co are supported by another driver */ {USB_DEVICE (0x0582 ,0x0044 ),/* UA-1000 high speed */ - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .ifnum =QUIRK_NODEV_INTERFACE }, }, {USB_DEVICE (0x0582 ,0x007d ),/* UA-101 high speed */ - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { .ifnum =QUIRK_NODEV_INTERFACE }, }, {USB_DEVICE (0x0582 ,0x008d ),/* UA-101 full speed */ - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { .ifnum =QUIRK_NODEV_INTERFACE }, },
@@ -1823,7 +1347,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), USB_DEVICE_ID_MATCH_INT_CLASS, .idVendor = 0x0582, .bInterfaceClass =USB_CLASS_VENDOR_SPEC , - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { .ifnum =QUIRK_ANY_INTERFACE , .type = QUIRK_AUTODETECT }
@@ -1838,12 +1362,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),* compliant USB MIDI ports for external MIDI and controls. */ USB_DEVICE_VENDOR_SPEC (0x06f8 ,0xb000 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Hercules" , .product_name = "DJ Console (WE)", - .ifnum =4 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(4) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1853,12 +1375,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* Midiman/M-Audio devices */ {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x1002 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "MidiSport 2x2", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(QUIRK_ANY_INTERFACE) { .out_cables =0x0003 , .in_cables = 0x0003 }
@@ -1866,12 +1386,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x1011 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "MidiSport 1x1", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(QUIRK_ANY_INTERFACE) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1879,12 +1397,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x1015 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "Keystation", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(QUIRK_ANY_INTERFACE) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -1892,12 +1408,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x1021 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "MidiSport 4x4", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(QUIRK_ANY_INTERFACE) { .out_cables =0x000f , .in_cables = 0x000f }
@@ -1910,12 +1424,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),* Thanks to Olaf Giesbrecht <[email protected]> */ USB_DEVICE_VER (0x0763 ,0x1031 ,0x0100 ,0x0109 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "MidiSport 8x8", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(QUIRK_ANY_INTERFACE) { .out_cables =0x01ff , .in_cables = 0x01ff }
@@ -1923,12 +1435,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x1033 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "MidiSport 8x8", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(QUIRK_ANY_INTERFACE) { .out_cables =0x01ff , .in_cables = 0x01ff }
@@ -1936,12 +1446,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x1041 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "MidiSport 2x4", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(QUIRK_ANY_INTERFACE) { .out_cables =0x000f , .in_cables = 0x0003 }
@@ -1949,76 +1457,41 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x2001 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "Quattro", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE {/* * Interfaces 0-2 are "Windows-compatible", 16-bit only, * and share endpoints with the other interfaces. * Ignore them. The other interfaces can do 24 bits, * but captured samples are big-endian (see usbaudio.c). */ - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =3 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =4 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =5 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =6 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =7 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =8 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =9 , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, + { QUIRK_DATA_IGNORE(2) }, + { QUIRK_DATA_IGNORE(3) }, + { QUIRK_DATA_STANDARD_AUDIO(4) }, + { QUIRK_DATA_STANDARD_AUDIO(5) }, + { QUIRK_DATA_IGNORE(6) }, + { QUIRK_DATA_STANDARD_AUDIO(7) }, + { QUIRK_DATA_STANDARD_AUDIO(8) }, + { + QUIRK_DATA_MIDI_MIDIMAN(9) { .out_cables =0x0001 , .in_cables = 0x0001 } }, - { - .ifnum =-1 - } +QUIRK_COMPOSITE_END } } }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x2003 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "AudioPhile", - .ifnum =6 , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(6) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -2026,12 +1499,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x2008 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="M-Audio" , .product_name = "Ozone", - .ifnum =3 , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(3) { .out_cables =0x0001 , .in_cables = 0x0001 }
@@ -2039,93 +1510,45 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, { USB_DEVICE_VENDOR_SPEC(0x0763, 0x200d), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name = "M-Audio", .product_name = "OmniStudio", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =3 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =4 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =5 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =6 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =7 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =8 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =9 , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, + { QUIRK_DATA_IGNORE(2) }, + { QUIRK_DATA_IGNORE(3) }, + { QUIRK_DATA_STANDARD_AUDIO(4) }, + { QUIRK_DATA_STANDARD_AUDIO(5) }, + { QUIRK_DATA_IGNORE(6) }, + { QUIRK_DATA_STANDARD_AUDIO(7) }, + { QUIRK_DATA_STANDARD_AUDIO(8) }, + { + QUIRK_DATA_MIDI_MIDIMAN(9) { .out_cables = 0x0001, .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, { USB_DEVICE(0x0763, 0x2019), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { /* .vendor_name = "M-Audio", */ /* .product_name = "Ozone Academic", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(0) }, + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =3 , - .type =QUIRK_MIDI_MIDIMAN , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(3) { .out_cables = 0x0001, .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } },
@@ -2135,21 +1558,14 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x2030 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "M-Audio", */ /* .product_name = "Fast Track C400", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = &(const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_MIXER , - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_MIXER(1) }, /* Playback */ { - .ifnum =2 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(2) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 6, .iface = 2,
@@ -2173,9 +1589,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), },/* Capture */ { - .ifnum = 3, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(3) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 4, .iface = 3,
@@ -2197,30 +1611,21 @@ YAMAHA_DEVICE(0x7010, "UB99"), .clock = 0x80, } }, -/* MIDI */ - { - .ifnum = -1 /* Interface = 4 */ - } +/* MIDI: Interface = 4*/ + QUIRK_COMPOSITE_END } } }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x2031 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "M-Audio", */ /* .product_name = "Fast Track C600", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = &(const struct snd_usb_audio_quirk []) { - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_MIXER , - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_MIXER(1) }, /* Playback */ { - .ifnum =2 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(2) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 8, .iface = 2,
@@ -2244,9 +1649,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), },/* Capture */ { - .ifnum = 3, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(3) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 6, .iface = 3,
@@ -2268,29 +1671,20 @@ YAMAHA_DEVICE(0x7010, "UB99"), .clock = 0x80, } }, -/* MIDI */ - { - .ifnum = -1 /* Interface = 4 */ - } +/* MIDI: Interface = 4 */ + QUIRK_COMPOSITE_END } } }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x2080 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "M-Audio", */ /* .product_name = "Fast Track Ultra", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_MIXER , - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_MIXER(0) }, { - .ifnum =1 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 8, .iface = 1,
@@ -2312,9 +1706,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 2, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(2) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 8, .iface = 2,
@@ -2336,28 +1728,19 @@ YAMAHA_DEVICE(0x7010, "UB99"), } },/* interface 3 (MIDI) is standard compliant */ - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } }, {USB_DEVICE_VENDOR_SPEC (0x0763 ,0x2081 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "M-Audio", */ /* .product_name = "Fast Track Ultra 8R", */ - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_MIXER , - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_MIXER(0) }, { - .ifnum =1 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 8, .iface = 1,
@@ -2379,9 +1762,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 2, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(2) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 8, .iface = 2,
@@ -2403,9 +1784,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } },/* interface 3 (MIDI) is standard compliant */ - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } },
@@ -2413,21 +1792,19 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* Casio devices */ {USB_DEVICE (0x07cf ,0x6801 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Casio" , .product_name = "PL-40R", - .ifnum =0 , - .type =QUIRK_MIDI_YAMAHA + QUIRK_DATA_MIDI_YAMAHA(0) } }, {/* this ID is used by several devices without a product ID */ USB_DEVICE (0x07cf ,0x6802 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Casio" , .product_name = "Keyboard", - .ifnum =0 , - .type =QUIRK_MIDI_YAMAHA +QUIRK_DATA_MIDI_YAMAHA (0 ) } },
@@ -2440,23 +1817,13 @@ YAMAHA_DEVICE(0x7010, "UB99"), .idVendor = 0x07fd, .idProduct = 0x0001, .bDeviceSubClass = 2, - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name = "MOTU", .product_name = "Fastlane", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_MIDI_RAW_BYTES - }, - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =-1 - } + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_RAW_BYTES(0) }, + { QUIRK_DATA_IGNORE(1) }, + QUIRK_COMPOSITE_END } } },
@@ -2464,12 +1831,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* Emagic devices */ {USB_DEVICE (0x086a ,0x0001 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Emagic" , .product_name = "Unitor8", - .ifnum =2 , - .type =QUIRK_MIDI_EMAGIC , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_EMAGIC(2) { .out_cables =0x80ff , .in_cables = 0x80ff }
@@ -2477,12 +1842,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE (0x086a ,0x0002 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Emagic" ,/* .product_name = "AMT8", */ - .ifnum =2 , - .type =QUIRK_MIDI_EMAGIC , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_EMAGIC(2) { .out_cables =0x80ff , .in_cables = 0x80ff }
@@ -2490,12 +1853,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE (0x086a ,0x0003 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Emagic" ,/* .product_name = "MT4", */ - .ifnum =2 , - .type =QUIRK_MIDI_EMAGIC , - .data = & (const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_EMAGIC(2) { .out_cables =0x800f , .in_cables = 0x8003 }
@@ -2505,38 +1866,35 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* KORG devices */ {USB_DEVICE_VENDOR_SPEC (0x0944 ,0x0200 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="KORG, Inc." ,/* .product_name = "PANDORA PX5D", */ - .ifnum =3 , - .type =QUIRK_MIDI_STANDARD_INTERFACE , + QUIRK_DATA_STANDARD_MIDI(3) } }, {USB_DEVICE_VENDOR_SPEC (0x0944 ,0x0201 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="KORG, Inc." ,/* .product_name = "ToneLab ST", */ - .ifnum =3 , - .type =QUIRK_MIDI_STANDARD_INTERFACE , +QUIRK_DATA_STANDARD_MIDI (3 ) } }, {USB_DEVICE_VENDOR_SPEC (0x0944 ,0x0204 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="KORG, Inc." ,/* .product_name = "ToneLab EX", */ - .ifnum =3 , - .type =QUIRK_MIDI_STANDARD_INTERFACE , +QUIRK_DATA_STANDARD_MIDI (3 ) } },/* AKAI devices */ {USB_DEVICE (0x09e8 ,0x0062 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="AKAI" , .product_name = "MPD16", .ifnum = 0,
@@ -2547,21 +1905,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* Akai MPC Element */ USB_DEVICE (0x09e8 ,0x0021 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_MIDI_STANDARD_INTERFACE - }, - { - .ifnum =-1 - } + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_STANDARD_MIDI(1) }, + QUIRK_COMPOSITE_END } } },
@@ -2570,66 +1918,36 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* Steinberg MI2 */ USB_DEVICE_VENDOR_SPEC (0x0a4e ,0x2040 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(0) }, + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, { - .ifnum =3 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = &(const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(3) { .out_cables =0x0001 , .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } }, {/* Steinberg MI4 */ USB_DEVICE_VENDOR_SPEC (0x0a4e ,0x4040 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = & (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE - }, + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(0) }, + { QUIRK_DATA_STANDARD_AUDIO(1) }, + { QUIRK_DATA_STANDARD_AUDIO(2) }, { - .ifnum =3 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = &(const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(3) { .out_cables =0x0001 , .in_cables = 0x0001 } }, - { - .ifnum =-1 - } + QUIRK_COMPOSITE_END } } },
@@ -2637,34 +1955,31 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* TerraTec devices */ {USB_DEVICE_VENDOR_SPEC (0x0ccd ,0x0012 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="TerraTec" , .product_name = "PHASE 26", - .ifnum =3 , - .type =QUIRK_MIDI_STANDARD_INTERFACE + QUIRK_DATA_STANDARD_MIDI(3) } }, {USB_DEVICE_VENDOR_SPEC (0x0ccd ,0x0013 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="TerraTec" , .product_name = "PHASE 26", - .ifnum =3 , - .type =QUIRK_MIDI_STANDARD_INTERFACE +QUIRK_DATA_STANDARD_MIDI (3 ) } }, {USB_DEVICE_VENDOR_SPEC (0x0ccd ,0x0014 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="TerraTec" , .product_name = "PHASE 26", - .ifnum =3 , - .type =QUIRK_MIDI_STANDARD_INTERFACE +QUIRK_DATA_STANDARD_MIDI (3 ) } }, {USB_DEVICE (0x0ccd ,0x0035 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Miditech" , .product_name = "Play'n Roll", .ifnum = 0,
@@ -2679,7 +1994,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* Novation EMS devices */ {USB_DEVICE_VENDOR_SPEC (0x1235 ,0x0001 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Novation" , .product_name = "ReMOTE Audio/XStation", .ifnum = 4,
@@ -2688,7 +2003,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE_VENDOR_SPEC (0x1235 ,0x0002 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Novation" , .product_name = "Speedio", .ifnum = 3,
@@ -2697,38 +2012,29 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {USB_DEVICE (0x1235 ,0x000a ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "Novation", */ /* .product_name = "Nocturn", */ - .ifnum =0 , - .type =QUIRK_MIDI_RAW_BYTES + QUIRK_DATA_RAW_BYTES(0) } }, {USB_DEVICE (0x1235 ,0x000e ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO {/* .vendor_name = "Novation", */ /* .product_name = "Launchpad", */ - .ifnum =0 , - .type =QUIRK_MIDI_RAW_BYTES + QUIRK_DATA_RAW_BYTES(0) } }, {USB_DEVICE (0x1235 ,0x0010 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Focusrite" , .product_name = "Saffire 6 USB", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_MIXER(0) }, { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_MIXER , - }, - { - .ifnum =0 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(0) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 4, .iface = 0,
@@ -2755,9 +2061,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 0, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(0) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 2, .iface = 0,
@@ -2779,28 +2083,19 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, - { - .ifnum = 1, - .type = QUIRK_MIDI_RAW_BYTES - }, - { - .ifnum = -1 - } + { QUIRK_DATA_RAW_BYTES(1) }, + QUIRK_COMPOSITE_END } } }, {USB_DEVICE (0x1235 ,0x0018 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Novation" , .product_name = "Twitch", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE { { - .ifnum =0 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = & (const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(0) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 4, .iface = 0,
@@ -2819,19 +2114,14 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, - { - .ifnum = 1, - .type = QUIRK_MIDI_RAW_BYTES - }, - { - .ifnum = -1 - } + { QUIRK_DATA_RAW_BYTES(1) }, + QUIRK_COMPOSITE_END } } }, {USB_DEVICE_VENDOR_SPEC (0x1235 ,0x4661 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Novation" , .product_name = "ReMOTE25", .ifnum = 0,
@@ -2843,25 +2133,16 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* VirusTI Desktop */ USB_DEVICE_VENDOR_SPEC (0x133e ,0x0815 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = &(const struct snd_usb_audio_quirk []) { + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { { - .ifnum =3 , - .type =QUIRK_MIDI_FIXED_ENDPOINT , - .data = &(const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(3) { .out_cables = 0x0003, .in_cables = 0x0003 } }, - { - .ifnum =4 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =-1 - } + { QUIRK_DATA_IGNORE(4) }, + QUIRK_COMPOSITE_END } } },
@@ -2889,7 +2170,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* QinHeng devices */ {USB_DEVICE (0x1a86 ,0x752d ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="QinHeng" , .product_name = "CH345", .ifnum = 1,
@@ -2903,7 +2184,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* Miditech devices */ {USB_DEVICE (0x4752 ,0x0011 ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Miditech" , .product_name = "Midistart-2", .ifnum = 0,
@@ -2915,7 +2196,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* this ID used by both Miditech MidiStudio-2 and CME UF-x */ USB_DEVICE (0x7104 ,0x2202 ), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + QUIRK_DRIVER_INFO { .ifnum =0 , .type = QUIRK_MIDI_CME }
@@ -2925,20 +2206,13 @@ YAMAHA_DEVICE(0x7010, "UB99"), {/* Thanks to Clemens Ladisch <[email protected]> */ USB_DEVICE (0x0dba ,0x1000 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Digidesign" , .product_name = "MBox", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []){ - { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_MIXER , - }, + QUIRK_DATA_COMPOSITE{ + { QUIRK_DATA_STANDARD_MIXER(0) }, { - .ifnum =1 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S24_3BE, .channels = 2, .iface = 1,
@@ -2959,9 +2233,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 1, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S24_3BE, .channels = 2, .iface = 1,
@@ -2982,9 +2254,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } },
@@ -2992,24 +2262,14 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* DIGIDESIGN MBOX 2 */ {USB_DEVICE (0x0dba ,0x3000 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Digidesign" , .product_name = "Mbox 2", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =2 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(2) { .formats =SNDRV_PCM_FMTBIT_S24_3BE , .channels = 2, .iface = 2,
@@ -3027,15 +2287,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, + { QUIRK_DATA_IGNORE(3) }, { - .ifnum = 3, - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 4, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = &(const struct audioformat ) { - .formats =SNDRV_PCM_FMTBIT_S24_3BE , + QUIRK_DATA_AUDIOFORMAT(4) { + .formats = SNDRV_PCM_FMTBIT_S24_3BE, .channels = 2, .iface = 4, .altsetting = 2,
@@ -3052,14 +2307,9 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, + { QUIRK_DATA_IGNORE(5) }, { - .ifnum = 5, - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 6, - .type = QUIRK_MIDI_MIDIMAN, - .data = &(const struct snd_usb_midi_endpoint_info ) { + QUIRK_DATA_MIDI_MIDIMAN(6) { .out_ep = 0x02, .out_cables = 0x0001, .in_ep = 0x81,
@@ -3067,33 +2317,21 @@ YAMAHA_DEVICE(0x7010, "UB99"), .in_cables = 0x0001 } }, - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } },/* DIGIDESIGN MBOX 3 */ {USB_DEVICE (0x0dba ,0x5000 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Digidesign" , .product_name = "Mbox 3", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, + { QUIRK_DATA_IGNORE(1) }, { - .ifnum =1 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =2 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(2) { .formats =SNDRV_PCM_FMTBIT_S24_3LE , .fmt_bits = 24, .channels = 4,
@@ -3120,9 +2358,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 3, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(3) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .fmt_bits = 24, .channels = 4,
@@ -3146,36 +2382,25 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 4, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = &(const struct snd_usb_midi_endpoint_info) { + QUIRK_DATA_MIDI_FIXED_ENDPOINT(4) { .out_cables = 0x0001, .in_cables = 0x0001 } }, - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } }, {/* Tascam US122 MKII - playback-only support */ USB_DEVICE_VENDOR_SPEC (0x0644 ,0x8021 ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="TASCAM" , .product_name = "US122 MKII", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_IGNORE(0) }, { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 2, .iface = 1,
@@ -3196,9 +2421,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } },
@@ -3206,20 +2429,13 @@ YAMAHA_DEVICE(0x7010, "UB99"),/* Denon DN-X1600 */ {USB_AUDIO_DEVICE (0x154e ,0x500e ), - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Denon" , .product_name = "DN-X1600", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []){ + QUIRK_DATA_COMPOSITE{ + { QUIRK_DATA_IGNORE(0) }, { - .ifnum =0 , - .type =QUIRK_IGNORE_INTERFACE , - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 8, .iface = 1,
@@ -3240,9 +2456,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - .ifnum = 2, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(2) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 8, .iface = 2,
@@ -3262,13 +2476,8 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, - { - .ifnum = 4, - .type = QUIRK_MIDI_STANDARD_INTERFACE, - }, - { - .ifnum = -1 - } + { QUIRK_DATA_STANDARD_MIDI(4) }, + QUIRK_COMPOSITE_END } } },
@@ -3277,17 +2486,13 @@ YAMAHA_DEVICE(0x7010, "UB99"), { USB_DEVICE(0x045e, 0x0283), .bInterfaceClass =USB_CLASS_PER_INTERFACE , - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + QUIRK_DRIVER_INFO { .vendor_name ="Microsoft" , .product_name = "XboxLive Headset/Xbox Communicator", - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = &(const struct snd_usb_audio_quirk []) { + QUIRK_DATA_COMPOSITE { {/* playback */ - .ifnum =0 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(0) { .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels = 1, .iface = 0,
@@ -3303,9 +2508,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, {/* capture */ - .ifnum = 1, - .type = QUIRK_AUDIO_FIXED_ENDPOINT, - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels = 1, .iface = 1,
@@ -3319,9 +2522,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), .rate_max = 16000 } }, - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } },
@@ -3330,18 +2531,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), {USB_DEVICE (0x200c ,0x100b ), .bInterfaceClass = USB_CLASS_PER_INTERFACE, - .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = &(const struct snd_usb_audio_quirk []) { + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_MIXER(0) }, { - .ifnum =0 , - .type =QUIRK_AUDIO_STANDARD_MIXER , - }, - { - .ifnum =1 , - .type =QUIRK_AUDIO_FIXED_ENDPOINT , - .data = &(const struct audioformat ) { + QUIRK_DATA_AUDIOFORMAT(1) { .formats = SNDRV_PCM_FMTBIT_S24_3LE, .channels = 4, .iface = 1,
@@ -3360,9 +2554,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, - { - .ifnum = -1 - } + QUIRK_COMPOSITE_END } } },
@@ -3375,28 +2567,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),* enabled in create_standard_audio_quirk(). */ USB_DEVICE (0x1686 ,0x00dd ), - .driver_info = (unsigned long ) & (const struct snd_usb_audio_quirk ) { - .ifnum =QUIRK_ANY_INTERFACE , - .type =QUIRK_COMPOSITE , - .data = (const struct snd_usb_audio_quirk []) { - { -/* Playback */ - .ifnum =1 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE , - }, - { -/* Capture */ - .ifnum =2 , - .type =QUIRK_AUDIO_STANDARD_INTERFACE , - }, - { -/* Midi */ - .ifnum =3 , - .type =QUIRK_MIDI_STANDARD_INTERFACE - }, - { - .ifnum =-1 - }, + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { + { QUIRK_DATA_STANDARD_AUDIO(1) }, /* Playback */ + { QUIRK_DATA_STANDARD_AUDIO(2) }, /* Capture */ + { QUIRK_DATA_STANDARD_MIDI(3) }, /* Midi */ + QUIRK_COMPOSITE_END } } },
@@ -3410,18 +2586,16 @@ YAMAHA_DEVICE(0x7010, "UB99"), USB_DEVICE_ID_MATCH_INT_SUBCLASS,
Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.43.0
Part of the diff is not shown here. View the raw message.
Greg Kroah-Hartman
maintainerPATCH 144/482 ALSA: usb-audio: Add quirk for RME Digiface USB
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cyan Nyan <[email protected]>
[ Upstream commit c032044e9672408c534d64a6df2b1ba14449e948 ]
Add trivial support for audio streaming on the RME Digiface USB. Binds only to the first interface to allow userspace to directly drive the complex I/O and matrix mixer controls.
--- sound/usb/quirks-table.h | 171 ++++++++++++++++++++++++++++++++++++++- sound/usb/quirks.c | 58 +++++++++++++ 2 files changed, 228 insertions(+), 1 deletion(-)
sound/usb/quirks-table.h +170 -1
@@ -3604,6 +3604,175 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, - +{ + /* Only claim interface 0 */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_PRODUCT | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_NUMBER, + .idVendor = 0x2a39, + .idProduct = 0x3f8c, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceNumber = 0, + QUIRK_DRIVER_INFO { + QUIRK_DATA_COMPOSITE { + /* + * Three modes depending on sample rate band, + * with different channel counts for in/out + */ + { + QUIRK_DATA_AUDIOFORMAT(0) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 34, // outputs + .fmt_bits = 24, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x02, + .ep_idx = 1, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000, + .rate_min = 32000, + .rate_max = 48000, + .nr_rates = 3, + .rate_table = (unsigned int[]) { + 32000, 44100, 48000, + }, + .sync_ep = 0x81, + .sync_iface = 0, + .sync_altsetting = 1, + .sync_ep_idx = 0, + .implicit_fb = 1, + }, + }, + { + QUIRK_DATA_AUDIOFORMAT(0) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 18, // outputs + .fmt_bits = 24, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x02, + .ep_idx = 1, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_64000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000, + .rate_min = 64000, + .rate_max = 96000, + .nr_rates = 3, + .rate_table = (unsigned int[]) { + 64000, 88200, 96000, + }, + .sync_ep = 0x81, + .sync_iface = 0, + .sync_altsetting = 1, + .sync_ep_idx = 0, + .implicit_fb = 1, + }, + }, + { + QUIRK_DATA_AUDIOFORMAT(0) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 10, // outputs + .fmt_bits = 24, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x02, + .ep_idx = 1, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_KNOT | + SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .rate_min = 128000, + .rate_max = 192000, + .nr_rates = 3, + .rate_table = (unsigned int[]) { + 128000, 176400, 192000, + }, + .sync_ep = 0x81, + .sync_iface = 0, + .sync_altsetting = 1, + .sync_ep_idx = 0, + .implicit_fb = 1, + }, + }, + { + QUIRK_DATA_AUDIOFORMAT(0) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 32, // inputs + .fmt_bits = 24, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x81, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000, + .rate_min = 32000, + .rate_max = 48000, + .nr_rates = 3, + .rate_table = (unsigned int[]) { + 32000, 44100, 48000, + } + } + }, + { + QUIRK_DATA_AUDIOFORMAT(0) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 16, // inputs + .fmt_bits = 24, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x81, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_64000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000, + .rate_min = 64000, + .rate_max = 96000, + .nr_rates = 3, + .rate_table = (unsigned int[]) { + 64000, 88200, 96000, + } + } + }, + { + QUIRK_DATA_AUDIOFORMAT(0) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 8, // inputs + .fmt_bits = 24, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x81, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_KNOT | + SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .rate_min = 128000, + .rate_max = 192000, + .nr_rates = 3, + .rate_table = (unsigned int[]) { + 128000, 176400, 192000, + } + } + }, + QUIRK_COMPOSITE_END + } + } +}, #undef USB_DEVICE_VENDOR_SPEC #undef USB_AUDIO_DEVICE
sound/usb/quirks.c +58 -0
82 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 145/482 ALSA: usb-audio: Add mixer quirk for RME Digiface USB
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Asahi Lina <[email protected]>
[ Upstream commit 611a96f6acf2e74fe28cb90908a9c183862348ce ]
Implement sync, output format, and input status mixer controls, to allow the interface to be used as a straight ADAT/SPDIF (+ Headphones) I/O interface.
This does not implement the matrix mixer, output gain controls, or input level meter feedback. The full mixer interface is only really usable using a dedicated userspace control app (there are too many mixer nodes for alsamixer to be usable), so for now we leave it up to userspace to directly control these features using raw USB control messages. This is similar to how it's done with some FireWire interfaces (ffado-mixer).
--- sound/usb/mixer_quirks.c | 413 +++++++++++++++++++++++++++++++++++++++ sound/usb/quirks-table.h | 1 + 2 files changed, 414 insertions(+)
sound/usb/mixer_quirks.c +413 -0
@@ -14,6 +14,7 @@* Przemek Rudy ([email protected]) */ +#include <linux/bitfield.h> #include <linux/hid.h> #include <linux/init.h> #include <linux/math64.h>
@@ -2926,6 +2927,415 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer)return 0 ; } +/* +* RME Digiface USB +*/ + +#define RME_DIGIFACE_READ_STATUS 17 +#define RME_DIGIFACE_STATUS_REG0L 0 +#define RME_DIGIFACE_STATUS_REG0H 1 +#define RME_DIGIFACE_STATUS_REG1L 2 +#define RME_DIGIFACE_STATUS_REG1H 3 +#define RME_DIGIFACE_STATUS_REG2L 4 +#define RME_DIGIFACE_STATUS_REG2H 5 +#define RME_DIGIFACE_STATUS_REG3L 6 +#define RME_DIGIFACE_STATUS_REG3H 7 + +#define RME_DIGIFACE_CTL_REG1 16 +#define RME_DIGIFACE_CTL_REG2 18 + +/* Reg is overloaded, 0-7 for status halfwords or 16 or 18 for control registers */ +#define RME_DIGIFACE_REGISTER (reg, mask) (((reg) << 16) | (mask)) +#define RME_DIGIFACE_INVERT BIT(31) + +/* Nonconst helpers */ +#define field_get (_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) +#define field_prep (_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask)) + +static int snd_rme_digiface_write_reg (struct snd_kcontrol *kcontrol,int item,u16 mask,u16 val) +{ +struct usb_mixer_elem_list *list =snd_kcontrol_chip (kcontrol); +struct snd_usb_audio *chip = list->mixer->chip; +struct usb_device *dev = chip->dev; +int err; + + err =snd_usb_ctl_msg (dev,usb_sndctrlpipe (dev,0 ), + item, +USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_DEVICE , + val, mask,NULL ,0 ); +if (err <0 ) +dev_err (&dev->dev, +"unable to issue control set request %d (ret = %d)" , + item, err); +return err; +} + +static int snd_rme_digiface_read_status (struct snd_kcontrol *kcontrol,u32 status[4 ]) +{ +struct usb_mixer_elem_list *list =snd_kcontrol_chip (kcontrol); +struct snd_usb_audio *chip = list->mixer->chip; +struct usb_device *dev = chip->dev; +__le32 buf[4 ]; +int err; + + err =snd_usb_ctl_msg (dev,usb_rcvctrlpipe (dev,0 ), +RME_DIGIFACE_READ_STATUS , +USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , +0 ,0 , + buf,sizeof (buf)); +if (err <0 ) { +dev_err (&dev->dev, +"unable to issue status read request (ret = %d)" , + err); + }else { +for (int i =0 ; i <ARRAY_SIZE (buf); i++) + status[i] =le32_to_cpu (buf[i]); + } +return err; +} + +static int snd_rme_digiface_get_status_val (struct snd_kcontrol *kcontrol) +{ +int err; +u32 status[4 ]; +bool invert = kcontrol->private_value &RME_DIGIFACE_INVERT ; +u8 reg = (kcontrol->private_value >>16 ) &0xff ; +u16 mask = kcontrol->private_value &0xffff ; +u16 val; + + err =snd_rme_digiface_read_status (kcontrol, status); +if (err <0 ) +return err; + +switch (reg) { +/* Status register halfwords */ + case RME_DIGIFACE_STATUS_REG0L ... RME_DIGIFACE_STATUS_REG3H: +break ; +case RME_DIGIFACE_CTL_REG1 :/* Control register 1, present in halfword 3L */ + reg =RME_DIGIFACE_STATUS_REG3L ; +break ; +case RME_DIGIFACE_CTL_REG2 :/* Control register 2, present in halfword 3H */ + reg =RME_DIGIFACE_STATUS_REG3H ; +break ; +default : +return -EINVAL ; + } + +if (reg &1 ) + val = status[reg >>1 ] >>16 ; +else + val = status[reg >>1 ] &0xffff ; + +if (invert) + val ^= mask; + +return field_get (mask, val); +} + +static int snd_rme_digiface_rate_get (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) +{ +int freq =snd_rme_digiface_get_status_val (kcontrol); + +if (freq <0 ) +return freq; +if (freq >=ARRAY_SIZE (snd_rme_rate_table)) +return -EIO ; + + ucontrol->value.integer.value[0 ] = snd_rme_rate_table[freq]; +return 0 ; +} + +static int snd_rme_digiface_enum_get (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) +{ +int val =snd_rme_digiface_get_status_val (kcontrol); + +if (val <0 ) +return val; + + ucontrol->value.enumerated.item[0 ] = val; +return 0 ; +} + +static int snd_rme_digiface_enum_put (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) +{ +bool invert = kcontrol->private_value &RME_DIGIFACE_INVERT ; +u8 reg = (kcontrol->private_value >>16 ) &0xff ; +u16 mask = kcontrol->private_value &0xffff ; +u16 val =field_prep (mask, ucontrol->value.enumerated.item[0 ]); + +if (invert) + val ^= mask; + +return snd_rme_digiface_write_reg (kcontrol, reg, mask, val); +} + +static int snd_rme_digiface_current_sync_get (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) +{ +int ret =snd_rme_digiface_enum_get (kcontrol, ucontrol); + +/* 7 means internal for current sync */ +if (ucontrol->value.enumerated.item[0 ] ==7 ) + ucontrol->value.enumerated.item[0 ] =0 ; + +return ret; +} + +static int snd_rme_digiface_sync_state_get (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) +{ +u32 status[4 ]; +int err; +bool valid, sync; + + err =snd_rme_digiface_read_status (kcontrol, status); +if (err <0 ) +return err; + + valid = status[0 ] &BIT (kcontrol->private_value); + sync = status[0 ] &BIT (5 + kcontrol->private_value); + +if (!valid) + ucontrol->value.enumerated.item[0 ] =SND_RME_CLOCK_NOLOCK ; +else if (!sync) + ucontrol->value.enumerated.item[0 ] =SND_RME_CLOCK_LOCK ; +else + ucontrol->value.enumerated.item[0 ] =SND_RME_CLOCK_SYNC ; +return 0 ; +} + + +static int snd_rme_digiface_format_info (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_info *uinfo) +{ +static const char *const format[] = { +"ADAT" ,"S/PDIF" + }; + +return snd_ctl_enum_info (uinfo,1 , +ARRAY_SIZE (format), format); +} + + +static int snd_rme_digiface_sync_source_info (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_info *uinfo) +{ +static const char *const sync_sources[] = { +"Internal" ,"Input 1" ,"Input 2" ,"Input 3" ,"Input 4" + }; + +return snd_ctl_enum_info (uinfo,1 , +ARRAY_SIZE (sync_sources), sync_sources); +} + +static int snd_rme_digiface_rate_info (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_info *uinfo) +{ + uinfo->type =SNDRV_CTL_ELEM_TYPE_INTEGER ; + uinfo->count =1 ; + uinfo->value.integer.min =0 ; + uinfo->value.integer.max =200000 ; + uinfo->value.integer.step =0 ; +return 0 ; +} + +static const struct snd_kcontrol_new snd_rme_digiface_controls[] = { + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 1 Sync" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_sync_state_info, + .get = snd_rme_digiface_sync_state_get, + .private_value =0 , + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 1 Format" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_digiface_format_info, + .get = snd_rme_digiface_enum_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG0H ,BIT (0 )) | +RME_DIGIFACE_INVERT , + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 1 Rate" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_digiface_rate_info, + .get = snd_rme_digiface_rate_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG1L ,GENMASK (3 ,0 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 2 Sync" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_sync_state_info, + .get = snd_rme_digiface_sync_state_get, + .private_value =1 , + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 2 Format" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_digiface_format_info, + .get = snd_rme_digiface_enum_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG0L ,BIT (13 )) | +RME_DIGIFACE_INVERT , + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 2 Rate" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_digiface_rate_info, + .get = snd_rme_digiface_rate_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG1L ,GENMASK (7 ,4 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 3 Sync" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_sync_state_info, + .get = snd_rme_digiface_sync_state_get, + .private_value =2 , + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 3 Format" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_digiface_format_info, + .get = snd_rme_digiface_enum_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG0L ,BIT (14 )) | +RME_DIGIFACE_INVERT , + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 3 Rate" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_digiface_rate_info, + .get = snd_rme_digiface_rate_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG1L ,GENMASK (11 ,8 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 4 Sync" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_sync_state_info, + .get = snd_rme_digiface_sync_state_get, + .private_value =3 , + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 4 Format" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_digiface_format_info, + .get = snd_rme_digiface_enum_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG0L ,GENMASK (15 ,12 )) | +RME_DIGIFACE_INVERT , + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Input 4 Rate" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_digiface_rate_info, + .get = snd_rme_digiface_rate_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG1L ,GENMASK (3 ,0 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Output 1 Format" , + .access =SNDRV_CTL_ELEM_ACCESS_READWRITE , + .info = snd_rme_digiface_format_info, + .get = snd_rme_digiface_enum_get, + .put = snd_rme_digiface_enum_put, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_CTL_REG2 ,BIT (0 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Output 2 Format" , + .access =SNDRV_CTL_ELEM_ACCESS_READWRITE , + .info = snd_rme_digiface_format_info, + .get = snd_rme_digiface_enum_get, + .put = snd_rme_digiface_enum_put, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_CTL_REG2 ,BIT (1 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Output 3 Format" , + .access =SNDRV_CTL_ELEM_ACCESS_READWRITE , + .info = snd_rme_digiface_format_info, + .get = snd_rme_digiface_enum_get, + .put = snd_rme_digiface_enum_put, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_CTL_REG2 ,BIT (3 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Output 4 Format" , + .access =SNDRV_CTL_ELEM_ACCESS_READWRITE , + .info = snd_rme_digiface_format_info, + .get = snd_rme_digiface_enum_get, + .put = snd_rme_digiface_enum_put, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_CTL_REG2 ,BIT (4 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Sync Source" , + .access =SNDRV_CTL_ELEM_ACCESS_READWRITE , + .info = snd_rme_digiface_sync_source_info, + .get = snd_rme_digiface_enum_get, + .put = snd_rme_digiface_enum_put, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_CTL_REG1 ,GENMASK (2 ,0 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Current Sync Source" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_digiface_sync_source_info, + .get = snd_rme_digiface_current_sync_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG0L ,GENMASK (12 ,10 )), + }, + { +/* +* This is writeable, but it is only set by the PCM rate. +* Mixer apps currently need to drive the mixer using raw USB requests, +* so they can also change this that way to configure the rate for +* stand-alone operation when the PCM is closed. +*/ + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="System Rate" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_rate_info, + .get = snd_rme_digiface_rate_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_CTL_REG1 ,GENMASK (6 ,3 )), + }, + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .name ="Current Rate" , + .access =SNDRV_CTL_ELEM_ACCESS_READ |SNDRV_CTL_ELEM_ACCESS_VOLATILE , + .info = snd_rme_rate_info, + .get = snd_rme_digiface_rate_get, + .private_value =RME_DIGIFACE_REGISTER (RME_DIGIFACE_STATUS_REG1H ,GENMASK (7 ,4 )), + } +}; + +static int snd_rme_digiface_controls_create (struct usb_mixer_interface *mixer) +{ +int err, i; + +for (i =0 ; i <ARRAY_SIZE (snd_rme_digiface_controls); ++i) { + err =add_single_ctl_with_resume (mixer,0 , +NULL , + &snd_rme_digiface_controls[i], +NULL ); +if (err <0 ) +return err; + } + +return 0 ; +} +/* * Pioneer DJ DJM Mixers *
@@ -3484,6 +3894,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)case USB_ID (0x2a39 ,0x3fb0 ):/* RME Babyface Pro FS */ err =snd_bbfpro_controls_create (mixer);break ; +case USB_ID (0x2a39 ,0x3f8c ):/* RME Digiface USB */ + err =snd_rme_digiface_controls_create (mixer); +break ;case USB_ID (0x2b73 ,0x0017 ):/* Pioneer DJ DJM-250MK2 */ err =snd_djm_controls_create (mixer,SND_DJM_250MK2_IDX );break ;
sound/usb/quirks-table.h +1 -0
@@ -3620,6 +3620,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),* Three modes depending on sample rate band, * with different channel counts for in/out */ + { QUIRK_DATA_STANDARD_MIXER(0) }, { QUIRK_DATA_AUDIOFORMAT(0) { .formats = SNDRV_PCM_FMTBIT_S32_LE,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 146/482 ALSA: usb-audio: Add logitech Audio profile quirk
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Pius <[email protected]>
[ Upstream commit a51c925c11d7b855167e64b63eb4378e5adfc11d ]
Specify shortnames for the following Logitech Devices: Rally bar, Rally bar mini, Tap, MeetUp and Huddle.
--- sound/usb/card.c | 6 ++++++ 1 file changed, 6 insertions(+)
sound/usb/card.c +6 -0
@@ -384,6 +384,12 @@ static const struct usb_audio_device_name usb_audio_names[] = {/* Creative/Toshiba Multimedia Center SB-0500 */ DEVICE_NAME (0x041e ,0x3048 ,"Toshiba" ,"SB-0500" ), +/* Logitech Audio Devices */ +DEVICE_NAME (0x046d ,0x0867 ,"Logitech, Inc." ,"Logi-MeetUp" ), +DEVICE_NAME (0x046d ,0x0874 ,"Logitech, Inc." ,"Logi-Tap-Audio" ), +DEVICE_NAME (0x046d ,0x087c ,"Logitech, Inc." ,"Logi-Huddle" ), +DEVICE_NAME (0x046d ,0x0898 ,"Logitech, Inc." ,"Logi-RB-Audio" ), +DEVICE_NAME (0x046d ,0x08d2 ,"Logitech, Inc." ,"Logi-RBM-Audio" ),DEVICE_NAME (0x046d ,0x0990 ,"Logitech, Inc." ,"QuickCam Pro 9000" ), DEVICE_NAME(0x05e1, 0x0408, "Syntek", "STK1160"),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 147/482 ASoC: codecs: wsa883x: Handle reading version failure
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 2fbf16992e5aa14acf0441320033a01a32309ded ]
If reading version and variant from registers fails (which is unlikely but possible, because it is a read over bus), the driver will proceed and perform device configuration based on uninitialized stack variables. Handle it a bit better - bail out without doing any init and failing the update status Soundwire callback.
--- sound/soc/codecs/wsa883x.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
sound/soc/codecs/wsa883x.c +11 -5
@@ -998,15 +998,19 @@ static const struct reg_sequence reg_init[] = { {WSA883X_GMAMP_SUP1, 0xE2}, }; -static void wsa883x_init (struct wsa883x_priv *wsa883x) +static int wsa883x_init (struct wsa883x_priv *wsa883x) {struct regmap *regmap = wsa883x->regmap; -int variant, version; +int variant, version, ret; -regmap_read (regmap,WSA883X_OTP_REG_0 , &variant); + ret =regmap_read (regmap,WSA883X_OTP_REG_0 , &variant); +if (ret) +return ret; wsa883x->variant = variant &WSA883X_ID_MASK ; -regmap_read (regmap,WSA883X_CHIP_ID0 , &version); + ret =regmap_read (regmap,WSA883X_CHIP_ID0 , &version); +if (ret) +return ret; wsa883x->version = version;switch (wsa883x->variant) {
@@ -1041,6 +1045,8 @@ static void wsa883x_init(struct wsa883x_priv *wsa883x)WSA883X_DRE_OFFSET_MASK , wsa883x->comp_offset); } + +return 0 ; } static int wsa883x_update_status(struct sdw_slave *slave,
@@ -1049,7 +1055,7 @@ static int wsa883x_update_status(struct sdw_slave *slave,struct wsa883x_priv *wsa883x =dev_get_drvdata (&slave->dev);if (status ==SDW_SLAVE_ATTACHED && slave->dev_num >0 ) -wsa883x_init (wsa883x); +return wsa883x_init (wsa883x);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 148/482 ALSA: control: Take power_ref lock primarily
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit fcc62b19104a67b9a2941513771e09389b75bd95 ]
The code path for kcontrol accesses have often nested locks of both card's controls_rwsem and power_ref, and applies in that order. However, what could take much longer is the latter, power_ref; it waits for the power state of the device, and it pretty much depends on the user's action.
This patch swaps the locking order of those locks to a more natural way, namely, power_ref -> controls_rwsem, in order to shorten the time of possible nested locks. For consistency, power_ref is taken always in the top-level caller side (that is, *_user() functions and the ioctl handler itself).
--- sound/core/control.c | 54 ++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-)
sound/core/control.c +34 -20
@@ -1164,9 +1164,7 @@ static int __snd_ctl_elem_info(struct snd_card *card,#ifdef CONFIG_SND_DEBUG info->access =0 ;#endif - result =snd_power_ref_and_wait (card); -if (!result) - result = kctl->info (kctl, info); + result = kctl->info (kctl, info);snd_power_unref (card);if (result >=0 ) {snd_BUG_ON (info->access);
@@ -1205,12 +1203,17 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl,static int snd_ctl_elem_info_user (struct snd_ctl_file *ctl,struct snd_ctl_elem_info __user *_info) { +struct snd_card *card = ctl->card;struct snd_ctl_elem_info info;int result;if (copy_from_user (&info, _info,sizeof (info)))return -EFAULT ; + result =snd_power_ref_and_wait (card); +if (result) +return result; result =snd_ctl_elem_info (ctl, &info); +snd_power_unref (card);if (result <0 )return result;/* drop internal access flags */
@@ -1254,10 +1257,7 @@ static int snd_ctl_elem_read(struct snd_card *card,if (!snd_ctl_skip_validation (&info))fill_remaining_elem_value (control, &info, pattern); - ret =snd_power_ref_and_wait (card); -if (!ret) - ret = kctl->get (kctl, control); -snd_power_unref (card); + ret = kctl->get (kctl, control);if (ret <0 )return ret; if (!snd_ctl_skip_validation(&info) &&
@@ -1282,7 +1282,11 @@ static int snd_ctl_elem_read_user(struct snd_card *card,if (IS_ERR (control))return PTR_ERR (no_free_ptr (control)); + result =snd_power_ref_and_wait (card); +if (result) +return result; result =snd_ctl_elem_read (card, control); +snd_power_unref (card);if (result <0 )return result;
@@ -1297,7 +1301,7 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,struct snd_kcontrol *kctl;struct snd_kcontrol_volatile *vd;unsigned int index_offset; -int result; +int result =0 ;down_write (&card->controls_rwsem); kctl =snd_ctl_find_id_locked (card, &control->id);
@@ -1315,9 +1319,8 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, }snd_ctl_build_ioff (&control->id, kctl, index_offset); - result =snd_power_ref_and_wait (card);/* validate input values */ -if (IS_ENABLED (CONFIG_SND_CTL_INPUT_VALIDATION ) && !result) { +if (IS_ENABLED (CONFIG_SND_CTL_INPUT_VALIDATION )) {struct snd_ctl_elem_info info;memset (&info,0 ,sizeof (info));
@@ -1329,7 +1332,6 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, }if (!result) result = kctl->put (kctl, control); -snd_power_unref (card);if (result <0 ) {up_write (&card->controls_rwsem);return result;
@@ -1358,7 +1360,11 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,return PTR_ERR (no_free_ptr (control)); card = file->card; + result =snd_power_ref_and_wait (card); +if (result <0 ) +return result; result =snd_ctl_elem_write (card, file, control); +snd_power_unref (card);if (result <0 )return result;
@@ -1827,7 +1833,7 @@ static int call_tlv_handler(struct snd_ctl_file *file, int op_flag, {SNDRV_CTL_TLV_OP_CMD, SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND}, };struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff (kctl, id)]; -int i, ret; +int i;/* Check support of the request for this element. */ for (i =0 ; i <ARRAY_SIZE (pairs); ++i) {
@@ -1845,11 +1851,7 @@ static int call_tlv_handler(struct snd_ctl_file *file, int op_flag, vd->owner != NULL && vd->owner != file)return -EPERM ; - ret =snd_power_ref_and_wait (file->card); -if (!ret) - ret = kctl->tlv.c (kctl, op_flag, size, buf); -snd_power_unref (file->card); -return ret; +return kctl->tlv.c (kctl, op_flag, size, buf); } static int read_tlv_buf(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id,
@@ -1962,16 +1964,28 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long argcase SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS :return snd_ctl_subscribe_events (ctl, ip);case SNDRV_CTL_IOCTL_TLV_READ : -scoped_guard (rwsem_read, &ctl->card->controls_rwsem) + err =snd_power_ref_and_wait (card); +if (err <0 ) +return err; +scoped_guard (rwsem_read, &card->controls_rwsem) err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ); +snd_power_unref (card);return err;case SNDRV_CTL_IOCTL_TLV_WRITE : -scoped_guard (rwsem_write, &ctl->card->controls_rwsem) + err =snd_power_ref_and_wait (card); +if (err <0 ) +return err; +scoped_guard (rwsem_write, &card->controls_rwsem) err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE); +snd_power_unref (card);return err;case SNDRV_CTL_IOCTL_TLV_COMMAND : -scoped_guard (rwsem_write, &ctl->card->controls_rwsem) + err =snd_power_ref_and_wait (card); +if (err <0 ) +return err; +scoped_guard (rwsem_write, &card->controls_rwsem) err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD); +snd_power_unref (card);return err;case SNDRV_CTL_IOCTL_POWER :return -ENOPROTOOPT ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 149/482 tools/x86/kcpuid: Protect against faulty "max subleaf" values
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ahmed S. Darwish <[email protected]>
[ Upstream commit cf96ab1a966b87b09fdd9e8cc8357d2d00776a3a ]
Protect against the kcpuid code parsing faulty max subleaf numbers through a min() expression. Thus, ensuring that max_subleaf will always be ≤ MAX_SUBLEAF_NUM.
Use "u32" for the subleaf numbers since kcpuid is compiled with -Wextra, which includes signed/unsigned comparisons warnings.
--- tools/arch/x86/kcpuid/kcpuid.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
tools/arch/x86/kcpuid/kcpuid.c +5 -7
@@ -7,7 +7,8 @@#include <string.h> #include <getopt.h> -#define ARRAY_SIZE (x) (sizeof(x) / sizeof((x)[0])) +#define ARRAY_SIZE (x) (sizeof(x) / sizeof((x)[0])) +#define min (a, b) (((a) < (b)) ? (a) : (b))typedef unsigned int u32 ;typedef unsigned long long u64 ;
@@ -207,12 +208,9 @@ static void raw_dump_range(struct cpuid_range *range)#define MAX_SUBLEAF_NUM 32struct cpuid_range *setup_cpuid_range (u32 input_eax) { -u32 max_func, idx_func; -int subleaf; +u32 max_func, idx_func, subleaf, max_subleaf; +u32 eax, ebx, ecx, edx, f = input_eax;struct cpuid_range *range; -u32 eax, ebx, ecx, edx; -u32 f = input_eax; -int max_subleaf;bool allzero; eax = input_eax;
@@ -258,7 +256,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)* others have to be tried (0xf) */ if (f ==0x7 || f ==0x14 || f ==0x17 || f ==0x18 ) - max_subleaf = (eax &0xff ) +1 ; + max_subleaf =min ((eax &0xff ) +1 , max_subleaf);if (f ==0xb ) max_subleaf =2 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 150/482 x86/pkeys: Add PKRU as a parameter in signal handling functions
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aruna Ramakrishna <[email protected]>
[ Upstream commit 24cf2bc982ffe02aeffb4a3885c71751a2c7023b ]
Assume there's a multithreaded application that runs untrusted user code. Each thread has its stack/code protected by a non-zero PKEY, and the PKRU register is set up such that only that particular non-zero PKEY is enabled. Each thread also sets up an alternate signal stack to handle signals, which is protected by PKEY zero. The PKEYs man page documents that the PKRU will be reset to init_pkru when the signal handler is invoked, which means that PKEY zero access will be enabled. But this reset happens after the kernel attempts to push fpu state to the alternate stack, which is not (yet) accessible by the kernel, which leads to a new SIGSEGV being sent to the application, terminating it.
Enabling both the non-zero PKEY (for the thread) and PKEY zero in userspace will not work for this use case. It cannot have the alt stack writeable by all - the rationale here is that the code running in that thread (using a non-zero PKEY) is untrusted and should not have access to the alternate signal stack (that uses PKEY zero), to prevent the return address of a function from being changed. The expectation is that kernel should be able to set up the alternate signal stack and deliver the signal to the application even if PKEY zero is explicitly disabled by the application. The signal handler accessibility should not be dictated by whatever PKRU value the thread sets up.
The PKRU register is managed by XSAVE, which means the sigframe contents must match the register contents - which is not the case here. It's required that the signal frame contains the user-defined PKRU value (so that it is restored correctly from sigcontext) but the actual register must be reset to init_pkru so that the alt stack is accessible and the signal can be delivered to the application. It seems that the proper fix here would be to remove PKRU from the XSAVE framework and manage it separately, which is quite complicated. As a workaround, do this:
orig_pkru = rdpkru();
wrpkru(orig_pkru & init_pkru_value);
xsave_to_user_sigframe();
put_user(pkru_sigframe_addr, orig_pkru)In preparation for writing PKRU to sigframe, pass PKRU as an additional parameter down the call chain from get_sigframe().
No functional change.
--- arch/x86/include/asm/fpu/signal.h | 2 +- arch/x86/kernel/fpu/signal.c | 6 +++--- arch/x86/kernel/signal.c | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-)
arch/x86/include/asm/fpu/signal.h +1 -1
@@ -29,7 +29,7 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,unsigned long fpu__get_fpstate_size (void ); -extern bool copy_fpstate_to_sigframe (void __user *buf,void __user *fp,int size); +extern bool copy_fpstate_to_sigframe (void __user *buf,void __user *fp,int size,u32 pkru);extern void fpu__clear_user_states (struct fpu *fpu);extern bool fpu__restore_sig (void __user *buf,int ia32_frame);
arch/x86/kernel/fpu/signal.c +3 -3
@@ -156,7 +156,7 @@ static inline bool save_xstate_epilog(void __user *buf, int ia32_frame,return !err; } -static inline int copy_fpregs_to_sigframe (struct xregs_state __user *buf) +static inline int copy_fpregs_to_sigframe (struct xregs_state __user *buf,u32 pkru) {if (use_xsave ())return xsave_to_user_sigframe (buf);
@@ -185,7 +185,7 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf)* For [f]xsave state, update the SW reserved fields in the [f]xsave frame * indicating the absence/presence of the extended state to the user. */ -bool copy_fpstate_to_sigframe (void __user *buf,void __user *buf_fx,int size) +bool copy_fpstate_to_sigframe (void __user *buf,void __user *buf_fx,int size,u32 pkru) {struct task_struct *tsk = current;struct fpstate *fpstate = tsk->thread.fpu.fpstate;
@@ -228,7 +228,7 @@ bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)fpregs_restore_userregs ();pagefault_disable (); - ret =copy_fpregs_to_sigframe (buf_fx); + ret =copy_fpregs_to_sigframe (buf_fx, pkru);pagefault_enable ();fpregs_unlock ();
arch/x86/kernel/signal.c +2 -1
@@ -84,6 +84,7 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size,unsigned long math_size =0 ;unsigned long sp = regs->sp;unsigned long buf_fx =0 ; +u32 pkru =read_pkru ();/* redzone */ if (!ia32_frame)
@@ -139,7 +140,7 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size, }/* save i387 and extended state */ -if (!copy_fpstate_to_sigframe (*fpstate, (void __user *)buf_fx, math_size)) +if (!copy_fpstate_to_sigframe (*fpstate, (void __user *)buf_fx, math_size, pkru))return (void __user *)-1L ;return (void __user *)sp;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 151/482 x86/pkeys: Restore altstack access in sigreturn()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aruna Ramakrishna <[email protected]>
[ Upstream commit d10b554919d4cc8fa8fe2e95b57ad2624728c8e4 ]
A process can disable access to the alternate signal stack by not enabling the altstack's PKEY in the PKRU register.
Nevertheless, the kernel updates the PKRU temporarily for signal handling. However, in sigreturn(), restore_sigcontext() will restore the PKRU to the user-defined PKRU value.
This will cause restore_altstack() to fail with a SIGSEGV as it needs read access to the altstack which is prohibited by the user-defined PKRU value.
Fix this by restoring altstack before restoring PKRU.
--- arch/x86/kernel/signal_64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/signal_64.c +3 -3
@@ -260,13 +260,13 @@ SYSCALL_DEFINE0(rt_sigreturn)set_current_blocked (&set); -if (!restore_sigcontext (regs, &frame->uc.uc_mcontext, uc_flags)) +if (restore_altstack (&frame->uc.uc_stack)) goto badframe; -if (restore_signal_shadow_stack ()) +if (!restore_sigcontext (regs, &frame->uc.uc_mcontext, uc_flags)) goto badframe; -if (restore_altstack (&frame->uc.uc_stack)) +if (restore_signal_shadow_stack ()) goto badframe;return regs->ax;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 152/482 x86/kexec: Add EFI config table identity mapping for kexec kernel
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tao Liu <[email protected]>
[ Upstream commit 5760929f6545c651682de3c2c6c6786816b17bb1 ]
A kexec kernel boot failure is sometimes observed on AMD CPUs due to an unmapped EFI config table array. This can be seen when "nogbpages" is on the kernel command line, and has been observed as a full BIOS reboot rather than a successful kexec.
This was also the cause of reported regressions attributed to Commit 7143c5f4cf20 ("x86/mm/ident_map: Use gbpages only where full GB page should be mapped.") which was subsequently reverted.
To avoid this page fault, explicitly include the EFI config table array in the kexec identity map.
Further explanation:
The following 2 commits caused the EFI config table array to be accessed when enabling sev at kernel startup.
commit ec1c66af3a30 ("x86/compressed/64: Detect/setup SEV/SME features
earlier during boot")
commit c01fce9cef84 ("x86/compressed: Add SEV-SNP feature
detection/setup")
This is in the code that examines whether SEV should be enabled or not, so it can even affect systems that are not SEV capable.
This may result in a page fault if the EFI config table array's address is unmapped. Since the page fault occurs before the new kernel establishes its own identity map and page fault routines, it is unrecoverable and kexec fails.
Most often, this problem is not seen because the EFI config table array gets included in the map by the luck of being placed at a memory address close enough to other memory areas that *are* included in the map created by kexec.
Both the "nogbpages" command line option and the "use gpbages only where full GB page should be mapped" change greatly reduce the chance of being included in the map by luck, which is why the problem appears.
--- arch/x86/kernel/machine_kexec_64.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
arch/x86/kernel/machine_kexec_64.c +27 -0
@@ -28,6 +28,7 @@#include <asm/setup.h> #include <asm/set_memory.h> #include <asm/cpu.h> +#include <asm/efi.h> #ifdef CONFIG_ACPI /*
@@ -87,6 +88,8 @@ map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p) {#ifdef CONFIG_EFI unsigned long mstart, mend; +void *kaddr; +int ret;if (!efi_enabled (EFI_BOOT ))return 0 ;
@@ -102,6 +105,30 @@ map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p)if (!mstart)return 0 ; + ret =kernel_ident_mapping_init (info, level4p, mstart, mend); +if (ret) +return ret; + + kaddr =memremap (mstart, mend - mstart,MEMREMAP_WB ); +if (!kaddr) { +pr_err ("Could not map UEFI system table\n" ); +return -ENOMEM ; + } + + mstart = efi_config_table; + +if (efi_enabled (EFI_64BIT )) { +efi_system_table_64_t *stbl = (efi_system_table_64_t *)kaddr; + + mend = mstart +sizeof (efi_config_table_64_t) * stbl->nr_tables; + }else { +efi_system_table_32_t *stbl = (efi_system_table_32_t *)kaddr; + + mend = mstart +sizeof (efi_config_table_32_t) * stbl->nr_tables; + } + +memunmap (kaddr); +return kernel_ident_mapping_init (info, level4p, mstart, mend);#endif return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 153/482 x86/mm/ident_map: Use gbpages only where full GB page should be mapped.
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Wahl <[email protected]>
[ Upstream commit cc31744a294584a36bf764a0ffa3255a8e69f036 ]
When ident_pud_init() uses only GB pages to create identity maps, large ranges of addresses not actually requested can be included in the resulting table; a 4K request will map a full GB. This can include a lot of extra address space past that requested, including areas marked reserved by the BIOS. That allows processor speculation into reserved regions, that on UV systems can cause system halts.
Only use GB pages when map creation requests include the full GB page of space. Fall back to using smaller 2M pages when only portions of a GB page are included in the request.
No attempt is made to coalesce mapping requests. If a request requires a map entry at the 2M (pmd) level, subsequent mapping requests within the same 1G region will also be at the pmd level, even if adjacent or overlapping such requests could have been combined to map a full GB page. Existing usage starts with larger regions and then adds smaller regions, so this should not have any great consequence.
--- arch/x86/mm/ident_map.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
arch/x86/mm/ident_map.c +18 -5
@@ -26,18 +26,31 @@ static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page,for (; addr < end; addr = next) {pud_t *pud = pud_page +pud_index (addr);pmd_t *pmd; +bool use_gbpage; next = (addr &PUD_MASK ) +PUD_SIZE ;if (next > end) next = end; -if (info->direct_gbpages) { -pud_t pudval; +/* if this is already a gbpage, this portion is already mapped */ +if (pud_leaf (*pud)) +continue ; + +/* Is using a gbpage allowed? */ + use_gbpage = info->direct_gbpages; -if (pud_present (*pud)) -continue ; +/* Don't use gbpage if it maps more than the requested region. */ +/* at the begining: */ + use_gbpage &= ((addr & ~PUD_MASK ) ==0 ); +/* ... or at the end: */ + use_gbpage &= ((next & ~PUD_MASK ) ==0 ); + +/* Never overwrite existing mappings */ + use_gbpage &= !pud_present (*pud); + +if (use_gbpage) { +pud_t pudval; - addr &=PUD_MASK ; pudval =__pud ((addr - info->offset) | info->page_flag);set_pud (pud, pudval);continue ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 154/482 ALSA: asihpi: Fix potential OOB array access
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 7b986c7430a6bb68d523dac7bfc74cbd5b44ef96 ]
ASIHPI driver stores some values in the static array upon a response from the driver, and its index depends on the firmware. We shouldn't trust it blindly.
This patch adds a sanity check of the array index to fit in the array size.
--- sound/pci/asihpi/hpimsgx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/asihpi/hpimsgx.c +1 -1
@@ -708,7 +708,7 @@ static u16 HPIMSGX__init(struct hpi_message *phm, phr->error =HPI_ERROR_PROCESSING_MESSAGE ;return phr->error; } -if (hr.error ==0 ) { +if (hr.error ==0 && hr.u.s.adapter_index <HPI_MAX_ADAPTERS ) {/* the adapter was created successfully save the mapping for future use */ hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 155/482 ALSA: hdsp: Break infinite MIDI input flush loop
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit c01f3815453e2d5f699ccd8c8c1f93a5b8669e59 ]
The current MIDI input flush on HDSP and HDSPM drivers relies on the hardware reporting the right value. If the hardware doesn't give the proper value but returns -1, it may be stuck at an infinite loop.
Add a counter and break if the loop is unexpectedly too long.
--- sound/pci/rme9652/hdsp.c | 6 ++++-- sound/pci/rme9652/hdspm.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-)
sound/pci/rme9652/hdsp.c +4 -2
@@ -1298,8 +1298,10 @@ static int snd_hdsp_midi_output_possible (struct hdsp *hdsp, int id)static void snd_hdsp_flush_midi_input (struct hdsp *hdsp,int id) { -while (snd_hdsp_midi_input_available (hdsp, id)) -snd_hdsp_midi_read_byte (hdsp, id); +int count =256 ; + +while (snd_hdsp_midi_input_available (hdsp, id) && --count) +snd_hdsp_midi_read_byte (hdsp, id); }static int snd_hdsp_midi_output_write (struct hdsp_midi *hmidi)
sound/pci/rme9652/hdspm.c +4 -2
@@ -1838,8 +1838,10 @@ static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id)static void snd_hdspm_flush_midi_input (struct hdspm *hdspm,int id) { -while (snd_hdspm_midi_input_available (hdspm, id)) -snd_hdspm_midi_read_byte (hdspm, id); +int count =256 ; + +while (snd_hdspm_midi_input_available (hdspm, id) && --count) +snd_hdspm_midi_read_byte (hdspm, id); }static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 156/482 tools/nolibc: powerpc: limit stack-protector workaround to GCC
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
[ Upstream commit 1daea158d0aae0770371f3079305a29fdb66829e ]
As mentioned in the comment, the workaround for __attribute__((no_stack_protector)) is only necessary on GCC. Avoid applying the workaround on clang, as clang does not recognize __attribute__((__optimize__)) and would fail.
--- tools/include/nolibc/arch-powerpc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/include/nolibc/arch-powerpc.h +1 -1
@@ -172,7 +172,7 @@ _ret; \ }) -#ifndef __powerpc64__ +#if !defined(__powerpc64__) && !defined(__clang__)/* FIXME: For 32-bit PowerPC, with newer gcc compilers (e.g. gcc 13.1.0), * "omit-frame-pointer" fails with __attribute__((no_stack_protector)) but * works with __attribute__((__optimize__("-fno-stack-protector")))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 157/482 selftests/nolibc: avoid passing NULL to printf("%s")
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
[ Upstream commit f1a58f61d88642ae1e6e97e9d72d73bc70a93cb8 ]
Clang on higher optimization levels detects that NULL is passed to printf("%s") and warns about it.
While printf() from nolibc gracefully handles that NULL, it is undefined behavior as per POSIX, so the warning is reasonable. Avoid the warning by transforming NULL into a non-NULL placeholder.
--- tools/testing/selftests/nolibc/nolibc-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/nolibc/nolibc-test.c +2 -2
@@ -534,7 +534,7 @@ int expect_strzr(const char *expr, int llen) {int ret =0 ; - llen +=printf (" = <%s> " , expr); + llen +=printf (" = <%s> " , expr ? expr :"(null)" );if (expr) { ret =1 ;result (llen,FAIL );
@@ -553,7 +553,7 @@ int expect_strnz(const char *expr, int llen) {int ret =0 ; - llen +=printf (" = <%s> " , expr); + llen +=printf (" = <%s> " , expr ? expr :"(null)" );if (!expr) { ret =1 ;result (llen,FAIL );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 158/482 x86/syscall: Avoid memcpy() for ia32 syscall_get_arguments()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit d19d638b1e6cf746263ef60b7d0dee0204d8216a ]
Modern (fortified) memcpy() prefers to avoid writing (or reading) beyond the end of the addressed destination (or source) struct member:
In function ‘fortify_memcpy_chk’,
inlined from ‘syscall_get_arguments’ at ./arch/x86/include/asm/syscall.h:85:2,
inlined from ‘populate_seccomp_data’ at kernel/seccomp.c:258:2,
inlined from ‘__seccomp_filter’ at kernel/seccomp.c:1231:3:./include/linux/fortify-string.h:580:25: error: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror=attribute-warning]
580 | __read_overflow2_field(q_size_field, size);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~As already done for x86_64 and compat mode, do not use memcpy() to extract syscall arguments from struct pt_regs but rather just perform direct assignments. Binary output differences are negligible, and actually ends up using less stack space:
- sub $0x84,%esp + sub $0x6c,%esp
and less text size:
text data bss dec hex filename
10794 252 0 11046 2b26 gcc-32b/kernel/seccomp.o.stock 10714 252 0 10966 2ad6 gcc-32b/kernel/seccomp.o.after
--- arch/x86/include/asm/syscall.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
arch/x86/include/asm/syscall.h +6 -1
@@ -82,7 +82,12 @@ static inline void syscall_get_arguments(struct task_struct *task,struct pt_regs *regs, unsigned long *args) { - memcpy(args, ®s->bx, 6 * sizeof(args[0])); + args[0 ] = regs->bx; + args[1 ] = regs->cx; + args[2 ] = regs->dx; + args[3 ] = regs->si; + args[4 ] = regs->di; + args[5 ] = regs->bp; }static inline int syscall_get_arch (struct task_struct *task)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 159/482 ASoC: Intel: boards: always check the result of acpi_dev_get_first_match_dev()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pierre-Louis Bossart <[email protected]>
[ Upstream commit 14e91ddd5c02d8c3e5a682ebfa0546352b459911 ]
The code seems mostly copy-pasted, with some machine drivers forgetting to test if the 'adev' result is NULL.
Add this check when missing, and use -ENOENT consistently as an error code.
--- sound/soc/intel/boards/bytcht_cx2072x.c | 4 ++++ sound/soc/intel/boards/bytcht_da7213.c | 4 ++++ sound/soc/intel/boards/bytcht_es8316.c | 2 +- sound/soc/intel/boards/bytcr_rt5640.c | 2 +- sound/soc/intel/boards/bytcr_rt5651.c | 2 +- sound/soc/intel/boards/cht_bsw_rt5645.c | 4 ++++ sound/soc/intel/boards/cht_bsw_rt5672.c | 4 ++++ sound/soc/intel/boards/sof_es8336.c | 2 +- sound/soc/intel/boards/sof_wm8804.c | 4 ++++ 9 files changed, 24 insertions(+), 4 deletions(-)
sound/soc/intel/boards/bytcht_cx2072x.c +4 -0
@@ -255,7 +255,11 @@ static int snd_byt_cht_cx2072x_probe(struct platform_device *pdev)snprintf (codec_name,sizeof (codec_name),"i2c-%s" ,acpi_dev_name (adev)); byt_cht_cx2072x_dais[dai_index].codecs->name = codec_name; + }else { +dev_err (&pdev->dev,"Error cannot find '%s' dev\n" , mach->id); +return -ENOENT ; } +acpi_dev_put (adev);/* override platform name, if required */
sound/soc/intel/boards/bytcht_da7213.c +4 -0
@@ -258,7 +258,11 @@ static int bytcht_da7213_probe(struct platform_device *pdev)snprintf (codec_name,sizeof (codec_name),"i2c-%s" ,acpi_dev_name (adev)); dailink[dai_index].codecs->name = codec_name; + }else { +dev_err (&pdev->dev,"Error cannot find '%s' dev\n" , mach->id); +return -ENOENT ; } +acpi_dev_put (adev);/* override platform name, if required */
sound/soc/intel/boards/bytcht_es8316.c +1 -1
@@ -562,7 +562,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) byt_cht_es8316_dais[dai_index].codecs->name = codec_name; }else {dev_err (dev,"Error cannot find '%s' dev\n" , mach->id); -return -ENXIO ; +return -ENOENT ; } codec_dev =acpi_get_first_physical_node (adev);
sound/soc/intel/boards/bytcr_rt5640.c +1 -1
@@ -1693,7 +1693,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name; }else {dev_err (dev,"Error cannot find '%s' dev\n" , mach->id); -return -ENXIO ; +return -ENOENT ; } codec_dev =acpi_get_first_physical_node (adev);
sound/soc/intel/boards/bytcr_rt5651.c +1 -1
@@ -926,7 +926,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name; }else {dev_err (dev,"Error cannot find '%s' dev\n" , mach->id); -return -ENXIO ; +return -ENOENT ; } codec_dev =acpi_get_first_physical_node (adev);
sound/soc/intel/boards/cht_bsw_rt5645.c +4 -0
@@ -582,7 +582,11 @@ static int snd_cht_mc_probe(struct platform_device *pdev)snprintf (cht_rt5645_codec_name,sizeof (cht_rt5645_codec_name),"i2c-%s" ,acpi_dev_name (adev)); cht_dailink[dai_index].codecs->name = cht_rt5645_codec_name; + }else { +dev_err (&pdev->dev,"Error cannot find '%s' dev\n" , mach->id); +return -ENOENT ; } +/* acpi_get_first_physical_node() returns a borrowed ref, no need to deref */ codec_dev =acpi_get_first_physical_node (adev);acpi_dev_put (adev);
sound/soc/intel/boards/cht_bsw_rt5672.c +4 -0
@@ -479,7 +479,11 @@ static int snd_cht_mc_probe(struct platform_device *pdev)snprintf (drv->codec_name,sizeof (drv->codec_name),"i2c-%s" ,acpi_dev_name (adev)); cht_dailink[dai_index].codecs->name = drv->codec_name; + }else { +dev_err (&pdev->dev,"Error cannot find '%s' dev\n" , mach->id); +return -ENOENT ; } +acpi_dev_put (adev);/* Use SSP0 on Bay Trail CR devices */
sound/soc/intel/boards/sof_es8336.c +1 -1
@@ -681,7 +681,7 @@ static int sof_es8336_probe(struct platform_device *pdev) dai_links[0 ].codecs->dai_name ="ES8326 HiFi" ; }else {dev_err (dev,"Error cannot find '%s' dev\n" , mach->id); -return -ENXIO ; +return -ENOENT ; } codec_dev =acpi_get_first_physical_node (adev);
sound/soc/intel/boards/sof_wm8804.c +4 -0
@@ -270,7 +270,11 @@ static int sof_wm8804_probe(struct platform_device *pdev)snprintf (codec_name,sizeof (codec_name),"%s%s" ,"i2c-" ,acpi_dev_name (adev)); dailink[dai_index].codecs->name = codec_name; + }else { +dev_err (&pdev->dev,"Error cannot find '%s' dev\n" , mach->id); +return -ENOENT ; } +acpi_dev_put (adev);snd_soc_card_set_drvdata (card, ctx);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 160/482 rcu-tasks: Fix access non-existent percpu rtpcp variable in rcu_tasks_need_gpcb()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zqiang <[email protected]>
[ Upstream commit fd70e9f1d85f5323096ad313ba73f5fe3d15ea41 ]
For kernels built with CONFIG_FORCE_NR_CPUS=y, the nr_cpu_ids is defined as NR_CPUS instead of the number of possible cpus, this will cause the following system panic:
smpboot: Allowing 4 CPUs, 0 hotplug CPUs
...setup_percpu: NR_CPUS:512 nr_cpumask_bits:512 nr_cpu_ids:512 nr_node_ids:1
...
BUG: unable to handle page fault for address: ffffffff9911c8c8 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 0 PID: 15 Comm: rcu_tasks_trace Tainted: G W 6.6.21 #1 5dc7acf91a5e8e9ac9dcfc35bee0245691283ea6 RIP: 0010:rcu_tasks_need_gpcb+0x25d/0x2c0 RSP: 0018:ffffa371c00a3e60 EFLAGS: 00010082 CR2: ffffffff9911c8c8 CR3: 000000040fa20005 CR4: 00000000001706f0 Call Trace: <TASK> ? __die+0x23/0x80 ? page_fault_oops+0xa4/0x180 ? exc_page_fault+0x152/0x180 ? asm_exc_page_fault+0x26/0x40 ? rcu_tasks_need_gpcb+0x25d/0x2c0 ? __pfx_rcu_tasks_kthread+0x40/0x40 rcu_tasks_one_gp+0x69/0x180 rcu_tasks_kthread+0x94/0xc0 kthread+0xe8/0x140 ? __pfx_kthread+0x40/0x40 ret_from_fork+0x34/0x80 ? __pfx_kthread+0x40/0x40 ret_from_fork_asm+0x1b/0x80 </TASK>
Considering that there may be holes in the CPU numbers, use the maximum possible cpu number, instead of nr_cpu_ids, for configuring enqueue and dequeue limits.
[ neeraj.upadhyay: Fix htmldocs build error reported by Stephen Rothwell ]
--- kernel/rcu/tasks.h | 82 ++++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 29 deletions(-)
kernel/rcu/tasks.h +53 -29
@@ -34,6 +34,7 @@ typedef void (*postgp_func_t)(struct rcu_tasks *rtp);* @rtp_blkd_tasks: List of tasks blocked as readers. * @rtp_exit_list: List of tasks in the latter portion of do_exit(). * @cpu: CPU number corresponding to this entry. +* @index: Index of this CPU in rtpcp_array of the rcu_tasks structure. * @rtpp: Pointer to the rcu_tasks structure. */ struct rcu_tasks_percpu {
@@ -49,6 +50,7 @@ struct rcu_tasks_percpu {struct list_head rtp_blkd_tasks;struct list_head rtp_exit_list;int cpu; +int index;struct rcu_tasks *rtpp; };
@@ -76,6 +78,7 @@ struct rcu_tasks_percpu {* @call_func: This flavor's call_rcu()-equivalent function. * @wait_state: Task state for synchronous grace-period waits (default TASK_UNINTERRUPTIBLE). * @rtpcpu: This flavor's rcu_tasks_percpu structure. +* @rtpcp_array: Array of pointers to rcu_tasks_percpu structure of CPUs in cpu_possible_mask. * @percpu_enqueue_shift: Shift down CPU ID this much when enqueuing callbacks. * @percpu_enqueue_lim: Number of per-CPU callback queues in use for enqueuing. * @percpu_dequeue_lim: Number of per-CPU callback queues in use for dequeuing.
@@ -110,6 +113,7 @@ struct rcu_tasks {call_rcu_func_t call_func;unsigned int wait_state;struct rcu_tasks_percpu __percpu *rtpcpu; +struct rcu_tasks_percpu **rtpcp_array;int percpu_enqueue_shift;int percpu_enqueue_lim;int percpu_dequeue_lim;
@@ -182,6 +186,8 @@ module_param(rcu_task_collapse_lim, int, 0444);static int rcu_task_lazy_lim__read_mostly =32 ;module_param (rcu_task_lazy_lim, int,0444 ); +static int rcu_task_cpu_ids; +/* RCU tasks grace-period state for debugging. */ #define RTGS_INIT 0#define RTGS_WAIT_WAIT_CBS 1
@@ -245,6 +251,8 @@ static void cblist_init_generic(struct rcu_tasks *rtp)int cpu;int lim;int shift; +int maxcpu; +int index =0 ;if (rcu_task_enqueue_lim <0 ) { rcu_task_enqueue_lim =1 ;
@@ -254,14 +262,9 @@ static void cblist_init_generic(struct rcu_tasks *rtp) } lim = rcu_task_enqueue_lim; -if (lim > nr_cpu_ids) - lim = nr_cpu_ids; - shift =ilog2 (nr_cpu_ids / lim); -if (((nr_cpu_ids -1 ) >> shift) >= lim) - shift++; -WRITE_ONCE (rtp->percpu_enqueue_shift, shift); -WRITE_ONCE (rtp->percpu_dequeue_lim, lim); -smp_store_release (&rtp->percpu_enqueue_lim, lim); + rtp->rtpcp_array =kcalloc (num_possible_cpus (),sizeof (struct rcu_tasks_percpu *),GFP_KERNEL ); +BUG_ON (!rtp->rtpcp_array); +for_each_possible_cpu (cpu) {struct rcu_tasks_percpu *rtpcp =per_cpu_ptr (rtp->rtpcpu, cpu);
@@ -273,14 +276,29 @@ static void cblist_init_generic(struct rcu_tasks *rtp)INIT_WORK (&rtpcp->rtp_work, rcu_tasks_invoke_cbs_wq); rtpcp->cpu = cpu; rtpcp->rtpp = rtp; + rtpcp->index = index; + rtp->rtpcp_array[index] = rtpcp; + index++;if (!rtpcp->rtp_blkd_tasks.next)INIT_LIST_HEAD (&rtpcp->rtp_blkd_tasks);if (!rtpcp->rtp_exit_list.next)INIT_LIST_HEAD (&rtpcp->rtp_exit_list); + maxcpu = cpu; } -pr_info ("%s: Setting shift to %d and lim to %d rcu_task_cb_adjust=%d.\n" , rtp->name, -data_race (rtp->percpu_enqueue_shift),data_race (rtp->percpu_enqueue_lim), rcu_task_cb_adjust); + rcu_task_cpu_ids = maxcpu +1 ; +if (lim > rcu_task_cpu_ids) + lim = rcu_task_cpu_ids; + shift =ilog2 (rcu_task_cpu_ids / lim); +if (((rcu_task_cpu_ids -1 ) >> shift) >= lim) + shift++; +WRITE_ONCE (rtp->percpu_enqueue_shift, shift); +WRITE_ONCE (rtp->percpu_dequeue_lim, lim); +smp_store_release (&rtp->percpu_enqueue_lim, lim); + +pr_info ("%s: Setting shift to %d and lim to %d rcu_task_cb_adjust=%d rcu_task_cpu_ids=%d.\n" , + rtp->name,data_race (rtp->percpu_enqueue_shift),data_race (rtp->percpu_enqueue_lim), + rcu_task_cb_adjust, rcu_task_cpu_ids); }// Compute wakeup time for lazy callback timer.
@@ -348,7 +366,7 @@ static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func, rtpcp->rtp_n_lock_retries =0 ; }if (rcu_task_cb_adjust && ++rtpcp->rtp_n_lock_retries > rcu_task_contend_lim && -READ_ONCE (rtp->percpu_enqueue_lim) != nr_cpu_ids) +READ_ONCE (rtp->percpu_enqueue_lim) != rcu_task_cpu_ids) needadjust = true;// Defer adjustment to avoid deadlock. }// Queuing callbacks before initialization not yet supported.
@@ -368,10 +386,10 @@ static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func,raw_spin_unlock_irqrestore_rcu_node (rtpcp, flags);if (unlikely (needadjust)) {raw_spin_lock_irqsave (&rtp->cbs_gbl_lock, flags); -if (rtp->percpu_enqueue_lim != nr_cpu_ids) { +if (rtp->percpu_enqueue_lim != rcu_task_cpu_ids) {WRITE_ONCE (rtp->percpu_enqueue_shift,0 ); -WRITE_ONCE (rtp->percpu_dequeue_lim, nr_cpu_ids); -smp_store_release (&rtp->percpu_enqueue_lim, nr_cpu_ids); +WRITE_ONCE (rtp->percpu_dequeue_lim, rcu_task_cpu_ids); +smp_store_release (&rtp->percpu_enqueue_lim, rcu_task_cpu_ids);pr_info ("Switching %s to per-CPU callback queuing.\n" , rtp->name); }raw_spin_unlock_irqrestore (&rtp->cbs_gbl_lock, flags);
@@ -444,6 +462,8 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp) dequeue_limit =smp_load_acquire (&rtp->percpu_dequeue_lim);for (cpu =0 ; cpu < dequeue_limit; cpu++) { +if (!cpu_possible (cpu)) +continue ;struct rcu_tasks_percpu *rtpcp =per_cpu_ptr (rtp->rtpcpu, cpu);/* Advance and accelerate any new callbacks. */
@@ -481,7 +501,7 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp)if (rcu_task_cb_adjust && ncbs <= rcu_task_collapse_lim) {raw_spin_lock_irqsave (&rtp->cbs_gbl_lock, flags);if (rtp->percpu_enqueue_lim >1 ) { -WRITE_ONCE (rtp->percpu_enqueue_shift,order_base_2 (nr_cpu_ids)); +WRITE_ONCE (rtp->percpu_enqueue_shift,order_base_2 (rcu_task_cpu_ids));smp_store_release (&rtp->percpu_enqueue_lim,1 ); rtp->percpu_dequeue_gpseq =get_state_synchronize_rcu (); gpdone = false;
@@ -496,7 +516,9 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp)pr_info ("Completing switch %s to CPU-0 callback queuing.\n" , rtp->name); }if (rtp->percpu_dequeue_lim ==1 ) { -for (cpu = rtp->percpu_dequeue_lim; cpu < nr_cpu_ids; cpu++) { +for (cpu = rtp->percpu_dequeue_lim; cpu < rcu_task_cpu_ids; cpu++) { +if (!cpu_possible (cpu)) +continue ;struct rcu_tasks_percpu *rtpcp =per_cpu_ptr (rtp->rtpcpu, cpu);WARN_ON_ONCE (rcu_segcblist_n_cbs (&rtpcp->cblist));
@@ -511,30 +533,32 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp)// Advance callbacks and invoke any that are ready. static void rcu_tasks_invoke_cbs (struct rcu_tasks *rtp,struct rcu_tasks_percpu *rtpcp) { -int cpu; -int cpunext;int cpuwq;unsigned long flags;int len; +int index;struct rcu_head *rhp;struct rcu_cblist rcl =RCU_CBLIST_INITIALIZER (rcl);struct rcu_tasks_percpu *rtpcp_next; - cpu = rtpcp->cpu; - cpunext = cpu *2 +1 ; -if (cpunext <smp_load_acquire (&rtp->percpu_dequeue_lim)) { - rtpcp_next =per_cpu_ptr (rtp->rtpcpu, cpunext); - cpuwq =rcu_cpu_beenfullyonline (cpunext) ? cpunext :WORK_CPU_UNBOUND ; -queue_work_on (cpuwq, system_wq, &rtpcp_next->rtp_work); - cpunext++; -if (cpunext <smp_load_acquire (&rtp->percpu_dequeue_lim)) { - rtpcp_next =per_cpu_ptr (rtp->rtpcpu, cpunext); - cpuwq =rcu_cpu_beenfullyonline (cpunext) ? cpunext :WORK_CPU_UNBOUND ; + index = rtpcp->index *2 +1 ; +if (index <num_possible_cpus ()) { + rtpcp_next = rtp->rtpcp_array[index]; +if (rtpcp_next->cpu <smp_load_acquire (&rtp->percpu_dequeue_lim)) { + cpuwq =rcu_cpu_beenfullyonline (rtpcp_next->cpu) ? rtpcp_next->cpu :WORK_CPU_UNBOUND ;queue_work_on (cpuwq, system_wq, &rtpcp_next->rtp_work); + index++; +if (index <num_possible_cpus ()) { + rtpcp_next = rtp->rtpcp_array[index]; +if (rtpcp_next->cpu <smp_load_acquire (&rtp->percpu_dequeue_lim)) { + cpuwq =rcu_cpu_beenfullyonline (rtpcp_next->cpu) ? rtpcp_next->cpu :WORK_CPU_UNBOUND ; +queue_work_on (cpuwq, system_wq, &rtpcp_next->rtp_work); + } + } } } -if (rcu_segcblist_empty (&rtpcp->cblist) || !cpu_possible (cpu)) +if (rcu_segcblist_empty (&rtpcp->cblist))return ;raw_spin_lock_irqsave_rcu_node (rtpcp, flags);rcu_segcblist_advance (&rtpcp->cblist,rcu_seq_current (&rtp->tasks_gp_seq));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 161/482 hwmon: (nct6775) add G15CF to ASUS WMI monitoring list
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Denis Pauk <[email protected]>
[ Upstream commit 1f432e4cf1dd3ecfec5ed80051b4611632a0fd51 ]
Boards G15CF has got a nct6775 chip, but by default there's no use of it because of resource conflict with WMI method.
Add the board to the WMI monitoring list.
Message-ID: <[email protected]>
--- drivers/hwmon/nct6775-platform.c | 1 + 1 file changed, 1 insertion(+)
drivers/hwmon/nct6775-platform.c +1 -0
@@ -1269,6 +1269,7 @@ static const char * const asus_msi_boards[] = {"EX-B760M-V5 D4" ,"EX-H510M-V3" ,"EX-H610M-V3 D4" , +"G15CF" ,"PRIME A620M-A" ,"PRIME B560-PLUS" , "PRIME B560-PLUS AC-HES",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 162/482 fbdev: efifb: Register sysfs groups through driver core
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
[ Upstream commit 95cdd538e0e5677efbdf8aade04ec098ab98f457 ]
The driver core can register and cleanup sysfs groups already. Make use of that functionality to simplify the error handling and cleanup.
Also avoid a UAF race during unregistering where the sysctl attributes were usable after the info struct was freed.
--- drivers/video/fbdev/efifb.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-)
drivers/video/fbdev/efifb.c +2 -9
@@ -561,15 +561,10 @@ static int efifb_probe(struct platform_device *dev)break ; } - err =sysfs_create_groups (&dev->dev.kobj, efifb_groups); -if (err) { -pr_err ("efifb: cannot add sysfs attrs\n" ); - goto err_unmap; - } err =fb_alloc_cmap (&info->cmap,256 ,0 );if (err <0 ) {pr_err ("efifb: cannot allocate colormap\n" ); - goto err_groups; + goto err_unmap; } err =devm_aperture_acquire_for_platform_device (dev, par->base, par->size);
@@ -587,8 +582,6 @@ static int efifb_probe(struct platform_device *dev) err_fb_dealloc_cmap:fb_dealloc_cmap (&info->cmap); -err_groups: -sysfs_remove_groups (&dev->dev.kobj, efifb_groups); err_unmap:if (mem_flags & (EFI_MEMORY_UC |EFI_MEMORY_WC ))iounmap (info->screen_base);
@@ -608,12 +601,12 @@ static void efifb_remove(struct platform_device *pdev)/* efifb_destroy takes care of info cleanup */ unregister_framebuffer (info); -sysfs_remove_groups (&pdev->dev.kobj, efifb_groups); }static struct platform_driver efifb_driver = { .driver = { .name ="efi-framebuffer" , + .dev_groups = efifb_groups, }, .probe = efifb_probe, .remove_new = efifb_remove,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 163/482 fbdev: pxafb: Fix possible use after free in pxafb_task()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kaixin Wang <[email protected]>
[ Upstream commit 4a6921095eb04a900e0000da83d9475eb958e61e ]
In the pxafb_probe function, it calls the pxafb_init_fbinfo function, after which &fbi->task is associated with pxafb_task. Moreover, within this pxafb_init_fbinfo function, the pxafb_blank function within the &pxafb_ops struct is capable of scheduling work.
If we remove the module which will call pxafb_remove to make cleanup, it will call unregister_framebuffer function which can call do_unregister_framebuffer to free fbi->fb through put_fb_info(fb_info), while the work mentioned above will be used. The sequence of operations that may lead to a UAF bug is as follows:
CPU0 CPU1
| pxafb_task
pxafb_remove |
unregister_framebuffer(info) |
do_unregister_framebuffer(fb_info) |
put_fb_info(fb_info) |
// free fbi->fb | set_ctrlr_state(fbi, state)
| __pxafb_lcd_power(fbi, 0)
| fbi->lcd_power(on, &fbi->fb.var)
| //use fbi->fbFix it by ensuring that the work is canceled before proceeding with the cleanup in pxafb_remove.
Note that only root user can remove the driver at runtime.
--- drivers/video/fbdev/pxafb.c | 1 + 1 file changed, 1 insertion(+)
drivers/video/fbdev/pxafb.c +1 -0
@@ -2403,6 +2403,7 @@ static void pxafb_remove(struct platform_device *dev) info = &fbi->fb;pxafb_overlay_exit (fbi); +cancel_work_sync (&fbi->task);unregister_framebuffer (info);pxafb_disable_controller (fbi);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 164/482 pmdomain: core: Dont hold the genpd-lock when calling dev_pm_domain_set()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ulf Hansson <[email protected]>
[ Upstream commit b87eee38605c396f0e1fa435939960e5c6cd41d6 ]
There is no need to hold the genpd-lock, while assigning the dev->pm_domain. In fact, it becomes a problem on a PREEMPT_RT based configuration as the genpd-lock may be a raw spinlock, while the lock acquired through the call to dev_pm_domain_set() is a regular spinlock.
To fix the problem, let's simply move the calls to dev_pm_domain_set() outside the genpd-lock.
--- drivers/pmdomain/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/pmdomain/core.c +3 -2
@@ -1694,7 +1694,6 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,genpd_lock (genpd);genpd_set_cpumask (genpd, gpd_data->cpu); -dev_pm_domain_set (dev, &genpd->domain); genpd->device_count++;if (gd)
@@ -1703,6 +1702,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,list_add_tail (&gpd_data->base.list_node, &genpd->dev_list);genpd_unlock (genpd); +dev_pm_domain_set (dev, &genpd->domain); out:if (ret)genpd_free_dev_data (dev, gpd_data);
@@ -1759,12 +1759,13 @@ static int genpd_remove_device(struct generic_pm_domain *genpd, genpd->gd->max_off_time_changed = true;genpd_clear_cpumask (genpd, gpd_data->cpu); -dev_pm_domain_set (dev,NULL );list_del_init (&pdd->list_node);genpd_unlock (genpd); +dev_pm_domain_set (dev,NULL ); +if (genpd->detach_dev) genpd->detach_dev (genpd, dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 165/482 rcuscale: Provide clear error when async specified without primitives
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul E. McKenney <[email protected]>
[ Upstream commit 11377947b5861fa59bf77c827e1dd7c081842cc9 ]
Currently, if the rcuscale module's async module parameter is specified for RCU implementations that do not have async primitives such as RCU Tasks Rude (which now lacks a call_rcu_tasks_rude() function), there will be a series of splats due to calls to a NULL pointer. This commit therefore warns of this situation, but switches to non-async testing.
--- kernel/rcu/rcuscale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/rcu/rcuscale.c +2 -2
@@ -498,7 +498,7 @@ rcu_scale_writer(void *arg)schedule_timeout_idle (torture_random (&tr) % writer_holdoff_jiffies +1 ); wdp = &wdpp[i]; *wdp =ktime_get_mono_fast_ns (); -if (gp_async) { +if (gp_async && !WARN_ON_ONCE (!cur_ops->async)) { retry:if (!rhp) rhp =kmalloc (sizeof (*rhp),GFP_KERNEL );
@@ -554,7 +554,7 @@ rcu_scale_writer(void *arg) i++;rcu_scale_wait_shutdown (); }while (!torture_must_stop ()); -if (gp_async) { +if (gp_async && cur_ops->async) { cur_ops->gp_barrier (); } writer_n_durations[me] = i_max +1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 166/482 power: reset: brcmstb: Do not go into infinite loop if reset fails
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Davis <[email protected]>
[ Upstream commit cf8c39b00e982fa506b16f9d76657838c09150cb ]
There may be other backup reset methods available, do not halt here so that other reset methods can be tried.
--- drivers/power/reset/brcmstb-reboot.c | 3 --- 1 file changed, 3 deletions(-)
drivers/power/reset/brcmstb-reboot.c +0 -3
@@ -62,9 +62,6 @@ static int brcmstb_restart_handler(struct notifier_block *this,return NOTIFY_DONE ; } -while (1 ) - ; -return NOTIFY_DONE ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 167/482 iommu/arm-smmu-v3: Match Stall behaviour for S2
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mostafa Saleh <[email protected]>
[ Upstream commit ce7cb08e22e09f43649b025c849a3ae3b80833c4 ]
According to the spec (ARM IHI 0070 F.b), in
"5.5 Fault configuration (A, R, S bits)":
A STE with stage 2 translation enabled and STE.S2S == 0 is
considered ILLEGAL if SMMU_IDR0.STALL_MODEL == 0b10.Also described in the pseudocode “SteIllegal()”
if STE.Config == '11x' then
[..]
if eff_idr0_stall_model == '10' && STE.S2S == '0' then
// stall_model forcing stall, but S2S == 0
return TRUE;Which means, S2S must be set when stall model is "ARM_SMMU_FEAT_STALL_FORCE", but currently the driver ignores that.
Although, the driver can do the minimum and only set S2S for “ARM_SMMU_FEAT_STALL_FORCE”, it is more consistent to match S1 behaviour, which also sets it for “ARM_SMMU_FEAT_STALL” if the master has requested stalls.
Also, since S2 stalls are enabled now, report them to the IOMMU layer and for VFIO devices it will fail anyway as VFIO doesn’t register an iopf handler.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++----- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + 2 files changed, 4 insertions(+), 5 deletions(-)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +3 -5
@@ -1000,7 +1000,8 @@ void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits) used_bits[2 ] |=cpu_to_le64 (STRTAB_STE_2_S2VMID |STRTAB_STE_2_VTCR |STRTAB_STE_2_S2AA64 |STRTAB_STE_2_S2ENDI | -STRTAB_STE_2_S2PTW |STRTAB_STE_2_S2R ); +STRTAB_STE_2_S2PTW |STRTAB_STE_2_S2S | +STRTAB_STE_2_S2R ); used_bits[3 ] |=cpu_to_le64 (STRTAB_STE_3_S2TTB_MASK ); }
@@ -1629,6 +1630,7 @@ void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,STRTAB_STE_2_S2ENDI | #endifSTRTAB_STE_2_S2PTW | + (master->stall_enabled ?STRTAB_STE_2_S2S :0 ) | STRTAB_STE_2_S2R); target->data[3] = cpu_to_le64(pgtbl_cfg->arm_lpae_s2_cfg.vttbr &
@@ -1722,10 +1724,6 @@ static int arm_smmu_handle_evt(struct arm_smmu_device *smmu, u64 *evt)return -EOPNOTSUPP ; } -/* Stage-2 is always pinned at the moment */ -if (evt[1 ] &EVTQ_1_S2 ) -return -EFAULT ; -if (!(evt[1 ] &EVTQ_1_STALL ))return -EOPNOTSUPP ;
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +1 -0
@@ -264,6 +264,7 @@ struct arm_smmu_ste {#define STRTAB_STE_2_S2AA64 (1UL << 51)#define STRTAB_STE_2_S2ENDI (1UL << 52)#define STRTAB_STE_2_S2PTW (1UL << 54) +#define STRTAB_STE_2_S2S (1UL << 57)#define STRTAB_STE_2_S2R (1UL << 58)#define STRTAB_STE_3_S2TTB_MASK GENMASK_ULL(51, 4)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 168/482 iommu/vt-d: Always reserve a domain ID for identity setup
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Baolu <[email protected]>
[ Upstream commit 2c13012e09190174614fd6901857a1b8c199e17d ]
We will use a global static identity domain. Reserve a static domain ID for it.
--- drivers/iommu/intel/iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iommu/intel/iommu.c +3 -3
@@ -1462,10 +1462,10 @@ static int iommu_init_domains(struct intel_iommu *iommu)* entry for first-level or pass-through translation modes should * be programmed with a domain id different from those used for * second-level or nested translation. We reserve a domain id for -* this purpose. +* this purpose. This domain id is also used for identity domain +* in legacy mode. */ -if (sm_supported (iommu)) -set_bit (FLPT_DEFAULT_DID , iommu->domain_ids); +set_bit (FLPT_DEFAULT_DID , iommu->domain_ids);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 169/482 iommu/vt-d: Fix potential lockup if qi_submit_sync called with 0 count
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanjay K Kumar <[email protected]>
[ Upstream commit 3cf74230c139f208b7fb313ae0054386eee31a81 ]
If qi_submit_sync() is invoked with 0 invalidation descriptors (for instance, for DMA draining purposes), we can run into a bug where a submitting thread fails to detect the completion of invalidation_wait. Subsequently, this led to a soft lockup. Currently, there is no impact by this bug on the existing users because no callers are submitting invalidations with 0 descriptors. This fix will enable future users (such as DMA drain) calling qi_submit_sync() with 0 count.
Suppose thread T1 invokes qi_submit_sync() with non-zero descriptors, while concurrently, thread T2 calls qi_submit_sync() with zero descriptors. Both threads then enter a while loop, waiting for their respective descriptors to complete. T1 detects its completion (i.e., T1's invalidation_wait status changes to QI_DONE by HW) and proceeds to call reclaim_free_desc() to reclaim all descriptors, potentially including adjacent ones of other threads that are also marked as QI_DONE.
During this time, while T2 is waiting to acquire the qi->q_lock, the IOMMU hardware may complete the invalidation for T2, setting its status to QI_DONE. However, if T1's execution of reclaim_free_desc() frees T2's invalidation_wait descriptor and changes its status to QI_FREE, T2 will not observe the QI_DONE status for its invalidation_wait and will indefinitely remain stuck.
This soft lockup does not occur when only non-zero descriptors are submitted.In such cases, invalidation descriptors are interspersed among wait descriptors with the status QI_IN_USE, acting as barriers. These barriers prevent the reclaim code from mistakenly freeing descriptors belonging to other submitters.
Considered the following example timeline:
T1 T2 ======================================== ID1 WD1 while(WD1!=QI_DONE) unlock lock WD1=QI_DONE* WD2 while(WD2!=QI_DONE) unlock lock WD1==QI_DONE? ID1=QI_DONE WD2=DONE* reclaim() ID1=FREE WD1=FREE WD2=FREE unlock soft lockup! T2 never sees QI_DONE in WD2
Where:
ID = invalidation descriptor
WD = wait descriptor
* Written by hardware
The root of the problem is that the descriptor status QI_DONE flag is used for two conflicting purposes:
1. signal a descriptor is ready for reclaim (to be freed)
2. signal by the hardware that a wait descriptor is complete
The solution (in this patch) is state separation by using QI_FREE flag for #1.
Once a thread's invalidation descriptors are complete, their status would be set to QI_FREE. The reclaim_free_desc() function would then only free descriptors marked as QI_FREE instead of those marked as QI_DONE. This change ensures that T2 (from the previous example) will correctly observe the completion of its invalidation_wait (marked as QI_DONE).
--- drivers/iommu/intel/dmar.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/iommu/intel/dmar.c +11 -5
@@ -1204,9 +1204,7 @@ static void free_iommu(struct intel_iommu *iommu)*/ static inline void reclaim_free_desc (struct q_inval *qi) { -while (qi->desc_status[qi->free_tail] ==QI_DONE || - qi->desc_status[qi->free_tail] ==QI_ABORT ) { - qi->desc_status[qi->free_tail] =QI_FREE ; +while (qi->desc_status[qi->free_tail] ==QI_FREE && qi->free_tail != qi->free_head) { qi->free_tail = (qi->free_tail +1 ) %QI_LENGTH ; qi->free_cnt++; }
@@ -1463,8 +1461,16 @@ int qi_submit_sync(struct intel_iommu *iommu, struct qi_desc *desc,raw_spin_lock (&qi->q_lock); } -for (i =0 ; i < count; i++) - qi->desc_status[(index + i) %QI_LENGTH ] =QI_DONE ; +/* +* The reclaim code can free descriptors from multiple submissions +* starting from the tail of the queue. When count == 0, the +* status of the standalone wait descriptor at the tail of the queue +* must be set to QI_FREE to allow the reclaim code to proceed. +* It is also possible that descriptors from one of the previous +* submissions has to be reclaimed by a subsequent submission. +*/ +for (i =0 ; i <= count; i++) + qi->desc_status[(index + i) %QI_LENGTH ] =QI_FREE ;reclaim_free_desc (qi);raw_spin_unlock_irqrestore (&qi->q_lock, flags);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 170/482 iommu/vt-d: Unconditionally flush device TLB for pasid table updates
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Baolu <[email protected]>
[ Upstream commit 1f5e307ca16c0c19186cbd56ac460a687e6daba0 ]
The caching mode of an IOMMU is irrelevant to the behavior of the device TLB. Previously, commit <304b3bde24b5> ("iommu/vt-d: Remove caching mode check before device TLB flush") removed this redundant check in the domain unmap path.
Checking the caching mode before flushing the device TLB after a pasid table entry is updated is unnecessary and can lead to inconsistent behavior.
Extends this consistency by removing the caching mode check in the pasid table update path.
--- drivers/iommu/intel/pasid.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)
drivers/iommu/intel/pasid.c +3 -9
@@ -261,9 +261,7 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,else iommu->flush.flush_iotlb (iommu, did,0 ,0 ,DMA_TLB_DSI_FLUSH ); -/* Device IOTLB doesn't need to be flushed in caching mode. */ -if (!cap_caching_mode (iommu->cap)) -devtlb_invalidation_with_pasid (iommu, dev, pasid); +devtlb_invalidation_with_pasid (iommu, dev, pasid); }/*
@@ -490,9 +488,7 @@ int intel_pasid_setup_dirty_tracking(struct intel_iommu *iommu, iommu->flush.flush_iotlb (iommu, did,0 ,0 ,DMA_TLB_DSI_FLUSH ); -/* Device IOTLB doesn't need to be flushed in caching mode. */ -if (!cap_caching_mode (iommu->cap)) -devtlb_invalidation_with_pasid (iommu, dev, pasid); +devtlb_invalidation_with_pasid (iommu, dev, pasid);return 0 ; }
@@ -569,9 +565,7 @@ void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu,pasid_cache_invalidation_with_pasid (iommu, did, pasid);qi_flush_piotlb (iommu, did, pasid,0 ,-1 ,0 ); -/* Device IOTLB doesn't need to be flushed in caching mode. */ -if (!cap_caching_mode (iommu->cap)) -devtlb_invalidation_with_pasid (iommu, dev, pasid); +devtlb_invalidation_with_pasid (iommu, dev, pasid); }/**
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 171/482 iommu/arm-smmu-v3: Do not use devm for the cd table allocations
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 47b2de35cab2b683f69d03515c2658c2d8515323 ]
The master->cd_table is entirely contained within the struct arm_smmu_master which is guaranteed to be freed by the core code under arm_smmu_release_device().
There is no reason to use devm here, arm_smmu_free_cd_tables() is reliably called to free the CD related memory. Remove it and save some memory.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29 +++++++++------------ 1 file changed, 13 insertions(+), 16 deletions(-)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +13 -16
@@ -1173,8 +1173,8 @@ static int arm_smmu_alloc_cd_leaf_table(struct arm_smmu_device *smmu, {size_t size =CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS <<3 ); - l1_desc->l2ptr =dmam_alloc_coherent (smmu->dev, size, - &l1_desc->l2ptr_dma,GFP_KERNEL ); + l1_desc->l2ptr =dma_alloc_coherent (smmu->dev, size, + &l1_desc->l2ptr_dma,GFP_KERNEL );if (!l1_desc->l2ptr) {dev_warn (smmu->dev,"failed to allocate context descriptor table\n" );
@@ -1373,17 +1373,17 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master) cd_table->num_l1_ents =DIV_ROUND_UP (max_contexts,CTXDESC_L2_ENTRIES ); - cd_table->l1_desc =devm_kcalloc (smmu->dev, cd_table->num_l1_ents, -sizeof (*cd_table->l1_desc), -GFP_KERNEL ); + cd_table->l1_desc =kcalloc (cd_table->num_l1_ents, +sizeof (*cd_table->l1_desc), +GFP_KERNEL );if (!cd_table->l1_desc)return -ENOMEM ; l1size = cd_table->num_l1_ents * (CTXDESC_L1_DESC_DWORDS <<3 ); } - cd_table->cdtab =dmam_alloc_coherent (smmu->dev, l1size, &cd_table->cdtab_dma, -GFP_KERNEL ); + cd_table->cdtab =dma_alloc_coherent (smmu->dev, l1size, + &cd_table->cdtab_dma,GFP_KERNEL );if (!cd_table->cdtab) {dev_warn (smmu->dev,"failed to allocate context descriptor\n" ); ret = -ENOMEM ;
@@ -1394,7 +1394,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master) err_free_l1:if (cd_table->l1_desc) { -devm_kfree (smmu->dev, cd_table->l1_desc); +kfree (cd_table->l1_desc); cd_table->l1_desc =NULL ; }return ret;
@@ -1414,21 +1414,18 @@ static void arm_smmu_free_cd_tables(struct arm_smmu_master *master)if (!cd_table->l1_desc[i].l2ptr)continue ; -dmam_free_coherent (smmu->dev, size, - cd_table->l1_desc[i].l2ptr, - cd_table->l1_desc[i].l2ptr_dma); +dma_free_coherent (smmu->dev, size, + cd_table->l1_desc[i].l2ptr, + cd_table->l1_desc[i].l2ptr_dma); } -devm_kfree (smmu->dev, cd_table->l1_desc); - cd_table->l1_desc =NULL ; +kfree (cd_table->l1_desc); l1size = cd_table->num_l1_ents * (CTXDESC_L1_DESC_DWORDS <<3 ); }else { l1size = cd_table->num_l1_ents * (CTXDESC_CD_DWORDS <<3 ); } -dmam_free_coherent (smmu->dev, l1size, cd_table->cdtab, cd_table->cdtab_dma); - cd_table->cdtab_dma =0 ; - cd_table->cdtab =NULL ; +dma_free_coherent (smmu->dev, l1size, cd_table->cdtab, cd_table->cdtab_dma); }bool arm_smmu_free_asid (struct arm_smmu_ctx_desc *cd)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 172/482 cgroup: Disallow mounting v1 hierarchies without controller implementation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Koutný <[email protected]>
[ Upstream commit 3c41382e920f1dd5c9f432948fe799c07af1cced ]
The configs that disable some v1 controllers would still allow mounting them but with no controller-specific files. (Making such hierarchies equivalent to named v1 hierarchies.) To achieve behavior consistent with actual out-compilation of a whole controller, the mounts should treat respective controllers as non-existent.
Wrap implementation into a helper function, leverage legacy_files to detect compiled out controllers. The effect is that mounts on v1 would fail and produce a message like:
[ 1543.999081] cgroup: Unknown subsys name 'memory'
--- kernel/cgroup/cgroup-v1.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
kernel/cgroup/cgroup-v1.c +10 -2
@@ -46,6 +46,12 @@ bool cgroup1_ssid_disabled(int ssid)return cgroup_no_v1_mask & (1 << ssid); } +static bool cgroup1_subsys_absent (struct cgroup_subsys *ss) +{ +/* Check also dfl_cftypes for file-less controllers, i.e. perf_event */ +return ss->legacy_cftypes ==NULL && ss->dfl_cftypes; +} +/** * cgroup_attach_task_all - attach task 'tsk' to all cgroups of task 'from' * @from: attach to all cgroups of a given task
@@ -932,7 +938,8 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)if (ret != -ENOPARAM )return ret;for_each_subsys (ss, i) { -if (strcmp (param->key, ss->legacy_name)) +if (strcmp (param->key, ss->legacy_name) || +cgroup1_subsys_absent (ss))continue ;if (!cgroup_ssid_enabled (i) ||cgroup1_ssid_disabled (i)) return invalfc(fc, "Disabled controller '%s'",
@@ -1024,7 +1031,8 @@ static int check_cgroupfs_options(struct fs_context *fc) mask = ~((u16 )1 << cpuset_cgrp_id);#endif for_each_subsys (ss, i) -if (cgroup_ssid_enabled (i) && !cgroup1_ssid_disabled (i)) +if (cgroup_ssid_enabled (i) && !cgroup1_ssid_disabled (i) && + !cgroup1_subsys_absent (ss)) enabled |=1 << i; ctx->subsys_mask &= enabled;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 173/482 drm/stm: Avoid use-after-free issues with crtc and plane
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Katya Orlova <[email protected]>
[ Upstream commit 19dd9780b7ac673be95bf6fd6892a184c9db611f ]
ltdc_load() calls functions drm_crtc_init_with_planes(), drm_universal_plane_init() and drm_encoder_init(). These functions should not be called with parameters allocated with devm_kzalloc() to avoid use-after-free issues [1].
Use allocations managed by the DRM framework.
Found by Linux Verification Center (linuxtesting.org).
[1]
https://lore.kernel.org/lkml/u366i76e3qhh3ra5oxrtngjtm2u5lterkekcz6y2jkndhuxzli@diujon4h7qwb/
--- drivers/gpu/drm/stm/drv.c | 3 +- drivers/gpu/drm/stm/ltdc.c | 73 ++++++++++---------------------------- 2 files changed, 20 insertions(+), 56 deletions(-)
drivers/gpu/drm/stm/drv.c +2 -1
@@ -25,6 +25,7 @@#include <drm/drm_module.h> #include <drm/drm_probe_helper.h> #include <drm/drm_vblank.h> +#include <drm/drm_managed.h> #include "ltdc.h"
@@ -75,7 +76,7 @@ static int drv_load(struct drm_device *ddev)DRM_DEBUG ("%s\n" , __func__); - ldev =devm_kzalloc (ddev->dev,sizeof (*ldev),GFP_KERNEL ); + ldev =drmm_kzalloc (ddev,sizeof (*ldev),GFP_KERNEL );if (!ldev)return -ENOMEM ;
drivers/gpu/drm/stm/ltdc.c +18 -55
177 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 174/482 drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 5559598742fb4538e4c51c48ef70563c49c2af23 ]
[WHAT & HOW]
"dcn20_validate_apply_pipe_split_flags" dereferences merge, and thus it cannot be a null pointer. Let's pass a valid pointer to avoid null dereference.
This fixes 2 FORWARD_NULL issues reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c | 3 ++- drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c +2 -1
@@ -2033,6 +2033,7 @@ bool dcn20_fast_validate_bw( {bool out = false;int split[MAX_PIPES ] = {0 }; +bool merge[MAX_PIPES ] = { false };int pipe_cnt, i, pipe_idx, vlevel;ASSERT (pipes);
@@ -2057,7 +2058,7 @@ bool dcn20_fast_validate_bw(if (vlevel > context->bw_ctx.dml.soc.num_states) goto validate_fail; - vlevel =dcn20_validate_apply_pipe_split_flags (dc, context, vlevel, split,NULL ); + vlevel =dcn20_validate_apply_pipe_split_flags (dc, context, vlevel, split, merge);/*initialize pipe_just_split_from to invalid idx*/ for (i =0 ; i <MAX_PIPES ; i++)
drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c +2 -1
@@ -774,6 +774,7 @@ bool dcn21_fast_validate_bw(struct dc *dc, {bool out = false;int split[MAX_PIPES ] = {0 }; +bool merge[MAX_PIPES ] = { false };int pipe_cnt, i, pipe_idx, vlevel;ASSERT (pipes);
@@ -816,7 +817,7 @@ bool dcn21_fast_validate_bw(struct dc *dc, goto validate_fail; } - vlevel =dcn20_validate_apply_pipe_split_flags (dc, context, vlevel, split,NULL ); + vlevel =dcn20_validate_apply_pipe_split_flags (dc, context, vlevel, split, merge);for (i =0 , pipe_idx =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 175/482 drm/amd/display: Check null pointers before using them
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 1ff12bcd7deaeed25efb5120433c6a45dd5504a8 ]
[WHAT & HOW]
These pointers are null checked previously in the same function, indicating they might be null as reported by Coverity. As a result, they need to be checked when used again.
This fixes 3 FORWARD_NULL issue reported by Coverity.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +8 -4
@@ -6951,6 +6951,9 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,int requested_bpc = drm_state ? drm_state->max_requested_bpc :8 ;enum dc_status dc_result =DC_OK ; +if (!dm_state) +return NULL ; + do { stream = create_stream_for_sink(connector, drm_mode, dm_state, old_stream,
@@ -8963,7 +8966,7 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,if (acrtc) old_crtc_state =drm_atomic_get_old_crtc_state (state, &acrtc->base); -if (!acrtc->wb_enabled) +if (!acrtc || !acrtc->wb_enabled)continue ; dm_old_crtc_state =to_dm_crtc_state (old_crtc_state);
@@ -9362,9 +9365,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)DRM_INFO ("[HDCP_DM] hdcp_update_display enable_encryption = %x\n" , enable_encryption); -hdcp_update_display ( - adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector, - new_con_state->hdcp_content_type, enable_encryption); +if (aconnector->dc_link) +hdcp_update_display ( + adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector, + new_con_state->hdcp_content_type, enable_encryption); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 176/482 drm/amdgpu: disallow multiple BO_HANDLES chunks in one submit
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pierre-Eric Pelloux-Prayer <[email protected]>
[ Upstream commit fec5f8e8c6bcf83ed7a392801d7b44c5ecfc1e82 ]
Before this commit, only submits with both a BO_HANDLES chunk and a 'bo_list_handle' would be rejected (by amdgpu_cs_parser_bos).
But if UMD sent multiple BO_HANDLES, what would happen is:
* only the last one would be really used
* all the others would leak memory as amdgpu_cs_p1_bo_handles would overwrite the previous p->bo_list value
This commit rejects submissions with multiple BO_HANDLES chunks to match the implementation of the parser.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +4 -0
@@ -263,6 +263,10 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,if (size <sizeof (struct drm_amdgpu_bo_list_in )) goto free_partial_kdata; +/* Only a single BO list is allowed to simplify handling. */ +if (p->bo_list) + ret = -EINVAL ; + ret =amdgpu_cs_p1_bo_handles (p, p->chunks[i].kdata);if (ret) goto free_partial_kdata;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 177/482 drm/amdkfd: amdkfd_free_gtt_mem clear the correct pointer
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang <[email protected]>
[ Upstream commit c86ad39140bbcb9dc75a10046c2221f657e8083b ]
Pass pointer reference to amdgpu_bo_unref to clear the correct pointer, otherwise amdgpu_bo_unref clear the local variable, the original pointer not set to NULL, this could cause use-after-free bug.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 14 +++++++------- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 4 ++-- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 2 +- .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +7 -7
@@ -360,15 +360,15 @@ int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size,return r; } -void amdgpu_amdkfd_free_gtt_mem (struct amdgpu_device *adev,void *mem_obj) +void amdgpu_amdkfd_free_gtt_mem (struct amdgpu_device *adev,void **mem_obj) { -struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj; +struct amdgpu_bo **bo = (struct amdgpu_bo **) mem_obj; -amdgpu_bo_reserve (bo, true); -amdgpu_bo_kunmap (bo); -amdgpu_bo_unpin (bo); -amdgpu_bo_unreserve (bo); -amdgpu_bo_unref (&(bo)); +amdgpu_bo_reserve (*bo, true); +amdgpu_bo_kunmap (*bo); +amdgpu_bo_unpin (*bo); +amdgpu_bo_unreserve (*bo); +amdgpu_bo_unref (bo); } int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size,
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +1 -1
@@ -233,7 +233,7 @@ int amdgpu_amdkfd_bo_validate_and_fence(struct amdgpu_bo *bo,int amdgpu_amdkfd_alloc_gtt_mem (struct amdgpu_device *adev,size_t size,void **mem_obj,uint64_t *gpu_addr,void **cpu_ptr,bool mqd_gfx9); -void amdgpu_amdkfd_free_gtt_mem (struct amdgpu_device *adev,void *mem_obj); +void amdgpu_amdkfd_free_gtt_mem (struct amdgpu_device *adev,void **mem_obj);int amdgpu_amdkfd_alloc_gws (struct amdgpu_device *adev,size_t size,void **mem_obj);void amdgpu_amdkfd_free_gws (struct amdgpu_device *adev,void *mem_obj);
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +1 -1
@@ -423,7 +423,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, err_create_queue:if (wptr_bo) -amdgpu_amdkfd_free_gtt_mem (dev->adev, wptr_bo); +amdgpu_amdkfd_free_gtt_mem (dev->adev, (void **)&wptr_bo); err_wptr_map_gart: err_bind_process: err_pdd:
drivers/gpu/drm/amd/amdkfd/kfd_device.c +2 -2
@@ -863,7 +863,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, kfd_doorbell_error:kfd_gtt_sa_fini (kfd); kfd_gtt_sa_init_error: -amdgpu_amdkfd_free_gtt_mem (kfd->adev, kfd->gtt_mem); +amdgpu_amdkfd_free_gtt_mem (kfd->adev, &kfd->gtt_mem); alloc_gtt_mem_failure: dev_err(kfd_device, "device %x:%x NOT added due to errors\n",
@@ -881,7 +881,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)kfd_doorbell_fini (kfd);ida_destroy (&kfd->doorbell_ida);kfd_gtt_sa_fini (kfd); -amdgpu_amdkfd_free_gtt_mem (kfd->adev, kfd->gtt_mem); +amdgpu_amdkfd_free_gtt_mem (kfd->adev, &kfd->gtt_mem); }kfree (kfd);
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +1 -1
@@ -2633,7 +2633,7 @@ static void deallocate_hiq_sdma_mqd(struct kfd_node *dev, {WARN (!mqd,"No hiq sdma mqd trunk to free" ); -amdgpu_amdkfd_free_gtt_mem (dev->adev, mqd->gtt_mem); +amdgpu_amdkfd_free_gtt_mem (dev->adev, &mqd->gtt_mem); }void device_queue_manager_uninit (struct device_queue_manager *dqm)
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +1 -1
@@ -223,7 +223,7 @@ void kfd_free_mqd_cp(struct mqd_manager *mm, void *mqd, struct kfd_mem_obj *mqd_mem_obj) {if (mqd_mem_obj->gtt_mem) { -amdgpu_amdkfd_free_gtt_mem (mm->dev->adev, mqd_mem_obj->gtt_mem); +amdgpu_amdkfd_free_gtt_mem (mm->dev->adev, &mqd_mem_obj->gtt_mem);kfree (mqd_mem_obj); }else {kfd_gtt_sa_free (mm->dev, mqd_mem_obj);
drivers/gpu/drm/amd/amdkfd/kfd_process.c +1 -1
@@ -1048,7 +1048,7 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)if (pdd->dev->kfd->shared_resources.enable_mes)amdgpu_amdkfd_free_gtt_mem (pdd->dev->adev, - pdd->proc_ctx_bo); + &pdd->proc_ctx_bo);/* * before destroying pdd, make sure to report availability * for auto suspend
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +2 -2
@@ -201,9 +201,9 @@ static void pqm_clean_queue_resource(struct process_queue_manager *pqm, }if (dev->kfd->shared_resources.enable_mes) { -amdgpu_amdkfd_free_gtt_mem (dev->adev, pqn->q->gang_ctx_bo); +amdgpu_amdkfd_free_gtt_mem (dev->adev, &pqn->q->gang_ctx_bo);if (pqn->q->wptr_bo) -amdgpu_amdkfd_free_gtt_mem (dev->adev, pqn->q->wptr_bo); +amdgpu_amdkfd_free_gtt_mem (dev->adev, (void **)&pqn->q->wptr_bo); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 178/482 drm/amd/display: Add null check for head_pipe in dcn201_acquire_free_pipe_for_layer
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit f22f4754aaa47d8c59f166ba3042182859e5dff7 ]
This commit addresses a potential null pointer dereference issue in the dcn201_acquire_free_pipe_for_layer function. The issue could occur when head_pipe is null.
The fix adds a check to ensure head_pipe is not null before asserting it. If head_pipe is null, the function returns NULL to prevent a potential null pointer dereference.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn201/dcn201_resource.c:1016 dcn201_acquire_free_pipe_for_layer() error: we previously assumed 'head_pipe' could be null (see line 1010)
--- .../gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c +3 -1
@@ -1005,8 +1005,10 @@ static struct pipe_ctx *dcn201_acquire_free_pipe_for_layer(struct pipe_ctx *head_pipe =resource_get_otg_master_for_stream (res_ctx, opp_head_pipe->stream);struct pipe_ctx *idle_pipe =resource_find_free_secondary_pipe_legacy (res_ctx, pool, head_pipe); -if (!head_pipe) +if (!head_pipe) {ASSERT (0 ); +return NULL ; + }if (!idle_pipe)return NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 179/482 drm/amd/display: Add null check for head_pipe in dcn32_acquire_idle_pipe_for_head_pipe_in_layer
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit ac2140449184a26eac99585b7f69814bd3ba8f2d ]
This commit addresses a potential null pointer dereference issue in the dcn32_acquire_idle_pipe_for_head_pipe_in_layer function. The issue could occur when head_pipe is null.
The fix adds a check to ensure head_pipe is not null before asserting it. If head_pipe is null, the function returns NULL to prevent a potential null pointer dereference.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn32/dcn32_resource.c:2690 dcn32_acquire_idle_pipe_for_head_pipe_in_layer() error: we previously assumed 'head_pipe' could be null (see line 2681)
--- .../gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +3 -1
@@ -2664,8 +2664,10 @@ static struct pipe_ctx *dcn32_acquire_idle_pipe_for_head_pipe_in_layer(struct resource_context *old_ctx = &stream->ctx->dc->current_state->res_ctx;int head_index; -if (!head_pipe) +if (!head_pipe) {ASSERT (0 ); +return NULL ; + }/* * Modified from dcn20_acquire_idle_pipe_for_layer
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 180/482 drm/amd/display: Add NULL check for clk_mgr and clk_mgr->funcs in dcn30_init_hw
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit cba7fec864172dadd953daefdd26e01742b71a6a ]
This commit addresses a potential null pointer dereference issue in the dcn30_init_hw function. The issue could occur when dc->clk_mgr or dc->clk_mgr->funcs is null.
The fix adds a check to ensure dc->clk_mgr and dc->clk_mgr->funcs is not null before accessing its functions. This prevents a potential null pointer dereference.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn30/dcn30_hwseq.c:789 dcn30_init_hw() error: we previously assumed 'dc->clk_mgr' could be null (see line 628)
--- drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +4 -3
@@ -626,7 +626,7 @@ void dcn30_init_hw(struct dc *dc)uint32_t backlight =MAX_BACKLIGHT_LEVEL ;uint32_t user_level =MAX_BACKLIGHT_LEVEL ; -if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) +if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks) dc->clk_mgr->funcs->init_clocks (dc->clk_mgr);// Initialize the dccg
@@ -787,11 +787,12 @@ void dcn30_init_hw(struct dc *dc)if (!dcb->funcs->is_accelerated_mode (dcb) && dc->res_pool->hubbub->funcs->init_watermarks) dc->res_pool->hubbub->funcs->init_watermarks (dc->res_pool->hubbub); -if (dc->clk_mgr->funcs->notify_wm_ranges) +if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->notify_wm_ranges) dc->clk_mgr->funcs->notify_wm_ranges (dc->clk_mgr);//if softmax is enabled then hardmax will be set by a different call -if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled) +if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->set_hard_max_memclk && + !dc->clk_mgr->dc_mode_softmax_enabled) dc->clk_mgr->funcs->set_hard_max_memclk (dc->clk_mgr);if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 181/482 drm/amd/display: Add NULL check for clk_mgr in dcn32_init_hw
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit c395fd47d1565bd67671f45cca281b3acc2c31ef ]
This commit addresses a potential null pointer dereference issue in the dcn32_init_hw function. The issue could occur when dc->clk_mgr is null.
The fix adds a check to ensure dc->clk_mgr is not null before accessing its functions. This prevents a potential null pointer dereference.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn32/dcn32_hwseq.c:961 dcn32_init_hw() error: we previously assumed 'dc->clk_mgr' could be null (see line 782)
--- drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +4 -3
@@ -752,7 +752,7 @@ void dcn32_init_hw(struct dc *dc)uint32_t backlight =MAX_BACKLIGHT_LEVEL ;uint32_t user_level =MAX_BACKLIGHT_LEVEL ; -if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) +if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks) dc->clk_mgr->funcs->init_clocks (dc->clk_mgr);// Initialize the dccg
@@ -931,10 +931,11 @@ void dcn32_init_hw(struct dc *dc)if (!dcb->funcs->is_accelerated_mode (dcb) && dc->res_pool->hubbub->funcs->init_watermarks) dc->res_pool->hubbub->funcs->init_watermarks (dc->res_pool->hubbub); -if (dc->clk_mgr->funcs->notify_wm_ranges) +if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->notify_wm_ranges) dc->clk_mgr->funcs->notify_wm_ranges (dc->clk_mgr); -if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled) +if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->set_hard_max_memclk && + !dc->clk_mgr->dc_mode_softmax_enabled) dc->clk_mgr->funcs->set_hard_max_memclk (dc->clk_mgr);if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 182/482 drm/xe/hdcp: Check GSC structure validity
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suraj Kandpal <[email protected]>
[ Upstream commit b4224f6bae3801d589f815672ec62800a1501b0d ]
Sometimes xe_gsc is not initialized when checked at HDCP capability check. Add gsc structure check to avoid null pointer error.
--- drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/gpu/drm/xe/display/xe_hdcp_gsc.c +6 -2
@@ -39,10 +39,14 @@ bool intel_hdcp_gsc_check_status(struct xe_device *xe) {struct xe_tile *tile =xe_device_get_root_tile (xe);struct xe_gt *gt = tile->media_gt; +struct xe_gsc *gsc = >->uc.gsc;bool ret = true; -if (!xe_uc_fw_is_enabled (>->uc.gsc.fw)) +if (!gsc && !xe_uc_fw_is_enabled (&gsc->fw)) { +drm_dbg_kms (&xe->drm, +"GSC Components not ready for HDCP2.x\n" );return false; + }xe_pm_runtime_get (xe);if (xe_force_wake_get (gt_to_fw (gt),XE_FW_GSC )) {
@@ -52,7 +56,7 @@ bool intel_hdcp_gsc_check_status(struct xe_device *xe) goto out; } -if (!xe_gsc_proxy_init_done (>->uc.gsc)) +if (!xe_gsc_proxy_init_done (gsc)) ret = false;xe_force_wake_put (gt_to_fw (gt),XE_FW_GSC );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 183/482 drm/amd/display: Add null check for top_pipe_to_program in commit_planes_for_stream
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit 66d71a72539e173a9b00ca0b1852cbaa5f5bf1ad ]
This commit addresses a null pointer dereference issue in the commit_planes_for_stream function at line 4140. The issue could occur when top_pipe_to_program is null.
The fix adds a check to ensure top_pipe_to_program is not null before accessing its stream_res. This prevents a null pointer dereference.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc.c:4140 commit_planes_for_stream() error: we previously assumed 'top_pipe_to_program' could be null (see line 3906)
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +2 -1
@@ -3970,7 +3970,8 @@ static void commit_planes_for_stream(struct dc *dc, }if ((update_type !=UPDATE_TYPE_FAST ) && stream->update_flags.bits.dsc_changed) -if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { +if (top_pipe_to_program && + top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { top_pipe_to_program->stream_res.tg->funcs->wait_for_state ( top_pipe_to_program->stream_res.tg,CRTC_STATE_VACTIVE );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 184/482 drm/amd/display: Use gpuvm_min_page_size_kbytes for DML2 surfaces
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Kazlauskas <[email protected]>
[ Upstream commit 31663521ede2edb622ee1b397ae3ac666d6351c5 ]
[Why]
It's currently hard coded to 256 when it should be using the SOC provided values. This can result in corruption with linear surfaces where we prefetch more PTE than the buffer can hold.
[How]
Update the min page size correctly for the plane.
--- .../display/dc/dml2/dml2_translation_helper.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c +14 -6
@@ -828,7 +828,9 @@ static void get_scaler_data_for_plane(const struct dc_plane_state *in, struct dcmemcpy (out, &temp_pipe->plane_res.scl_data,sizeof (*out)); } -static void populate_dummy_dml_plane_cfg (struct dml_plane_cfg_st *out,unsigned int location,const struct dc_stream_state *in) +static void populate_dummy_dml_plane_cfg (struct dml_plane_cfg_st *out,unsigned int location, +const struct dc_stream_state *in, +const struct soc_bounding_box_st *soc) {dml_uint_t width, height;
@@ -845,7 +847,7 @@ static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned out->CursorBPP[location] = dml_cur_32bit; out->CursorWidth[location] =256 ; - out->GPUVMMinPageSizeKBytes[location] =256 ; + out->GPUVMMinPageSizeKBytes[location] = soc->gpuvm_min_page_size_kbytes; out->ViewportWidth[location] = width; out->ViewportHeight[location] = height;
@@ -882,7 +884,9 @@ static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned out->ScalerEnabled[location] = false; } -static void populate_dml_plane_cfg_from_plane_state (struct dml_plane_cfg_st *out,unsigned int location,const struct dc_plane_state *in,struct dc_state *context) +static void populate_dml_plane_cfg_from_plane_state (struct dml_plane_cfg_st *out,unsigned int location, +const struct dc_plane_state *in,struct dc_state *context, +const struct soc_bounding_box_st *soc) {struct scaler_data *scaler_data =kzalloc (sizeof (*scaler_data),GFP_KERNEL );if (!scaler_data)
@@ -893,7 +897,7 @@ static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out out->CursorBPP[location] = dml_cur_32bit; out->CursorWidth[location] =256 ; - out->GPUVMMinPageSizeKBytes[location] =256 ; + out->GPUVMMinPageSizeKBytes[location] = soc->gpuvm_min_page_size_kbytes; out->ViewportWidth[location] = scaler_data->viewport.width; out->ViewportHeight[location] = scaler_data->viewport.height;
@@ -1174,7 +1178,8 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat disp_cfg_plane_location = dml_dispcfg->num_surfaces++;populate_dummy_dml_surface_cfg (&dml_dispcfg->surface, disp_cfg_plane_location, context->streams[i]); -populate_dummy_dml_plane_cfg (&dml_dispcfg->plane, disp_cfg_plane_location, context->streams[i]); +populate_dummy_dml_plane_cfg (&dml_dispcfg->plane, disp_cfg_plane_location, + context->streams[i], &dml2->v20.dml_core_ctx.soc); dml_dispcfg->plane.BlendingAndTiming[disp_cfg_plane_location] = disp_cfg_stream_location;
@@ -1190,7 +1195,10 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_statASSERT (disp_cfg_plane_location >=0 && disp_cfg_plane_location <= __DML2_WRAPPER_MAX_STREAMS_PLANES__);populate_dml_surface_cfg_from_plane_state (dml2->v20.dml_core_ctx.project, &dml_dispcfg->surface, disp_cfg_plane_location, context->stream_status[i].plane_states[j]); -populate_dml_plane_cfg_from_plane_state (&dml_dispcfg->plane, disp_cfg_plane_location, context->stream_status[i].plane_states[j], context); +populate_dml_plane_cfg_from_plane_state ( + &dml_dispcfg->plane, disp_cfg_plane_location, + context->stream_status[i].plane_states[j], context, + &dml2->v20.dml_core_ctx.soc);if (stream_mall_type ==SUBVP_MAIN ) { dml_dispcfg->plane.UseMALLForPStateChange[disp_cfg_plane_location] = dml_use_mall_pstate_change_sub_viewport;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 185/482 ata: pata_serverworks: Do not use the term blacklist
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit 858048568c9e3887d8b19e101ee72f129d65cb15 ]
Let's not use the term blacklist in the function serverworks_osb4_filter() documentation comment and rather simply refer to what that function looks at: the list of devices with groken UDMA5.
While at it, also constify the values of the csb_bad_ata100 array.
Of note is that all of this should probably be handled using libata quirk mechanism but it is unclear if these UDMA5 quirks are specific to this controller only.
--- drivers/ata/pata_serverworks.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/ata/pata_serverworks.c +9 -7
@@ -46,10 +46,11 @@#define SVWKS_CSB5_REVISION_NEW 0x92/* min PCI_REVISION_ID for UDMA5 (A2.0) */ #define SVWKS_CSB6_REVISION 0xa0/* min PCI_REVISION_ID for UDMA4 (A1.0) */ -/* Seagate Barracuda ATA IV Family drives in UDMA mode 5 -* can overrun their FIFOs when used with the CSB5 */ - -static const char *csb_bad_ata100[] = { +/* +* Seagate Barracuda ATA IV Family drives in UDMA mode 5 +* can overrun their FIFOs when used with the CSB5. +*/ +static const char *const csb_bad_ata100[] = {"ST320011A" ,"ST340016A" ,"ST360021A" ,
@@ -163,10 +164,11 @@ static unsigned int serverworks_osb4_filter(struct ata_device *adev, unsigned in* @adev: ATA device * @mask: Mask of proposed modes * -* Check the blacklist and disable UDMA5 if matched +* Check the list of devices with broken UDMA5 and +* disable UDMA5 if matched. */ - -static unsigned int serverworks_csb_filter (struct ata_device *adev,unsigned int mask) +static unsigned int serverworks_csb_filter (struct ata_device *adev, +unsigned int mask) {const char *p;char model_num[ATA_ID_PROD_LEN +1 ];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 186/482 ata: sata_sil: Rename sil_blacklist to sil_quirks
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit 93b0f9e11ce511353c65b7f924cf5f95bd9c3aba ]
Rename the array sil_blacklist to sil_quirks as this name is more neutral and is also consistent with how this driver define quirks with the SIL_QUIRK_XXX flags.
--- drivers/ata/sata_sil.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/ata/sata_sil.c +6 -6
@@ -128,7 +128,7 @@ static const struct pci_device_id sil_pci_tbl[] = {static const struct sil_drivelist {const char *product;unsigned int quirk; -} sil_blacklist [] = { +} sil_quirks[] = { {"ST320012AS" ,SIL_QUIRK_MOD15WRITE }, {"ST330013AS" ,SIL_QUIRK_MOD15WRITE }, {"ST340017AS" ,SIL_QUIRK_MOD15WRITE },
@@ -600,8 +600,8 @@ static void sil_thaw(struct ata_port *ap)* list, and apply the fixups to only the specific * devices/hosts/firmwares that need it. * -* 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted -* The Maxtor quirk is in the blacklist, but I'm keeping the original +* 20040111 - Seagate drives affected by the Mod15Write bug are quirked +* The Maxtor quirk is in sil_quirks, but I'm keeping the original * pessimistic fix for the following reasons... * - There seems to be less info on it, only one device gleaned off the * Windows driver, maybe only one is affected. More info would be greatly
@@ -620,9 +620,9 @@ static void sil_dev_config(struct ata_device *dev)ata_id_c_string (dev->id, model_num,ATA_ID_PROD ,sizeof (model_num)); -for (n =0 ; sil_blacklist[n].product; n++) -if (!strcmp (sil_blacklist[n].product, model_num)) { - quirks = sil_blacklist[n].quirk; +for (n =0 ; sil_quirks[n].product; n++) +if (!strcmp (sil_quirks[n].product, model_num)) { + quirks = sil_quirks[n].quirk;break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 187/482 scsi: smartpqi: Add new controller PCI IDs
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Strahan <[email protected]>
[ Upstream commit 0e21e73384d324f75ea16f3d622cfc433fa6209b ]
All PCI ID entries in hex.
Add new inagile PCI IDs:
VID / DID / SVID / SDID
---- ---- ---- ----
SMART-HBA 8242-24i 9005 / 028f / 1ff9 / 0045
RAID 8236-16i 9005 / 028f / 1ff9 / 0046
RAID 8240-24i 9005 / 028f / 1ff9 / 0047
SMART-HBA 8238-16i 9005 / 028f / 1ff9 / 0048
PM8222-SHBA 9005 / 028f / 1ff9 / 004a
RAID PM8204-2GB 9005 / 028f / 1ff9 / 004b
RAID PM8204-4GB 9005 / 028f / 1ff9 / 004c
PM8222-HBA 9005 / 028f / 1ff9 / 004f
MT0804M6R 9005 / 028f / 1ff9 / 0051
MT0801M6E 9005 / 028f / 1ff9 / 0052
MT0808M6R 9005 / 028f / 1ff9 / 0053
MT0800M6H 9005 / 028f / 1ff9 / 0054
RS0800M5H24i 9005 / 028f / 1ff9 / 006b
RS0800M5E8i 9005 / 028f / 1ff9 / 006c
RS0800M5H8i 9005 / 028f / 1ff9 / 006d
RS0804M5R16i 9005 / 028f / 1ff9 / 006f
RS0800M5E24i 9005 / 028f / 1ff9 / 0070
RS0800M5H16i 9005 / 028f / 1ff9 / 0071
RS0800M5E16i 9005 / 028f / 1ff9 / 0072
RT0800M7E 9005 / 028f / 1ff9 / 0086
RT0800M7H 9005 / 028f / 1ff9 / 0087
RT0804M7R 9005 / 028f / 1ff9 / 0088
RT0808M7R 9005 / 028f / 1ff9 / 0089
RT1608M6R16i 9005 / 028f / 1ff9 / 00a1Add new h3c pci_id:
VID / DID / SVID / SDID
---- ---- ---- ----
UN RAID P4408-Mr-2 9005 / 028f / 193d / 1110Add new powerleader pci ids:
VID / DID / SVID / SDID
---- ---- ---- ----
PL SmartROC PM8204 9005 / 028f / 1f3a / 0104--- drivers/scsi/smartpqi/smartpqi_init.c | 104 ++++++++++++++++++++++++++ 1 file changed, 104 insertions(+)
drivers/scsi/smartpqi/smartpqi_init.c +104 -0
@@ -9456,6 +9456,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x193d ,0x110b ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x193d ,0x1110 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x193d ,0x8460 )
@@ -9572,6 +9576,14 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x1bd4 ,0x0089 ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x00a1 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1f3a ,0x0104 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x19e5 ,0xd227 )
@@ -10164,6 +10176,98 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x1137 ,0x02fa ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0045 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0046 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0047 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0048 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x004a ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x004b ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x004c ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x004f ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0051 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0052 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0053 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0054 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x006b ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x006c ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x006d ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x006f ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0070 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0071 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0072 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0086 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0087 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0088 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x0089 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x1e93 ,0x1000 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 188/482 HID: Ignore battery for all ELAN I2C-HID devices
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
[ Upstream commit bcc31692a1d1e21f0d06c5f727c03ee299d2264e ]
Before this change there were 16 vid:pid based quirks to ignore the battery reported by Elan I2C-HID touchscreens on various Asus and HP laptops.
And a report has been received that the 04F3:2A00 I2C touchscreen on the HP ProBook x360 11 G5 EE/86CF also reports a non present battery.
Since I2C-HID devices are always builtin to laptops they are not battery owered so it should be safe to just ignore the battery on all Elan I2C-HID devices, rather then adding a 17th quirk for the 04F3:2A00 touchscreen.
As reported in the changelog of commit a3a5a37efba1 ("HID: Ignore battery for ELAN touchscreens 2F2C and 4116"), which added 2 new Elan touchscreen quirks about a month ago, the HID reported battery seems to be related to a stylus being used. But even when a stylus is in use it does not properly report the charge of the stylus battery, instead the reported battery charge jumps from 0% to 1%. So it is best to just ignore the HID battery.
--- drivers/hid/hid-ids.h | 16 ---------------- drivers/hid/hid-input.c | 37 +++++-------------------------------- 2 files changed, 5 insertions(+), 48 deletions(-)
drivers/hid/hid-ids.h +0 -16
@@ -417,24 +417,8 @@#define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401#define USB_DEVICE_ID_HP_X2 0x074d#define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 -#define I2C_DEVICE_ID_HP_ENVY_X360_15 0x2d05 -#define I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100 0x29CF -#define I2C_DEVICE_ID_HP_ENVY_X360_EU0009NV 0x2CF9 -#define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817 -#define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF -#define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8 -#define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82 -#define I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN 0x2F2C -#define I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN 0x4116#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 -#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A -#define I2C_DEVICE_ID_SURFACE_GO2_TOUCHSCREEN 0x2A1C -#define I2C_DEVICE_ID_LENOVO_YOGA_C630_TOUCHSCREEN 0x279F -#define I2C_DEVICE_ID_HP_SPECTRE_X360_13T_AW100 0x29F5 -#define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V1 0x2BED -#define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V2 0x2BEE -#define I2C_DEVICE_ID_HP_ENVY_X360_15_EU0556NG 0x2D02#define I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM 0x2F81#define USB_VENDOR_ID_ELECOM 0x056e
drivers/hid/hid-input.c +5 -32
@@ -373,14 +373,6 @@ static const struct hid_device_id hid_battery_quirks[] = { {HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_LOGITECH ,USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD ), HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN), - HID_BATTERY_QUIRK_IGNORE }, { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), HID_BATTERY_QUIRK_IGNORE }, { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
@@ -391,32 +383,13 @@ static const struct hid_device_id hid_battery_quirks[] = { HID_BATTERY_QUIRK_AVOID_QUERY }, {HID_USB_DEVICE (USB_VENDOR_ID_UGEE ,USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW ), HID_BATTERY_QUIRK_AVOID_QUERY }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_EU0009NV), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO2_TOUCHSCREEN), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_LENOVO_YOGA_C630_TOUCHSCREEN), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_13T_AW100), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V1), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V2), - HID_BATTERY_QUIRK_IGNORE }, - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15_EU0556NG), - HID_BATTERY_QUIRK_IGNORE }, { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM), HID_BATTERY_QUIRK_AVOID_QUERY }, +/* +* Elan I2C-HID touchscreens seem to all report a non present battery, +* set HID_BATTERY_QUIRK_IGNORE for all Elan I2C-HID devices. +*/ + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE }, {} };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 189/482 drm/amd/display: Handle null stream_status in planes_changed_for_existing_stream
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit 8141f21b941710ecebe49220b69822cab3abd23d ]
This commit adds a null check for 'stream_status' in the function 'planes_changed_for_existing_stream'. Previously, the code assumed 'stream_status' could be null, but did not handle the case where it was actually null. This could lead to a null pointer dereference.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_resource.c:3784 planes_changed_for_existing_stream() error: we previously assumed 'stream_status' could be null (see line 3774)
--- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc_resource.c +3 -1
@@ -3662,8 +3662,10 @@ static bool planes_changed_for_existing_stream(struct dc_state *context, } } -if (!stream_status) +if (!stream_status) {ASSERT (0 ); +return false; + }for (i =0 ; i < set_count; i++)if (set[i].stream == stream)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 190/482 drm/amd/display: Add NULL check for function pointer in dcn20_set_output_transfer_func
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit 62ed6f0f198da04e884062264df308277628004f ]
This commit adds a null check for the set_output_gamma function pointer in the dcn20_set_output_transfer_func function. Previously, set_output_gamma was being checked for null at line 1030, but then it was being dereferenced without any null check at line 1048. This could potentially lead to a null pointer dereference error if set_output_gamma is null.
To fix this, we now ensure that set_output_gamma is not null before dereferencing it. We do this by adding a null check for set_output_gamma before the call to set_output_gamma at line 1048.
--- drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +2 -1
@@ -1040,7 +1040,8 @@ bool dcn20_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,/* * if above if is not executed then 'params' equal to 0 and set in bypass */ - mpc->funcs->set_output_gamma (mpc, mpcc_id, params); +if (mpc->funcs->set_output_gamma) + mpc->funcs->set_output_gamma (mpc, mpcc_id, params);return true; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 191/482 drm/amd/display: Add NULL check for function pointer in dcn32_set_output_transfer_func
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit 28574b08c70e56d34d6f6379326a860b96749051 ]
This commit adds a null check for the set_output_gamma function pointer in the dcn32_set_output_transfer_func function. Previously, set_output_gamma was being checked for null, but then it was being dereferenced without any null check. This could lead to a null pointer dereference if set_output_gamma is null.
To fix this, we now ensure that set_output_gamma is not null before dereferencing it. We do this by adding a null check for set_output_gamma before the call to set_output_gamma.
--- drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +3 -1
@@ -581,7 +581,9 @@ bool dcn32_set_output_transfer_func(struct dc *dc, } } - mpc->funcs->set_output_gamma (mpc, mpcc_id, params); +if (mpc->funcs->set_output_gamma) + mpc->funcs->set_output_gamma (mpc, mpcc_id, params); +return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 192/482 drm/amd/display: Check null pointers before using dc->clk_mgr
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 95d9e0803e51d5a24276b7643b244c7477daf463 ]
[WHY & HOW]dc->clk_mgr is null checked previously in the same function, indicating it might be null.
Passing "dc" to "dc->hwss.apply_idle_power_optimizations", which dereferences null "dc->clk_mgr". (The function pointer resolves to "dcn35_apply_idle_power_optimizations".)
This fixes 1 FORWARD_NULL issue reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +2 -1
@@ -5211,7 +5211,8 @@ void dc_allow_idle_optimizations_internal(struct dc *dc, bool allow, char constif (allow == dc->idle_optimizations_allowed)return ; -if (dc->hwss.apply_idle_power_optimizations && dc->hwss.apply_idle_power_optimizations (dc, allow)) +if (dc->hwss.apply_idle_power_optimizations && dc->clk_mgr !=NULL && + dc->hwss.apply_idle_power_optimizations (dc, allow)) dc->idle_optimizations_allowed = allow; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 193/482 drm/amd/display: Add null check for afb in amdgpu_dm_plane_handle_cursor_update (v2)
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit cd9e9e0852d501f169aa3bb34e4b413d2eb48c37 ]
This commit adds a null check for the 'afb' variable in the amdgpu_dm_plane_handle_cursor_update function. Previously, 'afb' was assumed to be null, but was used later in the code without a null check. This could potentially lead to a null pointer dereference.
Changes since v1:
- Moved the null check for 'afb' to the line where 'afb' is used. (Alex)
Fixes the below:drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_plane.c:1298 amdgpu_dm_plane_handle_cursor_update() error: we previously assumed 'afb' could be null (see line 1252)
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +2 -1
@@ -1285,7 +1285,8 @@ void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane, adev->dm.dc->caps.color.dpp.gamma_corr) attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA =1 ; - attributes.pitch = afb->base.pitches[0 ] / afb->base.format->cpp[0 ]; +if (afb) + attributes.pitch = afb->base.pitches[0 ] / afb->base.format->cpp[0 ];if (crtc_state->stream) {mutex_lock (&adev->dm.dc_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 194/482 drm/amd/display: fix double free issue during amdgpu module unload
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit 20b5a8f9f4670a8503aa9fa95ca632e77c6bf55d ]
Flexible endpoints use DIGs from available inflexible endpoints, so only the encoders of inflexible links need to be freed. Otherwise, a double free issue may occur when unloading the amdgpu module.
[ 279.190523] RIP: 0010:__slab_free+0x152/0x2f0 [ 279.190577] Call Trace: [ 279.190580] <TASK> [ 279.190582] ? show_regs+0x69/0x80 [ 279.190590] ? die+0x3b/0x90 [ 279.190595] ? do_trap+0xc8/0xe0 [ 279.190601] ? do_error_trap+0x73/0xa0 [ 279.190605] ? __slab_free+0x152/0x2f0 [ 279.190609] ? exc_invalid_op+0x56/0x70 [ 279.190616] ? __slab_free+0x152/0x2f0 [ 279.190642] ? asm_exc_invalid_op+0x1f/0x30 [ 279.190648] ? dcn10_link_encoder_destroy+0x19/0x30 [amdgpu] [ 279.191096] ? __slab_free+0x152/0x2f0 [ 279.191102] ? dcn10_link_encoder_destroy+0x19/0x30 [amdgpu] [ 279.191469] kfree+0x260/0x2b0 [ 279.191474] dcn10_link_encoder_destroy+0x19/0x30 [amdgpu] [ 279.191821] link_destroy+0xd7/0x130 [amdgpu] [ 279.192248] dc_destruct+0x90/0x270 [amdgpu] [ 279.192666] dc_destroy+0x19/0x40 [amdgpu] [ 279.193020] amdgpu_dm_fini+0x16e/0x200 [amdgpu] [ 279.193432] dm_hw_fini+0x26/0x40 [amdgpu] [ 279.193795] amdgpu_device_fini_hw+0x24c/0x400 [amdgpu] [ 279.194108] amdgpu_driver_unload_kms+0x4f/0x70 [amdgpu] [ 279.194436] amdgpu_pci_remove+0x40/0x80 [amdgpu] [ 279.194632] pci_device_remove+0x3a/0xa0 [ 279.194638] device_remove+0x40/0x70 [ 279.194642] device_release_driver_internal+0x1ad/0x210 [ 279.194647] driver_detach+0x4e/0xa0 [ 279.194650] bus_remove_driver+0x6f/0xf0 [ 279.194653] driver_unregister+0x33/0x60 [ 279.194657] pci_unregister_driver+0x44/0x90 [ 279.194662] amdgpu_exit+0x19/0x1f0 [amdgpu] [ 279.194939] __do_sys_delete_module.isra.0+0x198/0x2f0 [ 279.194946] __x64_sys_delete_module+0x16/0x20 [ 279.194950] do_syscall_64+0x58/0x120 [ 279.194954] entry_SYSCALL_64_after_hwframe+0x6e/0x76 [ 279.194980] </TASK>
--- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/link/link_factory.c +1 -1
@@ -385,7 +385,7 @@ static void link_destruct(struct dc_link *link)if (link->panel_cntl) link->panel_cntl->funcs->destroy (&link->panel_cntl); -if (link->link_enc) { +if (link->link_enc && !link->is_dig_mapping_flexible) {/* Update link encoder resource tracking variables. These are used for * the dynamic assignment of link encoders to streams. Virtual links * are not assigned encoder resources on creation.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 195/482 drm/amdgpu: add list empty check to avoid null pointer issue
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Wang <[email protected]>
[ Upstream commit 4416377ae1fdc41a90b665943152ccd7ff61d3c5 ]
Add list empty check to avoid null pointer issues in some corner cases.
- list_for_each_entry_safe()
--- drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c +10 -0
@@ -80,6 +80,9 @@ static void aca_banks_release(struct aca_banks *banks) {struct aca_bank_node *node, *tmp; +if (list_empty (&banks->list)) +return ; +list_for_each_entry_safe (node, tmp, &banks->list, node) {list_del (&node->node);kvfree (node);
@@ -562,9 +565,13 @@ static void aca_error_fini(struct aca_error *aerr)struct aca_bank_error *bank_error, *tmp;mutex_lock (&aerr->lock); +if (list_empty (&aerr->list)) + goto out_unlock; +list_for_each_entry_safe (bank_error, tmp, &aerr->list, node)aca_bank_error_remove (aerr, bank_error); +out_unlock:mutex_destroy (&aerr->lock); }
@@ -680,6 +687,9 @@ static void aca_manager_fini(struct aca_handle_manager *mgr) {struct aca_handle *handle, *tmp; +if (list_empty (&mgr->list)) +return ; +list_for_each_entry_safe (handle, tmp, &mgr->list, node)amdgpu_aca_remove_handle (handle); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 196/482 jfs: UBSAN: shift-out-of-bounds in dbFindBits
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Remington Brasga <[email protected]>
[ Upstream commit b0b2fc815e514221f01384f39fbfbff65d897e1c ]
Fix issue with UBSAN throwing shift-out-of-bounds warning.
--- fs/jfs/jfs_dmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jfs/jfs_dmap.c +1 -1
@@ -3022,7 +3022,7 @@ static int dbFindBits(u32 word, int l2nb)/* scan the word for nb free bits at nb alignments. */ -for (bitno =0 ; mask !=0 ; bitno += nb, mask >>= nb) { +for (bitno =0 ; mask !=0 ; bitno += nb, mask = (mask >> nb)) {if ((mask & word) == mask)break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 197/482 jfs: Fix uaf in dbFreeBits
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
[ Upstream commit d6c1b3599b2feb5c7291f5ac3a36e5fa7cedb234 ]
[syzbot reported]
==================================================================
BUG: KASAN: slab-use-after-free in __mutex_lock_common kernel/locking/mutex.c:587 [inline] BUG: KASAN: slab-use-after-free in __mutex_lock+0xfe/0xd70 kernel/locking/mutex.c:752 Read of size 8 at addr ffff8880229254b0 by task syz-executor357/5216 CPU: 0 UID: 0 PID: 5216 Comm: syz-executor357 Not tainted 6.11.0-rc3-syzkaller-00156-gd7a5aa4b3c00 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/27/2024 Call Trace: <TASK> __dump_stack lib/dump_stack.c:93 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119 print_address_description mm/kasan/report.c:377 [inline] print_report+0x169/0x550 mm/kasan/report.c:488 kasan_report+0x143/0x180 mm/kasan/report.c:601 __mutex_lock_common kernel/locking/mutex.c:587 [inline] __mutex_lock+0xfe/0xd70 kernel/locking/mutex.c:752 dbFreeBits+0x7ea/0xd90 fs/jfs/jfs_dmap.c:2390 dbFreeDmap fs/jfs/jfs_dmap.c:2089 [inline] dbFree+0x35b/0x680 fs/jfs/jfs_dmap.c:409 dbDiscardAG+0x8a9/0xa20 fs/jfs/jfs_dmap.c:1650 jfs_ioc_trim+0x433/0x670 fs/jfs/jfs_discard.c:100 jfs_ioctl+0x2d0/0x3e0 fs/jfs/ioctl.c:131 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 Freed by task 5218: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579 poison_slab_object+0xe0/0x150 mm/kasan/common.c:240 __kasan_slab_free+0x37/0x60 mm/kasan/common.c:256 kasan_slab_free include/linux/kasan.h:184 [inline] slab_free_hook mm/slub.c:2252 [inline] slab_free mm/slub.c:4473 [inline] kfree+0x149/0x360 mm/slub.c:4594 dbUnmount+0x11d/0x190 fs/jfs/jfs_dmap.c:278 jfs_mount_rw+0x4ac/0x6a0 fs/jfs/jfs_mount.c:247 jfs_remount+0x3d1/0x6b0 fs/jfs/super.c:454 reconfigure_super+0x445/0x880 fs/super.c:1083 vfs_cmd_reconfigure fs/fsopen.c:263 [inline] vfs_fsconfig_locked fs/fsopen.c:292 [inline] __do_sys_fsconfig fs/fsopen.c:473 [inline] __se_sys_fsconfig+0xb6e/0xf80 fs/fsopen.c:345 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
[Analysis]
There are two paths (dbUnmount and jfs_ioc_trim) that generate race condition when accessing bmap, which leads to the occurrence of uaf.
Use the lock s_umount to synchronize them, in order to avoid uaf caused by race condition.
--- fs/jfs/jfs_discard.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
fs/jfs/jfs_discard.c +9 -2
@@ -65,7 +65,7 @@ void jfs_issue_discard(struct inode *ip, u64 blkno, u64 nblocks)int jfs_ioc_trim (struct inode *ip,struct fstrim_range *range) {struct inode *ipbmap =JFS_SBI (ip->i_sb)->ipbmap; -struct bmap *bmp =JFS_SBI (ip->i_sb)->bmap; +struct bmap *bmp;struct super_block *sb = ipbmap->i_sb;int agno, agno_end;u64 start, end, minlen;
@@ -83,10 +83,15 @@ int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range)if (minlen ==0 ) minlen =1 ; +down_read (&sb->s_umount); + bmp =JFS_SBI (ip->i_sb)->bmap; +if (minlen > bmp->db_agsize || start >= bmp->db_mapsize || - range->len < sb->s_blocksize) + range->len < sb->s_blocksize) { +up_read (&sb->s_umount);return -EINVAL ; + }if (end >= bmp->db_mapsize) end = bmp->db_mapsize -1 ;
@@ -100,6 +105,8 @@ int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range) trimmed +=dbDiscardAG (ip, agno, minlen); agno++; } + +up_read (&sb->s_umount); range->len = trimmed << sb->s_blocksize_bits;return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 198/482 jfs: check if leafidx greater than num leaves per dmap tree
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
[ Upstream commit d64ff0d2306713ff084d4b09f84ed1a8c75ecc32 ]
syzbot report a out of bounds in dbSplit, it because dmt_leafidx greater than num leaves per dmap tree, add a checking for dmt_leafidx in dbFindLeaf.
Shaggy:
Modified sanity check to apply to control pages as well as leaf pages.
--- fs/jfs/jfs_dmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/jfs/jfs_dmap.c +4 -1
@@ -2944,9 +2944,10 @@ static void dbAdjTree(dmtree_t *tp, int leafno, int newval, bool is_ctl)static int dbFindLeaf (dmtree_t *tp,int l2nb,int *leafidx,bool is_ctl) {int ti, n =0 , k, x =0 ; -int max_size; +int max_size, max_idx; max_size = is_ctl ?CTLTREESIZE :TREESIZE ; + max_idx = is_ctl ?LPERCTL :LPERDMAP ;/* first check the root of the tree to see if there is * sufficient free space.
@@ -2978,6 +2979,8 @@ static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl)*/ assert (n <4 ); } +if (le32_to_cpu (tp->dmt_leafidx) >= max_idx) +return -ENOSPC ;/* set the return to the leftmost leaf describing sufficient * free space.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 199/482 scsi: smartpqi: correct stream detection
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mahesh Rajashekhara <[email protected]>
[ Upstream commit 4c76114932d1d6fad2e72823e7898a3c960cf2a7 ]
Correct stream detection by initializing the structure pqi_scsi_dev_raid_map_data to 0s.
When the OS issues SCSI READ commands, the driver erroneously considers them as SCSI WRITES. If they are identified as sequential IOs, the driver then submits those requests via the RAID path instead of the AIO path.
The 'is_write' flag might be set for SCSI READ commands also. The driver may interpret SCSI READ commands as SCSI WRITE commands, resulting in IOs being submitted through the RAID path.
Note: This does not cause data corruption.
--- drivers/scsi/smartpqi/smartpqi_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/smartpqi/smartpqi_init.c +1 -1
@@ -5917,7 +5917,7 @@ static bool pqi_is_parity_write_stream(struct pqi_ctrl_info *ctrl_info,int rc;struct pqi_scsi_dev *device;struct pqi_stream_data *pqi_stream_data; -struct pqi_scsi_dev_raid_map_data rmd; +struct pqi_scsi_dev_raid_map_data rmd = {0 };if (!ctrl_info->enable_stream_detection)return false;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 200/482 scsi: smartpqi: add new controller PCI IDs
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Strahan <[email protected]>
[ Upstream commit dbc39b84540f746cc814e69b21e53e6d3e12329a ]
All PCI ID entries in Hex.
Add new cisco pci ids:
VID / DID / SVID / SDID
---- ---- ---- ----
9005 028f 1137 02fe
9005 028f 1137 02ff
9005 028f 1137 0300Add new h3c pci ids:
VID / DID / SVID / SDID
---- ---- ---- ----
9005 028f 193d 0462
9005 028f 193d 8462Add new ieit pci ids:
VID / DID / SVID / SDID
---- ---- ---- ----
9005 028f 1ff9 00a3--- drivers/scsi/smartpqi/smartpqi_init.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
drivers/scsi/smartpqi/smartpqi_init.c +24 -0
@@ -9428,6 +9428,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x152d ,0x8a37 ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x193d ,0x0462 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x193d ,0x1104 )
@@ -9468,6 +9472,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x193d ,0x8461 ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x193d ,0x8462 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x193d ,0xc460 )
@@ -10176,6 +10184,18 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x1137 ,0x02fa ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1137 ,0x02fe ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1137 ,0x02ff ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1137 ,0x0300 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x1ff9 ,0x0045 )
@@ -10352,6 +10372,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x1f51 ,0x1045 ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1ff9 ,0x00a3 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,PCI_ANY_ID ,PCI_ANY_ID )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 201/482 drm/msm/adreno: Assign msm_gpu->pdev earlier to avoid nullptrs
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit 16007768551d5bfe53426645401435ca8d2ef54f ]
There are some cases, such as the one uncovered by Commit 46d4efcccc68 ("drm/msm/a6xx: Avoid a nullptr dereference when speedbin setting fails") where
msm_gpu_cleanup() : platform_set_drvdata(gpu->pdev, NULL);
is called on gpu->pdev == NULL, as the GPU device has not been fully initialized yet.
Turns out that there's more than just the aforementioned path that causes this to happen (e.g. the case when there's speedbin data in the catalog, but opp-supported-hw is missing in DT).
Assigning msm_gpu->pdev earlier seems like the least painful solution to this, therefore do so.
Patchwork: https://patchwork.freedesktop.org/patch/602742/
--- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 1 + drivers/gpu/drm/msm/msm_gpu.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/adreno/adreno_gpu.c +1 -0
@@ -1079,6 +1079,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, adreno_gpu->chip_id = config->chip_id; gpu->allow_relocs = config->info->family <ADRENO_6XX_GEN1 ; + gpu->pdev = pdev;/* Only handle the core clock when GMU is not in use (or is absent). */ if (adreno_has_gmu_wrapper(adreno_gpu) ||
drivers/gpu/drm/msm/msm_gpu.c +0 -1
@@ -929,7 +929,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,if (IS_ERR (gpu->gpu_cx)) gpu->gpu_cx =NULL ; - gpu->pdev = pdev;platform_set_drvdata (pdev, &gpu->adreno_smmu);msm_devfreq_init (gpu);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 202/482 jfs: Fix uninit-value access of new_ea in ea_buffer
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Mengmeng <[email protected]>
[ Upstream commit 2b59ffad47db1c46af25ccad157bb3b25147c35c ]
syzbot reports that lzo1x_1_do_compress is using uninit-value:
=====================================================
BUG: KMSAN: uninit-value in lzo1x_1_do_compress+0x19f9/0x2510 lib/lzo/lzo1x_compress.c:178
...
Uninit was stored to memory at:
ea_put fs/jfs/xattr.c:639 [inline]
...
Local variable ea_buf created at:
__jfs_setxattr+0x5d/0x1ae0 fs/jfs/xattr.c:662 __jfs_xattr_set+0xe6/0x1f0 fs/jfs/xattr.c:934
=====================================================
The reason is ea_buf->new_ea is not initialized properly.
Fix this by using memset to empty its content at the beginning in ea_get().
--- fs/jfs/xattr.c | 2 ++ 1 file changed, 2 insertions(+)
fs/jfs/xattr.c +2 -0
@@ -434,6 +434,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)int rc;int quota_allocation =0 ; +memset (&ea_buf->new_ea,0 ,sizeof (ea_buf->new_ea)); +/* When fsck.jfs clears a bad ea, it doesn't clear the size */ if (ji->ea.flag ==0 ) ea_size =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 203/482 drm/amdgpu: add raven1 gfxoff quirk
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Liu <[email protected]>
[ Upstream commit 0126c0ae11e8b52ecfde9d1b174ee2f32d6c3a5d ]
Fix screen corruption with openkylin.
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +2 -0
@@ -1172,6 +1172,8 @@ static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = { { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc6 },/* Apple MacBook Pro (15-inch, 2019) Radeon Pro Vega 20 4 GB */ { 0x1002, 0x69af, 0x106b, 0x019a, 0xc0 }, +/* https://bbs.openkylin.top/t/topic/171497 */ + { 0x1002, 0x15d8, 0x19e5, 0x3e14, 0xc2 }, { 0, 0, 0, 0, 0 }, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 204/482 drm/amdgpu: enable gfxoff quirk on HP 705G4
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Liu <[email protected]>
[ Upstream commit 2c7795e245d993bcba2f716a8c93a5891ef910c9 ]
Enabling gfxoff quirk results in perfectly usable graphical user interface on HP 705G4 DM with R5 2400G.
Without the quirk, X server is completely unusable as every few seconds there is gpu reset due to ring gfx timeout.
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +2 -0
@@ -1174,6 +1174,8 @@ static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = { { 0x1002, 0x69af, 0x106b, 0x019a, 0xc0 },/* https://bbs.openkylin.top/t/topic/171497 */ { 0x1002, 0x15d8, 0x19e5, 0x3e14, 0xc2 }, +/* HP 705G4 DM with R5 2400G */ + { 0x1002, 0x15dd, 0x103c, 0x8464, 0xd6 }, { 0, 0, 0, 0, 0 }, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 205/482 drm/amdkfd: Fix resource leak in criu restore queue
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <[email protected]>
[ Upstream commit aa47fe8d3595365a935921a90d00bc33ee374728 ]
To avoid memory leaks, release q_extra_data when exiting the restore queue.
v2: Correct the proto (Alex)
--- drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +1 -0
@@ -984,6 +984,7 @@ int kfd_criu_restore_queue(struct kfd_process *p,pr_debug ("Queue id %d was restored successfully\n" , queue_id);kfree (q_data); +kfree (q_extra_data);return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 206/482 HID: multitouch: Add support for Thinkpad X12 Gen 2 Kbd Portfolio
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vishnu Sankar <[email protected]>
[ Upstream commit 65b72ea91a257a5f0cb5a26b01194d3dd4b85298 ]
This applies similar quirks used by previous generation device, so that Trackpoint and buttons on the touchpad works. New USB KBD PID 0x61AE for Thinkpad X12 Tab is added.
--- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-multitouch.c | 6 ++++++ 2 files changed, 7 insertions(+)
drivers/hid/hid-ids.h +1 -0
@@ -794,6 +794,7 @@#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5#define USB_DEVICE_ID_LENOVO_X12_TAB 0x60fe +#define USB_DEVICE_ID_LENOVO_X12_TAB2 0x61ae#define USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E 0x600e#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
drivers/hid/hid-multitouch.c +6 -0
@@ -2113,6 +2113,12 @@ static const struct hid_device_id mt_devices[] = { USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X12_TAB) }, +/* Lenovo X12 TAB Gen 2 */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, +HID_DEVICE (BUS_USB ,HID_GROUP_MULTITOUCH_WIN_8 , +USB_VENDOR_ID_LENOVO , + USB_DEVICE_ID_LENOVO_X12_TAB2) }, + /* Logitech devices */ { .driver_data = MT_CLS_NSMU, HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 207/482 platform/x86: touchscreen_dmi: add nanote-next quirk
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ckath <[email protected]>
[ Upstream commit c11619af35bae5884029bd14170c3e4b55ddf6f3 ]
Add touschscreen info for the nanote next (UMPC-03-SR).
After checking with multiple owners the DMI info really is this generic.
--- drivers/platform/x86/touchscreen_dmi.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
drivers/platform/x86/touchscreen_dmi.c +26 -0
@@ -840,6 +840,21 @@ static const struct ts_dmi_data rwc_nanote_p8_data = { .properties = rwc_nanote_p8_props, }; +static const struct property_entry rwc_nanote_next_props[] = { +PROPERTY_ENTRY_U32 ("touchscreen-min-x" ,5 ), +PROPERTY_ENTRY_U32 ("touchscreen-min-y" ,5 ), +PROPERTY_ENTRY_U32 ("touchscreen-size-x" ,1785 ), +PROPERTY_ENTRY_U32 ("touchscreen-size-y" ,1145 ), +PROPERTY_ENTRY_BOOL ("touchscreen-inverted-y" ), +PROPERTY_ENTRY_STRING ("firmware-name" ,"gsl1680-rwc-nanote-next.fw" ), + { } +}; + +static const struct ts_dmi_data rwc_nanote_next_data = { + .acpi_name ="MSSL1680:00" , + .properties = rwc_nanote_next_props, +}; +static const struct property_entry schneider_sct101ctm_props[] = {PROPERTY_ENTRY_U32 ("touchscreen-size-x" ,1715 ),PROPERTY_ENTRY_U32 ("touchscreen-size-y" ,1140 ),
@@ -1589,6 +1604,17 @@ const struct dmi_system_id touchscreen_dmi_table[] = {DMI_MATCH (DMI_PRODUCT_SKU ,"0001" ) }, }, + { +/* RWC NANOTE NEXT */ + .driver_data = (void *)&rwc_nanote_next_data, + .matches = { +DMI_MATCH (DMI_PRODUCT_NAME ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_BOARD_NAME ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_BOARD_VENDOR ,"To be filled by O.E.M." ), +/* Above matches are too generic, add bios-version match */ + DMI_MATCH(DMI_BIOS_VERSION, "S8A70R100-V005"), + }, + }, {/* Schneider SCT101CTM */ .driver_data = (void *)&schneider_sct101ctm_data,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 208/482 platform/x86/amd: pmf: Add quirk for TUF Gaming A14
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: aln8 <[email protected]>
[ Upstream commit 06369503d644068abd9e90918c6611274d94c126 ]
The ASUS TUF Gaming A14 has the same issue as the ROG Zephyrus G14 where it advertises SPS support but doesn't use it.
--- drivers/platform/x86/amd/pmf/pmf-quirks.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/platform/x86/amd/pmf/pmf-quirks.c +8 -0
@@ -37,6 +37,14 @@ static const struct dmi_system_id fwbug_list[] = { }, .driver_data = &quirk_no_sps_bug, }, + { + .ident = "ASUS TUF Gaming A14", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "FA401W"), + }, + .driver_data = &quirk_no_sps_bug, + }, {} };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 209/482 drm/stm: ltdc: reset plane transparency after plane disable
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yannick Fertre <[email protected]>
[ Upstream commit 02fa62d41c8abff945bae5bfc3ddcf4721496aca ]
The plane's opacity should be reseted while the plane is disabled. It prevents from seeing a possible global or layer background color set earlier.
--- drivers/gpu/drm/stm/ltdc.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/stm/ltdc.c +3 -0
@@ -1513,6 +1513,9 @@ static void ltdc_plane_atomic_disable(struct drm_plane *plane,/* Disable layer */ regmap_write_bits (ldev->regmap,LTDC_L1CR + lofs,LXCR_LEN |LXCR_CLUTEN |LXCR_HMEN ,0 ); +/* Reset the layer transparency to hide any related background color */ +regmap_write_bits (ldev->regmap,LTDC_L1CACR + lofs,LXCACR_CONSTA ,0x00 ); +/* Commit shadow registers = update plane at next vblank */ if (ldev->caps.plane_reg_shadow) regmap_write_bits(ldev->regmap, LTDC_L1RCR + lofs,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 210/482 drm/amd/display: Check null-initialized variables
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 367cd9ceba1933b63bc1d87d967baf6d9fd241d2 ]
[WHAT & HOW]drr_timing and subvp_pipe are initialized to null and they are not always assigned new values. It is necessary to check for null before dereferencing.
This fixes 2 FORWARD_NULL issues reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +4 -3
@@ -871,8 +871,9 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context)* for VBLANK: (VACTIVE region of the SubVP pipe can fit the MALL prefetch, VBLANK frame time, * and the max of (VBLANK blanking time, MALL region)). */ -if (stretched_drr_us < (1 / (double )drr_timing->min_refresh_in_uhz) *1000000 *1000000 && - subvp_active_us - prefetch_us - stretched_drr_us - max_vblank_mallregion >0 ) +if (drr_timing && + stretched_drr_us < (1 / (double )drr_timing->min_refresh_in_uhz) *1000000 *1000000 && + subvp_active_us - prefetch_us - stretched_drr_us - max_vblank_mallregion >0 ) schedulable = true;return schedulable;
@@ -937,7 +938,7 @@ static bool subvp_vblank_schedulable(struct dc *dc, struct dc_state *context)if (!subvp_pipe && pipe_mall_type ==SUBVP_MAIN ) subvp_pipe = pipe; } -if (found) { +if (found && subvp_pipe) { phantom_stream =dc_state_get_paired_subvp_stream (context, subvp_pipe->stream); main_timing = &subvp_pipe->stream->timing; phantom_timing = &phantom_stream->timing;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 211/482 drm/amd/display: Check phantom_stream before it is used
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 3718a619a8c0a53152e76bb6769b6c414e1e83f4 ]
dcn32_enable_phantom_stream can return null, so returned value must be checked before used.
This fixes 1 NULL_RETURNS issue reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +3 -0
@@ -1714,6 +1714,9 @@ void dcn32_add_phantom_pipes(struct dc *dc, struct dc_state *context,// be a valid candidate for SubVP (i.e. has a plane, stream, doesn't // already have phantom pipe assigned, etc.) by previous checks. phantom_stream =dcn32_enable_phantom_stream (dc, context, pipes, pipe_cnt, index); +if (!phantom_stream) +return ; +dcn32_enable_phantom_plane (dc, context, phantom_stream, index);for (i =0 ; i < dc->res_pool->pipe_count; i++) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 212/482 drm/amd/display: Check stream before comparing them
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 35ff747c86767937ee1e0ca987545b7eed7a0810 ]
[WHAT & HOW]amdgpu_dm can pass a null stream to dc_is_stream_unchanged. It is necessary to check for null before dereferencing them.
This fixes 1 FORWARD_NULL issue reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/core/dc_resource.c +2 -0
@@ -3134,6 +3134,8 @@ static bool are_stream_backends_same(bool dc_is_stream_unchanged (struct dc_stream_state *old_stream,struct dc_stream_state *stream) { +if (!old_stream || !stream) +return false;if (!are_stream_backends_same (old_stream, stream))return false;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 213/482 drm/amd/display: Check link_res->hpo_dp_link_enc before using it
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 0beca868cde8742240cd0038141c30482d2b7eb8 ]
[WHAT & HOW]
Functions dp_enable_link_phy and dp_disable_link_phy can pass link_res without initializing hpo_dp_link_enc and it is necessary to check for null before dereferencing.
This fixes 2 FORWARD_NULL issues reported by Coverity.
--- .../gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c +7 -0
@@ -28,6 +28,8 @@#include "dccg.h" #include "clk_mgr.h" +#define DC_LOGGER link->ctx->logger +void set_hpo_dp_throttled_vcp_size (struct pipe_ctx *pipe_ctx,struct fixed31_32 throttled_vcp_size) {
@@ -124,6 +126,11 @@ void disable_hpo_dp_link_output(struct dc_link *link,const struct link_resource *link_res, enum signal_type signal) { + if (!link_res->hpo_dp_link_enc) { + DC_LOG_ERROR("%s: invalid hpo_dp_link_enc\n", __func__); +return ; + } + link_res->hpo_dp_link_enc->funcs->link_disable (link_res->hpo_dp_link_enc); link_res->hpo_dp_link_enc->funcs->disable_link_phy ( link_res->hpo_dp_link_enc, signal);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 214/482 drm/amd/display: Fix index out of bounds in DCN30 degamma hardware format translation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit bc50b614d59990747dd5aeced9ec22f9258991ff ]
This commit addresses a potential index out of bounds issue in the cm3_helper_translate_curve_to_degamma_hw_format function in the DCN30 color management module. The issue could occur when the index 'i' exceeds the number of transfer function points (TRANSFER_FUNC_POINTS).
The fix adds a check to ensure 'i' is within bounds before accessing the transfer function points. If 'i' is out of bounds, the function returns false to indicate an error.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:338 cm3_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.red' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:339 cm3_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.green' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:340 cm3_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.blue' 1025 <= s32max
--- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c +2 -0
@@ -335,6 +335,8 @@ bool cm3_helper_translate_curve_to_degamma_hw_format( i += increment) {if (j == hw_points -1 )break ; +if (i >=TRANSFER_FUNC_POINTS ) +return false; rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 215/482 drm/amd/display: Fix index out of bounds in degamma hardware format translation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit b7e99058eb2e86aabd7a10761e76cae33d22b49f ]
Fixes index out of bounds issue in cm_helper_translate_curve_to_degamma_hw_format function. The issue could occur when the index 'i' exceeds the number of transfer function points (TRANSFER_FUNC_POINTS).
The fix adds a check to ensure 'i' is within bounds before accessing the transfer function points. If 'i' is out of bounds the function returns false to indicate an error.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_cm_common.c:594 cm_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.red' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_cm_common.c:595 cm_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.green' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_cm_common.c:596 cm_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.blue' 1025 <= s32max
--- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +2 -0
@@ -591,6 +591,8 @@ bool cm_helper_translate_curve_to_degamma_hw_format( i += increment) {if (j == hw_points -1 )break ; +if (i >=TRANSFER_FUNC_POINTS ) +return false; rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 216/482 drm/amd/display: Fix index out of bounds in DCN30 color transformation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit d81873f9e715b72d4f8d391c8eb243946f784dfc ]
This commit addresses a potential index out of bounds issue in the cm3_helper_translate_curve_to_hw_format function in the DCN30 color management module. The issue could occur when the index 'i' exceeds the number of transfer function points (TRANSFER_FUNC_POINTS).
The fix adds a check to ensure 'i' is within bounds before accessing the transfer function points. If 'i' is out of bounds, the function returns false to indicate an error.
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:180 cm3_helper_translate_curve_to_hw_format() error: buffer overflow 'output_tf->tf_pts.red' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:181 cm3_helper_translate_curve_to_hw_format() error: buffer overflow 'output_tf->tf_pts.green' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:182 cm3_helper_translate_curve_to_hw_format() error: buffer overflow 'output_tf->tf_pts.blue' 1025 <= s32max
--- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c +2 -0
@@ -177,6 +177,8 @@ bool cm3_helper_translate_curve_to_hw_format( i += increment) {if (j == hw_points)break ; +if (i >=TRANSFER_FUNC_POINTS ) +return false; rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 217/482 drm/amdgpu/gfx9: properly handle error ints on all pipes
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit 48695573d2feaf42812c1ad54e01caff0d1c2d71 ]
Need to handle the interrupt enables for all pipes.
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 44 +++++++++++++++++++++- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 50 +++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +43 -1
@@ -2477,7 +2477,7 @@ static void gfx_v9_0_enable_gui_idle_interrupt(struct amdgpu_device *adev, tmp =REG_SET_FIELD (tmp,CP_INT_CNTL_RING0 ,CNTX_BUSY_INT_ENABLE , enable ?1 :0 ); tmp =REG_SET_FIELD (tmp,CP_INT_CNTL_RING0 ,CNTX_EMPTY_INT_ENABLE , enable ?1 :0 ); tmp =REG_SET_FIELD (tmp,CP_INT_CNTL_RING0 ,CMP_BUSY_INT_ENABLE , enable ?1 :0 ); -if (adev->gfx.num_gfx_rings) +if (adev->gfx.num_gfx_rings) tmp =REG_SET_FIELD (tmp,CP_INT_CNTL_RING0 ,GFX_IDLE_INT_ENABLE , enable ?1 :0 );WREG32_SOC15 (GC ,0 , mmCP_INT_CNTL_RING0, tmp);
@@ -5772,17 +5772,59 @@ static void gfx_v9_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev, } } +static u32 gfx_v9_0_get_cpc_int_cntl (struct amdgpu_device *adev, +int me,int pipe) +{ +/* +* amdgpu controls only the first MEC. That's why this function only +* handles the setting of interrupts for this specific MEC. All other +* pipes' interrupts are set by amdkfd. +*/ +if (me !=1 ) +return 0 ; + +switch (pipe) { +case 0 : +return SOC15_REG_OFFSET (GC ,0 , mmCP_ME1_PIPE0_INT_CNTL); +case 1 : +return SOC15_REG_OFFSET (GC ,0 , mmCP_ME1_PIPE1_INT_CNTL); +case 2 : +return SOC15_REG_OFFSET (GC ,0 , mmCP_ME1_PIPE2_INT_CNTL); +case 3 : +return SOC15_REG_OFFSET (GC ,0 , mmCP_ME1_PIPE3_INT_CNTL); +default : +return 0 ; + } +} +static int gfx_v9_0_set_priv_reg_fault_state (struct amdgpu_device *adev,struct amdgpu_irq_src *source,unsigned type,enum amdgpu_interrupt_state state) { +u32 cp_int_cntl_reg, cp_int_cntl; +int i, j; +switch (state) {case AMDGPU_IRQ_STATE_DISABLE :case AMDGPU_IRQ_STATE_ENABLE :WREG32_FIELD15 (GC ,0 ,CP_INT_CNTL_RING0 ,PRIV_REG_INT_ENABLE , state ==AMDGPU_IRQ_STATE_ENABLE ?1 :0 ); +for (i =0 ; i < adev->gfx.mec.num_mec; i++) { +for (j =0 ; j < adev->gfx.mec.num_pipe_per_mec; j++) { +/* MECs start at 1 */ + cp_int_cntl_reg =gfx_v9_0_get_cpc_int_cntl (adev, i +1 , j); + +if (cp_int_cntl_reg) { + cp_int_cntl =RREG32_SOC15_IP (GC , cp_int_cntl_reg); + cp_int_cntl =REG_SET_FIELD (cp_int_cntl,CP_ME1_PIPE0_INT_CNTL , +PRIV_REG_INT_ENABLE , + state ==AMDGPU_IRQ_STATE_ENABLE ?1 :0 ); +WREG32_SOC15_IP (GC , cp_int_cntl_reg, cp_int_cntl); + } + } + }break ;default :break ;
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +46 -4
67 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 218/482 drm/amd/display: Avoid overflow assignment in link_dp_cts
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit a15268787b79fd183dd526cc16bec9af4f4e49a1 ]
sampling_rate is an uint8_t but is assigned an unsigned int, and thus it can overflow. As a result, sampling_rate is changed to uint32_t.
Similarly, LINK_QUAL_PATTERN_SET has a size of 2 bits, and it should only be assigned to a value less or equal than 4.
This fixes 2 INTEGER_OVERFLOW issues reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 2 +- drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c | 3 ++- drivers/gpu/drm/amd/display/include/dpcd_defs.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/dc_dp_types.h +1 -1
@@ -727,7 +727,7 @@ struct dp_audio_test_data_flags {struct dp_audio_test_data {struct dp_audio_test_data_flags flags; -uint8_t sampling_rate; +uint32_t sampling_rate;uint8_t channel_count;uint8_t pattern_type;uint8_t pattern_period[8 ];
drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +2 -1
@@ -775,7 +775,8 @@ bool dp_set_test_pattern(core_link_read_dpcd (link,DP_TRAINING_PATTERN_SET , &training_pattern.raw,sizeof (training_pattern)); - training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern; +if (pattern <=PHY_TEST_PATTERN_END_DP11 ) + training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;core_link_write_dpcd (link,DP_TRAINING_PATTERN_SET , &training_pattern.raw,sizeof (training_pattern));
drivers/gpu/drm/amd/display/include/dpcd_defs.h +1 -0
@@ -76,6 +76,7 @@ enum dpcd_phy_test_patterns {PHY_TEST_PATTERN_D10_2 ,PHY_TEST_PATTERN_SYMBOL_ERROR ,PHY_TEST_PATTERN_PRBS7 , +PHY_TEST_PATTERN_END_DP11 =PHY_TEST_PATTERN_PRBS7 ,PHY_TEST_PATTERN_80BIT_CUSTOM ,/* For DP1.2 only */ PHY_TEST_PATTERN_CP2520_1 , PHY_TEST_PATTERN_CP2520_2,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 219/482 drm/amd/display: Initialize get_bytes_per_elements default to 1
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 4067f4fa0423a89fb19a30b57231b384d77d2610 ]
Variables, used as denominators and maybe not assigned to other values, should not be 0. bytes_per_element_y & bytes_per_element_c are initialized by get_bytes_per_element() which should never return 0.
This fixes 10 DIVIDE_BY_ZERO issues reported by Coverity.
--- .../gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c | 2 +- .../gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +1 -1
@@ -78,7 +78,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,static unsigned int get_bytes_per_element (enum source_format_class source_format,bool is_chroma) { -unsigned int ret_val =0 ; +unsigned int ret_val =1 ;if (source_format == dm_444_16) {if (!is_chroma)
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c +1 -1
@@ -53,7 +53,7 @@ static void calculate_ttu_cursor(static unsigned int get_bytes_per_element (enum source_format_class source_format,bool is_chroma) { -unsigned int ret_val =0 ; +unsigned int ret_val =1 ;if (source_format == dm_444_16) {if (!is_chroma)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 220/482 drm/printer: Allow NULL data in devcoredump printer
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Brost <[email protected]>
[ Upstream commit 53369581dc0c68a5700ed51e1660f44c4b2bb524 ]
We want to determine the size of the devcoredump before writing it out. To that end, we will run the devcoredump printer with NULL data to get the size, alloc data based on the generated offset, then run the devcorecump again with a valid data pointer to print. This necessitates not writing data to the data pointer on the initial pass, when it is NULL.
v5:
- Better commit message (Jonathan)
- Add kerenl doc with examples (Jani)
--- drivers/gpu/drm/drm_print.c | 13 +++++---- include/drm/drm_print.h | 54 ++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 6 deletions(-)
drivers/gpu/drm/drm_print.c +8 -5
@@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str) copy = iterator->remain;/* Copy out the bit of the string that we need */ -memcpy (iterator->data, - str + (iterator->start - iterator->offset), copy); +if (iterator->data) +memcpy (iterator->data, + str + (iterator->start - iterator->offset), copy); iterator->offset = iterator->start + copy; iterator->remain -= copy;
@@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str) len =min_t (ssize_t,strlen (str), iterator->remain); -memcpy (iterator->data + pos, str, len); +if (iterator->data) +memcpy (iterator->data + pos, str, len); iterator->offset += len; iterator->remain -= len;
@@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {ssize_t pos = iterator->offset - iterator->start; -snprintf (((char *) iterator->data) + pos, - iterator->remain,"%pV" , vaf); +if (iterator->data) +snprintf (((char *) iterator->data) + pos, + iterator->remain,"%pV" , vaf); iterator->offset += len; iterator->remain -= len;
include/drm/drm_print.h +53 -1
66 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 221/482 perf,x86: avoid missing caller address in stack traces captured in uprobe
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <[email protected]>
[ Upstream commit cfa7f3d2c526c224a6271cc78a4a27a0de06f4f0 ]
When tracing user functions with uprobe functionality, it's common to install the probe (e.g., a BPF program) at the first instruction of the function. This is often going to be push %rbp instruction in function preamble, which means that within that function frame pointer hasn't been established yet. This leads to consistently missing an actual caller of the traced function, because perf_callchain_user() only records current IP (capturing traced function) and then following frame pointer chain (which would be caller's frame, containing the address of caller's caller).
So when we have target_1 -> target_2 -> target_3 call chain and we are tracing an entry to target_3, captured stack trace will report target_1 -> target_3 call chain, which is wrong and confusing.
This patch proposes a x86-64-specific heuristic to detect push %rbp (push %ebp on 32-bit architecture) instruction being traced. Given entire kernel implementation of user space stack trace capturing works under assumption that user space code was compiled with frame pointer register (%rbp/%ebp) preservation, it seems pretty reasonable to use this instruction as a strong indicator that this is the entry to the function. In that case, return address is still pointed to by %rsp/%esp, so we fetch it and add to stack trace before proceeding to unwind the rest using frame pointer-based logic.
We also check for endbr64 (for 64-bit modes) as another common pattern for function entry, as suggested by Josh Poimboeuf. Even if we get this wrong sometimes for uprobes attached not at the function entry, it's OK because stack trace will still be overall meaningful, just with one extra bogus entry. If we don't detect this, we end up with guaranteed to be missing caller function entry in the stack trace, which is worse overall.
--- arch/x86/events/core.c | 63 +++++++++++++++++++++++++++++++++++++++++ include/linux/uprobes.h | 2 ++ kernel/events/uprobes.c | 2 ++ 3 files changed, 67 insertions(+)
arch/x86/events/core.c +63 -0
@@ -41,6 +41,8 @@#include <asm/desc.h> #include <asm/ldt.h> #include <asm/unwind.h> +#include <asm/uprobes.h> +#include <asm/ibt.h> #include "perf_event.h"
@@ -2814,6 +2816,46 @@ static unsigned long get_segment_base(unsigned int segment)return get_desc_base (desc); } +#ifdef CONFIG_UPROBES +/* +* Heuristic-based check if uprobe is installed at the function entry. +* +* Under assumption of user code being compiled with frame pointers, +* `push %rbp/%ebp` is a good indicator that we indeed are. +* +* Similarly, `endbr64` (assuming 64-bit mode) is also a common pattern. +* If we get this wrong, captured stack trace might have one extra bogus +* entry, but the rest of stack trace will still be meaningful. +*/ +static bool is_uprobe_at_func_entry (struct pt_regs *regs) +{ +struct arch_uprobe *auprobe; + +if (!current->utask) +return false; + + auprobe = current->utask->auprobe; +if (!auprobe) +return false; + +/* push %rbp/%ebp */ +if (auprobe->insn[0 ] ==0x55 ) +return true; + +/* endbr64 (64-bit only) */ +if (user_64bit_mode (regs) &&is_endbr (*(u32 *)auprobe->insn)) +return true; + +return false; +} + +#else +static bool is_uprobe_at_func_entry (struct pt_regs *regs) +{ +return false; +} +#endif /* CONFIG_UPROBES */ +#ifdef CONFIG_IA32_EMULATION #include <linux/compat.h>
@@ -2825,6 +2867,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entunsigned long ss_base, cs_base;struct stack_frame_ia32 frame;const struct stack_frame_ia32 __user *fp; +u32 ret_addr;if (user_64bit_mode (regs))return 0 ;
@@ -2834,6 +2877,12 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent fp =compat_ptr (ss_base + regs->bp);pagefault_disable (); + +/* see perf_callchain_user() below for why we do this */ +if (is_uprobe_at_func_entry (regs) && + !get_user (ret_addr, (const u32 __user *)regs->sp)) +perf_callchain_store (entry, ret_addr); +while (entry->nr < entry->max_stack) {if (!valid_user_frame (fp,sizeof (frame)))break ;
@@ -2862,6 +2911,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs {struct stack_frame frame;const struct stack_frame __user *fp; +unsigned long ret_addr;if (perf_guest_state ()) {/* TODO: We don't support guest os callchain now */
@@ -2885,6 +2935,19 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regsreturn ;pagefault_disable (); + +/* +* If we are called from uprobe handler, and we are indeed at the very +* entry to user function (which is normally a `push %rbp` instruction, +* under assumption of application being compiled with frame pointers), +* we should read return address from *regs->sp before proceeding +* to follow frame pointers, otherwise we'll skip immediate caller +* as %rbp is not yet setup. +*/ +if (is_uprobe_at_func_entry (regs) && + !get_user (ret_addr, (const unsigned long __user *)regs->sp)) +perf_callchain_store (entry, ret_addr); +while (entry->nr < entry->max_stack) {if (!valid_user_frame (fp,sizeof (frame)))break ;
include/linux/uprobes.h +2 -0
@@ -76,6 +76,8 @@ struct uprobe_task {struct uprobe *active_uprobe;unsigned long xol_vaddr; +struct arch_uprobe *auprobe; +struct return_instance *return_instances;unsigned int depth; };
kernel/events/uprobes.c +2 -0
@@ -2071,6 +2071,7 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)bool need_prep = false;/* prepare return uprobe, when needed */ down_read (&uprobe->register_rwsem); + current->utask->auprobe = &uprobe->arch;for (uc = uprobe->consumers; uc; uc = uc->next) {int rc =0 ;
@@ -2085,6 +2086,7 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs) remove &= rc; } + current->utask->auprobe =NULL ;if (need_prep && !remove)prepare_uretprobe (uprobe, regs);/* put bp at return */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 222/482 scsi: aacraid: Rearrange order of struct aac_srb_unit
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit 6e5860b0ad4934baee8c7a202c02033b2631bb44 ]
struct aac_srb_unit contains struct aac_srb, which contains struct sgmap, which ends in a (currently) "fake" (1-element) flexible array. Converting this to a flexible array is needed so that runtime bounds checking won't think the array is fixed size (i.e. under CONFIG_FORTIFY_SOURCE=y and/or CONFIG_UBSAN_BOUNDS=y), as other parts of aacraid use struct sgmap as a flexible array.
It is not legal to have a flexible array in the middle of a structure, so it either needs to be split up or rearranged so that it is at the end of the structure. Luckily, struct aac_srb_unit, which is exclusively consumed/updated by aac_send_safw_bmic_cmd(), does not depend on member ordering.
The values set in the on-stack struct aac_srb_unit instance "srbu" by the only two callers, aac_issue_safw_bmic_identify() and aac_get_safw_ciss_luns(), do not contain anything in srbu.srb.sgmap.sg, and they both implicitly initialize srbu.srb.sgmap.count to 0 during memset(). For example:
memset(&srbu, 0, sizeof(struct aac_srb_unit));
srbcmd = &srbu.srb;
srbcmd->flags = cpu_to_le32(SRB_DataIn);
srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS;
srbcmd->cdb[1] = 2; /* extended reporting */
srbcmd->cdb[8] = (u8)(datasize >> 8);
srbcmd->cdb[9] = (u8)(datasize);
rcode = aac_send_safw_bmic_cmd(dev, &srbu, phys_luns, datasize);During aac_send_safw_bmic_cmd(), a separate srb is mapped into DMA, and has srbu.srb copied into it:
srb = fib_data(fibptr);
memcpy(srb, &srbu->srb, sizeof(struct aac_srb));Only then is srb.sgmap.count written and srb->sg populated:
srb->count = cpu_to_le32(xfer_len);
sg64 = (struct sgmap64 *)&srb->sg;
sg64->count = cpu_to_le32(1);
sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr));
sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr));
sg64->sg[0].count = cpu_to_le32(xfer_len);But this is happening in the DMA memory, not in srbu.srb. An attempt to copy the changes back to srbu does happen:
/*
* Copy the updated data for other dumping or other usage if
* needed
*/
memcpy(&srbu->srb, srb, sizeof(struct aac_srb));But this was never correct: the sg64 (3 u32s) overlap of srb.sg (2 u32s) always meant that srbu.srb would have held truncated information and any attempt to walk srbu.srb.sg.sg based on the value of srbu.srb.sg.count would result in attempting to parse past the end of srbu.srb.sg.sg[0] into srbu.srb_reply.
After getting a reply from hardware, the reply is copied into srbu.srb_reply:
srb_reply = (struct aac_srb_reply *)fib_data(fibptr);
memcpy(&srbu->srb_reply, srb_reply, sizeof(struct aac_srb_reply));This has always been fixed-size, so there's no issue here. It is worth noting that the two callers _never check_ srbu contents -- neither srbu.srb nor srbu.srb_reply is examined. (They depend on the mapped xfer_buf instead.)
Therefore, the ordering of members in struct aac_srb_unit does not matter, and the flexible array member can moved to the end.
(Additionally, the two memcpy()s that update srbu could be entirely removed as they are never consumed, but I left that as-is.)
--- drivers/scsi/aacraid/aacraid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/aacraid/aacraid.h +1 -1
@@ -2029,8 +2029,8 @@ struct aac_srb_reply };struct aac_srb_unit { -struct aac_srb srb;struct aac_srb_reply srb_reply; +struct aac_srb srb; };/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 223/482 scsi: lpfc: Validate hdwq pointers before dereferencing in reset/errata paths
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit 2be1d4f11944cd6283cb97268b3e17c4424945ca ]
When the HBA is undergoing a reset or is handling an errata event, NULL ptr dereference crashes may occur in routines such as lpfc_sli_flush_io_rings(), lpfc_dev_loss_tmo_callbk(), or lpfc_abort_handler().
Add NULL ptr checks before dereferencing hdwq pointers that may have been freed due to operations colliding with a reset or errata event handler.
--- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 ++- drivers/scsi/lpfc/lpfc_scsi.c | 13 +++++++++++-- drivers/scsi/lpfc/lpfc_sli.c | 11 +++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-)
drivers/scsi/lpfc/lpfc_hbadisc.c +2 -1
@@ -175,7 +175,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) ndlp->nlp_state, ndlp->fc4_xpt_flags);/* Don't schedule a worker thread event if the vport is going down. */ -if (test_bit (FC_UNLOADING , &vport->load_flag)) { +if (test_bit (FC_UNLOADING , &vport->load_flag) || + !test_bit (HBA_SETUP , &phba->hba_flag)) {spin_lock_irqsave (&ndlp->lock, iflags); ndlp->rport =NULL ;
drivers/scsi/lpfc/lpfc_scsi.c +11 -2
@@ -5555,11 +5555,20 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) iocb = &lpfc_cmd->cur_iocbq;if (phba->sli_rev ==LPFC_SLI_REV4 ) { - pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring; -if (!pring_s4) { +/* if the io_wq & pring are gone, the port was reset. */ +if (!phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq || + !phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring) { +lpfc_printf_vlog (vport,KERN_WARNING ,LOG_FCP , +"2877 SCSI Layer I/O Abort Request " +"IO CMPL Status x%x ID %d LUN %llu " +"HBA_SETUP %d\n" ,FAILED , + cmnd->device->id, + (u64 )cmnd->device->lun, +test_bit (HBA_SETUP , &phba->hba_flag)); ret =FAILED ; goto out_unlock_hba; } + pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring;spin_lock (&pring_s4->ring_lock); }/* the command is in process of being cancelled */
drivers/scsi/lpfc/lpfc_sli.c +11 -0
@@ -4687,6 +4687,17 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba)/* Look on all the FCP Rings for the iotag */ if (phba->sli_rev >=LPFC_SLI_REV4 ) {for (i =0 ; i < phba->cfg_hdw_queue; i++) { +if (!phba->sli4_hba.hdwq || + !phba->sli4_hba.hdwq[i].io_wq) { +lpfc_printf_log (phba,KERN_ERR ,LOG_SLI , +"7777 hdwq's deleted %lx " +"%lx %x %x\n" , + phba->pport->load_flag, + phba->hba_flag, + phba->link_state, + phba->sli.sli_flag); +return ; + } pring = phba->sli4_hba.hdwq[i].io_wq->pring;spin_lock_irq (&pring->ring_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 224/482 scsi: lpfc: Fix unsolicited FLOGI kref imbalance when in direct attached topology
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit b5c18c9dd138733c16893613345af44deadcf05e ]
In direct attached topology, certain target vendors that are quick to issue FLOGI followed by a cable pull for more than dev_loss_tmo may result in a kref imbalance for the remote port ndlp object.
Add an nlp_get when the defer_flogi_acc flag is set. This is expected to balance the nlp_put in the defer_flogi_acc clause in the lpfc_issue_els_flogi() routine. Because we need to retain the ndlp ptr, reorganize all of the defer_flogi_acc information into one lpfc_defer_flogi_acc struct.
--- drivers/scsi/lpfc/lpfc.h | 12 ++++++--- drivers/scsi/lpfc/lpfc_els.c | 46 +++++++++++++++++++------------- drivers/scsi/lpfc/lpfc_hbadisc.c | 11 ++++++-- 3 files changed, 46 insertions(+), 23 deletions(-)
drivers/scsi/lpfc/lpfc.h +9 -3
@@ -306,6 +306,14 @@ struct lpfc_stats {struct lpfc_hba ; +/* Data structure to keep withheld FLOGI_ACC information */ +struct lpfc_defer_flogi_acc { +bool flag; +u16 rx_id; +u16 ox_id; +struct lpfc_nodelist *ndlp; + +};#define LPFC_VMID_TIMER 300/* timer interval in seconds */
@@ -1430,9 +1438,7 @@ struct lpfc_hba {uint16_t vlan_id;struct list_head fcf_conn_rec_list; -bool defer_flogi_acc_flag; -uint16_t defer_flogi_acc_rx_id; -uint16_t defer_flogi_acc_ox_id; +struct lpfc_defer_flogi_acc defer_flogi_acc;spinlock_t ct_ev_lock;/* synchronize access to ct_ev_waiters */ struct list_head ct_ev_waiters;
drivers/scsi/lpfc/lpfc_els.c +28 -18
96 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_hbadisc.c +9 -2
@@ -1247,7 +1247,14 @@ lpfc_linkdown(struct lpfc_hba *phba)lpfc_scsi_dev_block (phba); offline =pci_channel_offline (phba->pcidev); - phba->defer_flogi_acc_flag = false; +/* Decrement the held ndlp if there is a deferred flogi acc */ +if (phba->defer_flogi_acc.flag) { +if (phba->defer_flogi_acc.ndlp) { +lpfc_nlp_put (phba->defer_flogi_acc.ndlp); + phba->defer_flogi_acc.ndlp =NULL ; + } + } + phba->defer_flogi_acc.flag = false;/* Clear external loopback plug detected flag */ phba->link_flag &= ~LS_EXTERNAL_LOOPBACK ;
@@ -1369,7 +1376,7 @@ lpfc_linkup_port(struct lpfc_vport *vport) (vport != phba->pport))return ; -if (phba->defer_flogi_acc_flag) { +if (phba->defer_flogi_acc.flag) {clear_bit (FC_ABORT_DISCOVERY , &vport->fc_flag);clear_bit (FC_RSCN_MODE , &vport->fc_flag);clear_bit (FC_NLP_MORE , &vport->fc_flag);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 225/482 scsi: lpfc: Update PRLO handling in direct attached topology
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit 1f0f7679ad8942f810b0f19ee9cf098c3502d66a ]
A kref imbalance occurs when handling an unsolicited PRLO in direct attached topology.
Rework PRLO rcv handling when in MAPPED state. Save the state that we were handling a PRLO by setting nlp_last_elscmd to ELS_CMD_PRLO. Then in the lpfc_cmpl_els_logo_acc() completion routine, manually restart discovery. By issuing the PLOGI, which nlp_gets, before nlp_put at the end of the lpfc_cmpl_els_logo_acc() routine, we are saving us from a final nlp_put. And, we are still allowing the unreg_rpi to happen.
--- drivers/scsi/lpfc/lpfc_els.c | 27 ++++++++++++++++----------- drivers/scsi/lpfc/lpfc_nportdisc.c | 22 ++++++++++++++++++++-- 2 files changed, 36 insertions(+), 13 deletions(-)
drivers/scsi/lpfc/lpfc_els.c +16 -11
@@ -5244,9 +5244,10 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,/* ACC to LOGO completes to NPort <nlp_DID> */ lpfc_printf_vlog (vport,KERN_INFO ,LOG_ELS ,"0109 ACC to LOGO completes to NPort x%x refcnt %d " -"Data: x%x x%x x%x\n" , - ndlp->nlp_DID,kref_read (&ndlp->kref), ndlp->nlp_flag, - ndlp->nlp_state, ndlp->nlp_rpi); +"last els x%x Data: x%x x%x x%x\n" , + ndlp->nlp_DID,kref_read (&ndlp->kref), + ndlp->nlp_last_elscmd, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi);/* This clause allows the LOGO ACC to complete and free resources * for the Fabric Domain Controller. It does deliberately skip
@@ -5258,18 +5259,22 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out;if (ndlp->nlp_state ==NLP_STE_NPR_NODE ) { -/* If PLOGI is being retried, PLOGI completion will cleanup the -* node. The NLP_NPR_2B_DISC flag needs to be retained to make -* progress on nodes discovered from last RSCN. -*/ -if ((ndlp->nlp_flag &NLP_DELAY_TMO ) && - (ndlp->nlp_last_elscmd ==ELS_CMD_PLOGI )) - goto out; -if (ndlp->nlp_flag &NLP_RPI_REGISTERED )lpfc_unreg_rpi (vport, ndlp); +/* If came from PRLO, then PRLO_ACC is done. +* Start rediscovery now. +*/ +if (ndlp->nlp_last_elscmd ==ELS_CMD_PRLO ) { +spin_lock_irq (&ndlp->lock); + ndlp->nlp_flag |=NLP_NPR_2B_DISC ; +spin_unlock_irq (&ndlp->lock); + ndlp->nlp_prev_state = ndlp->nlp_state; +lpfc_nlp_set_state (vport, ndlp,NLP_STE_PLOGI_ISSUE ); +lpfc_issue_els_plogi (vport, ndlp->nlp_DID,0 ); + } } + out:/* * The driver received a LOGO from the rport and has ACK'd it.
drivers/scsi/lpfc/lpfc_nportdisc.c +20 -2
@@ -2652,8 +2652,26 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,/* flush the target */ lpfc_sli_abort_iocb (vport, ndlp->nlp_sid,0 ,LPFC_CTX_TGT ); -/* Treat like rcv logo */ -lpfc_rcv_logo (vport, ndlp, cmdiocb,ELS_CMD_PRLO ); +/* Send PRLO_ACC */ +spin_lock_irq (&ndlp->lock); + ndlp->nlp_flag |=NLP_LOGO_ACC ; +spin_unlock_irq (&ndlp->lock); +lpfc_els_rsp_acc (vport,ELS_CMD_PRLO , cmdiocb, ndlp,NULL ); + +/* Save ELS_CMD_PRLO as the last elscmd and then set to NPR. +* lpfc_cmpl_els_logo_acc is expected to restart discovery. +*/ + ndlp->nlp_last_elscmd =ELS_CMD_PRLO ; + ndlp->nlp_prev_state = ndlp->nlp_state; + +lpfc_printf_vlog (vport,KERN_INFO ,LOG_NODE |LOG_ELS |LOG_DISCOVERY , +"3422 DID x%06x nflag x%x lastels x%x ref cnt %u\n" , + ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->nlp_last_elscmd, +kref_read (&ndlp->kref)); + +lpfc_nlp_set_state (vport, ndlp,NLP_STE_NPR_NODE ); +return ndlp->nlp_state; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 226/482 drm/amdgpu: fix unchecked return value warning for amdgpu_gfx
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit c0277b9d7c2ee9ee5dbc948548984f0fbb861301 ]
This resolves the unchecded return value warning reported by Coverity.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +14 -4
@@ -816,8 +816,11 @@ int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *rint r;if (amdgpu_ras_is_supported (adev, ras_block->block)) { -if (!amdgpu_persistent_edc_harvesting_supported (adev)) -amdgpu_ras_reset_error_status (adev,AMDGPU_RAS_BLOCK__GFX ); +if (!amdgpu_persistent_edc_harvesting_supported (adev)) { + r =amdgpu_ras_reset_error_status (adev,AMDGPU_RAS_BLOCK__GFX ); +if (r) +return r; + } r =amdgpu_ras_block_late_init (adev, ras_block);if (r)
@@ -961,7 +964,10 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_pr_err ("critical bug! too many kiq readers\n" ); goto failed_unlock; } -amdgpu_ring_alloc (ring,32 ); + r =amdgpu_ring_alloc (ring,32 ); +if (r) + goto failed_unlock; +amdgpu_ring_emit_rreg (ring, reg, reg_val_offs); r =amdgpu_fence_emit_polling (ring, &seq,MAX_KIQ_REG_WAIT );if (r)
@@ -1027,7 +1033,10 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint3 }spin_lock_irqsave (&kiq->ring_lock, flags); -amdgpu_ring_alloc (ring,32 ); + r =amdgpu_ring_alloc (ring,32 ); +if (r) + goto failed_unlock; +amdgpu_ring_emit_wreg (ring, reg, v); r =amdgpu_fence_emit_polling (ring, &seq,MAX_KIQ_REG_WAIT );if (r)
@@ -1063,6 +1072,7 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint3 failed_undo:amdgpu_ring_undo (ring); +failed_unlock:spin_unlock_irqrestore (&kiq->ring_lock, flags); failed_kiq_write:dev_err (adev->dev,"failed to write reg:%x\n" , reg);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 227/482 drm/amdgpu: fix unchecked return value warning for amdgpu_atombios
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit 92549780e32718d64a6d08bbbb3c6fffecb541c7 ]
This resolves the unchecded return value warning reported by Coverity.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 35 ++++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +21 -14
@@ -1018,8 +1018,9 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,if (clock_type ==COMPUTE_ENGINE_PLL_PARAM ) { args.v3.ulClockParams =cpu_to_le32 ((clock_type <<24 ) | clock); -amdgpu_atom_execute_table (adev->mode_info.atom_context, index, (uint32_t *)&args, -sizeof (args)); +if (amdgpu_atom_execute_table (adev->mode_info.atom_context, + index, (uint32_t *)&args,sizeof (args))) +return -EINVAL ; dividers->post_div = args.v3.ucPostDiv; dividers->enable_post_div = (args.v3.ucCntlFlag &
@@ -1039,8 +1040,9 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,if (strobe_mode) args.v5.ucInputFlag =ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN ; -amdgpu_atom_execute_table (adev->mode_info.atom_context, index, (uint32_t *)&args, -sizeof (args)); +if (amdgpu_atom_execute_table (adev->mode_info.atom_context, + index, (uint32_t *)&args,sizeof (args))) +return -EINVAL ; dividers->post_div = args.v5.ucPostDiv; dividers->enable_post_div = (args.v5.ucCntlFlag &
@@ -1058,8 +1060,9 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,/* fusion */ args.v4.ulClock =cpu_to_le32 (clock);/* 10 khz */ -amdgpu_atom_execute_table (adev->mode_info.atom_context, index, (uint32_t *)&args, -sizeof (args)); +if (amdgpu_atom_execute_table (adev->mode_info.atom_context, + index, (uint32_t *)&args,sizeof (args))) +return -EINVAL ; dividers->post_divider = dividers->post_div = args.v4.ucPostDiv; dividers->real_clock =le32_to_cpu (args.v4.ulClock);
@@ -1070,8 +1073,9 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev, args.v6_in.ulClock.ulComputeClockFlag = clock_type; args.v6_in.ulClock.ulClockFreq =cpu_to_le32 (clock);/* 10 khz */ -amdgpu_atom_execute_table (adev->mode_info.atom_context, index, (uint32_t *)&args, -sizeof (args)); +if (amdgpu_atom_execute_table (adev->mode_info.atom_context, + index, (uint32_t *)&args,sizeof (args))) +return -EINVAL ; dividers->whole_fb_div =le16_to_cpu (args.v6_out.ulFbDiv.usFbDiv); dividers->frac_fb_div =le16_to_cpu (args.v6_out.ulFbDiv.usFbDivFrac);
@@ -1113,8 +1117,9 @@ int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,if (strobe_mode) args.ucInputFlag |=MPLL_INPUT_FLAG_STROBE_MODE_EN ; -amdgpu_atom_execute_table (adev->mode_info.atom_context, index, (uint32_t *)&args, -sizeof (args)); +if (amdgpu_atom_execute_table (adev->mode_info.atom_context, + index, (uint32_t *)&args,sizeof (args))) +return -EINVAL ; mpll_param->clkfrac =le16_to_cpu (args.ulFbDiv.usFbDivFrac); mpll_param->clkf =le16_to_cpu (args.ulFbDiv.usFbDiv);
@@ -1211,8 +1216,9 @@ int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type, args.v2.ucVoltageMode =0 ; args.v2.usVoltageLevel =0 ; -amdgpu_atom_execute_table (adev->mode_info.atom_context, index, (uint32_t *)&args, -sizeof (args)); +if (amdgpu_atom_execute_table (adev->mode_info.atom_context, + index, (uint32_t *)&args,sizeof (args))) +return -EINVAL ; *voltage =le16_to_cpu (args.v2.usVoltageLevel);break ;
@@ -1221,8 +1227,9 @@ int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type, args.v3.ucVoltageMode =ATOM_GET_VOLTAGE_LEVEL ; args.v3.usVoltageLevel =cpu_to_le16 (voltage_id); -amdgpu_atom_execute_table (adev->mode_info.atom_context, index, (uint32_t *)&args, -sizeof (args)); +if (amdgpu_atom_execute_table (adev->mode_info.atom_context, + index, (uint32_t *)&args,sizeof (args))) +return -EINVAL ; *voltage =le16_to_cpu (args.v3.usVoltageLevel);break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 228/482 perf: Fix event_function_call() locking
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 558abc7e3f895049faa46b08656be4c60dc6e9fd ]
All the event_function/@func call context already uses perf_ctx_lock() except for the !ctx->is_active case. Make it all consistent.
--- kernel/events/core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
kernel/events/core.c +5 -4
@@ -263,6 +263,7 @@ static int event_function(void *info)static void event_function_call (struct perf_event *event,event_f func,void *data) {struct perf_event_context *ctx = event->ctx; +struct perf_cpu_context *cpuctx =this_cpu_ptr (&perf_cpu_context);struct task_struct *task =READ_ONCE (ctx->task);/* verified in event_function */ struct event_function_struct efs = { .event = event,
@@ -291,22 +292,22 @@ static void event_function_call(struct perf_event *event, event_f func, void *daif (!task_function_call (task, event_function, &efs))return ; -raw_spin_lock_irq (&ctx->lock); +perf_ctx_lock (cpuctx, ctx);/* * Reload the task pointer, it might have been changed by * a concurrent perf_event_context_sched_out(). */ task = ctx->task;if (task ==TASK_TOMBSTONE ) { -raw_spin_unlock_irq (&ctx->lock); +perf_ctx_unlock (cpuctx, ctx);return ; }if (ctx->is_active) { -raw_spin_unlock_irq (&ctx->lock); +perf_ctx_unlock (cpuctx, ctx); goto again; }func (event,NULL , ctx, data); -raw_spin_unlock_irq (&ctx->lock); +perf_ctx_unlock (cpuctx, ctx); }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 229/482 scsi: NCR5380: Initialize buffer for MSG IN and STATUS transfers
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Thain <[email protected]>
[ Upstream commit 1c71065df2df693d208dd32758171c1dece66341 ]
Following an incomplete transfer in MSG IN phase, the driver would not notice the problem and would make use of invalid data. Initialize 'tmp' appropriately and bail out if no message was received. For STATUS phase, preserve the existing status code unless a new value was transferred.
--- drivers/scsi/NCR5380.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/scsi/NCR5380.c +4 -0
@@ -1807,8 +1807,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)return ;case PHASE_MSGIN : len =1 ; + tmp =0xff ; data = &tmp;NCR5380_transfer_pio (instance, &phase, &len, &data,0 ); +if (tmp ==0xff ) +break ; ncmd->message = tmp;switch (tmp) {
@@ -1996,6 +1999,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)break ;case PHASE_STATIN : len =1 ; + tmp = ncmd->status; data = &tmp;NCR5380_transfer_pio (instance, &phase, &len, &data,0 ); ncmd->status = tmp;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 230/482 drm/radeon/r100: Handle unknown family in r100_cp_init_microcode()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit c6dbab46324b1742b50dc2fb5c1fee2c28129439 ]
With -Werror:
In function ‘r100_cp_init_microcode’,
inlined from ‘r100_cp_init’ at drivers/gpu/drm/radeon/r100.c:1136:7:
include/linux/printk.h:465:44: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
465 | #define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__)
| ^
include/linux/printk.h:437:17: note: in definition of macro ‘printk_index_wrap’
437 | _p_func(_fmt, ##__VA_ARGS__); \
| ^~~~~~~
include/linux/printk.h:508:9: note: in expansion of macro ‘printk’
508 | printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~
drivers/gpu/drm/radeon/r100.c:1062:17: note: in expansion of macro ‘pr_err’
1062 | pr_err("radeon_cp: Failed to load firmware \"%s\"\n", fw_name);
| ^~~~~~Fix this by converting the if/else if/... construct into a proper switch() statement with a default to handle the error case.
As a bonus, the generated code is ca. 100 bytes smaller (with gcc 11.4.0 targeting arm32).
--- drivers/gpu/drm/radeon/r100.c | 70 ++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 25 deletions(-)
drivers/gpu/drm/radeon/r100.c +45 -25
@@ -1016,45 +1016,65 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)DRM_DEBUG_KMS ("\n" ); -if ((rdev->family ==CHIP_R100 ) || (rdev->family ==CHIP_RV100 ) || - (rdev->family ==CHIP_RV200 ) || (rdev->family ==CHIP_RS100 ) || - (rdev->family ==CHIP_RS200 )) { +switch (rdev->family) { +case CHIP_R100 : +case CHIP_RV100 : +case CHIP_RV200 : +case CHIP_RS100 : +case CHIP_RS200 :DRM_INFO ("Loading R100 Microcode\n" ); fw_name =FIRMWARE_R100 ; - }else if ((rdev->family ==CHIP_R200 ) || - (rdev->family ==CHIP_RV250 ) || - (rdev->family ==CHIP_RV280 ) || - (rdev->family ==CHIP_RS300 )) { +break ; + +case CHIP_R200 : +case CHIP_RV250 : +case CHIP_RV280 : +case CHIP_RS300 :DRM_INFO ("Loading R200 Microcode\n" ); fw_name =FIRMWARE_R200 ; - }else if ((rdev->family ==CHIP_R300 ) || - (rdev->family ==CHIP_R350 ) || - (rdev->family ==CHIP_RV350 ) || - (rdev->family ==CHIP_RV380 ) || - (rdev->family ==CHIP_RS400 ) || - (rdev->family ==CHIP_RS480 )) { +break ; + +case CHIP_R300 : +case CHIP_R350 : +case CHIP_RV350 : +case CHIP_RV380 : +case CHIP_RS400 : +case CHIP_RS480 :DRM_INFO ("Loading R300 Microcode\n" ); fw_name =FIRMWARE_R300 ; - }else if ((rdev->family ==CHIP_R420 ) || - (rdev->family ==CHIP_R423 ) || - (rdev->family ==CHIP_RV410 )) { +break ; + +case CHIP_R420 : +case CHIP_R423 : +case CHIP_RV410 :DRM_INFO ("Loading R400 Microcode\n" ); fw_name =FIRMWARE_R420 ; - }else if ((rdev->family ==CHIP_RS690 ) || - (rdev->family ==CHIP_RS740 )) { +break ; + +case CHIP_RS690 : +case CHIP_RS740 :DRM_INFO ("Loading RS690/RS740 Microcode\n" ); fw_name =FIRMWARE_RS690 ; - }else if (rdev->family ==CHIP_RS600 ) { +break ; + +case CHIP_RS600 :DRM_INFO ("Loading RS600 Microcode\n" ); fw_name =FIRMWARE_RS600 ; - }else if ((rdev->family ==CHIP_RV515 ) || - (rdev->family ==CHIP_R520 ) || - (rdev->family ==CHIP_RV530 ) || - (rdev->family ==CHIP_R580 ) || - (rdev->family ==CHIP_RV560 ) || - (rdev->family ==CHIP_RV570 )) { +break ; + +case CHIP_RV515 : +case CHIP_R520 : +case CHIP_RV530 : +case CHIP_R580 : +case CHIP_RV560 : +case CHIP_RV570 :DRM_INFO ("Loading R500 Microcode\n" ); fw_name =FIRMWARE_R520 ; +break ; + +default : +DRM_ERROR ("Unsupported Radeon family %u\n" , rdev->family); +return -EINVAL ; } err =request_firmware (&rdev->me_fw, fw_name, rdev->dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 231/482 drm/amdgpu: Block MMR_READ IOCTL in reset
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Skvortsov <[email protected]>
[ Upstream commit 9e823f307074c0f82b5f6044943b0086e3079bed ]
Register access from userspace should be blocked until reset is complete.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 43 ++++++++++++++++++------- 1 file changed, 31 insertions(+), 12 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +31 -12
@@ -43,6 +43,7 @@#include "amdgpu_gem.h" #include "amdgpu_display.h" #include "amdgpu_ras.h" +#include "amdgpu_reset.h" #include "amd_pcie.h" void amdgpu_unregister_gpu_instance (struct amdgpu_device *adev)
@@ -778,6 +779,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ? -EFAULT :0 ; }case AMDGPU_INFO_READ_MMR_REG : { +int ret =0 ;unsigned int n, alloc_size;uint32_t *regs; unsigned int se_num = (info->read_mmr_reg.instance >>
@@ -787,24 +789,37 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) AMDGPU_INFO_MMR_SH_INDEX_SHIFT) &AMDGPU_INFO_MMR_SH_INDEX_MASK ; +if (!down_read_trylock (&adev->reset_domain->sem)) +return -ENOENT ; +/* set full masks if the userspace set all bits * in the bitfields */ -if (se_num ==AMDGPU_INFO_MMR_SE_INDEX_MASK ) +if (se_num ==AMDGPU_INFO_MMR_SE_INDEX_MASK ) { se_num =0xffffffff ; -else if (se_num >=AMDGPU_GFX_MAX_SE ) -return -EINVAL ; -if (sh_num ==AMDGPU_INFO_MMR_SH_INDEX_MASK ) + }else if (se_num >=AMDGPU_GFX_MAX_SE ) { + ret = -EINVAL ; + goto out; + } + +if (sh_num ==AMDGPU_INFO_MMR_SH_INDEX_MASK ) { sh_num =0xffffffff ; -else if (sh_num >=AMDGPU_GFX_MAX_SH_PER_SE ) -return -EINVAL ; + }else if (sh_num >=AMDGPU_GFX_MAX_SH_PER_SE ) { + ret = -EINVAL ; + goto out; + } -if (info->read_mmr_reg.count >128 ) -return -EINVAL ; +if (info->read_mmr_reg.count >128 ) { + ret = -EINVAL ; + goto out; + } regs =kmalloc_array (info->read_mmr_reg.count,sizeof (*regs),GFP_KERNEL ); -if (!regs) -return -ENOMEM ; +if (!regs) { + ret = -ENOMEM ; + goto out; + } + alloc_size = info->read_mmr_reg.count *sizeof (*regs);amdgpu_gfx_off_ctrl (adev, false);
@@ -816,13 +831,17 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) info->read_mmr_reg.dword_offset + i);kfree (regs);amdgpu_gfx_off_ctrl (adev, true); -return -EFAULT ; + ret = -EFAULT ; + goto out; } }amdgpu_gfx_off_ctrl (adev, true); n =copy_to_user (out, regs,min (size, alloc_size));kfree (regs); -return n ? -EFAULT :0 ; + ret = (n ? -EFAULT :0 ); +out: +up_read (&adev->reset_domain->sem); +return ret; }case AMDGPU_INFO_DEV_INFO : {struct drm_amdgpu_info_device *dev_info;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 232/482 drm/amdgpu/gfx9: use rlc safe mode for soft recovery
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit 3ec2ad7c34c412bd9264cd1ff235d0812be90e82 ]
Protect the MMIO access with safe mode.
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +2 -0
@@ -5701,7 +5701,9 @@ static void gfx_v9_0_ring_soft_recovery(struct amdgpu_ring *ring, unsigned vmid) value =REG_SET_FIELD (value,SQ_CMD ,MODE ,0x01 ); value =REG_SET_FIELD (value,SQ_CMD ,CHECK_VMID ,1 ); value =REG_SET_FIELD (value,SQ_CMD ,VM_ID , vmid); +amdgpu_gfx_rlc_enter_safe_mode (adev,0 );WREG32_SOC15 (GC ,0 , mmSQ_CMD, value); +amdgpu_gfx_rlc_exit_safe_mode (adev,0 ); } static void gfx_v9_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 233/482 drm/amdgpu/gfx11: enter safe mode before touching CP_INT_CNTL
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit b5be054c585110b2c5c1b180136800e8c41c7bb4 ]
Need to enter safe mode before touching GC MMIO.
--- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +2 -2
@@ -4497,6 +4497,8 @@ static int gfx_v11_0_soft_reset(void *handle)int r, i, j, k;struct amdgpu_device *adev = (struct amdgpu_device *)handle; +gfx_v11_0_set_safe_mode (adev,0 ); + tmp =RREG32_SOC15 (GC ,0 , regCP_INT_CNTL); tmp =REG_SET_FIELD (tmp,CP_INT_CNTL ,CMP_BUSY_INT_ENABLE ,0 ); tmp =REG_SET_FIELD (tmp,CP_INT_CNTL ,CNTX_BUSY_INT_ENABLE ,0 );
@@ -4504,8 +4506,6 @@ static int gfx_v11_0_soft_reset(void *handle) tmp =REG_SET_FIELD (tmp,CP_INT_CNTL ,GFX_IDLE_INT_ENABLE ,0 );WREG32_SOC15 (GC ,0 , regCP_INT_CNTL, tmp); -gfx_v11_0_set_safe_mode (adev,0 ); -mutex_lock (&adev->srbm_mutex);for (i =0 ; i < adev->gfx.mec.num_mec; ++i) {for (j =0 ; j < adev->gfx.mec.num_queue_per_pipe; j++) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 234/482 drm/xe: Use topology to determine page fault queue size
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stuart Summers <[email protected]>
[ Upstream commit 3338e4f90c143cf32f77d64f464cb7f2c2d24700 ]
Currently the page fault queue size is hard coded. However the hardware supports faulting for each EU and each CS. For some applications running on hardware with a large number of EUs and CSs, this can result in an overflow of the page fault queue.
Add a small calculation to determine the page fault queue size based on the number of EUs and CSs in the platform as detmined by fuses.
--- drivers/gpu/drm/xe/xe_gt_pagefault.c | 54 +++++++++++++++++++++------- drivers/gpu/drm/xe/xe_gt_types.h | 9 +++-- 2 files changed, 49 insertions(+), 14 deletions(-)
drivers/gpu/drm/xe/xe_gt_pagefault.c +42 -12
@@ -307,7 +307,7 @@ static bool get_pagefault(struct pf_queue *pf_queue, struct pagefault *pf)PFD_VIRTUAL_ADDR_LO_SHIFT ; pf_queue->tail = (pf_queue->tail +PF_MSG_LEN_DW ) % -PF_QUEUE_NUM_DW ; + pf_queue->num_dw; ret = true; }spin_unlock_irq (&pf_queue->lock);
@@ -319,7 +319,8 @@ static bool pf_queue_full(struct pf_queue *pf_queue) {lockdep_assert_held (&pf_queue->lock); -return CIRC_SPACE (pf_queue->head, pf_queue->tail,PF_QUEUE_NUM_DW ) <= +return CIRC_SPACE (pf_queue->head, pf_queue->tail, + pf_queue->num_dw) <=PF_MSG_LEN_DW ; }
@@ -332,22 +333,23 @@ int xe_guc_pagefault_handler(struct xe_guc *guc, u32 *msg, u32 len)u32 asid;bool full; -/* -* The below logic doesn't work unless PF_QUEUE_NUM_DW % PF_MSG_LEN_DW == 0 -*/ -BUILD_BUG_ON (PF_QUEUE_NUM_DW %PF_MSG_LEN_DW ); -if (unlikely (len !=PF_MSG_LEN_DW ))return -EPROTO ; asid =FIELD_GET (PFD_ASID , msg[1 ]); pf_queue = gt->usm.pf_queue + (asid %NUM_PF_QUEUE ); +/* +* The below logic doesn't work unless PF_QUEUE_NUM_DW % PF_MSG_LEN_DW == 0 +*/ +xe_gt_assert (gt, !(pf_queue->num_dw %PF_MSG_LEN_DW )); +spin_lock_irqsave (&pf_queue->lock, flags); full =pf_queue_full (pf_queue);if (!full) {memcpy (pf_queue->data + pf_queue->head, msg, len *sizeof (u32)); - pf_queue->head = (pf_queue->head + len) %PF_QUEUE_NUM_DW ; + pf_queue->head = (pf_queue->head + len) % + pf_queue->num_dw;queue_work (gt->usm.pf_wq, &pf_queue->worker); }else {drm_warn (&xe->drm,"PF Queue full, shouldn't be possible" );
@@ -406,26 +408,54 @@ static void pagefault_fini(void *arg) {struct xe_gt *gt = arg;struct xe_device *xe =gt_to_xe (gt); +int i;if (!xe->info.has_usm)return ;destroy_workqueue (gt->usm.acc_wq);destroy_workqueue (gt->usm.pf_wq); + +for (i =0 ; i <NUM_PF_QUEUE ; ++i) +kfree (gt->usm.pf_queue[i].data); +} + +static int xe_alloc_pf_queue (struct xe_gt *gt,struct pf_queue *pf_queue) +{ +xe_dss_mask_t all_dss; +int num_dss, num_eus; + +bitmap_or (all_dss, gt->fuse_topo.g_dss_mask, gt->fuse_topo.c_dss_mask, +XE_MAX_DSS_FUSE_BITS ); + + num_dss =bitmap_weight (all_dss,XE_MAX_DSS_FUSE_BITS ); + num_eus =bitmap_weight (gt->fuse_topo.eu_mask_per_dss, +XE_MAX_EU_FUSE_BITS ) * num_dss; + +/* user can issue separate page faults per EU and per CS */ + pf_queue->num_dw = + (num_eus +XE_NUM_HW_ENGINES ) *PF_MSG_LEN_DW ; + + pf_queue->gt = gt; + pf_queue->data =kzalloc (pf_queue->num_dw,GFP_KERNEL ); +spin_lock_init (&pf_queue->lock); +INIT_WORK (&pf_queue->worker, pf_queue_work_func); + +return 0 ; }int xe_gt_pagefault_init (struct xe_gt *gt) {struct xe_device *xe =gt_to_xe (gt); -int i; +int i, ret =0 ;if (!xe->info.has_usm)return 0 ;for (i =0 ; i <NUM_PF_QUEUE ; ++i) { - gt->usm.pf_queue[i].gt = gt; -spin_lock_init (>->usm.pf_queue[i].lock); -INIT_WORK (>->usm.pf_queue[i].worker, pf_queue_work_func); + ret =xe_alloc_pf_queue (gt, >->usm.pf_queue[i]); +if (ret) +return ret; }for (i =0 ; i <NUM_ACC_QUEUE ; ++i) { gt->usm.acc_queue[i].gt = gt;
drivers/gpu/drm/xe/xe_gt_types.h +7 -2
@@ -229,9 +229,14 @@ struct xe_gt {struct pf_queue {/** @usm.pf_queue.gt: back pointer to GT */ struct xe_gt *gt; -#define PF_QUEUE_NUM_DW 128/** @usm.pf_queue.data: data in the page fault queue */ -u32 data[PF_QUEUE_NUM_DW ]; +u32 *data; +/** +* @usm.pf_queue.num_dw: number of DWORDS in the page +* fault queue. Dynamically calculated based on the number +* of compute resources available. +*/ +u32 num_dw;/** * @usm.pf_queue.tail: tail pointer in DWs for page fault queue, * moved by worker which processes faults (consumer).
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 235/482 drm/amd/pm: ensure the fw_info is not null before using it
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit 186fb12e7a7b038c2710ceb2fb74068f1b5d55a4 ]
This resolves the dereference null return value warning reported by Coverity.
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c +2 -0
@@ -1185,6 +1185,8 @@ static int init_overdrive_limits(struct pp_hwmgr *hwmgr, fw_info =smu_atom_get_data_table (hwmgr->adev,GetIndexIntoMasterTable (DATA , FirmwareInfo), &size, &frev, &crev); +PP_ASSERT_WITH_CODE (fw_info !=NULL , +"Missing firmware info!" , return -EINVAL );if ((fw_info->ucTableFormatRevision ==1 ) && (le16_to_cpu (fw_info->usStructureSize) >=sizeof (ATOM_FIRMWARE_INFO_V1_4 )))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 236/482 drm/amdkfd: Check int source id for utcl2 poison event
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hawking Zhang <[email protected]>
[ Upstream commit db6341a9168d2a24ded526277eeab29724d76e9d ]
Traditional utcl2 fault_status polling does not work in SRIOV environment. The polling of fault status register from guest side will be dropped by hardware.
Driver should switch to check utcl2 interrupt source id to identify utcl2 poison event. It is set to 1 when poisoned data interrupts are signaled.
v2: drop the unused local variable (Tao)
--- .../gpu/drm/amd/amdkfd/kfd_int_process_v9.c | 18 +----------------- drivers/gpu/drm/amd/amdkfd/soc15_int.h | 1 + 2 files changed, 2 insertions(+), 17 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +1 -17
@@ -414,25 +414,9 @@ static void event_interrupt_wq_v9(struct kfd_node *dev, client_id == SOC15_IH_CLIENTID_UTCL2) {struct kfd_vm_fault_info info = {0 };uint16_t ring_id =SOC15_RING_ID_FROM_IH_ENTRY (ih_ring_entry); -uint32_t node_id =SOC15_NODEID_FROM_IH_ENTRY (ih_ring_entry); -uint32_t vmid_type =SOC15_VMID_TYPE_FROM_IH_ENTRY (ih_ring_entry); -int hub_inst =0 ;struct kfd_hsa_memory_exception_data exception_data; -/* gfxhub */ -if (!vmid_type && dev->adev->gfx.funcs->ih_node_to_logical_xcc) { - hub_inst = dev->adev->gfx.funcs->ih_node_to_logical_xcc (dev->adev, - node_id); -if (hub_inst <0 ) - hub_inst =0 ; - } - -/* mmhub */ -if (vmid_type && client_id ==SOC15_IH_CLIENTID_VMC ) - hub_inst = node_id /4 ; - -if (amdgpu_amdkfd_ras_query_utcl2_poison_status (dev->adev, - hub_inst, vmid_type)) { +if (source_id ==SOC15_INTSRC_VMC_UTCL2_POISON ) {event_interrupt_poison_consumption_v9 (dev, pasid, client_id);return ; }
drivers/gpu/drm/amd/amdkfd/soc15_int.h +1 -0
@@ -29,6 +29,7 @@#define SOC15_INTSRC_CP_BAD_OPCODE 183#define SOC15_INTSRC_SQ_INTERRUPT_MSG 239#define SOC15_INTSRC_VMC_FAULT 0 +#define SOC15_INTSRC_VMC_UTCL2_POISON 1#define SOC15_INTSRC_SDMA_TRAP 224#define SOC15_INTSRC_SDMA_ECC 220#define SOC21_INTSRC_SDMA_TRAP 49
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 237/482 drm/xe: Drop warn on xe_guc_pc_gucrc_disable in guc pc fini
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Brost <[email protected]>
[ Upstream commit a323782567812ee925e9b7926445532c7afe331b ]
Not a big deal if CT is down as driver is unloading, no need to warn.
--- drivers/gpu/drm/xe/xe_guc_pc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/xe/xe_guc_pc.c +1 -1
@@ -897,7 +897,7 @@ static void xe_guc_pc_fini(struct drm_device *drm, void *arg)struct xe_guc_pc *pc = arg;XE_WARN_ON (xe_force_wake_get (gt_to_fw (pc_to_gt (pc)),XE_FORCEWAKE_ALL )); -XE_WARN_ON (xe_guc_pc_gucrc_disable (pc)); +xe_guc_pc_gucrc_disable (pc);XE_WARN_ON (xe_guc_pc_stop (pc));xe_force_wake_put (gt_to_fw (pc_to_gt (pc)),XE_FORCEWAKE_ALL ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 238/482 of/irq: Refer to actual buffer size in of_irq_parse_one()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit 39ab331ab5d377a18fbf5a0e0b228205edfcc7f4 ]
Replace two open-coded calculations of the buffer size by invocations of sizeof() on the buffer itself, to make sure the code will always use the actual buffer size.
--- drivers/of/irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/of/irq.c +2 -2
@@ -357,8 +357,8 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar addr =of_get_property (device,"reg" , &addr_len);/* Prevent out-of-bounds read in case of longer interrupt parent address size */ -if (addr_len > (3 *sizeof (__be32))) - addr_len =3 *sizeof (__be32); +if (addr_len >sizeof (addr_buf)) + addr_len =sizeof (addr_buf);if (addr)memcpy (addr_buf, addr, addr_len);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 239/482 powerpc/pseries: Use correct data types from pseries_hp_errorlog struct
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haren Myneni <[email protected]>
[ Upstream commit b76e0d4215b6b622127ebcceaa7f603313ceaec4 ]
_be32 type is defined for some elements in pseries_hp_errorlog struct but also used them u32 after be32_to_cpu() conversion.
Example: In handle_dlpar_errorlog() hp_elog->_drc_u.drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
And later assigned to u32 typedlpar_cpu() - u32 drc_index = hp_elog->_drc_u.drc_index;
This incorrect usage is giving the following warnings and the patch resolve these warnings with the correct assignment.
arch/powerpc/platforms/pseries/dlpar.c:398:53: sparse: sparse:
incorrect type in argument 1 (different base types) @@ expected unsigned int [usertype] drc_index @@
got restricted __be32 [usertype] drc_index @@
...arch/powerpc/platforms/pseries/dlpar.c:418:43: sparse: sparse:
incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] drc_count @@ got unsigned int [usertype] @@
v3:
- Fix warnings from using incorrect data types in pseries_hp_errorlog struct
v2:
- Remove pr_info() and TODO comments
- Update more information in the commit logs
--- arch/powerpc/platforms/pseries/dlpar.c | 17 ----------------- arch/powerpc/platforms/pseries/hotplug-cpu.c | 2 +- arch/powerpc/platforms/pseries/hotplug-memory.c | 16 ++++++++-------- arch/powerpc/platforms/pseries/pmem.c | 2 +- 4 files changed, 10 insertions(+), 27 deletions(-)
arch/powerpc/platforms/pseries/dlpar.c +0 -17
@@ -334,23 +334,6 @@ int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog) {int rc; -/* pseries error logs are in BE format, convert to cpu type */ -switch (hp_elog->id_type) { -case PSERIES_HP_ELOG_ID_DRC_COUNT : - hp_elog->_drc_u.drc_count = -be32_to_cpu (hp_elog->_drc_u.drc_count); -break ; -case PSERIES_HP_ELOG_ID_DRC_INDEX : - hp_elog->_drc_u.drc_index = -be32_to_cpu (hp_elog->_drc_u.drc_index); -break ; -case PSERIES_HP_ELOG_ID_DRC_IC : - hp_elog->_drc_u.ic.count = -be32_to_cpu (hp_elog->_drc_u.ic.count); - hp_elog->_drc_u.ic.index = -be32_to_cpu (hp_elog->_drc_u.ic.index); - } -switch (hp_elog->resource) {case PSERIES_HP_ELOG_RESOURCE_MEM : rc =dlpar_memory (hp_elog);
arch/powerpc/platforms/pseries/hotplug-cpu.c +1 -1
@@ -757,7 +757,7 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)u32 drc_index;int rc; - drc_index = hp_elog->_drc_u.drc_index; + drc_index =be32_to_cpu (hp_elog->_drc_u.drc_index);lock_device_hotplug ();
arch/powerpc/platforms/pseries/hotplug-memory.c +8 -8
@@ -817,16 +817,16 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)case PSERIES_HP_ELOG_ACTION_ADD :switch (hp_elog->id_type) {case PSERIES_HP_ELOG_ID_DRC_COUNT : - count = hp_elog->_drc_u.drc_count; + count =be32_to_cpu (hp_elog->_drc_u.drc_count); rc =dlpar_memory_add_by_count (count);break ;case PSERIES_HP_ELOG_ID_DRC_INDEX : - drc_index = hp_elog->_drc_u.drc_index; + drc_index =be32_to_cpu (hp_elog->_drc_u.drc_index); rc =dlpar_memory_add_by_index (drc_index);break ;case PSERIES_HP_ELOG_ID_DRC_IC : - count = hp_elog->_drc_u.ic.count; - drc_index = hp_elog->_drc_u.ic.index; + count =be32_to_cpu (hp_elog->_drc_u.ic.count); + drc_index =be32_to_cpu (hp_elog->_drc_u.ic.index); rc =dlpar_memory_add_by_ic (count, drc_index);break ;default :
@@ -838,16 +838,16 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)case PSERIES_HP_ELOG_ACTION_REMOVE :switch (hp_elog->id_type) {case PSERIES_HP_ELOG_ID_DRC_COUNT : - count = hp_elog->_drc_u.drc_count; + count =be32_to_cpu (hp_elog->_drc_u.drc_count); rc =dlpar_memory_remove_by_count (count);break ;case PSERIES_HP_ELOG_ID_DRC_INDEX : - drc_index = hp_elog->_drc_u.drc_index; + drc_index =be32_to_cpu (hp_elog->_drc_u.drc_index); rc =dlpar_memory_remove_by_index (drc_index);break ;case PSERIES_HP_ELOG_ID_DRC_IC : - count = hp_elog->_drc_u.ic.count; - drc_index = hp_elog->_drc_u.ic.index; + count =be32_to_cpu (hp_elog->_drc_u.ic.count); + drc_index =be32_to_cpu (hp_elog->_drc_u.ic.index); rc =dlpar_memory_remove_by_ic (count, drc_index);break ;default :
arch/powerpc/platforms/pseries/pmem.c +1 -1
@@ -121,7 +121,7 @@ int dlpar_hp_pmem(struct pseries_hp_errorlog *hp_elog)return -EINVAL ; } - drc_index = hp_elog->_drc_u.drc_index; + drc_index =be32_to_cpu (hp_elog->_drc_u.drc_index);lock_device_hotplug ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 240/482 ovl: fsync after metadata copy-up
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
[ Upstream commit 7d6899fb69d25e1bc6f4700b7c1d92e6b608593d ]
For upper filesystems which do not use strict ordering of persisting metadata changes (e.g. ubifs), when overlayfs file is modified for the first time, copy up will create a copy of the lower file and its parent directories in the upper layer. Permission lost of the new upper parent directory was observed during power-cut stress test.
Fix by moving the fsync call to after metadata copy to make sure that the metadata copied up directory and files persists to disk before renaming from tmp to final destination.
With metacopy enabled, this change will hurt performance of workloads such as chown -R, so we keep the legacy behavior of fsync only on copyup of data.
--- fs/overlayfs/copy_up.c | 43 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)
fs/overlayfs/copy_up.c +39 -4
@@ -243,8 +243,24 @@ static int ovl_verify_area(loff_t pos, loff_t pos2, loff_t len, loff_t totlen)return 0 ; } +static int ovl_sync_file (struct path *path) +{ +struct file *new_file; +int err; + + new_file =ovl_path_open (path,O_LARGEFILE |O_RDONLY ); +if (IS_ERR (new_file)) +return PTR_ERR (new_file); + + err =vfs_fsync (new_file,0 ); +fput (new_file); + +return err; +} +static int ovl_copy_up_file (struct ovl_fs *ofs,struct dentry *dentry, -struct file *new_file,loff_t len) +struct file *new_file,loff_t len, +bool datasync) {struct path datapath;struct file *old_file;
@@ -342,7 +358,8 @@ static int ovl_copy_up_file(struct ovl_fs *ofs, struct dentry *dentry, len -= bytes; } -if (!error &&ovl_should_sync (ofs)) +/* call fsync once, either now or later along with metadata */ +if (!error &&ovl_should_sync (ofs) && datasync) error =vfs_fsync (new_file,0 ); out_fput:fput (old_file);
@@ -574,6 +591,7 @@ struct ovl_copy_up_ctx {bool indexed;bool metacopy;bool metacopy_digest; +bool metadata_fsync; };static int ovl_link_up (struct ovl_copy_up_ctx *c)
@@ -634,7 +652,8 @@ static int ovl_copy_up_data(struct ovl_copy_up_ctx *c, const struct path *temp)if (IS_ERR (new_file))return PTR_ERR (new_file); - err =ovl_copy_up_file (ofs, c->dentry, new_file, c->stat.size); + err =ovl_copy_up_file (ofs, c->dentry, new_file, c->stat.size, + !c->metadata_fsync);fput (new_file);return err;
@@ -701,6 +720,10 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp) err =ovl_set_attr (ofs, temp, &c->stat);inode_unlock (temp->d_inode); +/* fsync metadata before moving it into upper dir */ +if (!err &&ovl_should_sync (ofs) && c->metadata_fsync) + err =ovl_sync_file (&upperpath); +return err; }
@@ -860,7 +883,8 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c) temp = tmpfile->f_path.dentry;if (!c->metacopy && c->stat.size) { - err =ovl_copy_up_file (ofs, c->dentry, tmpfile, c->stat.size); + err =ovl_copy_up_file (ofs, c->dentry, tmpfile, c->stat.size, + !c->metadata_fsync);if (err) goto out_fput; }
@@ -1135,6 +1159,17 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, !kgid_has_mapping(current_user_ns(), ctx.stat.gid))return -EOVERFLOW ; +/* +* With metacopy disabled, we fsync after final metadata copyup, for +* both regular files and directories to get atomic copyup semantics +* on filesystems that do not use strict metadata ordering (e.g. ubifs). +* +* With metacopy enabled we want to avoid fsync on all meta copyup +* that will hurt performance of workloads such as chown -R, so we +* only fsync on data copyup as legacy behavior. +*/ + ctx.metadata_fsync = !OVL_FS (dentry->d_sb)->config.metacopy && + (S_ISREG (ctx.stat.mode) ||S_ISDIR (ctx.stat.mode)); ctx.metacopy =ovl_need_meta_copy_up (dentry, ctx.stat.mode, flags);if (parent) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 241/482 drm/amdgpu/gfx11: use rlc safe mode for soft recovery
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit 3f2d35c325534c1b7ac5072173f0dc7ca969dec2 ]
Protect the MMIO access with safe mode.
--- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +2 -0
@@ -5792,7 +5792,9 @@ static void gfx_v11_0_ring_soft_recovery(struct amdgpu_ring *ring, value =REG_SET_FIELD (value,SQ_CMD ,MODE ,0x01 ); value =REG_SET_FIELD (value,SQ_CMD ,CHECK_VMID ,1 ); value =REG_SET_FIELD (value,SQ_CMD ,VM_ID , vmid); +amdgpu_gfx_rlc_enter_safe_mode (adev,0 );WREG32_SOC15 (GC ,0 , regSQ_CMD, value); +amdgpu_gfx_rlc_exit_safe_mode (adev,0 ); } static void
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 242/482 drm/amdgpu/gfx10: use rlc safe mode for soft recovery
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit ead60e9c4e29c8574cae1be4fe3af1d9a978fb0f ]
Protect the MMIO access with safe mode.
--- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +2 -0
@@ -8897,7 +8897,9 @@ static void gfx_v10_0_ring_soft_recovery(struct amdgpu_ring *ring, value =REG_SET_FIELD (value,SQ_CMD ,MODE ,0x01 ); value =REG_SET_FIELD (value,SQ_CMD ,CHECK_VMID ,1 ); value =REG_SET_FIELD (value,SQ_CMD ,VM_ID , vmid); +amdgpu_gfx_rlc_enter_safe_mode (adev,0 );WREG32_SOC15 (GC ,0 , mmSQ_CMD, value); +amdgpu_gfx_rlc_exit_safe_mode (adev,0 ); } static void
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 243/482 platform/x86: lenovo-ymc: Ignore the 0x0 state
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gergo Koteles <[email protected]>
[ Upstream commit d9dca215708d32e7f88ac0591fbb187cbf368adb ]
While booting, Lenovo 14ARB7 reports 'lenovo-ymc: Unknown key 0 pressed' warning. This is caused by lenovo_ymc_probe() calling lenovo_ymc_notify() at probe time to get the initial tablet-mode-switch state and the key-code lenovo_ymc_notify() reads from the firmware is not initialized at probe time yet on the Lenovo 14ARB7.
The hardware/firmware does an ACPI notify on the WMI device itself when it initializes the tablet-mode-switch state later on.
Add 0x0 YMC state to the sparse keymap to silence the warning.
--- drivers/platform/x86/lenovo-ymc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/platform/x86/lenovo-ymc.c +2 -0
@@ -43,6 +43,8 @@ struct lenovo_ymc_private { };static const struct key_entry lenovo_ymc_keymap[] = { +/* Ignore the uninitialized state */ + {KE_IGNORE ,0x00 },/* Laptop */ {KE_SW ,0x01 , { .sw = {SW_TABLET_MODE ,0 } } },/* Tablet */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 244/482 tools/hv: Add memory allocation check in hv_fcopy_start
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Jun <[email protected]>
[ Upstream commit 94e86b174d103d941b4afc4f016af8af9e5352fa ]
Added error handling for memory allocation failures of file_name and path_name.
Message-ID: <[email protected]>
--- tools/hv/hv_fcopy_uio_daemon.c | 7 +++++++ 1 file changed, 7 insertions(+)
tools/hv/hv_fcopy_uio_daemon.c +7 -0
@@ -296,6 +296,13 @@ static int hv_fcopy_start(struct hv_start_fcopy *smsg_in) file_name = (char *)malloc (file_size *sizeof (char )); path_name = (char *)malloc (path_size *sizeof (char )); +if (!file_name || !path_name) { +free (file_name); +free (path_name); +syslog (LOG_ERR ,"Can't allocate memory for file name and/or path name" ); +return HV_E_FAIL ; + } +wcstoutf8 (file_name, (__u16 *)in_file_name, file_size);wcstoutf8 (path_name, (__u16 *)in_path_name, path_size);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 245/482 HID: i2c-hid: ensure various commands do not interfere with each other
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
[ Upstream commit b4ed18a3d56eabd18cfd9841ff05111e3cfbe8f9 ]
i2c-hid uses 2 shared buffers: command and "raw" input buffer for sending requests to peripherals and read data from peripherals when executing variety of commands. Such commands include reading of HID registers, requesting particular power mode, getting and setting reports and so on. Because all such requests use the same 2 buffers they should not execute simultaneously.
Fix this by introducing "cmd_lock" mutex and acquire it whenever we needs to access ihid->cmdbuf or idid->rawbuf.
--- drivers/hid/i2c-hid/i2c-hid-core.c | 42 +++++++++++++++++++----------- 1 file changed, 27 insertions(+), 15 deletions(-)
drivers/hid/i2c-hid/i2c-hid-core.c +27 -15
@@ -105,6 +105,7 @@ struct i2c_hid {wait_queue_head_t wait;/* For waiting the interrupt */ +struct mutex cmd_lock;/* protects cmdbuf and rawbuf */ struct mutex reset_lock;struct i2chid_ops *ops;
@@ -220,6 +221,8 @@ static int i2c_hid_xfer(struct i2c_hid *ihid,static int i2c_hid_read_register (struct i2c_hid *ihid,__le16 reg,void *buf,size_t len) { +guard (mutex)(&ihid->cmd_lock); + *(__le16 *)ihid->cmdbuf = reg;return i2c_hid_xfer (ihid, ihid->cmdbuf,sizeof (__le16), buf, len);
@@ -252,6 +255,8 @@ static int i2c_hid_get_report(struct i2c_hid *ihid,i2c_hid_dbg (ihid,"%s\n" , __func__); +guard (mutex)(&ihid->cmd_lock); +/* Command register goes first */ *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister; length +=sizeof (__le16);
@@ -342,6 +347,8 @@ static int i2c_hid_set_or_send_report(struct i2c_hid *ihid,if (!do_set &&le16_to_cpu (ihid->hdesc.wMaxOutputLength) ==0 )return -ENOSYS ; +guard (mutex)(&ihid->cmd_lock); +if (do_set) {/* Command register goes first */ *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
@@ -384,6 +391,8 @@ static int i2c_hid_set_power_command(struct i2c_hid *ihid, int power_state) {size_t length; +guard (mutex)(&ihid->cmd_lock); +/* SET_POWER uses command register */ *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister; length =sizeof (__le16);
@@ -440,25 +449,27 @@ static int i2c_hid_start_hwreset(struct i2c_hid *ihid)if (ret)return ret; -/* Prepare reset command. Command register goes first. */ - *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister; - length +=sizeof (__le16); -/* Next is RESET command itself */ - length +=i2c_hid_encode_command (ihid->cmdbuf + length, -I2C_HID_OPCODE_RESET ,0 ,0 ); + scoped_guard(mutex, &ihid->cmd_lock) { +/* Prepare reset command. Command register goes first. */ + *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister; + length +=sizeof (__le16); +/* Next is RESET command itself */ + length +=i2c_hid_encode_command (ihid->cmdbuf + length, +I2C_HID_OPCODE_RESET ,0 ,0 ); -set_bit (I2C_HID_RESET_PENDING , &ihid->flags); +set_bit (I2C_HID_RESET_PENDING , &ihid->flags); - ret =i2c_hid_xfer (ihid, ihid->cmdbuf, length,NULL ,0 ); -if (ret) { -dev_err (&ihid->client->dev, -"failed to reset device: %d\n" , ret); - goto err_clear_reset; - } + ret =i2c_hid_xfer (ihid, ihid->cmdbuf, length,NULL ,0 ); +if (ret) { +dev_err (&ihid->client->dev, +"failed to reset device: %d\n" , ret); +break ; + } -return 0 ; +return 0 ; + } -err_clear_reset: +/* Clean up if sending reset command failed */ clear_bit (I2C_HID_RESET_PENDING , &ihid->flags);i2c_hid_set_power (ihid,I2C_HID_PWR_SLEEP );return ret;
@@ -1200,6 +1211,7 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, ihid->is_panel_follower =drm_is_panel_follower (&client->dev);init_waitqueue_head (&ihid->wait); +mutex_init (&ihid->cmd_lock);mutex_init (&ihid->reset_lock);INIT_WORK (&ihid->panel_follower_prepare_work, ihid_core_panel_prepare_work);
Signature · 1 line
2.43.0