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