scsi: Add LeapRAID driver support
Subsystems (3)
Dongdong Hao
maintainerv2 cover scsi: Add LeapRAID driver support
Hi,
This series adds initial upstream support for the LeapIO LeapRAID PCIe SAS/SATA RAID controller driver.
Patch 1 adds the new leapraid SCSI driver under drivers/scsi/leapraid/, hooks it into the SCSI build system, and adds a MAINTAINERS entry.
Patch 2 adds the driver documentation under Documentation/scsi/.
Changes in v2:
- resend the series with corrected threading
- no code changes since v1
The earlier resend accidentally reused old threading information, which caused the series to appear incorrectly in the public archive.
Thanks,
Dongdong Hao
Dongdong Hao (2):
scsi: leapraid: Add new SCSI driver
scsi: leapraid: Add driver documentation
Documentation/scsi/index.rst | 1 + Documentation/scsi/leapraid.rst | 139 + MAINTAINERS | 7 + drivers/scsi/Kconfig | 1 + drivers/scsi/Makefile | 1 + drivers/scsi/leapraid/Kconfig | 14 + drivers/scsi/leapraid/Makefile | 10 + drivers/scsi/leapraid/leapraid.h | 2071 +++++ drivers/scsi/leapraid/leapraid_app.c | 705 ++ drivers/scsi/leapraid/leapraid_func.c | 9053 ++++++++++++++++++++ drivers/scsi/leapraid/leapraid_func.h | 1566 ++++ drivers/scsi/leapraid/leapraid_os.c | 2516 ++++++ drivers/scsi/leapraid/leapraid_transport.c | 1387 +++ 13 files changed, 17471 insertions(+) create mode 100644 Documentation/scsi/leapraid.rst create mode 100644 drivers/scsi/leapraid/Kconfig create mode 100644 drivers/scsi/leapraid/Makefile create mode 100644 drivers/scsi/leapraid/leapraid.h create mode 100644 drivers/scsi/leapraid/leapraid_app.c create mode 100644 drivers/scsi/leapraid/leapraid_func.c create mode 100644 drivers/scsi/leapraid/leapraid_func.h create mode 100644 drivers/scsi/leapraid/leapraid_os.c create mode 100644 drivers/scsi/leapraid/leapraid_transport.c
Signature · 1 line
2.25.1
Dongdong Hao
maintainerPATCH v2 1/2 scsi: leapraid: Add new SCSI driver
The LeapRAID driver provides support for LeapRAID PCIe RAID controllers, enabling communication between the host operating system, firmware, and hardware for efficient storage management.
The driver is organized into several logical modules, each with a clear responsibility:
leapraid_os.c: Integrates with the Linux SCSI subsystem, handling host template callbacks, PCIe device probing, and initialization.
leapraid_func.c: Contains low-level routines for firmware/hardware interaction, interrupt handling, and reset logic.
leapraid_app.c: Provides the ioctl interface for user-space tools.
leapraid_transport.c: Manages interactions with the SCSI transport layer for SAS PHYs and ports.
leapraid_func.h: Contains internal definitions shared among driver modules.
leapraid.h: Contains low-level hardware definitions for driver/firmware interaction.
The leapraid_probe() function orchestrates the setup: it allocates the adapter structure and SCSI host, configures hardware interfaces, and registers it with the SCSI mid-layer. Following registration, scsi_scan_host() is invoked to initiate device discovery, with firmware reporting devices via interrupt-driven events.
This initial commit provides the necessary infrastructure for subsequent development of full I/O path handling, error recovery, and advanced management features.
--- MAINTAINERS | 7 + drivers/scsi/Kconfig | 1 + drivers/scsi/Makefile | 1 + drivers/scsi/leapraid/Kconfig | 14 + drivers/scsi/leapraid/Makefile | 10 + drivers/scsi/leapraid/leapraid.h | 2071 +++++ drivers/scsi/leapraid/leapraid_app.c | 705 ++ drivers/scsi/leapraid/leapraid_func.c | 9053 ++++++++++++++++++++ drivers/scsi/leapraid/leapraid_func.h | 1566 ++++ drivers/scsi/leapraid/leapraid_os.c | 2516 ++++++ drivers/scsi/leapraid/leapraid_transport.c | 1387 +++ 11 files changed, 17331 insertions(+) create mode 100644 drivers/scsi/leapraid/Kconfig create mode 100644 drivers/scsi/leapraid/Makefile create mode 100644 drivers/scsi/leapraid/leapraid.h create mode 100644 drivers/scsi/leapraid/leapraid_app.c create mode 100644 drivers/scsi/leapraid/leapraid_func.c create mode 100644 drivers/scsi/leapraid/leapraid_func.h create mode 100644 drivers/scsi/leapraid/leapraid_os.c create mode 100644 drivers/scsi/leapraid/leapraid_transport.c
MAINTAINERS +7 -0
@@ -14507,6 +14507,13 @@ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening F: scripts/leaking_addresses.pl +LEAPIO SCSI RAID DRIVER +M: Dongdong Hao <[email protected]> +L: [email protected] +S: Supported +F: Documentation/scsi/leapraid.rst +F: drivers/scsi/leapraid/ + LED SUBSYSTEM M: Lee Jones <[email protected]> M: Pavel Machek <[email protected]>
drivers/scsi/Kconfig +1 -0
@@ -499,6 +499,7 @@ source "drivers/scsi/esas2r/Kconfig" source "drivers/scsi/megaraid/Kconfig.megaraid" source "drivers/scsi/mpt3sas/Kconfig" source "drivers/scsi/mpi3mr/Kconfig" +source "drivers/scsi/leapraid/Kconfig" source "drivers/scsi/smartpqi/Kconfig" config SCSI_HPTIOP
drivers/scsi/Makefile +1 -0
@@ -91,6 +91,7 @@ obj-$(CONFIG_SCSI_BFA_FC) += bfa/ obj-$(CONFIG_SCSI_CHELSIO_FCOE) += csiostor/ obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o obj-$(CONFIG_SCSI_HPSA) += hpsa.o +obj-$(CONFIG_SCSI_LEAPRAID) += leapraid/ obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi/ obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/ obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o
drivers/scsi/leapraid/Kconfig new file +14 -0
@@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +config SCSI_LEAPRAID + tristate "LeapIO RAID Adapter" + depends on PCI && SCSI + select SCSI_SAS_ATTRS + help + This driver supports LeapIO PCIe-based storage + and RAID controllers. + + <http://www.leap-io.com> + + To compile this driver as a module, choose M here: the + resulting kernel module will be named leapraid.
drivers/scsi/leapraid/Makefile new file +10 -0
@@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the LEAPRAID drivers. +# + +obj-$(CONFIG_SCSI_LEAPRAID) += leapraid.o +leapraid-objs += leapraid_func.o \ + leapraid_os.o \ + leapraid_transport.o \ + leapraid_app.o
drivers/scsi/leapraid/leapraid.h new file +2071 -0
2,071 lines not on this page · raw message
drivers/scsi/leapraid/leapraid_app.c new file +705 -0
705 lines not on this page · raw message
drivers/scsi/leapraid/leapraid_func.c new file +9053 -0
173 lines not on this page · raw message
drivers/scsi/leapraid/leapraid_func.h new file +1566 -0
1,566 lines not on this page · raw message
drivers/scsi/leapraid/leapraid_os.c new file +2516 -0
2,516 lines not on this page · raw message
drivers/scsi/leapraid/leapraid_transport.c new file +1387 -0
1,387 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.25.1
Part of the diff is not shown here. View the raw message.
Re: [PATCH v2 1/2] scsi: leapraid: Add new SCSI driver
Quoted 35 lines · Dongdong Hao
The LeapRAID driver provides support for LeapRAID PCIe RAID controllers, enabling communication between the host operating system, firmware, and hardware for efficient storage management.
The driver is organized into several logical modules, each with a clear responsibility:
leapraid_os.c: Integrates with the Linux SCSI subsystem, handling host template callbacks, PCIe device probing, and initialization.
leapraid_func.c: Contains low-level routines forfirmware/hardwareinteraction, interrupt handling, and reset logic.
leapraid_app.c: Provides the ioctl interface for user-space tools.
leapraid_transport.c: Manages interactions with the SCSI transport layer for SAS PHYs and ports.
leapraid_func.h: Contains internal definitions shared among driver modules.
leapraid.h: Contains low-level hardware definitions for driver/firmware interaction.The
leapraid_probe()function orchestrates the setup: it allocates the adapter structure and SCSI host, configures hardware interfaces, and registers it with the SCSI mid-layer. Following registration,scsi_scan_host()is invoked to initiate device discovery, with firmware reporting devices via interrupt-driven events.This initial commit provides the necessary infrastructure for subsequent development of full I/O path handling, error recovery, and advanced management features.
Signed-off-by Dongdong Hao <[email protected]>
[...]
drivers/scsi/leapraid/leapraid_app.c line 683
Quoted 10 lines
drivers/scsi/leapraid/leapraid_app.c new file +9
-0+static long bad_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +return -ENOTTY ; +} +static const struct file_operations leapraid_ctl_fops = { + .owner =THIS_MODULE , + .unlocked_ioctl = leapraid_ctl_ioctl, + .mmap = leapraid_fw_mmap, + .compat_ioctl = bad_ioctl,
You do not need to define .compat_ioctl if not supported. The ioctl syscall will return -ENOTTY when .compat_ioctl is undefined. So drop bad_ioctl()
[...]
drivers/scsi/leapraid/leapraid_func.c line 2185
Quoted 8 lines
drivers/scsi/leapraid/leapraid_func.c new file +8
-0+out_cleanup: + adapter->driver_cmds.cfg_op_cmd.status =LEAPRAID_CMD_NOT_USED ; +mutex_unlock (&adapter->driver_cmds.cfg_op_cmd.mutex); +if (issue_reset) { +if (adapter->scan_dev_desc.first_scan_dev_fired) { +dev_info (&adapter->pdev->dev, +"%s:%d cfg-req: Failure, issuing reset\n" , + __func__, __LINE__);
Shouldn't this be a dev_err() ? or dev_warn() ?
Quoted 8 lines
drivers/scsi/leapraid/leapraid_func.c new file +8
-0+leapraid_hard_reset_handler (adapter,FULL_RESET ); + }else { +dev_warn (&adapter->pdev->dev, +"cfg-req: CMD fail in init, skip reset\n" ); + } + rc = -EFAULT ; + } +return rc;
[...]
drivers/scsi/leapraid/leapraid_func.c line 2913
Quoted 7 lines
drivers/scsi/leapraid/leapraid_func.c new file +7
-0+ adapter_state =leapraid_get_adapter_state (adapter); +if (adapter_state !=LEAPRAID_DB_OPERATIONAL ) { +dev_info (&adapter->pdev->dev,"%s:%d: call hard_reset 0x%x\n" , + __func__, __LINE__, adapter_state); + rc =leapraid_hard_reset_handler (adapter,FULL_RESET ); +dev_warn (&adapter->pdev->dev,"%s: Hard reset %s\n" , + __func__, rc ==0 ?"success" :"failed" );
A warning in the case of success is a little odd. Maybe stay silent for the success case and dev_err() for the failure case ?
Quoted 5 lines
drivers/scsi/leapraid/leapraid_func.c new file +5
-0+ + adapter_state =leapraid_get_adapter_state (adapter); +if (rc && adapter_state !=LEAPRAID_DB_OPERATIONAL ) +return ; + }
[...]
drivers/scsi/leapraid/leapraid_func.c line 3409
Quoted 4 lines
drivers/scsi/leapraid/leapraid_func.c new file +4
-0+static struct leapraid_fw_evt_work *leapraid_alloc_fw_evt_work (void ) +{ +struct leapraid_fw_evt_work *fw_evt = +kzalloc (sizeof (*fw_evt),GFP_ATOMIC );
Please add a blank line here.
drivers/scsi/leapraid/leapraid_func.c line 3411
Quoted 2 lines
drivers/scsi/leapraid/leapraid_func.c new file +2
-0+if (!fw_evt) +return NULL ;
Maybe simplify here:
if (fw_evt) kref_init(&fw_evt->refcnt); return fw_evt;
Quoted 4 lines
drivers/scsi/leapraid/leapraid_func.c new file +4
-0+ +kref_init (&fw_evt->refcnt); +return fw_evt; +}
[...]
Quoted 13 lines
drivers/scsi/leapraid/leapraid_func.c new file +13
-0+static void leapraid_remove_unresp_raid_volumes ( +struct leapraid_adapter *adapter) +{ +unsigned long flags; +struct leapraid_raid_volume *raid_volume, *raid_volume_next; +LIST_HEAD (head); + +spin_lock_irqsave (&adapter->dev_topo.raid_volume_lock, flags); +list_for_each_entry_safe (raid_volume, raid_volume_next, + &adapter->dev_topo.raid_volume_list, list) { +if (!raid_volume->resp) +list_move_tail (&raid_volume->list, &head); +else
drivers/scsi/leapraid/leapraid_func.c line 5028
Quoted 10 lines
drivers/scsi/leapraid/leapraid_func.c new file +10
-0+ raid_volume->resp =0 ; + } +spin_unlock_irqrestore (&adapter->dev_topo.raid_volume_lock, flags); + +list_for_each_entry_safe (raid_volume, raid_volume_next, &head, list) { +leapraid_sas_volume_delete_by_ptr (adapter, raid_volume); + } + +dev_info (&adapter->pdev->dev, +"Unresponsive RAID volumes removed\n" );
Maybe dev_warn() here ?
Quoted 12 lines
drivers/scsi/leapraid/leapraid_func.c new file +12
-0+static void leapraid_remove_unresp_sas_exp (struct leapraid_adapter *adapter) +{ +struct leapraid_topo_node *topo_node_exp, *topo_node_exp_next; +unsigned long flags; +LIST_HEAD (head); + +spin_lock_irqsave (&adapter->dev_topo.topo_node_lock, flags); +list_for_each_entry_safe (topo_node_exp, topo_node_exp_next, + &adapter->dev_topo.exp_list, list) { +if (!topo_node_exp->resp) +list_move_tail (&topo_node_exp->list, &head); +else
drivers/scsi/leapraid/leapraid_func.c line 5052
Quoted 10 lines
drivers/scsi/leapraid/leapraid_func.c new file +10
-0+ topo_node_exp->resp =0 ; + } +spin_unlock_irqrestore (&adapter->dev_topo.topo_node_lock, flags); + +list_for_each_entry_safe (topo_node_exp, topo_node_exp_next, + &head, list) +leapraid_exp_node_rm (adapter, topo_node_exp); + +dev_info (&adapter->pdev->dev, +"Unresponsive SAS expanders removed\n" );
And here too ?
[...]
drivers/scsi/leapraid/leapraid_func.c line 5414
Quoted 13 lines
drivers/scsi/leapraid/leapraid_func.c new file +13
-0+static void leapraid_scan_all_dev_after_reset (struct leapraid_adapter *adapter) +{ +dev_info (&adapter->pdev->dev,"Begin scanning devices\n" ); + +leapraid_sas_host_add (adapter, adapter->dev_topo.card.phys_num >0 ); +leapraid_scan_exp_after_reset (adapter); +if (adapter->adapter_attr.raid_support) { +leapraid_scan_phy_disks_after_reset (adapter); +leapraid_scan_vol_after_reset (adapter); + } +leapraid_scan_sas_dev_after_reset (adapter); + +dev_info (&adapter->pdev->dev,"Devices scan complete\n" );
Maybe drop this message to not polute too much the kernel log ?
[...]
Quoted 16 lines
drivers/scsi/leapraid/leapraid_func.c new file +16
-0+static u8 leapraid_handle_scan_cb (struct leapraid_adapter *adapter, +struct leapraid_driver_cmd *cmd, +struct leapraid_rep *rep) +{ +u16 status; + + cmd->status &= ~LEAPRAID_CMD_PENDING ; + + status =le16_to_cpu (rep->adapter_status) & +LEAPRAID_ADAPTER_STATUS_MASK ; + +if (status !=LEAPRAID_ADAPTER_STATUS_SUCCESS ) + adapter->scan_dev_desc.scan_dev_failed =1 ; + +if (!cmd->async_scan_dev) { +complete (&cmd->done);
drivers/scsi/leapraid/leapraid_func.c line 5936
Quoted 10 lines
drivers/scsi/leapraid/leapraid_func.c new file +10
-0+return 1 ; + } + +if (status ==LEAPRAID_ADAPTER_STATUS_SUCCESS ) +leapraid_scan_dev_complete (adapter); +else + adapter->scan_dev_desc.scan_start_failed = status; + +return 1 ; +}
This function only returns 1. It has a single caller site. So make it void and...
Quoted 4 lines
drivers/scsi/leapraid/leapraid_func.c new file +4
-0+static bool leapraid_driver_cmds_done (struct leapraid_adapter *adapter, +u16 taskid,u8 msix_index, +u32 rep_paddr,u8 cb_idx) +{
[...]
drivers/scsi/leapraid/leapraid_func.c line 5995
Quoted 4 lines
drivers/scsi/leapraid/leapraid_func.c new file +4
-0+if (_sp_cmd->cb_idx ==LEAPRAID_SCAN_DEV_CB_IDX ) +return leapraid_handle_scan_cb (adapter, + _sp_cmd, + leap_mpi_rep);
call thr function here and "retrun true".
Quoted 10 lines
drivers/scsi/leapraid/leapraid_func.c new file +10
-0+ +if (_sp_cmd->cb_idx ==LEAPRAID_CTL_CB_IDX ) +leapraid_handle_ctl_cb (adapter, leap_mpi_rep, taskid); + } + + _sp_cmd->status &= ~LEAPRAID_CMD_PENDING ; +complete (&_sp_cmd->done); + +return true; +}
[...]
Quoted 8 lines
drivers/scsi/leapraid/leapraid_os.c new file +8
-0+static int leapraid_tm_post_processing (struct leapraid_adapter *adapter, +u16 hdl,uint channel,uint id, +uint lun,u8 type,u16 taskid_task) +{ +int rc; + + rc =leapraid_tm_cmd_map_status (adapter, channel, id, lun, + type, taskid_task);
drivers/scsi/leapraid/leapraid_os.c line 162
Quoted 10 lines
drivers/scsi/leapraid/leapraid_os.c new file +10
-0+if (rc ==SUCCESS ) +return rc; + +leapraid_mask_int (adapter); +leapraid_sync_irqs (adapter, true); +leapraid_unmask_int (adapter); + + rc =leapraid_tm_cmd_map_status (adapter, channel, id, lun, type, + taskid_task); +return rc;
return leapraid_tm_cmd_map_status(adapter, channel, id, lun, type, taskid_task);
is a little better :)
[...]
Quoted 8 lines
drivers/scsi/leapraid/leapraid_os.c new file +8
-0+static inline bool leapraid_is_scmd_permitted (struct leapraid_adapter *adapter, +struct scsi_cmnd *scmd) +{ +u8 opcode; + +if (adapter->access_ctrl.pcie_recovering || +atomic_read (&adapter->overheat_desc.thermal_alert)) +return false;
drivers/scsi/leapraid/leapraid_os.c line 811
Quoted 10 lines
drivers/scsi/leapraid/leapraid_os.c new file +10
-0+ +if (adapter->access_ctrl.host_removing) { +if (leapraid_pci_removed (adapter)) +return false; + + opcode = scmd->cmnd[0 ]; +if (opcode ==SYNCHRONIZE_CACHE || opcode ==START_STOP ) +return true; + +return false;
Simplify:
return opcode == SYNCHRONIZE_CACHE || opcode == START_STOP;
drivers/scsi/leapraid/leapraid_func.c line 117
Quoted 3 lines
drivers/scsi/leapraid/leapraid_func.c new file +3
-0+ } +return true; +}
[...]
With these nits corrected, feel free to add:
Martin,
I did 3 rounds of reviews with the author off-list. So I think this is all good enough to get in, which will simplify fixes/improvements going forward.
Signature · 2 lines
Damien Le Moal Western Digital Research
Dongdong Hao
maintainerPATCH v2 2/2 scsi: leapraid: Add driver documentation
In reply to Dongdong HaoThis patch adds the necessary documentation for the LeapRAID SCSI driver to the kernel's documentation tree.
--- Documentation/scsi/index.rst | 1 + Documentation/scsi/leapraid.rst | 139 ++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 Documentation/scsi/leapraid.rst
Documentation/scsi/index.rst +1 -0
@@ -56,6 +56,7 @@ SCSI host adapter drivers g_NCR5380 hpsa hptiop + leapraid libsas lpfc megaraid
Documentation/scsi/leapraid.rst new file +139 -0
139 lines not on this page · raw message
Signature · 1 line
2.25.1