hc
2023-02-13 e440ec23c5a540cdd3f7464e8779219be6fd3d95
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * Copyright (c) 1996-2002 Russell King.
 */
 
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/errno.h>
#include <linux/ide.h>
#include <linux/init.h>
 
#include <asm/ecard.h>
 
static const struct ide_port_info rapide_port_info = {
   .host_flags        = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
   .chipset        = ide_generic,
};
 
static void rapide_setup_ports(struct ide_hw *hw, void __iomem *base,
                  void __iomem *ctrl, unsigned int sz, int irq)
{
   unsigned long port = (unsigned long)base;
   int i;
 
   for (i = 0; i <= 7; i++) {
       hw->io_ports_array[i] = port;
       port += sz;
   }
   hw->io_ports.ctl_addr = (unsigned long)ctrl;
   hw->irq = irq;
}
 
static int rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
{
   void __iomem *base;
   struct ide_host *host;
   int ret;
   struct ide_hw hw, *hws[] = { &hw };
 
   ret = ecard_request_resources(ec);
   if (ret)
       goto out;
 
   base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
   if (!base) {
       ret = -ENOMEM;
       goto release;
   }
 
   memset(&hw, 0, sizeof(hw));
   rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq);
   hw.dev = &ec->dev;
 
   ret = ide_host_add(&rapide_port_info, hws, 1, &host);
   if (ret)
       goto release;
 
   ecard_set_drvdata(ec, host);
   goto out;
 
 release:
   ecard_release_resources(ec);
 out:
   return ret;
}
 
static void rapide_remove(struct expansion_card *ec)
{
   struct ide_host *host = ecard_get_drvdata(ec);
 
   ecard_set_drvdata(ec, NULL);
 
   ide_host_remove(host);
 
   ecard_release_resources(ec);
}
 
static struct ecard_id rapide_ids[] = {
   { MANU_YELLOWSTONE, PROD_YELLOWSTONE_RAPIDE32 },
   { 0xffff, 0xffff }
};
 
static struct ecard_driver rapide_driver = {
   .probe        = rapide_probe,
   .remove        = rapide_remove,
   .id_table    = rapide_ids,
   .drv = {
       .name    = "rapide",
   },
};
 
static int __init rapide_init(void)
{
   return ecard_register_driver(&rapide_driver);
}
 
static void __exit rapide_exit(void)
{
   ecard_remove_driver(&rapide_driver);
}
 
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Yellowstone RAPIDE driver");
 
module_init(rapide_init);
module_exit(rapide_exit);