linux-2.6.25/sd_probe()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#hf41c32b]
#backlinks
*説明 [#d462b787]
-パス: [[linux-2.6.25/drivers/scsi/sd.c]]
-FIXME: これは何?
--説明
**引数 [#j04dc2b9]
-struct device *dev
--
**返り値 [#x0edd28e]
-int
--
**参考 [#s40c9fe7]
-sd_index_idr は
--[[linux-2.6.25/DEFINE_IDR()]]
static DEFINE_IDR(sd_index_idr);
-sd_template は SCSI ブロックデバイスのデフォルトの動作を...
--[[linux-2.6.25/sd_template]]
--[[linux-2.6.25/sd_probe()]]
--[[linux-2.6.25/sd_remove()]]
--[[linux-2.6.25/sd_suspend()]]
--[[linux-2.6.25/sd_resume()]]
--[[linux-2.6.25/sd_shutdown()]]
--[[linux-2.6.25/sd_rescan()]]
--[[linux-2.6.25/sd_done()]]
static struct scsi_driver sd_template = {
.owner = THIS_MODULE,
.gendrv = {
.name = "sd",
.probe = sd_probe,
.remove = sd_remove,
.suspend = sd_suspend,
.resume = sd_resume,
.shutdown = sd_shutdown,
},
.rescan = sd_rescan,
.done = sd_done,
};
-sd_disk_class は SCSI ブロックデバイスドライバのクラスを...
--[[linux-2.6.25/class]]
--[[linux-2.6.25/THIS_MODULE]]
--[[linux-2.6.25/scsi_disk_release()]]
--sd_disk_attrs も static 変数である。
static struct class sd_disk_class = {
.name = "scsi_disk",
.owner = THIS_MODULE,
.release = scsi_disk_release,
.class_dev_attrs = sd_disk_attrs,
};
-sd_disk_attrs は SCSI ブロックデバイスドライバのクラスの
属性を表す。
--[[linux-2.6.25/__ATTR()]]
--cache_type メンバ
---
---読み、[[linux-2.6.25/sd_show_cache_type()]]
---書き、[[linux-2.6.25/sd_store_cache_type()]]
--FUA メンバ
---
---読み、[[linux-2.6.25/sd_show_fua()]]
---書けない
--allow_restart メンバ
---
---読み、[[linux-2.6.25/sd_show_allow_restart()]]
---書き、[[linux-2.6.25/sd_store_allow_restart()]]
--manage_start_stop メンバ
---
---読み、[[linux-2.6.25/sd_show_manage_start_stop()]]
---書き、[[linux-2.6.25/sd_store_manage_start_stop()]]
static struct class_device_attribute sd_disk_attrs[] = {
__ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cach...
sd_store_cache_type),
__ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
__ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_a...
sd_store_allow_restart),
__ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_sh...
sd_store_manage_start_stop),
__ATTR_NULL,
};
-sd_fops は SCSI ブロックデバイスに対する操作を表す。
--これらの関数はブロックデバイスへの要求に応じて、
ブロックデバイスサブシステムから呼び出される。
static struct block_device_operations sd_fops = {
.owner = THIS_MODULE,
.open = sd_open,
.release = sd_release,
.ioctl = sd_ioctl,
.getgeo = sd_getgeo,
#ifdef CONFIG_COMPAT
.compat_ioctl = sd_compat_ioctl,
#endif
.media_changed = sd_media_changed,
.revalidate_disk = sd_revalidate_disk,
};
*実装 [#kf000cbc]
/**
* sd_probe - called during driver initialization a...
* new scsi device is attached to the system. It is...
* for each scsi device (not just disks) present.
* @dev: pointer to device object
*
* Returns 0 if successful (or not interested in th...
* (e.g. scanner)); 1 when there is an error.
*
* Note: this function is invoked from the scsi mid...
* This function sets up the mapping between a given
* <host,channel,id,lun> (found in sdp) and new dev...
* (e.g. /dev/sda). More precisely it is the block ...
* and minor number that is chosen here.
*
* Assume sd_attach is not re-entrant (for time bei...
* Also think about sd_attach() and sd_remove() run...
**/
static int sd_probe(struct device *dev)
{
struct scsi_device *sdp = to_scsi_device(dev);
struct scsi_disk *sdkp;
struct gendisk *gd;
u32 index;
int error;
-
--[[linux-2.6.25/to_scsi_device()]]
--[[linux-2.6.25/scsi_device]]
--[[linux-2.6.25/scsi_disk]]
--[[linux-2.6.25/gendisk]]
error = -ENODEV;
if (sdp->type != TYPE_DISK && sdp->type != TYPE_...
sdp->type != TYPE_RBC)
goto out;
SCSI_LOG_HLQUEUE(3, sdev_printk(KERN_INFO, sdp,
"sd_attach\n"));
-
--[[linux-2.6.25/SCSI_LOG_HLQUEUE()]]
--[[linux-2.6.25/sdev_printk()]]
error = -ENOMEM;
sdkp = kzalloc(sizeof(*sdkp), GFP_KERNEL);
if (!sdkp)
goto out;
-scsi_disk 構造体のメモリを確保&領域をゼロクリアする。
--kzalloc は kmalloc + memset によるゼロクリアで、libc の...
--[[linux-2.6.25/kzalloc()]]
gd = alloc_disk(16);
if (!gd)
goto out_free;
-16個のマイナー番号を用いるディスクを確保する。
--[[linux-2.6.25/alloc_disk()]]
if (!idr_pre_get(&sd_index_idr, GFP_KERNEL))
goto out_put;
-
--[[linux-2.6.25/idr_pre_get()]]
spin_lock(&sd_index_lock);
error = idr_get_new(&sd_index_idr, NULL, &index);
spin_unlock(&sd_index_lock);
-
--[[linux-2.6.25/idr_get_new()]]
if (index >= SD_MAX_DISKS)
error = -EBUSY;
if (error)
goto out_put;
sdkp->device = sdp;
sdkp->driver = &sd_template;
sdkp->disk = gd;
sdkp->index = index;
sdkp->openers = 0;
sdkp->previous_state = 1;
-
--sdkp の型は scsi_disk 構造体である。
--[[linux-2.6.25/scsi_disk]]
--sd_template はドライバが行うデフォルトの処理を
記述したテンプレート変数である。
---[[linux-2.6.25/scsi_driver]]
if (!sdp->timeout) {
if (sdp->type != TYPE_MOD)
sdp->timeout = SD_TIMEOUT;
else
sdp->timeout = SD_MOD_TIMEOUT;
}
-タイムアウト時間が設定されていない場合はデフォルト値を入...
--SD_TIMEOUT は 30秒
--SD_MOD_TIMEOUT は 75秒
--[[linux-2.6.25/include/scsi/sd.h]] で定義されている。
class_device_initialize(&sdkp->cdev);
sdkp->cdev.dev = &sdp->sdev_gendev;
sdkp->cdev.class = &sd_disk_class;
strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bu...
-
--[[linux-2.6.25/class_device_initialize()]]
--[[linux-2.6.25/strncpy()]]
--sd_disk_class は SCSI ブロックデバイスドライバのクラス...
---[[linux-2.6.25/class]]
if (class_device_add(&sdkp->cdev))
goto out_put;
-
--[[linux-2.6.25/class_device_add()]]
get_device(&sdp->sdev_gendev);
-
--[[linux-2.6.25/get_device()]]
gd->major = sd_major((index & 0xf0) >> 4);
gd->first_minor = ((index & 0xf) << 4) | (index ...
gd->minors = 16;
gd->fops = &sd_fops;
-
--sd_fops は SCSI ブロックデバイスの操作を記述した構造体...
--[[linux-2.6.25/sd_major()]]
if (index < 26) {
sprintf(gd->disk_name, "sd%c", 'a' + ind...
} else if (index < (26 + 1) * 26) {
sprintf(gd->disk_name, "sd%c%c",
'a' + index / 26 - 1,'a' + index...
} else {
const unsigned int m1 = (index / 26 - 1)...
const unsigned int m2 = (index / 26 - 1)...
const unsigned int m3 = index % 26;
sprintf(gd->disk_name, "sd%c%c%c",
'a' + m1, 'a' + m2, 'a' + m3);
}
-SCSI ディスクデバイスの名前を生成する。
--1 <= n <= 26: sda, sdb, ...
--27 <= n <= 26^2 + 26 = 702: sdaa, sdab, ..., sdba, sdbb...
--702 <= n <= 65535: sdaaa, sdaab, ...
--[[linux-2.6.25/sprintf()]]
gd->private_data = &sdkp->driver;
gd->queue = sdkp->device->request_queue;
-
--
sd_revalidate_disk(gd);
-
--[[linux-2.6.25/sd_revalidate_disk()]]
blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
-
--[[linux-2.6.25/blk_queue_prep_rq()]]
gd->driverfs_dev = &sdp->sdev_gendev;
gd->flags = GENHD_FL_DRIVERFS;
if (sdp->removable)
gd->flags |= GENHD_FL_REMOVABLE;
dev_set_drvdata(dev, sdkp);
add_disk(gd);
-システムにブロックデバイスを登録する。
--[[linux-2.6.25/dev_set_drvdata()]]
--[[linux-2.6.25/add_disk()]]
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdi...
sdp->removable ? "removable " : "");
return 0;
out_put:
put_disk(gd);
-システムからブロックデバイスを削除する。
--[[linux-2.6.25/put_disk()]]
out_free:
kfree(sdkp);
-SCSI ブロックデバイスのための領域を削除する。
--[[linux-2.6.25/put_disk()]]
out:
return error;
}
*コメント [#wc426329]
終了行:
*参照元 [#hf41c32b]
#backlinks
*説明 [#d462b787]
-パス: [[linux-2.6.25/drivers/scsi/sd.c]]
-FIXME: これは何?
--説明
**引数 [#j04dc2b9]
-struct device *dev
--
**返り値 [#x0edd28e]
-int
--
**参考 [#s40c9fe7]
-sd_index_idr は
--[[linux-2.6.25/DEFINE_IDR()]]
static DEFINE_IDR(sd_index_idr);
-sd_template は SCSI ブロックデバイスのデフォルトの動作を...
--[[linux-2.6.25/sd_template]]
--[[linux-2.6.25/sd_probe()]]
--[[linux-2.6.25/sd_remove()]]
--[[linux-2.6.25/sd_suspend()]]
--[[linux-2.6.25/sd_resume()]]
--[[linux-2.6.25/sd_shutdown()]]
--[[linux-2.6.25/sd_rescan()]]
--[[linux-2.6.25/sd_done()]]
static struct scsi_driver sd_template = {
.owner = THIS_MODULE,
.gendrv = {
.name = "sd",
.probe = sd_probe,
.remove = sd_remove,
.suspend = sd_suspend,
.resume = sd_resume,
.shutdown = sd_shutdown,
},
.rescan = sd_rescan,
.done = sd_done,
};
-sd_disk_class は SCSI ブロックデバイスドライバのクラスを...
--[[linux-2.6.25/class]]
--[[linux-2.6.25/THIS_MODULE]]
--[[linux-2.6.25/scsi_disk_release()]]
--sd_disk_attrs も static 変数である。
static struct class sd_disk_class = {
.name = "scsi_disk",
.owner = THIS_MODULE,
.release = scsi_disk_release,
.class_dev_attrs = sd_disk_attrs,
};
-sd_disk_attrs は SCSI ブロックデバイスドライバのクラスの
属性を表す。
--[[linux-2.6.25/__ATTR()]]
--cache_type メンバ
---
---読み、[[linux-2.6.25/sd_show_cache_type()]]
---書き、[[linux-2.6.25/sd_store_cache_type()]]
--FUA メンバ
---
---読み、[[linux-2.6.25/sd_show_fua()]]
---書けない
--allow_restart メンバ
---
---読み、[[linux-2.6.25/sd_show_allow_restart()]]
---書き、[[linux-2.6.25/sd_store_allow_restart()]]
--manage_start_stop メンバ
---
---読み、[[linux-2.6.25/sd_show_manage_start_stop()]]
---書き、[[linux-2.6.25/sd_store_manage_start_stop()]]
static struct class_device_attribute sd_disk_attrs[] = {
__ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cach...
sd_store_cache_type),
__ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
__ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_a...
sd_store_allow_restart),
__ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_sh...
sd_store_manage_start_stop),
__ATTR_NULL,
};
-sd_fops は SCSI ブロックデバイスに対する操作を表す。
--これらの関数はブロックデバイスへの要求に応じて、
ブロックデバイスサブシステムから呼び出される。
static struct block_device_operations sd_fops = {
.owner = THIS_MODULE,
.open = sd_open,
.release = sd_release,
.ioctl = sd_ioctl,
.getgeo = sd_getgeo,
#ifdef CONFIG_COMPAT
.compat_ioctl = sd_compat_ioctl,
#endif
.media_changed = sd_media_changed,
.revalidate_disk = sd_revalidate_disk,
};
*実装 [#kf000cbc]
/**
* sd_probe - called during driver initialization a...
* new scsi device is attached to the system. It is...
* for each scsi device (not just disks) present.
* @dev: pointer to device object
*
* Returns 0 if successful (or not interested in th...
* (e.g. scanner)); 1 when there is an error.
*
* Note: this function is invoked from the scsi mid...
* This function sets up the mapping between a given
* <host,channel,id,lun> (found in sdp) and new dev...
* (e.g. /dev/sda). More precisely it is the block ...
* and minor number that is chosen here.
*
* Assume sd_attach is not re-entrant (for time bei...
* Also think about sd_attach() and sd_remove() run...
**/
static int sd_probe(struct device *dev)
{
struct scsi_device *sdp = to_scsi_device(dev);
struct scsi_disk *sdkp;
struct gendisk *gd;
u32 index;
int error;
-
--[[linux-2.6.25/to_scsi_device()]]
--[[linux-2.6.25/scsi_device]]
--[[linux-2.6.25/scsi_disk]]
--[[linux-2.6.25/gendisk]]
error = -ENODEV;
if (sdp->type != TYPE_DISK && sdp->type != TYPE_...
sdp->type != TYPE_RBC)
goto out;
SCSI_LOG_HLQUEUE(3, sdev_printk(KERN_INFO, sdp,
"sd_attach\n"));
-
--[[linux-2.6.25/SCSI_LOG_HLQUEUE()]]
--[[linux-2.6.25/sdev_printk()]]
error = -ENOMEM;
sdkp = kzalloc(sizeof(*sdkp), GFP_KERNEL);
if (!sdkp)
goto out;
-scsi_disk 構造体のメモリを確保&領域をゼロクリアする。
--kzalloc は kmalloc + memset によるゼロクリアで、libc の...
--[[linux-2.6.25/kzalloc()]]
gd = alloc_disk(16);
if (!gd)
goto out_free;
-16個のマイナー番号を用いるディスクを確保する。
--[[linux-2.6.25/alloc_disk()]]
if (!idr_pre_get(&sd_index_idr, GFP_KERNEL))
goto out_put;
-
--[[linux-2.6.25/idr_pre_get()]]
spin_lock(&sd_index_lock);
error = idr_get_new(&sd_index_idr, NULL, &index);
spin_unlock(&sd_index_lock);
-
--[[linux-2.6.25/idr_get_new()]]
if (index >= SD_MAX_DISKS)
error = -EBUSY;
if (error)
goto out_put;
sdkp->device = sdp;
sdkp->driver = &sd_template;
sdkp->disk = gd;
sdkp->index = index;
sdkp->openers = 0;
sdkp->previous_state = 1;
-
--sdkp の型は scsi_disk 構造体である。
--[[linux-2.6.25/scsi_disk]]
--sd_template はドライバが行うデフォルトの処理を
記述したテンプレート変数である。
---[[linux-2.6.25/scsi_driver]]
if (!sdp->timeout) {
if (sdp->type != TYPE_MOD)
sdp->timeout = SD_TIMEOUT;
else
sdp->timeout = SD_MOD_TIMEOUT;
}
-タイムアウト時間が設定されていない場合はデフォルト値を入...
--SD_TIMEOUT は 30秒
--SD_MOD_TIMEOUT は 75秒
--[[linux-2.6.25/include/scsi/sd.h]] で定義されている。
class_device_initialize(&sdkp->cdev);
sdkp->cdev.dev = &sdp->sdev_gendev;
sdkp->cdev.class = &sd_disk_class;
strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bu...
-
--[[linux-2.6.25/class_device_initialize()]]
--[[linux-2.6.25/strncpy()]]
--sd_disk_class は SCSI ブロックデバイスドライバのクラス...
---[[linux-2.6.25/class]]
if (class_device_add(&sdkp->cdev))
goto out_put;
-
--[[linux-2.6.25/class_device_add()]]
get_device(&sdp->sdev_gendev);
-
--[[linux-2.6.25/get_device()]]
gd->major = sd_major((index & 0xf0) >> 4);
gd->first_minor = ((index & 0xf) << 4) | (index ...
gd->minors = 16;
gd->fops = &sd_fops;
-
--sd_fops は SCSI ブロックデバイスの操作を記述した構造体...
--[[linux-2.6.25/sd_major()]]
if (index < 26) {
sprintf(gd->disk_name, "sd%c", 'a' + ind...
} else if (index < (26 + 1) * 26) {
sprintf(gd->disk_name, "sd%c%c",
'a' + index / 26 - 1,'a' + index...
} else {
const unsigned int m1 = (index / 26 - 1)...
const unsigned int m2 = (index / 26 - 1)...
const unsigned int m3 = index % 26;
sprintf(gd->disk_name, "sd%c%c%c",
'a' + m1, 'a' + m2, 'a' + m3);
}
-SCSI ディスクデバイスの名前を生成する。
--1 <= n <= 26: sda, sdb, ...
--27 <= n <= 26^2 + 26 = 702: sdaa, sdab, ..., sdba, sdbb...
--702 <= n <= 65535: sdaaa, sdaab, ...
--[[linux-2.6.25/sprintf()]]
gd->private_data = &sdkp->driver;
gd->queue = sdkp->device->request_queue;
-
--
sd_revalidate_disk(gd);
-
--[[linux-2.6.25/sd_revalidate_disk()]]
blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
-
--[[linux-2.6.25/blk_queue_prep_rq()]]
gd->driverfs_dev = &sdp->sdev_gendev;
gd->flags = GENHD_FL_DRIVERFS;
if (sdp->removable)
gd->flags |= GENHD_FL_REMOVABLE;
dev_set_drvdata(dev, sdkp);
add_disk(gd);
-システムにブロックデバイスを登録する。
--[[linux-2.6.25/dev_set_drvdata()]]
--[[linux-2.6.25/add_disk()]]
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdi...
sdp->removable ? "removable " : "");
return 0;
out_put:
put_disk(gd);
-システムからブロックデバイスを削除する。
--[[linux-2.6.25/put_disk()]]
out_free:
kfree(sdkp);
-SCSI ブロックデバイスのための領域を削除する。
--[[linux-2.6.25/put_disk()]]
out:
return error;
}
*コメント [#wc426329]
ページ名: