Skip to content

Commit 7efd0a7

Browse files
committed
Merge tag 'ata-6.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux
Pull ata fixes from Damien Le Moal: - Add the mask_port_map parameter to the ahci driver. This is a follow-up to the recent snafu with the ASMedia controller and its virtual port hidding port-multiplier devices. As ASMedia confirmed that there is no way to determine if these slow-to-probe virtual ports are actually representing the ports of a port-multiplier devices, this new parameter allow masking ports to significantly speed up probing during system boot, resulting in shorter boot times. - A fix for an incorrect handling of a port unlock in ata_scsi_dev_rescan(). - Allow command duration limits to be detected for ACS-4 devices are there are such devices out in the field. * tag 'ata-6.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux: ata: libata-core: Allow command duration limits detection for ACS-4 drives ata: libata-scsi: Fix ata_scsi_dev_rescan() error path ata: ahci: Add mask_port_map module parameter
2 parents 76b0e9c + c0297e7 commit 7efd0a7

File tree

3 files changed

+91
-5
lines changed

3 files changed

+91
-5
lines changed

drivers/ata/ahci.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,87 @@ static int mobile_lpm_policy = -1;
666666
module_param(mobile_lpm_policy, int, 0644);
667667
MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
668668

669+
static char *ahci_mask_port_map;
670+
module_param_named(mask_port_map, ahci_mask_port_map, charp, 0444);
671+
MODULE_PARM_DESC(mask_port_map,
672+
"32-bits port map masks to ignore controllers ports. "
673+
"Valid values are: "
674+
"\"<mask>\" to apply the same mask to all AHCI controller "
675+
"devices, and \"<pci_dev>=<mask>,<pci_dev>=<mask>,...\" to "
676+
"specify different masks for the controllers specified, "
677+
"where <pci_dev> is the PCI ID of an AHCI controller in the "
678+
"form \"domain:bus:dev.func\"");
679+
680+
static void ahci_apply_port_map_mask(struct device *dev,
681+
struct ahci_host_priv *hpriv, char *mask_s)
682+
{
683+
unsigned int mask;
684+
685+
if (kstrtouint(mask_s, 0, &mask)) {
686+
dev_err(dev, "Invalid port map mask\n");
687+
return;
688+
}
689+
690+
hpriv->mask_port_map = mask;
691+
}
692+
693+
static void ahci_get_port_map_mask(struct device *dev,
694+
struct ahci_host_priv *hpriv)
695+
{
696+
char *param, *end, *str, *mask_s;
697+
char *name;
698+
699+
if (!strlen(ahci_mask_port_map))
700+
return;
701+
702+
str = kstrdup(ahci_mask_port_map, GFP_KERNEL);
703+
if (!str)
704+
return;
705+
706+
/* Handle single mask case */
707+
if (!strchr(str, '=')) {
708+
ahci_apply_port_map_mask(dev, hpriv, str);
709+
goto free;
710+
}
711+
712+
/*
713+
* Mask list case: parse the parameter to apply the mask only if
714+
* the device name matches.
715+
*/
716+
param = str;
717+
end = param + strlen(param);
718+
while (param && param < end && *param) {
719+
name = param;
720+
param = strchr(name, '=');
721+
if (!param)
722+
break;
723+
724+
*param = '\0';
725+
param++;
726+
if (param >= end)
727+
break;
728+
729+
if (strcmp(dev_name(dev), name) != 0) {
730+
param = strchr(param, ',');
731+
if (param)
732+
param++;
733+
continue;
734+
}
735+
736+
mask_s = param;
737+
param = strchr(mask_s, ',');
738+
if (param) {
739+
*param = '\0';
740+
param++;
741+
}
742+
743+
ahci_apply_port_map_mask(dev, hpriv, mask_s);
744+
}
745+
746+
free:
747+
kfree(str);
748+
}
749+
669750
static void ahci_pci_save_initial_config(struct pci_dev *pdev,
670751
struct ahci_host_priv *hpriv)
671752
{
@@ -688,6 +769,10 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
688769
"Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n");
689770
}
690771

772+
/* Handle port map masks passed as module parameter. */
773+
if (ahci_mask_port_map)
774+
ahci_get_port_map_mask(&pdev->dev, hpriv);
775+
691776
ahci_save_initial_config(&pdev->dev, hpriv);
692777
}
693778

drivers/ata/libata-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2539,7 +2539,7 @@ static void ata_dev_config_cdl(struct ata_device *dev)
25392539
bool cdl_enabled;
25402540
u64 val;
25412541

2542-
if (ata_id_major_version(dev->id) < 12)
2542+
if (ata_id_major_version(dev->id) < 11)
25432543
goto not_supported;
25442544

25452545
if (!ata_log_supported(dev, ATA_LOG_IDENTIFY_DEVICE) ||

drivers/ata/libata-scsi.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4745,7 +4745,7 @@ void ata_scsi_dev_rescan(struct work_struct *work)
47454745
* bail out.
47464746
*/
47474747
if (ap->pflags & ATA_PFLAG_SUSPENDED)
4748-
goto unlock;
4748+
goto unlock_ap;
47494749

47504750
if (!sdev)
47514751
continue;
@@ -4758,20 +4758,21 @@ void ata_scsi_dev_rescan(struct work_struct *work)
47584758
if (do_resume) {
47594759
ret = scsi_resume_device(sdev);
47604760
if (ret == -EWOULDBLOCK)
4761-
goto unlock;
4761+
goto unlock_scan;
47624762
dev->flags &= ~ATA_DFLAG_RESUMING;
47634763
}
47644764
ret = scsi_rescan_device(sdev);
47654765
scsi_device_put(sdev);
47664766
spin_lock_irqsave(ap->lock, flags);
47674767

47684768
if (ret)
4769-
goto unlock;
4769+
goto unlock_ap;
47704770
}
47714771
}
47724772

4773-
unlock:
4773+
unlock_ap:
47744774
spin_unlock_irqrestore(ap->lock, flags);
4775+
unlock_scan:
47754776
mutex_unlock(&ap->scsi_scan_mutex);
47764777

47774778
/* Reschedule with a delay if scsi_rescan_device() returned an error */

0 commit comments

Comments
 (0)