rtsx.c のパッチ検討 #台風そん

メモを見つつ検討。なんとなく朝は二度寝をキメてて (.config を誤って削除してしまいモチベーションが完全に切れましたorz)、昼飯後は囲碁を見つつごろごろしてたんですが、酒でも入れてやろうかな、とソースを開いてたりしたらなんとなくエンジンがかかってきました。

検討メモ

以下に控えつつ。printk を検索した順で。

static int queuecommand_lck(struct scsi_cmnd *srb,
			void (*done)(struct scsi_cmnd *))
{
	struct rtsx_dev *dev = host_to_rtsx(srb->device->host);
	struct rtsx_chip *chip = dev->chip;

	/* check for state-transition errors */
	if (chip->srb != NULL) {
		printk(KERN_ERR "Error in %s: chip->srb = %p\n",
			__func__, chip->srb);

このケイスは rtsx_dev から struct device 構造体なナニを手繰れます。struct rtsx_dev 型の定義が以下なカンジで

struct rtsx_dev {
	struct pci_dev *pci;

struct pci_dev 型に

	struct	device	dev;		/* Generic device interface */

という属性があるので上のソレだと以下に直すんかな。

	if (chip->srb != NULL) {
	        dev_err(&dev->pci->dev, "Error in %s: chip->srb = %p\n",
			__func__, chip->srb);

次の手続きも struct rtsx_dev 型で云々してますね。

static int command_abort(struct scsi_cmnd *srb)
{
	struct Scsi_Host *host = srb->device->host;
	struct rtsx_dev *dev = host_to_rtsx(host);
	struct rtsx_chip *chip = dev->chip;

	printk(KERN_INFO "%s called\n", __func__);

次、あるいはその次とかは struct rtsx_dev 型のソレを取得しないと駄目かな。

static int device_reset(struct scsi_cmnd *srb)
{
	int result = 0;

	printk(KERN_INFO "%s called\n", __func__);

	return result < 0 ? FAILED : SUCCESS;
}

/* Simulate a SCSI bus reset by resetting the device's USB port. */
static int bus_reset(struct scsi_cmnd *srb)
{
	int result = 0;

	printk(KERN_INFO "%s called\n", __func__);

以下を追加して

	struct rtsx_dev *dev = host_to_rtsx(srb->device->host);

printk が以下なカンジになるのかな。

	dev_info(&dev->pci->dev, "%s called\n", __func__);

次に出てくるソレは引数が strct rtsx_dev 型なので楽ですね。

static int rtsx_acquire_irq(struct rtsx_dev *dev)
{
	struct rtsx_chip *chip = dev->chip;

	printk(KERN_INFO "%s: chip->msi_en = %d, pci->irq = %d\n",

で、次は struct pci_dev 型な引数になってます。これも楽。

static int rtsx_suspend(struct pci_dev *pci, pm_message_t state)
{
	struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
	struct rtsx_chip *chip;

	printk(KERN_INFO "Ready to suspend\n");

一応、struct rtsx_dev 型のオブジェクトを取得してるので一応そこから取るか。次も同様ですね。

static int rtsx_resume(struct pci_dev *pci)
{
	struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
	struct rtsx_chip *chip;

	printk(KERN_INFO "Ready to resume\n");

同様の手続き定義が続きます。

  • static void rtsx_shutdown(struct pci_dev)

を、次に出てくるのもアレゲ

static int rtsx_control_thread(void *__dev)
{
	struct rtsx_dev *dev = (struct rtsx_dev *)__dev;
	struct rtsx_chip *chip = dev->chip;
	struct Scsi_Host *host = rtsx_to_host(dev);

これも struct rtsx_dev 型のローカル変数使えば良いか。最後、同様の手続き定義が続きます。

  • static int rtsx_polling_thread(void *)
  • static int rtsx_scan_thread(void *)

次に printk が出てくるのは、というと。

static void rtsx_release_resources(struct rtsx_dev *dev)
{
	printk(KERN_INFO "-- %s\n", __func__);

これも引数に struct rtsx_dev 型を頂戴してるので楽ですな。

むむ

そろそろ微妙になってきた。

static int __devinit rtsx_probe(struct pci_dev *pci,
				const struct pci_device_id *pci_id)
{
	struct Scsi_Host *host;
	struct rtsx_dev *dev;
	int err = 0;
	struct task_struct *th;

	RTSX_DEBUGP("Realtek PCI-E card reader detected\n");

	err = pci_enable_device(pci);
	if (err < 0) {
		printk(KERN_ERR "PCI enable device failed!\n");

これ、なんとなく struct pci_dev なオブジェクトの初期化っぽく見えるなぁ。ここ、もう少し色々確認した方が良さげ。
で、drivers/scsi 配下を漁ってみたら以下なサンプルあり (drivers/scsi/pmcraid.c)。

static int __devinit pmcraid_probe(
	struct pci_dev *pdev,
	const struct pci_device_id *dev_id
)
{
	struct pmcraid_instance *pinstance;
	struct Scsi_Host *host;
	void __iomem *mapped_pci_addr;
	int rc = PCIBIOS_SUCCESSFUL;

/* snip */
	rc = pci_enable_device(pdev);

	if (rc) {
		dev_err(&pdev->dev, "Cannot enable adapter\n");

あ、有効とかなんとかは構わずどんどん使えてきやりとりをどっかで見ましたな。つうことでパッチを作って投げましょう。

もうひとつ

上の probe 手続きでも出てきてるんですが、

	RTSX_DEBUGP("Realtek PCI-E card reader detected\n");

このマクロ対応をしないといけないのが非常にアレ。とりあえずマクロの定義だけ残しておいて全部 dev_debug だかに変えれば良いのかな。