drivers/scsi/st.c
Source file repositories/reference/linux-study-clean/drivers/scsi/st.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/st.c- Extension
.c- Size
- 135465 bytes
- Lines
- 5055
- 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.
- 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/compat.hlinux/fs.hlinux/kernel.hlinux/sched/signal.hlinux/mm.hlinux/init.hlinux/string.hlinux/slab.hlinux/errno.hlinux/mtio.hlinux/major.hlinux/cdrom.hlinux/ioctl.hlinux/fcntl.hlinux/spinlock.hlinux/blkdev.hlinux/moduleparam.hlinux/cdev.hlinux/idr.hlinux/delay.hlinux/mutex.hlinux/uaccess.hasm/dma.hlinux/unaligned.hscsi/scsi.hscsi/scsi_dbg.hscsi/scsi_device.hscsi/scsi_driver.hscsi/scsi_eh.hscsi/scsi_host.hscsi/scsi_ioctl.h
Detected Declarations
struct st_reject_datafunction scsi_tape_putfunction driverfunction st_analyze_sensefunction st_chk_resultfunction DEBfunction DEBfunction st_release_requestfunction st_do_statsfunction st_scsi_execute_endfunction st_scsi_executefunction write_behind_checkfunction write_behind_checkfunction cross_eoffunction st_flush_write_bufferfunction flush_bufferfunction set_mode_densblkfunction st_int_ioctlfunction do_door_lockfunction reset_statefunction test_readyfunction readyfunction st_openfunction st_flushfunction st_releasefunction rw_checksfunction DEBfunction setup_bufferingfunction DEBfunction release_bufferingfunction st_writefunction copy_from_userfunction read_tapefunction st_readfunction DEBfunction st_set_optionsfunction read_mode_pagefunction write_mode_pagefunction thisfunction do_load_unloadfunction deb_space_printfunction deb_space_printfunction get_locationfunction set_locationfunction find_partitionfunction switch_partitionfunction nbr_partitionsfunction format_medium
Annotated Snippet
static const struct file_operations st_fops =
{
.owner = THIS_MODULE,
.read = st_read,
.write = st_write,
.unlocked_ioctl = st_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = st_compat_ioctl,
#endif
.open = st_open,
.flush = st_flush,
.release = st_release,
.llseek = noop_llseek,
};
static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
{
int i, error;
dev_t cdev_devno;
struct cdev *cdev;
struct device *dev;
struct st_modedef *STm = &(tape->modes[mode]);
char name[10];
int dev_num = tape->index;
cdev_devno = MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, rew));
cdev = cdev_alloc();
if (!cdev) {
pr_err("st%d: out of memory. Device not attached.\n", dev_num);
error = -ENOMEM;
goto out;
}
cdev->owner = THIS_MODULE;
cdev->ops = &st_fops;
STm->cdevs[rew] = cdev;
error = cdev_add(cdev, cdev_devno, 1);
if (error) {
pr_err("st%d: Can't add %s-rewind mode %d\n", dev_num,
rew ? "non" : "auto", mode);
pr_err("st%d: Device not attached.\n", dev_num);
goto out_free;
}
i = mode << (4 - ST_NBR_MODE_BITS);
snprintf(name, 10, "%s%s%s", rew ? "n" : "",
tape->name, st_formats[i]);
dev = device_create(&st_sysfs_class, &tape->device->sdev_gendev,
cdev_devno, &tape->modes[mode], "%s", name);
if (IS_ERR(dev)) {
pr_err("st%d: device_create failed\n", dev_num);
error = PTR_ERR(dev);
goto out_free;
}
STm->devs[rew] = dev;
return 0;
out_free:
cdev_del(STm->cdevs[rew]);
out:
STm->cdevs[rew] = NULL;
STm->devs[rew] = NULL;
return error;
}
static int create_cdevs(struct scsi_tape *tape)
{
int mode, error;
for (mode = 0; mode < ST_NBR_MODES; ++mode) {
error = create_one_cdev(tape, mode, 0);
if (error)
return error;
error = create_one_cdev(tape, mode, 1);
if (error)
return error;
}
return sysfs_create_link(&tape->device->sdev_gendev.kobj,
&tape->modes[0].devs[0]->kobj, "tape");
}
static void remove_cdevs(struct scsi_tape *tape)
{
int mode, rew;
sysfs_remove_link(&tape->device->sdev_gendev.kobj, "tape");
for (mode = 0; mode < ST_NBR_MODES; mode++) {
struct st_modedef *STm = &(tape->modes[mode]);
Annotation
- Immediate include surface: `linux/module.h`, `linux/compat.h`, `linux/fs.h`, `linux/kernel.h`, `linux/sched/signal.h`, `linux/mm.h`, `linux/init.h`, `linux/string.h`.
- Detected declarations: `struct st_reject_data`, `function scsi_tape_put`, `function driver`, `function st_analyze_sense`, `function st_chk_result`, `function DEB`, `function DEB`, `function st_release_request`, `function st_do_stats`, `function st_scsi_execute_end`.
- 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.
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.