aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/swim3.c
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 /drivers/block/swim3.c
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>
Diffstat (limited to 'drivers/block/swim3.c')
-rw-r--r--drivers/block/swim3.c39
1 files changed, 16 insertions, 23 deletions
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