aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-12-01 09:36:28 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-12-09 01:09:14 -0500
commitd58b0c39e32f1b410af4d070f9d1a1416057c166 (patch)
treea4a9011c229c5d8d7b953dd5e1b0b70fa28d0a37
parent128b4a0ef74e8d48033513e41a413087ba30e36b (diff)
powerpc/macio: Rework hotplug media bay support
The hotplug mediabay has tendrils deep into drivers/ide code which makes a libata port reather difficult. In addition it's ugly and could be done better. This reworks the interface between the mediabay and the rest of the world so that: - Any macio_driver can now have a mediabay_event callback which will be called when that driver sits on a mediabay and it's been either plugged or unplugged. The device type is passed as an argument. We can now move all the IDE cruft into the IDE driver itself - A check_media_bay() function can be used to take a peek at the type of device currently in the bay if any, a cleaner variant of the previous function with the same name. - A pair of lock/unlock functions are exposed to allow the IDE driver to block the hotplug callbacks during the initial setup and probing of the bay in order to avoid nasty race conditions. - The mediabay code no longer needs to spin on the status register of the IDE interface when it detects an IDE device, this is done just fine by the IDE code itself Overall, less code, simpler, and allows for another driver than our old drivers/ide based one. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/macio.h3
-rw-r--r--arch/powerpc/include/asm/mediabay.h27
-rw-r--r--drivers/block/swim3.c39
-rw-r--r--drivers/ide/pmac.c92
-rw-r--r--drivers/macintosh/mediabay.c328
5 files changed, 214 insertions, 275 deletions
diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h
index 86d5fed1c49f..a062c57696d0 100644
--- a/arch/powerpc/include/asm/macio.h
+++ b/arch/powerpc/include/asm/macio.h
@@ -134,6 +134,9 @@ struct macio_driver
134 int (*resume)(struct macio_dev* dev); 134 int (*resume)(struct macio_dev* dev);
135 int (*shutdown)(struct macio_dev* dev); 135 int (*shutdown)(struct macio_dev* dev);
136 136
137#ifdef CONFIG_PMAC_MEDIABAY
138 void (*mediabay_event)(struct macio_dev* dev, int mb_state);
139#endif
137 struct device_driver driver; 140 struct device_driver driver;
138}; 141};
139#define to_macio_driver(drv) container_of(drv,struct macio_driver, driver) 142#define to_macio_driver(drv) container_of(drv,struct macio_driver, driver)
diff --git a/arch/powerpc/include/asm/mediabay.h b/arch/powerpc/include/asm/mediabay.h
index b2efb3325808..11037a4133ee 100644
--- a/arch/powerpc/include/asm/mediabay.h
+++ b/arch/powerpc/include/asm/mediabay.h
@@ -17,26 +17,31 @@
17#define MB_POWER 6 /* media bay contains a Power device (???) */ 17#define MB_POWER 6 /* media bay contains a Power device (???) */
18#define MB_NO 7 /* media bay contains nothing */ 18#define MB_NO 7 /* media bay contains nothing */
19 19
20/* Number of bays in the machine or 0 */ 20struct macio_dev;
21extern int media_bay_count;
22 21
23#ifdef CONFIG_BLK_DEV_IDE_PMAC 22#ifdef CONFIG_PMAC_MEDIABAY
24#include <linux/ide.h>
25 23
26int check_media_bay_by_base(unsigned long base, int what); 24/* Check the content type of the bay, returns MB_NO if the bay is still
27/* called by IDE PMAC host driver to register IDE controller for media bay */ 25 * transitionning
28int media_bay_set_ide_infos(struct device_node *which_bay, unsigned long base, 26 */
29 int irq, ide_hwif_t *hwif); 27extern int check_media_bay(struct macio_dev *bay);
30 28
31int check_media_bay(struct device_node *which_bay, int what); 29/* The ATA driver uses the calls below to temporarily hold on the
30 * media bay callbacks while initializing the interface
31 */
32extern void lock_media_bay(struct macio_dev *bay);
33extern void unlock_media_bay(struct macio_dev *bay);
32 34
33#else 35#else
34 36
35static inline int check_media_bay(struct device_node *which_bay, int what) 37static inline int check_media_bay(struct macio_dev *bay)
36{ 38{
37 return -ENODEV; 39 return MB_NO;
38} 40}
39 41
42static inline void lock_media_bay(struct macio_dev *bay) { }
43static inline void unlock_media_bay(struct macio_dev *bay) { }
44
40#endif 45#endif
41 46
42#endif /* __KERNEL__ */ 47#endif /* __KERNEL__ */
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index 6380ad8d91bd..59ca2b77b574 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -200,7 +200,7 @@ struct floppy_state {
200 int ejected; 200 int ejected;
201 wait_queue_head_t wait; 201 wait_queue_head_t wait;
202 int wanted; 202 int wanted;
203 struct device_node* media_bay; /* NULL when not in bay */ 203 struct macio_dev *mdev;
204 char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)]; 204 char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)];
205}; 205};
206 206
@@ -303,14 +303,13 @@ static int swim3_readbit(struct floppy_state *fs, int bit)
303static void do_fd_request(struct request_queue * q) 303static void do_fd_request(struct request_queue * q)
304{ 304{
305 int i; 305 int i;
306 for(i=0;i<floppy_count;i++) 306
307 { 307 for(i=0; i<floppy_count; i++) {
308#ifdef CONFIG_PMAC_MEDIABAY 308 struct floppy_state *fs = &floppy_states[i];
309 if (floppy_states[i].media_bay && 309 if (fs->mdev->media_bay &&
310 check_media_bay(floppy_states[i].media_bay, MB_FD)) 310 check_media_bay(fs->mdev->media_bay) != MB_FD)
311 continue; 311 continue;
312#endif /* CONFIG_PMAC_MEDIABAY */ 312 start_request(fs);
313 start_request(&floppy_states[i]);
314 } 313 }
315} 314}
316 315
@@ -849,10 +848,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
849 if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN)) 848 if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
850 return -EPERM; 849 return -EPERM;
851 850
852#ifdef CONFIG_PMAC_MEDIABAY 851 if (fs->mdev->media_bay &&
853 if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD)) 852 check_media_bay(fs->mdev->media_bay) != MB_FD)
854 return -ENXIO; 853 return -ENXIO;
855#endif
856 854
857 switch (cmd) { 855 switch (cmd) {
858 case FDEJECT: 856 case FDEJECT:
@@ -876,10 +874,9 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
876 int n, err = 0; 874 int n, err = 0;
877 875
878 if (fs->ref_count == 0) { 876 if (fs->ref_count == 0) {
879#ifdef CONFIG_PMAC_MEDIABAY 877 if (fs->mdev->media_bay &&
880 if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD)) 878 check_media_bay(fs->mdev->media_bay) != MB_FD)
881 return -ENXIO; 879 return -ENXIO;
882#endif
883 out_8(&sw->setup, S_IBM_DRIVE | S_FCLK_DIV2); 880 out_8(&sw->setup, S_IBM_DRIVE | S_FCLK_DIV2);
884 out_8(&sw->control_bic, 0xff); 881 out_8(&sw->control_bic, 0xff);
885 out_8(&sw->mode, 0x95); 882 out_8(&sw->mode, 0x95);
@@ -963,10 +960,9 @@ static int floppy_revalidate(struct gendisk *disk)
963 struct swim3 __iomem *sw; 960 struct swim3 __iomem *sw;
964 int ret, n; 961 int ret, n;
965 962
966#ifdef CONFIG_PMAC_MEDIABAY 963 if (fs->mdev->media_bay &&
967 if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD)) 964 check_media_bay(fs->mdev->media_bay) != MB_FD)
968 return -ENXIO; 965 return -ENXIO;
969#endif
970 966
971 sw = fs->swim3; 967 sw = fs->swim3;
972 grab_drive(fs, revalidating, 0); 968 grab_drive(fs, revalidating, 0);
@@ -1009,7 +1005,6 @@ static const struct block_device_operations floppy_fops = {
1009static int swim3_add_device(struct macio_dev *mdev, int index) 1005static int swim3_add_device(struct macio_dev *mdev, int index)
1010{ 1006{
1011 struct device_node *swim = mdev->ofdev.node; 1007 struct device_node *swim = mdev->ofdev.node;
1012 struct device_node *mediabay;
1013 struct floppy_state *fs = &floppy_states[index]; 1008 struct floppy_state *fs = &floppy_states[index];
1014 int rc = -EBUSY; 1009 int rc = -EBUSY;
1015 1010
@@ -1036,9 +1031,7 @@ static int swim3_add_device(struct macio_dev *mdev, int index)
1036 } 1031 }
1037 dev_set_drvdata(&mdev->ofdev.dev, fs); 1032 dev_set_drvdata(&mdev->ofdev.dev, fs);
1038 1033
1039 mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? 1034 if (mdev->media_bay == NULL)
1040 swim->parent : NULL;
1041 if (mediabay == NULL)
1042 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); 1035 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
1043 1036
1044 memset(fs, 0, sizeof(*fs)); 1037 memset(fs, 0, sizeof(*fs));
@@ -1068,7 +1061,7 @@ static int swim3_add_device(struct macio_dev *mdev, int index)
1068 fs->secpercyl = 36; 1061 fs->secpercyl = 36;
1069 fs->secpertrack = 18; 1062 fs->secpertrack = 18;
1070 fs->total_secs = 2880; 1063 fs->total_secs = 2880;
1071 fs->media_bay = mediabay; 1064 fs->mdev = mdev;
1072 init_waitqueue_head(&fs->wait); 1065 init_waitqueue_head(&fs->wait);
1073 1066
1074 fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space); 1067 fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space);
@@ -1093,7 +1086,7 @@ static int swim3_add_device(struct macio_dev *mdev, int index)
1093 init_timer(&fs->timeout); 1086 init_timer(&fs->timeout);
1094 1087
1095 printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, 1088 printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count,
1096 mediabay ? "in media bay" : ""); 1089 mdev->media_bay ? "in media bay" : "");
1097 1090
1098 return 0; 1091 return 0;
1099 1092
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 97642a7a79c4..7a4e788cab2f 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -43,10 +43,7 @@
43#include <asm/pmac_feature.h> 43#include <asm/pmac_feature.h>
44#include <asm/sections.h> 44#include <asm/sections.h>
45#include <asm/irq.h> 45#include <asm/irq.h>
46
47#ifndef CONFIG_PPC64
48#include <asm/mediabay.h> 46#include <asm/mediabay.h>
49#endif
50 47
51#define DRV_NAME "ide-pmac" 48#define DRV_NAME "ide-pmac"
52 49
@@ -59,13 +56,14 @@ typedef struct pmac_ide_hwif {
59 int irq; 56 int irq;
60 int kind; 57 int kind;
61 int aapl_bus_id; 58 int aapl_bus_id;
62 unsigned mediabay : 1;
63 unsigned broken_dma : 1; 59 unsigned broken_dma : 1;
64 unsigned broken_dma_warn : 1; 60 unsigned broken_dma_warn : 1;
65 struct device_node* node; 61 struct device_node* node;
66 struct macio_dev *mdev; 62 struct macio_dev *mdev;
67 u32 timings[4]; 63 u32 timings[4];
68 volatile u32 __iomem * *kauai_fcr; 64 volatile u32 __iomem * *kauai_fcr;
65 ide_hwif_t *hwif;
66
69 /* Those fields are duplicating what is in hwif. We currently 67 /* Those fields are duplicating what is in hwif. We currently
70 * can't use the hwif ones because of some assumptions that are 68 * can't use the hwif ones because of some assumptions that are
71 * beeing done by the generic code about the kind of dma controller 69 * beeing done by the generic code about the kind of dma controller
@@ -854,6 +852,11 @@ sanitize_timings(pmac_ide_hwif_t *pmif)
854 pmif->timings[2] = pmif->timings[3] = value2; 852 pmif->timings[2] = pmif->timings[3] = value2;
855} 853}
856 854
855static int on_media_bay(pmac_ide_hwif_t *pmif)
856{
857 return pmif->mdev && pmif->mdev->media_bay != NULL;
858}
859
857/* Suspend call back, should be called after the child devices 860/* Suspend call back, should be called after the child devices
858 * have actually been suspended 861 * have actually been suspended
859 */ 862 */
@@ -866,7 +869,7 @@ static int pmac_ide_do_suspend(pmac_ide_hwif_t *pmif)
866 disable_irq(pmif->irq); 869 disable_irq(pmif->irq);
867 870
868 /* The media bay will handle itself just fine */ 871 /* The media bay will handle itself just fine */
869 if (pmif->mediabay) 872 if (on_media_bay(pmif))
870 return 0; 873 return 0;
871 874
872 /* Kauai has bus control FCRs directly here */ 875 /* Kauai has bus control FCRs directly here */
@@ -889,7 +892,7 @@ static int pmac_ide_do_suspend(pmac_ide_hwif_t *pmif)
889static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif) 892static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif)
890{ 893{
891 /* Hard reset & re-enable controller (do we really need to reset ? -BenH) */ 894 /* Hard reset & re-enable controller (do we really need to reset ? -BenH) */
892 if (!pmif->mediabay) { 895 if (!on_media_bay(pmif)) {
893 ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1); 896 ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1);
894 ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1); 897 ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1);
895 msleep(10); 898 msleep(10);
@@ -950,13 +953,11 @@ static void pmac_ide_init_dev(ide_drive_t *drive)
950 pmac_ide_hwif_t *pmif = 953 pmac_ide_hwif_t *pmif =
951 (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); 954 (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
952 955
953 if (pmif->mediabay) { 956 if (on_media_bay(pmif)) {
954#ifdef CONFIG_PMAC_MEDIABAY 957 if (check_media_bay(pmif->mdev->media_bay) == MB_CD) {
955 if (check_media_bay_by_base(pmif->regbase, MB_CD) == 0) {
956 drive->dev_flags &= ~IDE_DFLAG_NOPROBE; 958 drive->dev_flags &= ~IDE_DFLAG_NOPROBE;
957 return; 959 return;
958 } 960 }
959#endif
960 drive->dev_flags |= IDE_DFLAG_NOPROBE; 961 drive->dev_flags |= IDE_DFLAG_NOPROBE;
961 } 962 }
962} 963}
@@ -1072,26 +1073,23 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif,
1072 writel(KAUAI_FCR_UATA_MAGIC | 1073 writel(KAUAI_FCR_UATA_MAGIC |
1073 KAUAI_FCR_UATA_RESET_N | 1074 KAUAI_FCR_UATA_RESET_N |
1074 KAUAI_FCR_UATA_ENABLE, pmif->kauai_fcr); 1075 KAUAI_FCR_UATA_ENABLE, pmif->kauai_fcr);
1075
1076 pmif->mediabay = 0;
1077 1076
1078 /* Make sure we have sane timings */ 1077 /* Make sure we have sane timings */
1079 sanitize_timings(pmif); 1078 sanitize_timings(pmif);
1080 1079
1080 /* If we are on a media bay, wait for it to settle and lock it */
1081 if (pmif->mdev)
1082 lock_media_bay(pmif->mdev->media_bay);
1083
1081 host = ide_host_alloc(&d, hws, 1); 1084 host = ide_host_alloc(&d, hws, 1);
1082 if (host == NULL) 1085 if (host == NULL) {
1083 return -ENOMEM; 1086 rc = -ENOMEM;
1084 hwif = host->ports[0]; 1087 goto bail;
1088 }
1089 hwif = pmif->hwif = host->ports[0];
1085 1090
1086#ifndef CONFIG_PPC64 1091 if (on_media_bay(pmif)) {
1087 /* XXX FIXME: Media bay stuff need re-organizing */ 1092 /* Fixup bus ID for media bay */
1088 if (np->parent && np->parent->name
1089 && strcasecmp(np->parent->name, "media-bay") == 0) {
1090#ifdef CONFIG_PMAC_MEDIABAY
1091 media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq,
1092 hwif);
1093#endif /* CONFIG_PMAC_MEDIABAY */
1094 pmif->mediabay = 1;
1095 if (!bidp) 1093 if (!bidp)
1096 pmif->aapl_bus_id = 1; 1094 pmif->aapl_bus_id = 1;
1097 } else if (pmif->kind == controller_ohare) { 1095 } else if (pmif->kind == controller_ohare) {
@@ -1100,9 +1098,7 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif,
1100 * units, I keep the old way 1098 * units, I keep the old way
1101 */ 1099 */
1102 ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1); 1100 ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1);
1103 } else 1101 } else {
1104#endif
1105 {
1106 /* This is necessary to enable IDE when net-booting */ 1102 /* This is necessary to enable IDE when net-booting */
1107 ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1); 1103 ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1);
1108 ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1); 1104 ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1);
@@ -1112,17 +1108,21 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif,
1112 } 1108 }
1113 1109
1114 printk(KERN_INFO DRV_NAME ": Found Apple %s controller (%s), " 1110 printk(KERN_INFO DRV_NAME ": Found Apple %s controller (%s), "
1115 "bus ID %d%s, irq %d\n", model_name[pmif->kind], 1111 "bus ID %d%s, irq %d\n", model_name[pmif->kind],
1116 pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id, 1112 pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id,
1117 pmif->mediabay ? " (mediabay)" : "", hw->irq); 1113 on_media_bay(pmif) ? " (mediabay)" : "", hw->irq);
1118 1114
1119 rc = ide_host_register(host, &d, hws); 1115 rc = ide_host_register(host, &d, hws);
1120 if (rc) { 1116 if (rc)
1121 ide_host_free(host); 1117 pmif->hwif = NULL;
1122 return rc;
1123 }
1124 1118
1125 return 0; 1119 if (pmif->mdev)
1120 unlock_media_bay(pmif->mdev->media_bay);
1121
1122 bail:
1123 if (rc && host)
1124 ide_host_free(host);
1125 return rc;
1126} 1126}
1127 1127
1128static void __devinit pmac_ide_init_ports(struct ide_hw *hw, unsigned long base) 1128static void __devinit pmac_ide_init_ports(struct ide_hw *hw, unsigned long base)
@@ -1362,6 +1362,25 @@ pmac_ide_pci_resume(struct pci_dev *pdev)
1362 return rc; 1362 return rc;
1363} 1363}
1364 1364
1365#ifdef CONFIG_PMAC_MEDIABAY
1366static void pmac_ide_macio_mb_event(struct macio_dev* mdev, int mb_state)
1367{
1368 pmac_ide_hwif_t *pmif =
1369 (pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
1370
1371 switch(mb_state) {
1372 case MB_CD:
1373 if (!pmif->hwif->present)
1374 ide_port_scan(pmif->hwif);
1375 break;
1376 default:
1377 if (pmif->hwif->present)
1378 ide_port_unregister_devices(pmif->hwif);
1379 }
1380}
1381#endif /* CONFIG_PMAC_MEDIABAY */
1382
1383
1365static struct of_device_id pmac_ide_macio_match[] = 1384static struct of_device_id pmac_ide_macio_match[] =
1366{ 1385{
1367 { 1386 {
@@ -1386,6 +1405,9 @@ static struct macio_driver pmac_ide_macio_driver =
1386 .probe = pmac_ide_macio_attach, 1405 .probe = pmac_ide_macio_attach,
1387 .suspend = pmac_ide_macio_suspend, 1406 .suspend = pmac_ide_macio_suspend,
1388 .resume = pmac_ide_macio_resume, 1407 .resume = pmac_ide_macio_resume,
1408#ifdef CONFIG_PMAC_MEDIABAY
1409 .mediabay_event = pmac_ide_macio_mb_event,
1410#endif
1389}; 1411};
1390 1412
1391static const struct pci_device_id pmac_ide_pci_match[] = { 1413static const struct pci_device_id pmac_ide_pci_match[] = {
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 029ad8ce8a7e..08002b88f342 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -33,15 +33,6 @@
33#include <linux/adb.h> 33#include <linux/adb.h>
34#include <linux/pmu.h> 34#include <linux/pmu.h>
35 35
36
37#define MB_DEBUG
38
39#ifdef MB_DEBUG
40#define MBDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg)
41#else
42#define MBDBG(fmt, arg...) do { } while (0)
43#endif
44
45#define MB_FCR32(bay, r) ((bay)->base + ((r) >> 2)) 36#define MB_FCR32(bay, r) ((bay)->base + ((r) >> 2))
46#define MB_FCR8(bay, r) (((volatile u8 __iomem *)((bay)->base)) + (r)) 37#define MB_FCR8(bay, r) (((volatile u8 __iomem *)((bay)->base)) + (r))
47 38
@@ -76,28 +67,14 @@ struct media_bay_info {
76 int index; 67 int index;
77 int cached_gpio; 68 int cached_gpio;
78 int sleeping; 69 int sleeping;
70 int user_lock;
79 struct mutex lock; 71 struct mutex lock;
80#ifdef CONFIG_BLK_DEV_IDE_PMAC
81 ide_hwif_t *cd_port;
82 void __iomem *cd_base;
83 int cd_irq;
84 int cd_retry;
85#endif
86#if defined(CONFIG_BLK_DEV_IDE_PMAC)
87 int cd_index;
88#endif
89}; 72};
90 73
91#define MAX_BAYS 2 74#define MAX_BAYS 2
92 75
93static struct media_bay_info media_bays[MAX_BAYS]; 76static struct media_bay_info media_bays[MAX_BAYS];
94int media_bay_count = 0; 77static int media_bay_count = 0;
95
96#ifdef CONFIG_BLK_DEV_IDE_PMAC
97/* check the busy bit in the media-bay ide interface
98 (assumes the media-bay contains an ide device) */
99#define MB_IDE_READY(i) ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0)
100#endif
101 78
102/* 79/*
103 * Wait that number of ms between each step in normal polling mode 80 * Wait that number of ms between each step in normal polling mode
@@ -130,21 +107,11 @@ int media_bay_count = 0;
130 107
131/* 108/*
132 * Wait this many ticks after an IDE device (e.g. CD-ROM) is inserted 109 * Wait this many ticks after an IDE device (e.g. CD-ROM) is inserted
133 * (or until the device is ready) before waiting for busy bit to disappear 110 * (or until the device is ready) before calling into the driver
134 */ 111 */
135#define MB_IDE_WAIT 1000 112#define MB_IDE_WAIT 1000
136 113
137/* 114/*
138 * Timeout waiting for busy bit of an IDE device to go down
139 */
140#define MB_IDE_TIMEOUT 5000
141
142/*
143 * Max retries of the full power up/down sequence for an IDE device
144 */
145#define MAX_CD_RETRIES 3
146
147/*
148 * States of a media bay 115 * States of a media bay
149 */ 116 */
150enum { 117enum {
@@ -153,7 +120,6 @@ enum {
153 mb_enabling_bay, /* enable bits set, waiting MB_RESET_DELAY */ 120 mb_enabling_bay, /* enable bits set, waiting MB_RESET_DELAY */
154 mb_resetting, /* reset bit unset, waiting MB_SETUP_DELAY */ 121 mb_resetting, /* reset bit unset, waiting MB_SETUP_DELAY */
155 mb_ide_resetting, /* IDE reset bit unser, waiting MB_IDE_WAIT */ 122 mb_ide_resetting, /* IDE reset bit unser, waiting MB_IDE_WAIT */
156 mb_ide_waiting, /* Waiting for BUSY bit to go away until MB_IDE_TIMEOUT */
157 mb_up, /* Media bay full */ 123 mb_up, /* Media bay full */
158 mb_powering_down /* Powering down (avoid too fast down/up) */ 124 mb_powering_down /* Powering down (avoid too fast down/up) */
159}; 125};
@@ -373,12 +339,12 @@ static inline void set_mb_power(struct media_bay_info* bay, int onoff)
373 if (onoff) { 339 if (onoff) {
374 bay->ops->power(bay, 1); 340 bay->ops->power(bay, 1);
375 bay->state = mb_powering_up; 341 bay->state = mb_powering_up;
376 MBDBG("mediabay%d: powering up\n", bay->index); 342 pr_debug("mediabay%d: powering up\n", bay->index);
377 } else { 343 } else {
378 /* Make sure everything is powered down & disabled */ 344 /* Make sure everything is powered down & disabled */
379 bay->ops->power(bay, 0); 345 bay->ops->power(bay, 0);
380 bay->state = mb_powering_down; 346 bay->state = mb_powering_down;
381 MBDBG("mediabay%d: powering down\n", bay->index); 347 pr_debug("mediabay%d: powering down\n", bay->index);
382 } 348 }
383 bay->timer = msecs_to_jiffies(MB_POWER_DELAY); 349 bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
384} 350}
@@ -387,107 +353,118 @@ static void poll_media_bay(struct media_bay_info* bay)
387{ 353{
388 int id = bay->ops->content(bay); 354 int id = bay->ops->content(bay);
389 355
390 if (id == bay->last_value) { 356 static char *mb_content_types[] = {
391 if (id != bay->content_id) { 357 "a floppy drive",
392 bay->value_count += msecs_to_jiffies(MB_POLL_DELAY); 358 "a floppy drive",
393 if (bay->value_count >= msecs_to_jiffies(MB_STABLE_DELAY)) { 359 "an unsuported audio device",
394 /* If the device type changes without going thru 360 "an ATA device",
395 * "MB_NO", we force a pass by "MB_NO" to make sure 361 "an unsupported PCI device",
396 * things are properly reset 362 "an unknown device",
397 */ 363 };
398 if ((id != MB_NO) && (bay->content_id != MB_NO)) { 364
399 id = MB_NO; 365 if (id != bay->last_value) {
400 MBDBG("mediabay%d: forcing MB_NO\n", bay->index);
401 }
402 MBDBG("mediabay%d: switching to %d\n", bay->index, id);
403 set_mb_power(bay, id != MB_NO);
404 bay->content_id = id;
405 if (id == MB_NO) {
406#ifdef CONFIG_BLK_DEV_IDE_PMAC
407 bay->cd_retry = 0;
408#endif
409 printk(KERN_INFO "media bay %d is empty\n", bay->index);
410 }
411 }
412 }
413 } else {
414 bay->last_value = id; 366 bay->last_value = id;
415 bay->value_count = 0; 367 bay->value_count = 0;
368 return;
369 }
370 if (id == bay->content_id)
371 return;
372
373 bay->value_count += msecs_to_jiffies(MB_POLL_DELAY);
374 if (bay->value_count >= msecs_to_jiffies(MB_STABLE_DELAY)) {
375 /* If the device type changes without going thru
376 * "MB_NO", we force a pass by "MB_NO" to make sure
377 * things are properly reset
378 */
379 if ((id != MB_NO) && (bay->content_id != MB_NO)) {
380 id = MB_NO;
381 pr_debug("mediabay%d: forcing MB_NO\n", bay->index);
382 }
383 pr_debug("mediabay%d: switching to %d\n", bay->index, id);
384 set_mb_power(bay, id != MB_NO);
385 bay->content_id = id;
386 if (id >= MB_NO || id < 0)
387 printk(KERN_INFO "mediabay%d: Bay is now empty\n", bay->index);
388 else
389 printk(KERN_INFO "mediabay%d: Bay contains %s\n",
390 bay->index, mb_content_types[id]);
416 } 391 }
417} 392}
418 393
419#ifdef CONFIG_BLK_DEV_IDE_PMAC 394int check_media_bay(struct macio_dev *baydev)
420int check_media_bay(struct device_node *which_bay, int what)
421{ 395{
422 int i; 396 struct media_bay_info* bay;
397 int id;
423 398
424 for (i=0; i<media_bay_count; i++) 399 if (baydev == NULL)
425 if (media_bays[i].mdev && which_bay == media_bays[i].mdev->ofdev.node) { 400 return MB_NO;
426 if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up) 401
427 return 0; 402 /* This returns an instant snapshot, not locking, sine
428 media_bays[i].cd_index = -1; 403 * we may be called with the bay lock held. The resulting
429 return -EINVAL; 404 * fuzzyness of the result if called at the wrong time is
430 } 405 * not actually a huge deal
431 return -ENODEV; 406 */
407 bay = macio_get_drvdata(baydev);
408 if (bay == NULL)
409 return MB_NO;
410 id = bay->content_id;
411 if (bay->state != mb_up)
412 return MB_NO;
413 if (id == MB_FD1)
414 return MB_FD;
415 return id;
432} 416}
433EXPORT_SYMBOL(check_media_bay); 417EXPORT_SYMBOL_GPL(check_media_bay);
434 418
435int check_media_bay_by_base(unsigned long base, int what) 419void lock_media_bay(struct macio_dev *baydev)
436{ 420{
437 int i; 421 struct media_bay_info* bay;
438
439 for (i=0; i<media_bay_count; i++)
440 if (media_bays[i].mdev && base == (unsigned long) media_bays[i].cd_base) {
441 if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up)
442 return 0;
443 media_bays[i].cd_index = -1;
444 return -EINVAL;
445 }
446 422
447 return -ENODEV; 423 if (baydev == NULL)
424 return;
425 bay = macio_get_drvdata(baydev);
426 if (bay == NULL)
427 return;
428 mutex_lock(&bay->lock);
429 bay->user_lock = 1;
448} 430}
449EXPORT_SYMBOL_GPL(check_media_bay_by_base); 431EXPORT_SYMBOL_GPL(lock_media_bay);
450 432
451int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, 433void unlock_media_bay(struct macio_dev *baydev)
452 int irq, ide_hwif_t *hwif)
453{ 434{
454 int i; 435 struct media_bay_info* bay;
455 436
456 for (i=0; i<media_bay_count; i++) { 437 if (baydev == NULL)
457 struct media_bay_info* bay = &media_bays[i]; 438 return;
458 439 bay = macio_get_drvdata(baydev);
459 if (bay->mdev && which_bay == bay->mdev->ofdev.node) { 440 if (bay == NULL)
460 int timeout = 5000, index = hwif->index; 441 return;
461 442 if (bay->user_lock) {
462 mutex_lock(&bay->lock); 443 bay->user_lock = 0;
463 444 mutex_unlock(&bay->lock);
464 bay->cd_port = hwif;
465 bay->cd_base = (void __iomem *) base;
466 bay->cd_irq = irq;
467
468 if ((MB_CD != bay->content_id) || bay->state != mb_up) {
469 mutex_unlock(&bay->lock);
470 return 0;
471 }
472 printk(KERN_DEBUG "Registered ide%d for media bay %d\n", index, i);
473 do {
474 if (MB_IDE_READY(i)) {
475 bay->cd_index = index;
476 mutex_unlock(&bay->lock);
477 return 0;
478 }
479 mdelay(1);
480 } while(--timeout);
481 printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i);
482 mutex_unlock(&bay->lock);
483 return -ENODEV;
484 }
485 } 445 }
446}
447EXPORT_SYMBOL_GPL(unlock_media_bay);
486 448
487 return -ENODEV; 449static int mb_broadcast_hotplug(struct device *dev, void *data)
450{
451 struct media_bay_info* bay = data;
452 struct macio_dev *mdev;
453 struct macio_driver *drv;
454 int state;
455
456 if (dev->bus != &macio_bus_type)
457 return 0;
458
459 state = bay->state == mb_up ? bay->content_id : MB_NO;
460 if (state == MB_FD1)
461 state = MB_FD;
462 mdev = to_macio_device(dev);
463 drv = to_macio_driver(dev->driver);
464 if (dev->driver && drv->mediabay_event)
465 drv->mediabay_event(mdev, state);
466 return 0;
488} 467}
489EXPORT_SYMBOL_GPL(media_bay_set_ide_infos);
490#endif /* CONFIG_BLK_DEV_IDE_PMAC */
491 468
492static void media_bay_step(int i) 469static void media_bay_step(int i)
493{ 470{
@@ -497,8 +474,8 @@ static void media_bay_step(int i)
497 if (bay->state != mb_powering_down) 474 if (bay->state != mb_powering_down)
498 poll_media_bay(bay); 475 poll_media_bay(bay);
499 476
500 /* If timer expired or polling IDE busy, run state machine */ 477 /* If timer expired run state machine */
501 if ((bay->state != mb_ide_waiting) && (bay->timer != 0)) { 478 if (bay->timer != 0) {
502 bay->timer -= msecs_to_jiffies(MB_POLL_DELAY); 479 bay->timer -= msecs_to_jiffies(MB_POLL_DELAY);
503 if (bay->timer > 0) 480 if (bay->timer > 0)
504 return; 481 return;
@@ -508,100 +485,50 @@ static void media_bay_step(int i)
508 switch(bay->state) { 485 switch(bay->state) {
509 case mb_powering_up: 486 case mb_powering_up:
510 if (bay->ops->setup_bus(bay, bay->last_value) < 0) { 487 if (bay->ops->setup_bus(bay, bay->last_value) < 0) {
511 MBDBG("mediabay%d: device not supported (kind:%d)\n", i, bay->content_id); 488 pr_debug("mediabay%d: device not supported (kind:%d)\n",
489 i, bay->content_id);
512 set_mb_power(bay, 0); 490 set_mb_power(bay, 0);
513 break; 491 break;
514 } 492 }
515 bay->timer = msecs_to_jiffies(MB_RESET_DELAY); 493 bay->timer = msecs_to_jiffies(MB_RESET_DELAY);
516 bay->state = mb_enabling_bay; 494 bay->state = mb_enabling_bay;
517 MBDBG("mediabay%d: enabling (kind:%d)\n", i, bay->content_id); 495 pr_debug("mediabay%d: enabling (kind:%d)\n", i, bay->content_id);
518 break; 496 break;
519 case mb_enabling_bay: 497 case mb_enabling_bay:
520 bay->ops->un_reset(bay); 498 bay->ops->un_reset(bay);
521 bay->timer = msecs_to_jiffies(MB_SETUP_DELAY); 499 bay->timer = msecs_to_jiffies(MB_SETUP_DELAY);
522 bay->state = mb_resetting; 500 bay->state = mb_resetting;
523 MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id); 501 pr_debug("mediabay%d: releasing bay reset (kind:%d)\n",
502 i, bay->content_id);
524 break; 503 break;
525 case mb_resetting: 504 case mb_resetting:
526 if (bay->content_id != MB_CD) { 505 if (bay->content_id != MB_CD) {
527 MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id); 506 pr_debug("mediabay%d: bay is up (kind:%d)\n", i,
507 bay->content_id);
528 bay->state = mb_up; 508 bay->state = mb_up;
509 device_for_each_child(&bay->mdev->ofdev.dev,
510 bay, mb_broadcast_hotplug);
529 break; 511 break;
530 } 512 }
531#ifdef CONFIG_BLK_DEV_IDE_PMAC 513 pr_debug("mediabay%d: releasing ATA reset (kind:%d)\n",
532 MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id); 514 i, bay->content_id);
533 bay->ops->un_reset_ide(bay); 515 bay->ops->un_reset_ide(bay);
534 bay->timer = msecs_to_jiffies(MB_IDE_WAIT); 516 bay->timer = msecs_to_jiffies(MB_IDE_WAIT);
535 bay->state = mb_ide_resetting; 517 bay->state = mb_ide_resetting;
536#else
537 printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i);
538 set_mb_power(bay, 0);
539#endif /* CONFIG_BLK_DEV_IDE_PMAC */
540 break; 518 break;
541#ifdef CONFIG_BLK_DEV_IDE_PMAC 519
542 case mb_ide_resetting: 520 case mb_ide_resetting:
543 bay->timer = msecs_to_jiffies(MB_IDE_TIMEOUT); 521 pr_debug("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
544 bay->state = mb_ide_waiting; 522 bay->state = mb_up;
545 MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id); 523 device_for_each_child(&bay->mdev->ofdev.dev,
524 bay, mb_broadcast_hotplug);
546 break; 525 break;
547 case mb_ide_waiting: 526
548 if (bay->cd_base == NULL) {
549 bay->timer = 0;
550 bay->state = mb_up;
551 MBDBG("mediabay%d: up before IDE init\n", i);
552 break;
553 } else if (MB_IDE_READY(i)) {
554 bay->timer = 0;
555 bay->state = mb_up;
556 if (bay->cd_index < 0) {
557 printk("mediabay %d, registering IDE...\n", i);
558 pmu_suspend();
559 ide_port_scan(bay->cd_port);
560 if (bay->cd_port->present)
561 bay->cd_index = bay->cd_port->index;
562 pmu_resume();
563 }
564 if (bay->cd_index == -1) {
565 /* We eventually do a retry */
566 bay->cd_retry++;
567 printk("IDE register error\n");
568 set_mb_power(bay, 0);
569 } else {
570 printk(KERN_DEBUG "media-bay %d is ide%d\n", i, bay->cd_index);
571 MBDBG("mediabay %d IDE ready\n", i);
572 }
573 break;
574 } else if (bay->timer > 0)
575 bay->timer -= msecs_to_jiffies(MB_POLL_DELAY);
576 if (bay->timer <= 0) {
577 printk("\nIDE Timeout in bay %d !, IDE state is: 0x%02x\n",
578 i, readb(bay->cd_base + 0x70));
579 MBDBG("mediabay%d: nIDE Timeout !\n", i);
580 set_mb_power(bay, 0);
581 bay->timer = 0;
582 }
583 break;
584#endif /* CONFIG_BLK_DEV_IDE_PMAC */
585 case mb_powering_down: 527 case mb_powering_down:
586 bay->state = mb_empty; 528 bay->state = mb_empty;
587#ifdef CONFIG_BLK_DEV_IDE_PMAC 529 device_for_each_child(&bay->mdev->ofdev.dev,
588 if (bay->cd_index >= 0) { 530 bay, mb_broadcast_hotplug);
589 printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i, 531 pr_debug("mediabay%d: end of power down\n", i);
590 bay->cd_index);
591 ide_port_unregister_devices(bay->cd_port);
592 bay->cd_index = -1;
593 }
594 if (bay->cd_retry) {
595 if (bay->cd_retry > MAX_CD_RETRIES) {
596 /* Should add an error sound (sort of beep in dmasound) */
597 printk("\nmedia-bay %d, IDE device badly inserted or unrecognised\n", i);
598 } else {
599 /* Force a new power down/up sequence */
600 bay->content_id = MB_NO;
601 }
602 }
603#endif /* CONFIG_BLK_DEV_IDE_PMAC */
604 MBDBG("mediabay%d: end of power down\n", i);
605 break; 532 break;
606 } 533 }
607} 534}
@@ -676,11 +603,6 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de
676 bay->last_value = bay->ops->content(bay); 603 bay->last_value = bay->ops->content(bay);
677 bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY); 604 bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
678 bay->state = mb_empty; 605 bay->state = mb_empty;
679 do {
680 msleep(MB_POLL_DELAY);
681 media_bay_step(i);
682 } while((bay->state != mb_empty) &&
683 (bay->state != mb_up));
684 606
685 /* Mark us ready by filling our mdev data */ 607 /* Mark us ready by filling our mdev data */
686 macio_set_drvdata(mdev, bay); 608 macio_set_drvdata(mdev, bay);
@@ -725,7 +647,7 @@ static int media_bay_resume(struct macio_dev *mdev)
725 set_mb_power(bay, 0); 647 set_mb_power(bay, 0);
726 msleep(MB_POWER_DELAY); 648 msleep(MB_POWER_DELAY);
727 if (bay->ops->content(bay) != bay->content_id) { 649 if (bay->ops->content(bay) != bay->content_id) {
728 printk("mediabay%d: content changed during sleep...\n", bay->index); 650 printk("mediabay%d: Content changed during sleep...\n", bay->index);
729 mutex_unlock(&bay->lock); 651 mutex_unlock(&bay->lock);
730 return 0; 652 return 0;
731 } 653 }
@@ -733,9 +655,6 @@ static int media_bay_resume(struct macio_dev *mdev)
733 bay->last_value = bay->content_id; 655 bay->last_value = bay->content_id;
734 bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY); 656 bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
735 bay->timer = msecs_to_jiffies(MB_POWER_DELAY); 657 bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
736#ifdef CONFIG_BLK_DEV_IDE_PMAC
737 bay->cd_retry = 0;
738#endif
739 do { 658 do {
740 msleep(MB_POLL_DELAY); 659 msleep(MB_POLL_DELAY);
741 media_bay_step(bay->index); 660 media_bay_step(bay->index);
@@ -823,9 +742,6 @@ static int __init media_bay_init(void)
823 for (i=0; i<MAX_BAYS; i++) { 742 for (i=0; i<MAX_BAYS; i++) {
824 memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info)); 743 memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info));
825 media_bays[i].content_id = -1; 744 media_bays[i].content_id = -1;
826#ifdef CONFIG_BLK_DEV_IDE_PMAC
827 media_bays[i].cd_index = -1;
828#endif
829 } 745 }
830 if (!machine_is(powermac)) 746 if (!machine_is(powermac))
831 return 0; 747 return 0;