Merge from vendor branch LIBSTDC++:
[dragonfly.git] / release / sysinstall / pccard.c
1 /*
2  * PC-card support for sysinstall
3  *
4  * $FreeBSD: src/release/sysinstall/pccard.c,v 1.10.2.7 2001/09/27 06:53:11 murray Exp $
5  * $DragonFly: src/release/sysinstall/Attic/pccard.c,v 1.3 2003/08/22 18:33:53 dillon Exp $
6  *
7  * Copyright (c) 1997-1999
8  *      Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org>.  All rights reserved.
9  *
10  * This software may be used, modified, copied, and distributed, in
11  * both source and binary form provided that the above copyright and
12  * these terms are retained. Under no circumstances is the author
13  * responsible for the proper functioning of this software, nor does
14  * the author assume any responsibility for damages incurred with its
15  * use.
16  */
17
18 #include "sysinstall.h"
19 #include <sys/fcntl.h>
20 #include <sys/time.h>
21 #include <bus/pccard/cardinfo.h>
22
23 int     pccard_mode = 0;
24
25 /*
26  * Set up defines for pccardd interrupt selection.
27  */
28 #ifdef PC98
29 #define IRQ_COUNT       11
30 #else
31 #define IRQ_COUNT       9
32 #endif /* PC98 */
33 #define IRQ_10          0x00001
34 #define IRQ_11          0x00002
35 #define IRQ_03          0x00004
36 #define IRQ_09          0x00008
37 #define IRQ_04          0x00010
38 #define IRQ_07          0x00020
39 #define IRQ_05          0x00040
40 #define IRQ_06          0x00080
41 #define IRQ_15          0x00100
42 #ifdef PC98
43 #define IRQ_12          0x00200
44 #define IRQ_13          0x00400
45 #endif /* PC98 */
46
47 unsigned int CardIrq;
48
49 typedef struct _irq {
50     char *my_name;
51     char *my_flag;
52     unsigned int my_mask;
53     unsigned int my_bit;
54 } Irq;
55
56 /* Fill in with potential free IRQs for pccardd */
57 static Irq IrqTable[] = {
58     { "irq_03", "-i 3",  ~IRQ_03, IRQ_03 },
59     { "irq_04", "-i 4",  ~IRQ_04, IRQ_04 },
60     { "irq_05", "-i 5",  ~IRQ_05, IRQ_05 },
61     { "irq_06", "-i 6",  ~IRQ_06, IRQ_06 },
62     { "irq_07", "-i 7",  ~IRQ_07, IRQ_07 },
63     { "irq_09", "-i 9",  ~IRQ_09, IRQ_09 },
64     { "irq_10", "-i 10", ~IRQ_10, IRQ_10 },
65     { "irq_11", "-i 11", ~IRQ_11, IRQ_11 },
66     { "irq_15", "-i 15", ~IRQ_15, IRQ_15 },
67 #ifdef PC98
68     { "irq_12", "-i 12", ~IRQ_12, IRQ_12 },
69     { "irq_13", "-i 13", ~IRQ_13, IRQ_13 },
70 #endif /* PC98 */
71     {NULL},
72 };
73
74 int
75 pccardIrqReset(dialogMenuItem *self)
76 {
77     CardIrq = 0;
78     return DITEM_SUCCESS | DITEM_REDRAW;
79 }
80
81 static int
82 checkTrue(dialogMenuItem *item)
83 {
84     return TRUE;
85 }
86
87 DMenu MenuPCICMem = {
88     DMENU_NORMAL_TYPE | DMENU_SELECTION_RETURNS,
89     "Please select free address area used by PC-card controller",
90     "PC-card controller uses memory area to get card information.\n"
91     "Please specify an address that is not used by other devices.\n"
92     "If you're uncertain of detailed specification of your hardware,\n"
93 #ifdef PC98
94     "leave it untouched (default == 0xd0000).\n"
95     "If you use PC-9801 P, NS/A, NX/C, NL/R or PC-9821 Ne please \n"
96     "select [DA] here.",
97 #else
98     "leave it untouched (default == 0xd0000).",
99 #endif /* PC98 */
100     "Press F1 for more HELP",
101     "pccard",
102     { { "Default",  "I/O address 0xd0000 - 0xd3fff",
103         NULL, dmenuSetVariable, NULL, "_pcicmem=0"},
104       { "D4", "I/O address 0xd4000 - 0xd7fff",
105         NULL, dmenuSetVariable, NULL, "_pcicmem=1"},
106       { "D8", "I/O address 0xd8000 - 0xdbfff",
107         NULL,  dmenuSetVariable, NULL, "_pcicmem=2"},
108       { "DC", "I/O address 0xdc000 - 0xdffff",
109         NULL,  dmenuSetVariable, NULL, "_pcicmem=3"},
110 #ifdef PC98
111       { "DA", "I/O address 0xda000 - 0xdbfff",
112         NULL,  dmenuSetVariable, NULL, "_pcicmem=4"},
113 #endif /* PC98 */
114       { NULL } },
115 };
116
117 DMenu MenuCardIRQ = {
118     DMENU_CHECKLIST_TYPE | DMENU_SELECTION_RETURNS,
119     "Please specify the IRQs that may be used by PC-Cards",
120     "(NOTE: remove any cards that will NOT be used for installation).\n"
121     "The IRQs that you choose must be free (unshared), or you risk \n"
122     "subpar performance and/or a complete system lockup (choose wisely).\n"
123     "One way to determine which IRQs are available is to \"cheat\" and\n"
124     "use the Windows 9x/2000 Device Manager as a reference prior to the\n"
125     "installation.\n",
126     "Select Free IRQ for PC-Cardd",
127     NULL,
128     { { "X Exit",    "Exit this menu",
129         checkTrue, dmenuExit, NULL, NULL, '<', '<', '<' }, 
130     { "Reset",     "Reset selected IRQ list",
131         NULL, pccardIrqReset, NULL, NULL, ' ', ' ', ' ' },
132 #ifdef PC98
133     { "3 IRQ 3",    "(INT 0) is 2nd serial port, internal modem",
134         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_03 },
135     { "4 IRQ 5",    "(INT 1) is Infrared communication, SCSI I/F, (2nd serial)",
136         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_05 },
137     { "5 IRQ 6",    "(INT 2) is PC-card Controller",
138         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_06 },
139     { "6 IRQ 9",    "(INT 3) is IDE disk Controller",
140         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_09 },
141     { "7 IRQ 10",   "(INT 41) is often free",
142         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_10 },
143     { "8 IRQ 12",   "(INT 5) is Internal sound",
144         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_12 },
145     { "9 IRQ 13",   "(INT 6) is Bus Mouse",
146         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_13 },
147 #else
148     { "3 IRQ 10",   "IRQ 10 is often free (verify in BIOS)",
149         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_10 },
150     { "4 IRQ 11",   "Verify IRQ 11 is not being used as PCI shared interrupt",
151         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_11 },
152     { "5 IRQ 3",   "IRQ 3 is often free in most laptops",
153         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_03 },
154     { "6 IRQ 9",   "IRQ 9 may be used by video or sound or USB",
155         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_09 },
156     { "7 IRQ 4",   "IRQ 4, usually COM1 (disable in BIOS to make free)",
157         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_04 },
158     { "8 IRQ 7",   "IRQ 7, usually LPT1 (disable in BIOS to make free)",
159         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_07 },
160     { "9 IRQ 5",   "IRQ 5, usually ISA Audio (disable in BIOS to make free)", 
161         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_05 },
162     { "10 IRQ 15", "IRQ 15, usually Secondary IDE channel",
163         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_15 },
164     { "11 IRQ 6",  "IRQ 6 will be free if laptop only has USB floppy drive",
165         dmenuFlagCheck, dmenuSetFlag, NULL, &CardIrq, '[', 'X', ']', IRQ_06 },
166 #endif /* PC98 */
167     { NULL } },
168 };
169
170 void
171 pccardInitialize(void)
172 {
173     int fd;
174     int t;
175     int i;
176     int pcic_mem = 0xd0000;
177     int beep_newstat;
178     char card_device[16];
179     char card_irq[256] = "";
180     char temp[256];
181     char *spcic_mem;
182     char pccardd_cmd[256];
183     WINDOW *w;
184     
185     pccard_mode = 1;
186     
187     if (!RunningAsInit && !Fake) {
188         /* It's not my job... */
189         return;
190     }
191
192     sprintf(card_device, CARD_DEVICE, 0);
193
194     if ((fd = open(card_device, O_RDWR)) < 0) {
195         msgDebug("Can't open PC-card controller %s.\n", card_device);
196         return;
197     }
198     else if (msgYesNo("Found PC-card slot(s).\n"
199                       "Use PC-card device as installation media?\n")) {
200         return;
201     }
202     close(fd);
203
204     variable_set2("_pccard_install", "YES", 0);
205
206     dmenuOpenSimple(&MenuPCICMem, FALSE);
207     spcic_mem = variable_get("_pcicmem");
208     dmenuOpenSimple(&MenuCardIRQ, FALSE);
209
210     sscanf(spcic_mem, "%d", &t);
211     switch (t) {
212       case 0:
213         pcic_mem = 0xd0000;
214         variable_set2("pccard_mem", "DEFAULT", 1);
215         break;
216       case 1:
217         pcic_mem = 0xd4000;
218         variable_set2("pccard_mem", "0xd4000", 1);
219         break;
220       case 2:
221         pcic_mem = 0xd8000;
222         variable_set2("pccard_mem", "0xd8000", 1);
223         break;
224       case 3:
225         pcic_mem = 0xdc000;
226         variable_set2("pccard_mem", "0xdc000", 1);
227         break;
228 #ifdef PC98
229       case 4:
230         pcic_mem = 0xda000;
231         variable_set2("pccard_mem", "0xda000", 1);
232         break;
233 #endif /* PC98 */
234     }
235
236     /* get card_irq out of CardIrq somehow */
237     if (CardIrq) {
238         for (i = 0; i < IRQ_COUNT; i++) {
239             if ((CardIrq & IrqTable[i].my_bit) != 0) {
240                 sprintf(temp, "%s %s", card_irq, IrqTable[i].my_flag);
241                 strcpy(card_irq, temp);
242             }
243         } 
244     }
245
246     w = savescr();
247     dialog_clear_norefresh();
248     msgConfirm("Now we start initializing PC-card controller and cards.\n"
249                "If you've executed this installer from a PC-card floppy\n"
250                "drive, this is the last chance to replace it with\n"
251                "installation media (PC-card Ethernet, CD, DVD, etc.).\n"
252                "Please insert installation media and press [Enter].\n"
253                "If you've not plugged the PC-card installation media\n"
254                "in yet, please plug it in now and press [Enter].\n"
255                "Otherwise, just press [Enter] to proceed."); 
256
257     dialog_clear();
258     msgNotify("Initializing PC-card controller....");
259
260     if (!Fake) {
261         if ((fd = open(card_device, O_RDWR)) < 1) {
262             msgNotify("Can't open PC-card controller %s.\n", card_device);
263             restorescr(w);
264             return;
265         }
266
267         if (ioctl(fd, PIOCRWMEM, &pcic_mem) < 0) {
268             msgNotify("ioctl %s failed.\n", card_device);
269             restorescr(w);
270             return;
271         }
272         beep_newstat = 2;
273         if (ioctl(fd, PIOCSBEEP, &beep_newstat) < 0) {
274             msgNotify("Warning: unable to set pccard insertion beep type for %s",
275                 card_device);
276             restorescr(w);
277             return;
278         }
279
280     }
281
282     strcpy(pccardd_cmd, "/stand/pccardd ");
283     strcat(pccardd_cmd, card_irq);
284     strcat(pccardd_cmd, " -z");
285
286     variable_set2("pccardd_flags", card_irq, 1);
287     variable_set2("pccard_enable", "YES", 1);
288
289     vsystem("%s", pccardd_cmd);
290     restorescr(w);
291 }