drivers/scsi/sd.c

Source file repositories/reference/linux-study-clean/drivers/scsi/sd.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/sd.c
Extension
.c
Size
120719 bytes
Lines
4524
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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.

Dependency Surface

Detected Declarations

Annotated Snippet

error = device_add(&sdkp->disk_dev);
	if (error) {
		put_device(&sdkp->disk_dev);
		put_disk(gd);
		goto out;
	}

	dev_set_drvdata(dev, sdkp);

	gd->major = sd_major((index & 0xf0) >> 4);
	gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
	gd->minors = SD_MINORS;

	gd->fops = &sd_fops;
	gd->private_data = sdkp;

	/* defaults, until the device tells us otherwise */
	sdp->sector_size = 512;
	sdkp->capacity = 0;
	sdkp->media_present = 1;
	sdkp->write_prot = 0;
	sdkp->cache_override = 0;
	sdkp->WCE = 0;
	sdkp->RCD = 0;
	sdkp->ATO = 0;
	sdkp->first_scan = 1;
	sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS;

	sd_revalidate_disk(gd);
	if (sdp->sector_size > PAGE_SIZE) {
		if (sd_large_pool_create()) {
			error = -ENOMEM;
			goto out_free_index;
		}
	}

	if (sdp->removable) {
		gd->flags |= GENHD_FL_REMOVABLE;
		gd->events |= DISK_EVENT_MEDIA_CHANGE;
		gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT;
	}

	blk_pm_runtime_init(sdp->request_queue, dev);
	if (sdp->rpm_autosuspend) {
		pm_runtime_set_autosuspend_delay(dev,
			sdp->host->rpm_autosuspend_delay);
	}

	error = device_add_disk(dev, gd, NULL);
	if (error) {
		device_unregister(&sdkp->disk_dev);
		put_disk(gd);
		if (sdp->sector_size > PAGE_SIZE)
			sd_large_pool_destroy();
		goto out;
	}

	if (sdkp->security) {
		sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit);
		if (sdkp->opal_dev)
			sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n");
	}

	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
		  sdp->removable ? "removable " : "");
	scsi_autopm_put_device(sdp);

	return 0;

 out_free_index:
	ida_free(&sd_index_ida, index);
 out_put:
	put_disk(gd);
 out_free:
	kfree(sdkp);
 out:
	scsi_autopm_put_device(sdp);
	return error;
}

static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
{
	unsigned char cmd[6] = { START_STOP };	/* START_VALID */
	struct scsi_sense_hdr sshdr;
	struct scsi_failure failure_defs[] = {
		{
			/* Power on, reset, or bus device reset occurred */
			.sense = UNIT_ATTENTION,
			.asc = 0x29,
			.ascq = 0,

Annotation

Implementation Notes