]>
git.ipfire.org Git - people/trikolon/ipfire-2.x.git/blob - src/hwinfo/src/hd/pcmcia.c
10 #include <sys/mount.h>
11 #include <linux/hdreg.h>
17 static void read_cardinfo(hd_data_t
*hd_data
);
18 static void assign_bridges(hd_data_t
*hd_data
);
19 static void add_sysfs_stuff(hd_data_t
*hd_data
, hd_t
*hd
);
21 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22 * PCMCIA info via cardctl
24 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
28 void hd_scan_pcmcia(hd_data_t
*hd_data
)
30 if(!hd_probe_feature(hd_data
, pr_pcmcia
)) return;
32 hd_data
->module
= mod_pcmcia
;
35 remove_hd_entries(hd_data
);
37 read_cardinfo(hd_data
);
39 assign_bridges(hd_data
);
44 void read_cardinfo(hd_data_t
*hd_data
)
46 str_list_t
*sl
, *sl0
, *sl1
;
47 int i0
, i1
, pcmcia_sock
, manf_id0
, manf_id1
, func
, prod_info
;
48 char buf0
[256], buf1
[256], buf2
[256], buf3
[256];
50 unsigned cardbus
= 0; /* bitmask: cardbus vs. pc-card */
52 sl0
= read_file("| /sbin/cardctl status 2>/dev/null", 0, 0);
54 ADD2LOG("----- cardctl status -----\n");
55 for(sl
= sl0
; sl
; sl
= sl
->next
) {
56 ADD2LOG(" %s", sl
->str
);
58 ADD2LOG("----- cardctl status end -----\n");
60 for(pcmcia_sock
= -1, sl
= sl0
; sl
; sl
= sl
->next
) {
61 if(sscanf(sl
->str
, " Socket %d:", &i0
) == 1) {
66 if(strstr(sl
->str
, " CardBus card")) {
67 if(pcmcia_sock
>= 0 && pcmcia_sock
< 8 * (int) sizeof cardbus
) {
68 cardbus
|= 1 << pcmcia_sock
;
77 sl0
= read_file("| /sbin/cardctl ident 2>/dev/null", 0, 0);
79 ADD2LOG("----- cardctl ident -----\n");
80 for(sl
= sl0
; sl
; sl
= sl
->next
) {
81 ADD2LOG(" %s", sl
->str
);
83 ADD2LOG("----- cardctl ident end -----\n");
86 pcmcia_sock
= manf_id0
= manf_id1
= func
= prod_info
= -1, sl
= sl0
;
90 if(sscanf(sl
->str
, " manfid: %i, %i", &i0
, &i1
) == 2) {
95 if(sscanf(sl
->str
, " function: %d", &i0
) == 1) {
97 * "multifunction", "memory", "serial", "parallel",
98 * "fixed disk", "video", "network", "AIMS",
107 " product info: \"%255[^\"]\", \"%255[^\"]\", \"%255[^\"]\", \"%255[^\"]\"",
108 buf0
, buf1
, buf2
, buf3
114 if(sscanf(sl
->str
, " Socket %d:", &i0
) == 1) {
121 if(i1
|| !sl
->next
) {
122 if(pcmcia_sock
>= 0 && (prod_info
>= 1 || manf_id0
!= -1)) {
123 hd
= add_hd_entry(hd_data
, __LINE__
, 0);
124 hd
->bus
.id
= bus_pcmcia
;
125 hd
->slot
= pcmcia_sock
;
126 hd
->hotplug_slot
= pcmcia_sock
+ 1;
127 if(manf_id0
!= -1 && manf_id1
!= -1) {
128 hd
->vendor
.id
= MAKE_ID(TAG_PCMCIA
, manf_id0
);
129 hd
->device
.id
= MAKE_ID(TAG_PCMCIA
, manf_id1
);
131 if(pcmcia_sock
< 8 * (int) sizeof cardbus
&& (cardbus
& (1 << pcmcia_sock
))) {
132 hd
->hotplug
= hp_cardbus
;
135 hd
->hotplug
= hp_pcmcia
;
139 hd
->base_class
.id
= bc_network
;
140 hd
->sub_class
.id
= 0x80; /* other */
142 if(prod_info
>= 1) add_str_list(&hd
->extra_info
, buf0
);
143 if(prod_info
>= 2) add_str_list(&hd
->extra_info
, buf1
);
144 if(prod_info
>= 3) add_str_list(&hd
->extra_info
, buf2
);
145 if(prod_info
>= 4) add_str_list(&hd
->extra_info
, buf3
);
147 hd
->vendor
.name
= new_str(buf0
);
148 hd
->device
.name
= new_str(buf1
);
150 for(sl1
= hd
->extra_info
; sl1
; sl1
= sl1
->next
) {
151 if(strstr(sl1
->str
, "Ethernet")) hd
->sub_class
.id
= 0; /* ethernet */
153 !hd
->revision
.name
&&
156 !strncasecmp(sl1
->str
, "rev.", sizeof "rev." - 1) ||
158 (sl1
->str
[0] == 'V' || sl1
->str
[0] == 'v') &&
159 (sl1
->str
[1] >= '0' && sl1
->str
[1] <= '9')
163 hd
->revision
.name
= new_str(sl1
->str
);
168 manf_id0
= manf_id1
= func
= prod_info
= -1;
171 if(i1
) pcmcia_sock
= i0
;
180 * Identify hotpluggable devices.
182 void assign_bridges(hd_data_t
*hd_data
)
184 hd_t
*hd
, *hd1
, *bridge_hd
;
185 unsigned p_sock
[8], p_socks
, u
= 0;
187 for(hd
= hd_data
->hd
; hd
; hd
= hd
->next
) {
188 if((bridge_hd
= hd_get_device_by_idx(hd_data
, hd
->attached_to
))) {
190 bridge_hd
->base_class
.id
== bc_bridge
&&
191 bridge_hd
->sub_class
.id
== sc_bridge_cardbus
193 hd
->hotplug
= hp_cardbus
;
196 bridge_hd
->base_class
.id
== bc_bridge
&&
197 bridge_hd
->sub_class
.id
== sc_bridge_pcmcia
199 hd
->hotplug
= hp_pcmcia
;
204 for(p_socks
= 0, hd
= hd_data
->hd
; hd
; hd
= hd
->next
) {
206 u
< sizeof p_sock
/ sizeof *p_sock
&&
207 is_pcmcia_ctrl(hd_data
, hd
)
209 p_sock
[p_socks
++] = hd
->idx
;
214 for(hd
= hd_data
->hd
; hd
; hd
= hd
->next
) {
217 hd
->bus
.id
== bus_pcmcia
&&
218 hd
->slot
< p_socks
&&
221 for(u
= p_sock
[hd
->slot
], hd1
= hd_data
->hd
; hd1
; hd1
= hd1
->next
) {
222 if(hd1
->tag
.remove
) continue;
223 if(hd1
->status
.available
== status_no
) continue;
224 if(hd1
->attached_to
== u
) break;
227 hd1
->hotplug
= hd
->hotplug
;
228 hd1
->hotplug_slot
= hd
->hotplug_slot
;
229 if(!hd1
->extra_info
) {
230 hd1
->extra_info
= hd
->extra_info
;
231 hd
->extra_info
= NULL
;
236 hd
->attached_to
= p_sock
[hd
->slot
];
237 add_sysfs_stuff(hd_data
, hd
);
239 p_sock
[hd
->slot
] = 0;
243 remove_tagged_hd_entries(hd_data
);
248 void add_sysfs_stuff(hd_data_t
*hd_data
, hd_t
*hd
)
252 struct sysfs_device
*sf_dev
;
254 hd_par
= hd_get_device_by_idx(hd_data
, hd
->attached_to
);
256 if(!hd_par
|| !hd_par
->sysfs_id
|| hd
->sysfs_id
) return;
258 str_printf(&s
, 0, "/sys%s/%d.0", hd_par
->sysfs_id
, hd
->slot
);
260 sf_dev
= sysfs_open_device_path(s
);
263 hd
->sysfs_id
= new_str(hd_sysfs_id(s
));
264 s1
= hd_sysfs_find_driver(hd_data
, hd
->sysfs_id
, 1);
265 if(s1
) add_str_list(&hd
->drivers
, s1
);
268 sysfs_close_device(sf_dev
);