- outb(WBSD_CONF_ID_LO, config_ports[i]);
- id |= inb(config_ports[i] + 1);
-
- for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++)
- {
- if (id == valid_ids[k])
- {
- host->chip_id = id;
- host->config = config_ports[i];
- host->unlock_code = unlock_codes[i];
-
- return 0;
- }
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+
+ host->dma = -1;
+
+ /*
+ * Set host parameters.
+ */
+ mmc->ops = &wbsd_ops;
+ mmc->f_min = 375000;
+ mmc->f_max = 24000000;
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ mmc->caps = MMC_CAP_4_BIT_DATA;
+
+ spin_lock_init(&host->lock);
+
+ /*
+ * Set up timers
+ */
+ init_timer(&host->ignore_timer);
+ host->ignore_timer.data = (unsigned long)host;
+ host->ignore_timer.function = wbsd_reset_ignore;
+
+ /*
+ * Maximum number of segments. Worst case is one sector per segment
+ * so this will be 64kB/512.
+ */
+ mmc->max_hw_segs = 128;
+ mmc->max_phys_segs = 128;
+
+ /*
+ * Maximum number of sectors in one transfer. Also limited by 64kB
+ * buffer.
+ */
+ mmc->max_sectors = 128;
+
+ /*
+ * Maximum segment size. Could be one segment with the maximum number
+ * of segments.
+ */
+ mmc->max_seg_size = mmc->max_sectors * 512;
+
+ dev_set_drvdata(dev, mmc);
+
+ return 0;
+}
+
+static void __devexit wbsd_free_mmc(struct device *dev)
+{
+ struct mmc_host *mmc;
+ struct wbsd_host *host;
+
+ mmc = dev_get_drvdata(dev);
+ if (!mmc)
+ return;
+
+ host = mmc_priv(mmc);
+ BUG_ON(host == NULL);
+
+ del_timer_sync(&host->ignore_timer);
+
+ mmc_free_host(mmc);
+
+ dev_set_drvdata(dev, NULL);
+}
+
+/*
+ * Scan for known chip id:s
+ */
+
+static int __devinit wbsd_scan(struct wbsd_host *host)
+{
+ int i, j, k;
+ int id;
+
+ /*
+ * Iterate through all ports, all codes to
+ * find hardware that is in our known list.
+ */
+ for (i = 0; i < ARRAY_SIZE(config_ports); i++) {
+ if (!request_region(config_ports[i], 2, DRIVER_NAME))
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(unlock_codes); j++) {
+ id = 0xFFFF;
+
+ host->config = config_ports[i];
+ host->unlock_code = unlock_codes[j];
+
+ wbsd_unlock_config(host);
+
+ outb(WBSD_CONF_ID_HI, config_ports[i]);
+ id = inb(config_ports[i] + 1) << 8;
+
+ outb(WBSD_CONF_ID_LO, config_ports[i]);
+ id |= inb(config_ports[i] + 1);
+
+ wbsd_lock_config(host);
+
+ for (k = 0; k < ARRAY_SIZE(valid_ids); k++) {
+ if (id == valid_ids[k]) {
+ host->chip_id = id;
+
+ return 0;
+ }