drivers/scsi/hpsa.c
Source file repositories/reference/linux-study-clean/drivers/scsi/hpsa.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/hpsa.c- Extension
.c- Size
- 278976 bytes
- Lines
- 10007
- Domain
- Driver Families
- Bucket
- drivers/scsi
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/interrupt.hlinux/types.hlinux/pci.hlinux/kernel.hlinux/slab.hlinux/delay.hlinux/fs.hlinux/timer.hlinux/init.hlinux/spinlock.hlinux/compat.hlinux/blktrace_api.hlinux/uaccess.hlinux/io.hlinux/dma-mapping.hlinux/completion.hlinux/moduleparam.hscsi/scsi.hscsi/scsi_cmnd.hscsi/scsi_device.hscsi/scsi_host.hscsi/scsi_tcq.hscsi/scsi_eh.hscsi/scsi_transport_sas.hscsi/scsi_dbg.hlinux/cciss_ioctl.hlinux/string.hlinux/bitmap.hlinux/atomic.hlinux/jiffies.hlinux/percpu-defs.h
Detected Declarations
struct Commandfunction hpsa_is_cmd_idlefunction decode_sense_datafunction check_for_unit_attentionfunction check_for_busyfunction host_show_lockup_detectedfunction host_store_hp_ssd_smart_path_statusfunction host_store_raid_offload_debugfunction host_store_rescanfunction hpsa_turn_off_ioaccel_for_devicefunction host_show_firmware_revisionfunction host_show_commands_outstandingfunction host_show_transport_modefunction host_show_hp_ssd_smart_path_statusfunction board_id_in_arrayfunction ctlr_is_hard_resettablefunction ctlr_is_soft_resettablefunction ctlr_is_resettablefunction host_show_resettablefunction is_logical_dev_addr_modefunction is_logical_devicefunction raid_level_showfunction lunid_showfunction unique_id_showfunction sas_address_showfunction host_show_hp_ssd_smart_path_enabledfunction path_info_showfunction host_show_ctlr_numfunction host_show_legacy_boardfunction next_commandfunction set_performant_modefunction set_ioaccel1_performant_modefunction set_ioaccel2_tmf_performant_modefunction set_ioaccel2_performant_modefunction is_firmware_flash_cmdfunction dial_down_lockup_detection_during_fw_flashfunction dial_up_lockup_detection_on_fw_flash_completefunction __enqueue_cmd_and_start_iofunction enqueue_cmd_and_start_iofunction is_hba_lunidfunction is_scsi_rev_5function hpsa_find_target_lunfunction hpsa_show_dev_msgfunction hpsa_scsi_add_entryfunction hpsa_scsi_update_entryfunction hpsa_scsi_replace_entryfunction hpsa_scsi_remove_entryfunction fixup_botched_add
Annotated Snippet
static struct pci_driver hpsa_pci_driver = {
.name = HPSA,
.probe = hpsa_init_one,
.remove = hpsa_remove_one,
.id_table = hpsa_pci_device_id, /* id_table */
.shutdown = hpsa_shutdown,
.driver.pm = &hpsa_pm_ops,
};
/* Fill in bucket_map[], given nsgs (the max number of
* scatter gather elements supported) and bucket[],
* which is an array of 8 integers. The bucket[] array
* contains 8 different DMA transfer sizes (in 16
* byte increments) which the controller uses to fetch
* commands. This function fills in bucket_map[], which
* maps a given number of scatter gather elements to one of
* the 8 DMA transfer sizes. The point of it is to allow the
* controller to only do as much DMA as needed to fetch the
* command, with the DMA transfer size encoded in the lower
* bits of the command address.
*/
static void calc_bucket_map(int bucket[], int num_buckets,
int nsgs, int min_blocks, u32 *bucket_map)
{
int i, j, b, size;
/* Note, bucket_map must have nsgs+1 entries. */
for (i = 0; i <= nsgs; i++) {
/* Compute size of a command with i SG entries */
size = i + min_blocks;
b = num_buckets; /* Assume the biggest bucket */
/* Find the bucket that is just big enough */
for (j = 0; j < num_buckets; j++) {
if (bucket[j] >= size) {
b = j;
break;
}
}
/* for a command with i SG entries, use bucket b. */
bucket_map[i] = b;
}
}
/*
* return -ENODEV on err, 0 on success (or no action)
* allocates numerous items that must be freed later
*/
static int hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
{
int i;
unsigned long register_value;
unsigned long transMethod = CFGTBL_Trans_Performant |
(trans_support & CFGTBL_Trans_use_short_tags) |
CFGTBL_Trans_enable_directed_msix |
(trans_support & (CFGTBL_Trans_io_accel1 |
CFGTBL_Trans_io_accel2));
struct access_method access = SA5_performant_access;
/* This is a bit complicated. There are 8 registers on
* the controller which we write to to tell it 8 different
* sizes of commands which there may be. It's a way of
* reducing the DMA done to fetch each command. Encoded into
* each command's tag are 3 bits which communicate to the controller
* which of the eight sizes that command fits within. The size of
* each command depends on how many scatter gather entries there are.
* Each SG entry requires 16 bytes. The eight registers are programmed
* with the number of 16-byte blocks a command of that size requires.
* The smallest command possible requires 5 such 16 byte blocks.
* the largest command possible requires SG_ENTRIES_IN_CMD + 4 16-byte
* blocks. Note, this only extends to the SG entries contained
* within the command block, and does not extend to chained blocks
* of SG elements. bft[] contains the eight values we write to
* the registers. They are not evenly distributed, but have more
* sizes for small commands, and fewer sizes for larger commands.
*/
int bft[8] = {5, 6, 8, 10, 12, 20, 28, SG_ENTRIES_IN_CMD + 4};
#define MIN_IOACCEL2_BFT_ENTRY 5
#define HPSA_IOACCEL2_HEADER_SZ 4
int bft2[16] = {MIN_IOACCEL2_BFT_ENTRY, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19,
HPSA_IOACCEL2_HEADER_SZ + IOACCEL2_MAXSGENTRIES};
BUILD_BUG_ON(ARRAY_SIZE(bft2) != 16);
BUILD_BUG_ON(ARRAY_SIZE(bft) != 8);
BUILD_BUG_ON(offsetof(struct io_accel2_cmd, sg) >
16 * MIN_IOACCEL2_BFT_ENTRY);
BUILD_BUG_ON(sizeof(struct ioaccel2_sg_element) != 16);
BUILD_BUG_ON(28 > SG_ENTRIES_IN_CMD + 4);
/* 5 = 1 s/g entry or 4k
* 6 = 2 s/g entry or 8k
* 8 = 4 s/g entry or 16k
Annotation
- Immediate include surface: `linux/module.h`, `linux/interrupt.h`, `linux/types.h`, `linux/pci.h`, `linux/kernel.h`, `linux/slab.h`, `linux/delay.h`, `linux/fs.h`.
- Detected declarations: `struct Command`, `function hpsa_is_cmd_idle`, `function decode_sense_data`, `function check_for_unit_attention`, `function check_for_busy`, `function host_show_lockup_detected`, `function host_store_hp_ssd_smart_path_status`, `function host_store_raid_offload_debug`, `function host_store_rescan`, `function hpsa_turn_off_ioaccel_for_device`.
- Atlas domain: Driver Families / drivers/scsi.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.